From d37c05aaad0d3beea2ad15bfecdd8b46026bf53f Mon Sep 17 00:00:00 2001 From: zhaichao Date: Fri, 28 Aug 2026 14:24:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=A1=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/SchoolCalendarEditor.vue | 53 +++++++++++-------- .../views/teachBusiness/calendar/index.vue | 35 ++++-------- .../views/teachBusiness/semester/index.vue | 42 +++++---------- 3 files changed, 52 insertions(+), 78 deletions(-) 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">