diff --git a/frontend/src/api/teachBusiness/timetable.js b/frontend/src/api/teachBusiness/timetable.js
new file mode 100644
index 000000000..4dca5ab93
--- /dev/null
+++ b/frontend/src/api/teachBusiness/timetable.js
@@ -0,0 +1,89 @@
+import request from '@/utils/request'
+
+// 课表查询管理(KCBController /kcb,前端 baseURL 为 /api,此处不重复 /api 前缀)
+// 接口依据:课表页面接口规格
+// 查询实体 TimetableQuery:nd 年度(可选,不传自动取当前学期)、xydbh 学员队编号/班次(可选,按班次筛选)
+
+/**
+ * 今日课表
+ * GET /kcb/today/list
+ * @param params TimetableQuery:nd、xydbh(均可选)
+ * 返回:今日课表记录(实体字段 bh/sksj/kc/zrdw/bc/jy/cd/jxnrxff/bz)
+ */
+export function listToday(data) {
+ return request({
+ url: '/kcb/today/list',
+ method: 'get',
+ params: data
+ })
+}
+
+/**
+ * 本周课表
+ * GET /kcb/week/list
+ * @param params TimetableQuery:nd、xydbh(均可选)
+ * 返回:本周课表记录
+ */
+export function listWeek(data) {
+ return request({
+ url: '/kcb/week/list',
+ method: 'get',
+ params: data
+ })
+}
+
+/**
+ * 班次课表(分页)
+ * GET /kcb/class/list
+ * @param params pageNum、pageSize,cond=TimetableQuery:nd、xydbh
+ * 返回:PageResult<班次课程记录>(records/total)
+ */
+export function listClass(params) {
+ return request({
+ url: '/kcb/class/list',
+ method: 'get',
+ params
+ })
+}
+
+/**
+ * 下载学期教学实施计划 Excel
+ * GET /kcb/class/export-plan
+ * @param data TimetableQuery:nd、xydbh
+ */
+export function exportClassPlan(data) {
+ return request({
+ url: '/kcb/class/export-plan',
+ method: 'get',
+ params: data,
+ responseType: 'blob'
+ })
+}
+
+/**
+ * 下载学期成绩表 Excel
+ * GET /kcb/class/export-grades
+ * @param data TimetableQuery:nd、xydbh
+ */
+export function exportClassGrades(data) {
+ return request({
+ url: '/kcb/class/export-grades',
+ method: 'get',
+ params: data,
+ responseType: 'blob'
+ })
+}
+
+/**
+ * 班次课程列表另存 Excel
+ * GET /kcb/class/export-courses
+ * @param data TimetableQuery:nd、xydbh
+ */
+export function exportClassCourses(data) {
+ return request({
+ url: '/kcb/class/export-courses',
+ method: 'get',
+ params: data,
+ responseType: 'blob'
+ })
+}
\ No newline at end of file
diff --git a/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue b/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue
index 5b1f45f3b..e7a47594f 100644
--- a/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue
+++ b/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue
@@ -18,7 +18,7 @@
事件名称:
-
加粗显示
+
加粗显示
可排课
正课
备注显示
@@ -74,18 +74,8 @@
:data-key="cellKey(wIdx, col.colIndex)"
@dblclick="onCellDblClick(wIdx, col)"
>
-
{{ getEvent(wIdx, col.colIndex).name }}
+
{{ getEvent(wIdx, col.colIndex).name }}
{{ dateNumberOf(wIdx, col.dayIndex) }}
-
-
@@ -147,8 +137,6 @@ export default {
totalWeeks: 0,
dateRangeText: '',
weeks: [],
- // 加粗显示:全局开关,勾选后所有有事件的格子事件名加粗(纯前端效果,不持久化)
- boldDisplay: false,
// 显示开关(默认不勾选,每天仅显示 1-2/3-4/5-6 三个节次)
show78: false,
showNight: false,
@@ -156,6 +144,7 @@ export default {
// 工具栏表单
toolbar: {
eventName: '',
+ bold: false,
schedulable: false,
mainCourse: false,
remarkShow: false,
@@ -163,6 +152,8 @@ export default {
},
// 事件存储:key = cellKey -> event
events: {},
+ // 暂存被隐藏节次列上的事件:key = 周-星期-节次 -> event,列再次显示时恢复
+ hiddenEvents: {},
// 选择集(用数组以保证 Vue2 响应式)
selectedKeys: [],
// 拖拽状态
@@ -188,6 +179,10 @@ export default {
})
})
return cols
+ },
+ // xqxlb 的年度(nd)为年份(如 2026),由 6 位学期代号(如 202601)截取前 4 位得出
+ xqxlbNd() {
+ return Number(String(this.nd).slice(0, 4))
}
},
watch: {
@@ -197,7 +192,43 @@ export default {
if (val) this.loadSemester()
}
},
- visibleColumns() {
+ visibleColumns(newCols, oldCols) {
+ // 节次列显隐会改变列索引,按「周期-星期-节次」重定位事件,避免事件随时间格列偏移
+ if (oldCols && oldCols.length) {
+ const oldPosOf = index => (oldCols[index] || null)
+ const newIndex = (dayIndex, slotKey) => {
+ const c = newCols.find(x => x.dayIndex === dayIndex && x.slotKey === slotKey)
+ return c ? c.colIndex : -1
+ }
+ const next = {}
+ Object.keys(this.events).forEach(key => {
+ const m = key.match(/^w(\d+)-c(\d+)$/)
+ if (!m) return
+ const wIdx = +m[1]
+ const old = oldPosOf(+m[2])
+ if (!old) return
+ const newC = newIndex(old.dayIndex, old.slotKey)
+ if (newC < 0) {
+ // 该节次列被隐藏:事件暂存,待列再次显示时恢复
+ this.hiddenEvents[this.cellStableKey(wIdx, old.dayIndex, old.slotKey)] = this.events[key]
+ return
+ }
+ next['w' + wIdx + '-c' + newC] = this.events[key]
+ })
+ // 恢复重新显示的隐藏节次事件
+ Object.keys(this.hiddenEvents).forEach(stable => {
+ const p = stable.split('-')
+ const wIdx = +p[0]
+ const dayIndex = +p[1]
+ const slotKey = p[2]
+ const newC = newIndex(dayIndex, slotKey)
+ if (newC >= 0) {
+ next['w' + wIdx + '-c' + newC] = this.hiddenEvents[stable]
+ delete this.hiddenEvents[stable]
+ }
+ })
+ this.events = next
+ }
// 列变化后清空无效选择(列索引含义会变)
this.selectedKeys = []
}
@@ -225,9 +256,9 @@ export default {
this.$message.warning('学期详情获取失败,请确认学期数据')
})
},
- // 从后端拉取本学期校历假期,渲染到对应时间格(nd 为 6 位学期代号,如 202601)
+ // 从后端拉取本学期校历事件,渲染到对应时间格(年度由 6 位学期代号截取前 4 位)
loadXqxlbEvents() {
- listXqxlb({ nd: this.nd }).then(res => {
+ listXqxlb({ nd: this.xqxlbNd }).then(res => {
const data = res.data
const list = Array.isArray(data) ? data : (data && data.records) || []
return list
@@ -235,15 +266,22 @@ export default {
const loaded = {}
list.forEach(item => {
const pos = this.locateXqxlb(item)
- if (pos) {
- loaded[pos.key] = {
- bh: item.bh,
- name: item.jqmc || '',
- schedulable: !!item.kpk,
- mainCourse: !!item.zdpk,
- remarkShow: !!item.bzxs,
- remark: item.bz || ''
- }
+ if (!pos) return
+ const ev = {
+ bh: item.bh,
+ name: item.jqmc || '',
+ bold: !!item.jc,
+ schedulable: !!item.kpk,
+ mainCourse: !!item.zdpk,
+ remarkShow: !!item.bzxs,
+ remark: item.bz || ''
+ }
+ const colIndex = this.colIndexOf(pos.dayIndex, pos.slotKey)
+ if (colIndex >= 0) {
+ loaded[this.cellKey(pos.wIdx, colIndex)] = ev
+ } else {
+ // 该节次列当前隐藏:暂存(含 bh),待列显示时由 visibleColumns 监听恢复
+ this.hiddenEvents[this.cellStableKey(pos.wIdx, pos.dayIndex, pos.slotKey)] = ev
}
})
// 合并到现有格子(后端数据覆盖已有状态)
@@ -252,7 +290,7 @@ export default {
this.$message.warning('校历事件加载失败')
})
},
- // 根据假期记录反推时间格 key(jqsj 日期 + courseClass 节次)
+ // 根据假期记录反推时间格位置(jqsj 日期 + courseClass 节次),与列是否可见无关
locateXqxlb(item) {
if (!this.startDate || !item.jqsj) return null
const d = new Date(String(item.jqsj).slice(0, 10).replace(/-/g, '/'))
@@ -263,9 +301,7 @@ export default {
const dayIndex = offset % 7
const slotKey = this.courseClassToSlotKey(item.courseClass)
if (slotKey === null) return null
- const colIndex = this.colIndexOf(dayIndex, slotKey)
- if (colIndex < 0) return null
- return { key: this.cellKey(wIdx, colIndex) }
+ return { wIdx, dayIndex, slotKey }
},
// 后端 courseClass 节次范围 -> 前端节次 key
courseClassToSlotKey(courseClass) {
@@ -307,6 +343,10 @@ export default {
cellKey(wIdx, colIndex) {
return 'w' + wIdx + '-c' + colIndex
},
+ // 稳定的单元格身份:不随列显隐变化的周-星期-节次
+ cellStableKey(wIdx, dayIndex, slotKey) {
+ return wIdx + '-' + dayIndex + '-' + slotKey
+ },
getEvent(wIdx, colIndex) {
return this.events[this.cellKey(wIdx, colIndex)] || null
},
@@ -437,6 +477,7 @@ export default {
this.$set(this.events, key, {
bh: prev ? prev.bh : undefined,
name: name,
+ bold: this.toolbar.bold,
schedulable: this.toolbar.schedulable,
mainCourse: this.toolbar.mainCourse,
remarkShow: this.toolbar.remarkShow,
@@ -467,6 +508,7 @@ export default {
return
}
this.toolbar.eventName = target.name
+ this.toolbar.bold = !!target.bold
this.toolbar.schedulable = !!target.schedulable
this.toolbar.mainCourse = !!target.mainCourse
this.toolbar.remarkShow = !!target.remarkShow
@@ -477,6 +519,7 @@ export default {
const ev = this.getEvent(wIdx, col.colIndex)
if (ev) {
this.toolbar.eventName = ev.name
+ this.toolbar.bold = !!ev.bold
this.toolbar.schedulable = !!ev.schedulable
this.toolbar.mainCourse = !!ev.mainCourse
this.toolbar.remarkShow = !!ev.remarkShow
@@ -489,6 +532,7 @@ export default {
this.selectedKeys = []
this.absorbPreview = ''
this.events = {}
+ this.hiddenEvents = {}
this.loadXqxlbEvents()
this.$message.info('已刷新')
},
@@ -526,10 +570,10 @@ export default {
return {
delFlag: 0,
bh: ev.bh || undefined,
- nd: this.nd,
+ nd: this.xqxlbNd,
jqsj: fmtDate(d),
jqmc: ev.name || '',
- jc: null,
+ jc: !!ev.bold,
bz: ev.remark || null,
kpk: !!ev.schedulable,
bzxs: !!ev.remarkShow,
@@ -694,16 +738,6 @@ export default {
background: #d4ecdf !important;
}
}
-
- /* 状态标记小方块 */
- .sce-flag {
- position: absolute;
- width: 7px;
- height: 7px;
- border-radius: 1px;
- }
- .sce-flag-noschedule { left: 2px; top: 2px; background: #909399; }
- .sce-flag-maincourse { right: 2px; top: 2px; background: #409eff; }
}
.sce-status {
diff --git a/frontend/src/views/teachBusiness/calendar/index.vue b/frontend/src/views/teachBusiness/calendar/index.vue
index b9885121f..d5bcb56fd 100644
--- a/frontend/src/views/teachBusiness/calendar/index.vue
+++ b/frontend/src/views/teachBusiness/calendar/index.vue
@@ -42,16 +42,6 @@
>
{{ getEvent(wIdx, col.colIndex).name }}
-
-
{{ dateNumberOf(wIdx, col.dayIndex) }}
@@ -199,9 +189,9 @@ export default {
this.$message.warning('学期详情获取失败,请确认学期数据')
})
},
- // 从后端拉取本学期校历假期,渲染到对应时间格(nd 为 6 位学期代号,如 202601)
+ // 从后端拉取本学期校历事件,渲染到对应时间格(年度为 6 位学期代号截取前 4 位)
loadXqxlbEvents() {
- listXqxlb({ nd: this.nd }).then(res => {
+ listXqxlb({ nd: String(this.nd).slice(0, 4) }).then(res => {
const data = res.data
const list = Array.isArray(data) ? data : (data && data.records) || []
const loaded = {}
@@ -485,16 +475,6 @@ export default {
&.has-event .cal-event-name { color: #00663e; font-weight: 500; }
&.no-schedule { background: #fde2e2; }
}
-
- /* 状态标记小方块 */
- .cal-flag {
- position: absolute;
- width: 7px;
- height: 7px;
- border-radius: 1px;
- }
- .cal-flag-noschedule { left: 2px; top: 2px; background: #909399; }
- .cal-flag-maincourse { right: 2px; top: 2px; background: #409eff; }
}
/* 底部状态栏 */
diff --git a/frontend/src/views/teachBusiness/syllabus/index.vue b/frontend/src/views/teachBusiness/syllabus/index.vue
index 72dd933b6..b2cf102df 100644
--- a/frontend/src/views/teachBusiness/syllabus/index.vue
+++ b/frontend/src/views/teachBusiness/syllabus/index.vue
@@ -74,7 +74,7 @@
{{ fmtDateTime(scope.row.tysj) }}
-
+
编辑
删除
diff --git a/frontend/src/views/teachBusiness/timetable/index.vue b/frontend/src/views/teachBusiness/timetable/index.vue
index ad328d5e6..721c52067 100644
--- a/frontend/src/views/teachBusiness/timetable/index.vue
+++ b/frontend/src/views/teachBusiness/timetable/index.vue
@@ -1,228 +1,126 @@
-
-
+
+
-
-
-
-
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 查询
-
-
-
-
{{ shiftTitle }}
+
{{ pageTitle }}
-
-
-
- 学期教学实施计划
-
-
- 学期课程表(周次星期)
-
-
- 学期课程表(班次视图)
-
-
- 学期课程表(排课周)含选修
-
-
- 学期教学实施计划(含选修)
-
-
- 学期课程表(周次星期)详细
-
-
- 学期成绩表
-
-
- 课程列表另存Excel
-
-
+
+
+
+ 学期教学实施计划
+ 学期成绩表
+ 课程列表另存Excel
+
+
-
+
-
+
-
-
- {{ scope.row._kcmc || '-' }}
- {{ scope.row.jc || '-' }}
+
+
+ {{ row.kcmc || '-' }}
+ {{ row.kssk || '-' }}
-
-
- {{ scope.row._zrjy || '-' }}
- 第{{ scope.row.kcxh || '-' }}次课
-
-
-
-
-
-
-
-
- {{ scope.row._ssjy || '-' }}
-
-
-
- {{ scope.row.rs || '-' }} 人
- {{ scope.row.jsbh || '-' }}
-
-
-
-
- {{ fmtKbbdsj(scope.row.kbbdsj) }}
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
@@ -231,14 +129,9 @@