Files
education/frontend/node_modules/.cache/vue-loader/59090f3535c69e29bdef09ddb121c28b.json
T

1 line
22 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"remainingRequest":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!C:\\Users\\Admin\\Desktop\\education\\frontend\\src\\views\\teachBusiness\\timetable\\index.vue?vue&type=style&index=0&id=7658b300&scoped=true&lang=scss","dependencies":[{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\src\\views\\teachBusiness\\timetable\\index.vue","mtime":1787648748775},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\css-loader\\dist\\cjs.js","mtime":1787309792478},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\loaders\\stylePostLoader.js","mtime":1787309794547},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\postcss-loader\\src\\index.js","mtime":1787309793084},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\sass-loader\\dist\\cjs.js","mtime":1787309791955},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\cache-loader\\dist\\cjs.js","mtime":1787309791955},{"path":"C:\\Users\\Admin\\Desktop\\education\\frontend\\node_modules\\vue-loader\\lib\\index.js","mtime":1787309793790}],"contextDependencies":[],"result":[{"type":"Buffer","data":"base64:CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoNCi50aW1ldGFibGUtcGFnZSB7DQogIC50aW1ldGFibGUtdGFicyB7DQogICAgYmFja2dyb3VuZDogI2ZmZjsNCiAgICBwYWRkaW5nOiAwIDE2cHg7DQogICAgYm9yZGVyOiAxcHggc29saWQgI2ViZWVmNTsNCiAgICBib3JkZXItcmFkaXVzOiA2cHg7DQogIH0NCg0KICAudGFiLWJvZHkgew0KICAgIHBhZGRpbmctYm90dG9tOiAxNnB4Ow0KICB9DQoNCiAgLnN1Yi10ZXh0IHsNCiAgICBmb250LXNpemU6IDEycHg7DQogICAgY29sb3I6ICM5MDkzOTk7DQogICAgbWFyZ2luLXRvcDogMnB4Ow0KICB9DQoNCiAgLyog5pel5pyfL+WRqOasoeWvvOiIqiAqLw0KICAuZGF0ZS1oZWFkZXIsDQogIC53ZWVrLWhlYWRlciB7DQogICAgZGlzcGxheTogZmxleDsNCiAgICBhbGlnbi1pdGVtczogY2VudGVyOw0KICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOw0KICAgIGdhcDogMjRweDsNCiAgICBtYXJnaW4tYm90dG9tOiAxMnB4Ow0KICAgIHBhZGRpbmc6IDE0cHggMTZweDsNCiAgICBiYWNrZ3JvdW5kOiAjZmFmYWZhOw0KICAgIGJvcmRlcjogMXB4IHNvbGlkICNlYmVlZjU7DQogICAgYm9yZGVyLXJhZGl1czogNHB4Ow0KDQogICAgLm5hdi1saW5rIHsNCiAgICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgICB9DQoNCiAgICAuZGF0ZS10aXRsZSwNCiAgICAud2Vlay10aXRsZSB7DQogICAgICBmb250LXNpemU6IDE2cHg7DQogICAgICBmb250LXdlaWdodDogNzAwOw0KICAgICAgY29sb3I6ICMzMDMxMzM7DQogICAgfQ0KICB9DQoNCiAgLyog54+t5qyhICovDQogIC5zZWFyY2gtY2FyZCB7DQogICAgbWFyZ2luLWJvdHRvbTogMTJweDsNCg0KICAgIC5zZWFyY2gtZm9ybSB7DQogICAgICBtYXJnaW4tYm90dG9tOiAwOw0KICAgIH0NCg0KICAgIC5zaGlmdC1zZWxlY3Qgew0KICAgICAgd2lkdGg6IDI0MHB4Ow0KICAgIH0NCiAgfQ0KDQogIC5wYWdlLXRpdGxlIHsNCiAgICBmb250LXNpemU6IDE3cHg7DQogICAgZm9udC13ZWlnaHQ6IDcwMDsNCiAgICBjb2xvcjogIzMwMzEzMzsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogICAgbWFyZ2luLWJvdHRvbTogMTJweDsNCiAgfQ0KDQogIC5hY3Rpb24tY2FyZCB7DQogICAgbWFyZ2luLWJvdHRvbTogMTJweDsNCg0KICAgIC5idXR0b24tcm93IHsNCiAgICAgIGRpc3BsYXk6IGZsZXg7DQogICAgICBmbGV4LXdyYXA6IHdyYXA7DQogICAgICBnYXA6IDhweDsNCiAgICB9DQogIH0NCn0NCg=="},{"version":3,"sources":["index.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0XA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.vue","sourceRoot":"src/views/teachBusiness/timetable","sourcesContent":["<template>\r\n <div class=\"app-container timetable-page\">\r\n <el-tabs v-model=\"activeTab\" class=\"timetable-tabs\">\r\n <!-- ==================== 今日教学实施计划 ==================== -->\r\n <el-tab-pane label=\"今日教学实施计划\" name=\"today\">\r\n <div class=\"tab-body\">\r\n <div class=\"date-header\">\r\n <el-link type=\"primary\" :underline=\"false\" class=\"nav-link\" @click=\"handlePrevDay\">前一天</el-link>\r\n <div class=\"date-title\">{{ dateTitle }}</div>\r\n <el-link type=\"primary\" :underline=\"false\" class=\"nav-link\" @click=\"handleNextDay\">后一天</el-link>\r\n </div>\r\n\r\n <div class=\"table-card\">\r\n <el-table :data=\"todayData\" v-loading=\"loading\" stripe border>\r\n <el-table-column type=\"index\" label=\"序号\" width=\"55\" align=\"center\" />\r\n <el-table-column label=\"上课时间\" width=\"130\" align=\"center\">\r\n <template #default=\"{ row }\">{{ formatJc(row.jc) }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"kcmc\" label=\"课程\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"zrdw\" label=\"责任单位\" width=\"110\" align=\"center\" />\r\n <el-table-column prop=\"bc\" label=\"班次\" width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"skjy\" label=\"教员\" width=\"90\" align=\"center\" />\r\n <el-table-column label=\"场地\" width=\"140\" align=\"center\" show-overflow-tooltip>\r\n <template #default=\"{ row }\">{{ row.jxcd || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column label=\"教学内容方法\" min-width=\"160\" show-overflow-tooltip header-align=\"center\">\r\n <template #default=\"{ row }\">{{ row.jxnrff || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"jybz\" label=\"备注\" width=\"100\" show-overflow-tooltip header-align=\"center\">\r\n <template #default=\"{ row }\">{{ row.jybz || '-' }}</template>\r\n </el-table-column>\r\n </el-table>\r\n <el-empty v-show=\"!loading && !todayData.length\" description=\"暂无教学计划数据\" />\r\n </div>\r\n </div>\r\n </el-tab-pane>\r\n\r\n <!-- ==================== 本周教学实施计划 ==================== -->\r\n <el-tab-pane label=\"本周教学实施计划\" name=\"week\">\r\n <div class=\"tab-body\">\r\n <div class=\"week-header\">\r\n <el-link type=\"primary\" :underline=\"false\" class=\"nav-link\" @click=\"handlePrevWeek\">上一周</el-link>\r\n <div class=\"week-title\">{{ weekRangeText }}</div>\r\n <el-link type=\"primary\" :underline=\"false\" class=\"nav-link\" @click=\"handleNextWeek\">下一周</el-link>\r\n </div>\r\n\r\n <div class=\"table-card\">\r\n <el-table :data=\"weekData\" v-loading=\"loading\" stripe border>\r\n <el-table-column type=\"index\" label=\"序号\" width=\"55\" align=\"center\" />\r\n <el-table-column label=\"上课时间\" width=\"170\" align=\"center\" show-overflow-tooltip>\r\n <template #default=\"{ row }\">{{ row.sjsj || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"kcmc\" label=\"课程\" min-width=\"130\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"zrdw\" label=\"责任单位\" width=\"100\" align=\"center\" />\r\n <el-table-column prop=\"bc\" label=\"班次\" width=\"130\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"skjy\" label=\"教员\" width=\"90\" align=\"center\" />\r\n <el-table-column label=\"场地\" width=\"140\" align=\"center\" show-overflow-tooltip>\r\n <template #default=\"{ row }\">{{ row.jxcd || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column label=\"教学内容方法\" min-width=\"150\" show-overflow-tooltip header-align=\"center\">\r\n <template #default=\"{ row }\">{{ row.jxnrff || '-' }}</template>\r\n </el-table-column>\r\n <el-table-column prop=\"jybz\" label=\"备注\" width=\"100\" show-overflow-tooltip header-align=\"center\">\r\n <template #default=\"{ row }\">{{ row.jybz || '-' }}</template>\r\n </el-table-column>\r\n </el-table>\r\n <el-empty v-show=\"!loading && !weekData.length\" description=\"本周暂无教学计划数据\" />\r\n </div>\r\n </div>\r\n </el-tab-pane>\r\n\r\n <!-- ==================== 教学班次教学实施计划 ==================== -->\r\n <el-tab-pane label=\"教学班次教学实施计划\" name=\"shift\">\r\n <div class=\"tab-body\">\r\n <!-- 选择条件 -->\r\n <div class=\"search-card\">\r\n <el-form :model=\"searchForm\" inline class=\"search-form\">\r\n <el-form-item label=\"队别班次\">\r\n <el-select v-model=\"searchForm.teamClass\" placeholder=\"请选择队别班次\" clearable filterable class=\"shift-select\">\r\n <el-option v-for=\"item in teamClassOptions\" :key=\"item\" :label=\"item\" :value=\"item\" />\r\n </el-select>\r\n </el-form-item>\r\n <el-form-item>\r\n <el-button type=\"primary\" icon=\"el-icon-search\" size=\"mini\" @click=\"handleQuery\">查询</el-button>\r\n </el-form-item>\r\n </el-form>\r\n </div>\r\n\r\n <!-- 标题 -->\r\n <div class=\"page-title\">{{ pageTitle }}</div>\r\n\r\n <!-- 下载操作按钮 -->\r\n <el-card shadow=\"never\" class=\"action-card\">\r\n <div class=\"button-row\">\r\n <el-button type=\"primary\" plain size=\"mini\" @click=\"handleExportPlan\">学期教学实施计划</el-button>\r\n <el-button type=\"primary\" plain size=\"mini\" @click=\"handleExportGrades\">学期成绩表</el-button>\r\n <el-button type=\"primary\" plain size=\"mini\" @click=\"handleExportCourses\">课程列表另存Excel</el-button>\r\n </div>\r\n </el-card>\r\n\r\n <!-- 数据表格 -->\r\n <div class=\"table-card\">\r\n <el-table :data=\"shiftData\" v-loading=\"loading\" border stripe style=\"width: 100%\">\r\n <el-table-column type=\"index\" label=\"序号\" width=\"60\" align=\"center\" />\r\n <el-table-column label=\"课程名称/课时系数\" min-width=\"220\" align=\"center\">\r\n <template #default=\"{ row }\">\r\n <div>{{ row.kcmc || '-' }}</div>\r\n <div class=\"sub-text\">{{ row.kssk || '-' }}</div>\r\n </template>\r\n </el-table-column>\r\n <el-table-column prop=\"zrjs\" label=\"责任教员/课次\" min-width=\"150\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"bc\" label=\"班次\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"nj\" label=\"年级\" width=\"80\" align=\"center\" />\r\n <el-table-column prop=\"zy\" label=\"专业\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"jhxs\" label=\"计划学时\" width=\"90\" align=\"center\" />\r\n <el-table-column prop=\"yxxs\" label=\"运行学时\" width=\"90\" align=\"center\" />\r\n <el-table-column prop=\"khlxfs\" label=\"考核类型方式\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"ssjs\" label=\"实施教员\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"rscd\" label=\"人数/场地\" min-width=\"140\" align=\"center\" show-overflow-tooltip />\r\n <el-table-column prop=\"kcjd\" label=\"课程进度\" width=\"120\" align=\"center\" />\r\n <el-table-column prop=\"ssjhbg\" label=\"实施计划变更\" min-width=\"120\" align=\"center\" show-overflow-tooltip />\r\n </el-table>\r\n <el-empty v-show=\"!loading && !shiftData.length\" description=\"请选择队别班次后查询\" />\r\n </div>\r\n </div>\r\n </el-tab-pane>\r\n </el-tabs>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nimport { listToday, listWeek, listClass, exportClassPlan, exportClassGrades, exportClassCourses } from '@/api/teachBusiness/timetable'\r\nimport { listTeam } from '@/api/studentRecords/team'\r\n\r\nconst JC_SECTION = {\r\n 1: '1-2节', 2: '3-4节', 3: '5-6节', 4: '7-8节', 5: '9-10节', 6: '11-12节'\r\n}\r\n\r\nconst WEEK_DAY_NAMES = ['日', '一', '二', '三', '四', '五', '六']\r\n\r\nfunction pad2(n) {\r\n return n < 10 ? '0' + n : '' + n\r\n}\r\n\r\nfunction formatDate(d) {\r\n return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate())\r\n}\r\n\r\nfunction getMonday(d) {\r\n const day = d.getDay() || 7\r\n const monday = new Date(d)\r\n monday.setDate(d.getDate() - day + 1)\r\n return monday\r\n}\r\n\r\nexport default {\r\n name: 'Timetable',\r\n data() {\r\n return {\r\n activeTab: 'today',\r\n loading: false,\r\n // 今日\r\n todayDate: new Date(),\r\n todayData: [],\r\n // 本周\r\n weekStart: getMonday(new Date()),\r\n weekData: [],\r\n // 班次\r\n searchForm: { teamClass: '' },\r\n teamClassOptions: [],\r\n teamMap: {},\r\n shiftData: []\r\n }\r\n },\r\n computed: {\r\n dateTitle() {\r\n return formatDate(this.todayDate) + ' 今日教学实施计划'\r\n },\r\n weekRangeText() {\r\n const end = new Date(this.weekStart)\r\n end.setDate(end.getDate() + 6)\r\n return formatDate(this.weekStart) + '(' + this.weekDayName(this.weekStart) + ') 至 ' +\r\n formatDate(end) + '(' + this.weekDayName(end) + ') 本周教学实施计划'\r\n },\r\n pageTitle() {\r\n const name = this.searchForm.teamClass || ''\r\n return (name ? name + ' ' : '') + '教学班次教学实施计划'\r\n }\r\n },\r\n created() {\r\n this.loadTeamOptions()\r\n this.getTodayList()\r\n this.getWeekList()\r\n },\r\n methods: {\r\n weekDayName(d) {\r\n return WEEK_DAY_NAMES[d.getDay()]\r\n },\r\n formatJc(jc) {\r\n if (jc === null || jc === undefined || jc === '') return '第?节'\r\n return JC_SECTION[jc] || ('第' + jc + '节')\r\n },\r\n /* ---------- 今日:日期导航 ---------- */\r\n handlePrevDay() {\r\n const d = new Date(this.todayDate)\r\n d.setDate(d.getDate() - 1)\r\n this.todayDate = d\r\n this.getTodayList()\r\n },\r\n handleNextDay() {\r\n const d = new Date(this.todayDate)\r\n d.setDate(d.getDate() + 1)\r\n this.todayDate = d\r\n this.getTodayList()\r\n },\r\n /* ---------- 本周:周次导航 ---------- */\r\n handlePrevWeek() {\r\n const d = new Date(this.weekStart)\r\n d.setDate(d.getDate() - 7)\r\n this.weekStart = d\r\n this.getWeekList()\r\n },\r\n handleNextWeek() {\r\n const d = new Date(this.weekStart)\r\n d.setDate(d.getDate() + 7)\r\n this.weekStart = d\r\n this.getWeekList()\r\n },\r\n /* ---------- 队别班次下拉(真实接口) ---------- */\r\n loadTeamOptions() {\r\n listTeam({ pageNum: 1, pageSize: 1000 }).then(response => {\r\n const data = response.data || {}\r\n const list = data.records || []\r\n const map = {}\r\n ;(list || []).forEach(item => {\r\n if (item.xydmc) map[item.xydmc] = item.xydbh\r\n })\r\n this.teamMap = map\r\n this.teamClassOptions = list.map(item => item.xydmc).filter(Boolean)\r\n }).catch(() => {\r\n this.teamMap = {}\r\n this.teamClassOptions = []\r\n })\r\n },\r\n /* ---------- 数据字段映射(接口字段 -> 页面字段) ---------- */\r\n parseSection(sksj) {\r\n const m = String(sksj || '').match(/第(\\d+)节/)\r\n return m ? Number(m[1]) : undefined\r\n },\r\n mapLessonRow(apiRow) {\r\n // 接口今日/本周实体:bh sksj kc zrdw bc jy cd jxnrxff bz\r\n const row = Object.assign({}, apiRow)\r\n row.kcmc = apiRow.kc\r\n row.skjy = apiRow.jy\r\n row.jxcd = apiRow.cd\r\n row.jxnrff = apiRow.jxnrxff\r\n row.jybz = apiRow.bz\r\n row.sjsj = apiRow.sksj\r\n row.jc = this.parseSection(apiRow.sksj)\r\n return row\r\n },\r\n mapClassRow(apiRow) {\r\n // 接口班次实体:sskcbh kcmcksxs zrjykc jhxs yxxs khlxfs ssjy rscd ssjhbg\r\n const row = Object.assign({}, apiRow)\r\n const parts = String(apiRow.kcmcksxs || '').split(' / ')\r\n row.kcmc = parts[0] || '-'\r\n row.kssk = parts[1] || '-'\r\n row.zrjs = apiRow.zrjykc\r\n row.ssjs = apiRow.ssjy\r\n return row\r\n },\r\n /* ---------- 今日:拉取数据 ---------- */\r\n getTodayList() {\r\n this.loading = true\r\n listToday({}).then(response => {\r\n const data = response.data\r\n this.todayData = Array.isArray(data)\r\n ? (data || []).map(item => this.mapLessonRow(item))\r\n : ((data && data.records) || []).map(item => this.mapLessonRow(item))\r\n this.loading = false\r\n }).catch(() => {\r\n this.todayData = []\r\n this.loading = false\r\n })\r\n },\r\n /* ---------- 本周:拉取数据 ---------- */\r\n getWeekList() {\r\n this.loading = true\r\n listWeek({}).then(response => {\r\n const data = response.data\r\n this.weekData = Array.isArray(data)\r\n ? (data || []).map(item => this.mapLessonRow(item))\r\n : ((data && data.records) || []).map(item => this.mapLessonRow(item))\r\n this.loading = false\r\n }).catch(() => {\r\n this.weekData = []\r\n this.loading = false\r\n })\r\n },\r\n /* ---------- 班次:拉取数据 ---------- */\r\n getShiftList() {\r\n if (!this.searchForm.teamClass) return\r\n const xydbh = this.teamMap[this.searchForm.teamClass] || this.searchForm.teamClass\r\n const params = { xydbh: xydbh, pageNum: 1, pageSize: 1000 }\r\n this.loading = true\r\n listClass(params).then(response => {\r\n const data = response.data || {}\r\n this.shiftData = (data.records || []).map(item => this.mapClassRow(item))\r\n this.loading = false\r\n }).catch(() => {\r\n this.shiftData = []\r\n this.loading = false\r\n })\r\n },\r\n /* ---------- 班次:查询 ---------- */\r\n handleQuery() {\r\n if (!this.searchForm.teamClass) {\r\n this.$message.warning('请先选择队别班次')\r\n return\r\n }\r\n this.getShiftList()\r\n },\r\n /* ---------- 下载 ---------- */\r\n downloadBlob(blob, filename) {\r\n const link = document.createElement('a')\r\n link.href = window.URL.createObjectURL(blob)\r\n link.download = filename\r\n document.body.appendChild(link)\r\n link.click()\r\n document.body.removeChild(link)\r\n window.URL.revokeObjectURL(link.href)\r\n },\r\n shiftQueryParams() {\r\n if (!this.searchForm.teamClass) return null\r\n const xydbh = this.teamMap[this.searchForm.teamClass] || this.searchForm.teamClass\r\n return { xydbh: xydbh }\r\n },\r\n /** 下载学期教学实施计划 Excel(GET /kcb/class/export-plan) */\r\n handleExportPlan() {\r\n const params = this.shiftQueryParams()\r\n if (!params) {\r\n this.$message.warning('请先选择队别班次')\r\n return\r\n }\r\n exportClassPlan(params).then(blob => {\r\n this.downloadBlob(blob, '学期教学实施计划.xlsx')\r\n this.$message.success('学期教学实施计划导出成功')\r\n }).catch(() => {})\r\n },\r\n /** 下载学期成绩表 Excel(GET /kcb/class/export-grades) */\r\n handleExportGrades() {\r\n const params = this.shiftQueryParams()\r\n if (!params) {\r\n this.$message.warning('请先选择队别班次')\r\n return\r\n }\r\n exportClassGrades(params).then(blob => {\r\n this.downloadBlob(blob, '学期成绩表.xlsx')\r\n this.$message.success('学期成绩表导出成功')\r\n }).catch(() => {})\r\n },\r\n /** 班次课程列表另存 Excel(GET /kcb/class/export-courses) */\r\n handleExportCourses() {\r\n const params = this.shiftQueryParams()\r\n if (!params) {\r\n this.$message.warning('请先选择队别班次')\r\n return\r\n }\r\n exportClassCourses(params).then(blob => {\r\n this.downloadBlob(blob, '班次课程列表.xlsx')\r\n this.$message.success('班次课程列表导出成功')\r\n }).catch(() => {})\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n.timetable-page {\r\n .timetable-tabs {\r\n background: #fff;\r\n padding: 0 16px;\r\n border: 1px solid #ebeef5;\r\n border-radius: 6px;\r\n }\r\n\r\n .tab-body {\r\n padding-bottom: 16px;\r\n }\r\n\r\n .sub-text {\r\n font-size: 12px;\r\n color: #909399;\r\n margin-top: 2px;\r\n }\r\n\r\n /* 日期/周次导航 */\r\n .date-header,\r\n .week-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 24px;\r\n margin-bottom: 12px;\r\n padding: 14px 16px;\r\n background: #fafafa;\r\n border: 1px solid #ebeef5;\r\n border-radius: 4px;\r\n\r\n .nav-link {\r\n font-size: 14px;\r\n }\r\n\r\n .date-title,\r\n .week-title {\r\n font-size: 16px;\r\n font-weight: 700;\r\n color: #303133;\r\n }\r\n }\r\n\r\n /* 班次 */\r\n .search-card {\r\n margin-bottom: 12px;\r\n\r\n .search-form {\r\n margin-bottom: 0;\r\n }\r\n\r\n .shift-select {\r\n width: 240px;\r\n }\r\n }\r\n\r\n .page-title {\r\n font-size: 17px;\r\n font-weight: 700;\r\n color: #303133;\r\n text-align: center;\r\n margin-bottom: 12px;\r\n }\r\n\r\n .action-card {\r\n margin-bottom: 12px;\r\n\r\n .button-row {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n }\r\n }\r\n}\r\n</style>\r\n"]}]}