diff --git a/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue b/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue
index a6a483ed..17d14e6e 100644
--- a/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue
+++ b/frontend/src/views/teachBusiness/calendar/components/SchoolCalendarEditor.vue
@@ -123,6 +123,16 @@ function fmtDate(d) {
return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate())
}
+// 生成 32 位小写 UUID(去横线),与后端 UuidUtil.getUUID 一致,用于 bh 缺失时兜底
+function genUUID() {
+ let s = ''
+ const chars = '0123456789abcdef'
+ for (let i = 0; i < 32; i++) {
+ s += chars[Math.floor(Math.random() * 16)]
+ }
+ return s
+}
+
export default {
name: 'SchoolCalendarEditor',
props: {
@@ -182,12 +192,10 @@ export default {
})
return cols
},
- // xqxlb 的 nd 存的是「年份」,必须与某条记录的 jqsj 实际日期同一年,
- // 按「学期代号前4位」取会与格子真实年月脱节(如 2027 春学期首周落在 2026 年)。
- // 这里统一以「日历起点 calendarStart 所在年」作为年度口径。
+ // xqxlb 的 nd 后端已统一为「6 位学期代号」(如 202701),与 this.nd 一致。
+ // 不再按日历起点/季度取年份,避免跨年度学期解析出错。
xqxlbNd() {
- if (this.calendarStart) return this.calendarStart.getFullYear()
- return Number(String(this.nd).slice(0, 4))
+ return Number(String(this.nd).slice(0, 6)) || Number(this.nd) || 0
}
},
watch: {
@@ -269,15 +277,10 @@ export default {
// 调用 /xqxlb/add 只按本学期 kxrq/jsrq 预生成这一张网格,再重新拉取,
// 这样后续 /xqxlb/update 的 updateById 才能命中每一格。(区间有覆盖则跳过,幂等)
loadXqxlbEvents() {
- const fetchList = () => {
- console.warn('[校历编辑] 查询nd=', this.xqxlbNd, '学期nd=', this.nd)
- return listXqxlb({ nd: this.xqxlbNd }).then(res => {
- const data = res.data
- const arr = Array.isArray(data) ? data : (data && data.records) || []
- console.warn('[校历编辑] 返回条数=', arr.length, '含事件名=', arr.filter(it => it.jqmc).map(it => ({ nd: it.nd, jqsj: it.jqsj, jqmc: it.jqmc, courseClass: it.courseClass })).slice(0, 10))
- return arr
- })
- }
+ const fetchList = () => listXqxlb({ nd: this.xqxlbNd }).then(res => {
+ const data = res.data
+ return Array.isArray(data) ? data : (data && data.records) || []
+ })
const render = (list) => {
// 后端 add() 的按「月日」去重对已存的全量日期不生效,同一年度多次打开/刷新会
// 积累同一格的重复占位记录(各带不同 bh)。updateById 只改其中一行,其余空记录
@@ -519,9 +522,9 @@ export default {
return
}
const name = this.toolbar.eventName.trim()
- // 空名称时按清除处理
+ // 设定时未填写事件名:提示,不触发清除
if (!name) {
- this.deleteEvent()
+ this.$message.warning('请输入事件名')
return
}
const keys = [...this.selectedKeys]
@@ -610,8 +613,14 @@ export default {
const payload = this.buildXqxlbPayload(key, this.events[key])
if (!payload) return Promise.resolve(false)
return updateXqxlb(payload)
- .then(() => true)
- .catch(() => false)
+ .then(() => {
+ console.warn('[设定] key=', key, 'bh来源=', this.events[key] && this.events[key].bh ? '已有' : '生成', 'bh=', payload.bh, 'nd=', payload.nd, 'name=', payload.jqmc)
+ return true
+ })
+ .catch(err => {
+ console.warn('[设定] key=', key, '保存失败', err && (err.message || err))
+ return false
+ })
})
return Promise.all(tasks).then(results => {
const ok = results.filter(r => r === true).length
@@ -659,10 +668,10 @@ export default {
d.setDate(this.calendarStart.getDate() + pos.wIdx * 7 + pos.dayIndex)
return {
delFlag: 0,
- bh: ev.bh || undefined,
- // nd 必须与 jqsj 同一年:取本条记录真实日期的年份,
- // 不能沿用学派代号前4位(如 2027 春学期首周可能落在 2026 年,会存错年度、查不到)。
- nd: d.getFullYear(),
+ // bh 编号必须传:有后端记录则沿用其 bh,否则前端生成 UUID 兜底(避免 payload 缺主键导致 updateById 失效)
+ bh: ev.bh || genUUID(),
+ // nd 后端已统一为 6 位学期代号(如 202701),与查询口径一致,不再取记录日期的年份
+ nd: this.xqxlbNd,
jqsj: fmtDate(d),
jqmc: ev.name || '',
jc: !!ev.bold,
diff --git a/frontend/src/views/teachBusiness/calendar/index.vue b/frontend/src/views/teachBusiness/calendar/index.vue
index a482b627..daf43c30 100644
--- a/frontend/src/views/teachBusiness/calendar/index.vue
+++ b/frontend/src/views/teachBusiness/calendar/index.vue
@@ -193,31 +193,14 @@ export default {
})
},
// 从后端拉取校历事件,渲染到对应时间格
- // xqxlb.nd 存的是记录真实日期的年份,不是学期代号前4位(避免跨年度学期查询出错)
+ // xqxlb.nd 后端已统一为 6 位学期代号(如 202701),与 this.nd 一致,一次查询即可
loadXqxlbEvents() {
- if (!this.calendarStart) return
- // 学期校历从 calendarStart 到 endDate,查询覆盖整个跨度的全部年份
- const startYear = this.calendarStart.getFullYear()
- const endYear = (this.endDate || this.calendarStart).getFullYear()
- // 一次性拉取覆盖起止年份的所有记录,由前端过滤
- const requests = []
- const range = []
- for (let y = startYear; y <= endYear; y++) {
- range.push(y)
- requests.push(listXqxlb({ nd: y }))
- }
- console.warn('[校历只读] 查询nd范围=', range, 'calendarStart=', fmtDate(this.calendarStart), 'endDate=', this.endDate ? fmtDate(this.endDate) : null)
- Promise.all(requests).then(responses => {
- const list = []
- responses.forEach(res => {
- const data = res.data
- const part = Array.isArray(data) ? data : (data && data.records) || []
- list.push(...part)
- })
- console.warn('[校历只读] listXqxlb 返回记录条数=', list.length, 'nd字段分布=', list.reduce((m, it) => { const k = String(it.nd); m[k] = (m[k] || 0) + 1; return m }, {}), '样例=', list.slice(0, 3).map(it => ({ nd: it.nd, jqsj: it.jqsj, jqmc: it.jqmc, courseClass: it.courseClass })))
+ if (!this.calendarStart || !this.nd) return
+ listXqxlb({ nd: Number(String(this.nd).slice(0, 6)) || Number(this.nd) }).then(res => {
+ const data = res.data
+ const list = Array.isArray(data) ? data : (data && data.records) || []
const loaded = {}
- let matched = 0
- // 23694 条里同一格可能有多条(add() 去重失效累积的重复占位)。
+ // 同一格可能有多条(后端 add() 去重失效累积的重复占位)。
// 按格子去重:同一格优先保留「有事件名(jqmc非空)」的那条,避免空占位把事件盖成空白。
const unique = {}
list.forEach(item => {
@@ -239,11 +222,11 @@ export default {
remarkShow: !!item.bzxs,
remark: item.bz || ''
}
- if (item.jqmc) matched++
})
- console.warn('[校历只读] 定位到的事件条数=', matched, 'events=', Object.keys(loaded).length, loaded)
this.events = loaded
- }).catch(e => { console.error('[校历只读] 拉取失败', e) })
+ }).catch(() => {
+ this.$message.warning('校历事件加载失败')
+ })
},
// 根据假期记录反推时间格 key(jqsj 日期 + courseClass 节次)
locateXqxlb(item) {
diff --git a/frontend/src/views/teachBusiness/semester/index.vue b/frontend/src/views/teachBusiness/semester/index.vue
index 452815cb..c627ef00 100644
--- a/frontend/src/views/teachBusiness/semester/index.vue
+++ b/frontend/src/views/teachBusiness/semester/index.vue
@@ -6,22 +6,16 @@
新添
-
编辑校历
-
-
- 批量删除
-
-
-
+ @current-change="handleCurrentChange">
{{ getSemesterName(scope.row.nd) }}
@@ -214,14 +208,8 @@ export default {
total: 0,
// 学期列表数据
semesterList: [],
- // 选中的学期数组
- ids: [],
// 当前点击选中的学期
currentSemester: null,
- // 非单个禁用
- single: true,
- // 非多个禁用
- multiple: true,
// 弹出层标题
title: "",
// 是否显示弹出层
@@ -365,12 +353,6 @@ export default {
this.loading = false
})
},
- /** 多选变化 */
- handleSelectionChange(selection) {
- this.ids = selection.map(item => item.nd)
- this.single = selection.length !== 1
- this.multiple = !selection.length
- },
/** 单击行选中变化:记录当前选中的学期,用于启用「编辑校历」 */
handleCurrentChange(currentRow) {
this.currentSemester = currentRow || null
@@ -405,7 +387,7 @@ export default {
},
/** 编辑按钮 */
handleUpdate(row) {
- const semesterId = row && row.nd ? row.nd : this.ids[0]
+ const semesterId = row && row.nd ? row.nd : ''
if (!semesterId) return
this.reset()
this.isAdd = false
@@ -443,21 +425,21 @@ export default {
/** 编辑校历按钮:对当前选中的学期编辑校历 */
handleEditCalendar() {
const row = this.currentSemester
- if (!row || !row.nd) return
+ if (!row || !row.nd) {
+ this.$modal.msgWarning('请选择学期')
+ return
+ }
this.$router.push({
path: '/teachBusiness/semester/semesterCalendar',
query: { nd: row.nd, name: this.getSemesterName(row.nd) }
})
},
- /** 删除按钮 */
+ /** 删除按钮:单行删除 */
handleDelete(row) {
- const semesterIds = row && row.nd ? [row.nd] : this.ids
- if (!semesterIds.length) return
- const names = semesterIds.map(nd => this.getSemesterName(nd)).join('、')
- this.$modal.confirm('确认删除学期【' + names + '】吗?').then(() => {
- // 批量删除:逐个调用
- const delList = semesterIds.map(nd => delSemester(nd))
- return Promise.all(delList)
+ if (!row || !row.nd) return
+ const name = this.getSemesterName(row.nd)
+ this.$modal.confirm('确认删除学期【' + name + '】吗?').then(() => {
+ return delSemester(row.nd)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")