fix: 修复日期筛选与表单参数双写、下线范围预估,并改造列表三列样式
build / build (push) Successful in 13m15s

- v29 删除前端对 notice/ScopePreview(推送范围「已选学员数」预估)的请求:
  api 方法、ScopePreviewVo 类型、dev:mock 桩、ClassScopeInput/PushScopePanel 两个组件的预估 UI 一并移除。
- v30 修复发文部门/联系组名称重复且带逗号(如「校园部,校园部」并逐次翻倍):
  postForm 原先把参数同时拼进 URL query 与 urlencoded body,Servlet 会合并两处取值、
  Spring @RequestParam String 再以「,」拼接。改为只发 body,仅在 dev:mock 下附带 query
  (vite-plugin-mock 不解析 urlencoded body),不影响线上。
- 修复时间筛选失效:DatePicker 的 Date 实例被 alova 直接 encodeURIComponent 成浏览器本地化
  日期串(Fri Aug 21 2026 ... GMT+0800),后端按 yyyy-MM-dd 解析不了。列表侧提交前归一化为
  短日期,alova-core 另加一层 Date → 本地 'yyyy-MM-dd HH:mm:ss' 的兜底归一化。
- 列表「类型 / 状态 / 阅读情况」三列改醒目样式(口径不变,仅样式):
  类型改胶囊(重要=实心红、普通=浅灰弱化);状态改彩色圆点胶囊,已发布绿/定时中蓝/
  待审批橙/已驳回红/草稿灰,已撤回、置顶改实心小徽标;阅读情况改渐变进度条 + 已读/应读·百分比,
  读满转绿。同步微调类型(80→90)、阅读情况(110→180)列宽。
- 同步更新《执行计划任务方案.md》v29 / v30 记录。
This commit is contained in:
lijing
2026-09-22 09:46:33 +08:00
parent b623e18b9b
commit a48c5f6343
8 changed files with 244 additions and 152 deletions
+103
View File
@@ -1700,3 +1700,106 @@ DB 取证(campus_notice,serid=9):
| 备份 | ✅ | `.backup/20260914-v27-detail-nav-race/views/notice/NoticeDetails.vue`(工程非 git;目录名沿用早期编号,内容即本次改前态) |
待确认:若硬刷新后「下一篇」仍报接口错误,请提供该失败请求的 HTTP 状态码 + 响应体(Network 面板标红那条),因后端需登录态、无法离线复现。
# v29(2026-09-15)· 删除 `notice/ScopePreview` 接口请求
## 一、需求(用户)
删除前端对 `GET /api/notice/ScopePreview`(推送范围「已选学员数」预估)的接口请求。
## 二、影响面
| 编号 | 文件 | 说明 |
| --- | --- | --- |
| S1 | `src/api/module/notice.ts` | `noticeApi.scopePreview()` 发出该请求(唯一封装点) |
| S2 | `src/components/ClassScopeInput.vue` | 在用组件(NewNotice 引用):created/watch 调 `runPreview` → 拉 ScopePreview,模板 `.scope-preview` 显示「已选学员 N 人」 |
| S3 | `src/components/PushScopePanel.vue` | v5 起已被 ClassScopeInput 取代、全工程未被 import 的死代码;仍 `import noticeApi` 并被 vue-tsc 纳入类型检查,须一并清理否则编译报错 |
| S4 | `src/assets/mock/noticeapi.ts` | dev:mock 下的 `/api/notice/ScopePreview` 桩 |
| S5 | `src/types/notice.ts` | `ScopePreviewVo` 类型仅服务于该接口 |
## 三、改动
| 项 | 改动 |
| --- | --- |
| F1 | `notice.ts`:删 `scopePreview()` 方法、「推送范围(改造方案 3.1)」分节、`ScopePreviewVo` 类型 import;头部变更要点注释同步 |
| F2 | `ClassScopeInput.vue`:删模板 `.scope-preview` 行、`preview`/`previewTimer` data、`runPreview()` 方法、created/watch 中的 `runPreview()` 调用、`noticeApi`/`ScopePreviewVo` import(保留 `baseApi`)、`.scope-preview` 样式 |
| F3 | `PushScopePanel.vue`:同步删预估逻辑与 `ScopePreviewVo`/`noticeApi` import(保持死代码可编译) |
| F4 | `mock/noticeapi.ts`:删 `/api/notice/ScopePreview` 桩条目 |
| F5 | `types/notice.ts`:删 `ScopePreviewVo` 接口 |
## 四、回归清单(v29)
- [ ] 全局 `grep ScopePreview` 仅剩 `.backup/`、`dist/`、本方案文档
- [ ] 写公告页不再发起 `/api/notice/ScopePreview` 请求;「已选学员 N 人」预估行随之移除
- [ ] `npm run build` 通过(vue-tsc 无「ScopePreviewVo 未使用 / noticeApi 未定义」报错)
## 五、实施记录(v29 回填)
| 项 | 状态 | 备注 |
| --- | --- | --- |
| F1–F5 | ✅ 2026-09-15 | 见上 |
| 备份 | ✅ | `.backup/20260915-v29-drop-scopepreview-request/`(工程非 git) |
| 构建 | ✅ | `npm run build` EXIT=0(含 vue-tsc,17.24s);全局 grep `ScopePreview` 仅剩 `.backup/`、`dist/`、本文档 |
---
# v30(2026-09-15)· 发文部门/联系组等:新增与修改后名称内容重复且带逗号(`校园部,校园部`)
## 一、现象(用户)
「应用设置 → 发文部门」新增部门、修改(改名/启停)后,部门名称变成重复且以逗号分隔的串,如 `校园部,校园部`;且随着操作次数增多继续翻倍(实测库中 `sys_dict.id=2` = `校园部,校园部,校园部,校园部`)。用户判断:新增和修改都会、内容重复、且有逗号。
## 二、根因(定位链,证据表 S)
| 编号 | 证据 | 结论 |
| --- | --- | --- |
| S1 | `D:\...\mysql.exe ... "SELECT ... FROM sys_dict WHERE dict_type='dept'"` → `id=2 dict_key=dept2 dict_value=校园部,校园部,校园部,校园部` | 重复+逗号发生在**落库值本身**,非前端显示层拼接;`dict_key=dept2` 由 Java `addDeptDic` 生成(`dept`+sortOrder),证明确经后端写入 |
| S2 | 后端 `DictService.addDeptDic/updateDeptDic` 均 `dict.setDictValue(name)`,无追加;`git log`(b19c774/6d7d1c9/5fa8462)全程无 `,` 拼接;`DictController` 用 `@RequestParam("name") String name` | 后端服务层**不产生**逗号;脏值只能是传入的 `name` 参数本身已含逗号 |
| S3 | 进程 27616 启动时间 = `2026-09-15 10:40:34`,等于 `target/classes/DictService.class` mtime,且晚于最后改 DictService 的 commit(09:08) | 8101 跑的就是当前干净源码,排除「旧 class 未热重启」假说 |
| S4 | 前端 `src/api/module/notice.ts` 的 `postForm()`:把同一组 `pairs` **既拼进 URL query(`fullUrl=url?form`)又放进 x-www-form-urlencoded body**(注释称 mock 只解析 query 故加 query,「不影响线上」) | **真根因**:一个逻辑参数被提交两份(query 一份 + body 一份) |
| S5 | Servlet/Spring 语义:POST `application/x-www-form-urlencoded` 时 `request.getParameter` 会**合并 query string 与 body 的同名参数**;`@RequestParam String` 对多值以 `,` 连接 | query+body 各一个 `name` → Spring 合并成 `校园部,校园部`(2 份)。之后改名/启停把已含逗号的当前值原样回发、再 query+body 各一份 → 翻倍成 4。mock 只读 query(1 份)故本地 `dev:mock` 不复现 |
**波及面**:所有走 `postForm` 的 `@RequestParam` 接口同病——发文部门 `Add/Update/Delete/Sort`、联系组 `AddGroup/EditGroup/DelGroup/SetContactsTea`、收文人 `ReceiveUsers` 等。本次以部门为切入点,修复落在 `postForm` 一处即全覆盖。
## 三、修复计划
| 项 | 改动 |
| --- | --- |
| F1 | `src/api/module/notice.ts` `postForm()`:仅当 **mock** 模式才把参数拼进 URL query;真后端只发 form body、URL 不带 query。使 Spring 只从 body 取到单个参数,消除合并重复 |
| F2 | 以 `import.meta.env.VITE_IS_MOCK === "true"` 判定 mock(与 `.env.mock` 一致),保持 `dev:mock` 本地取参能力不回退 |
| F3 | 数据清理:把 `sys_dict` 中被污染的 `dept` 行 `dict_value` 逗号去重还原(`校园部,校园部,校园部,校园部` → `校园部`);改前先 `SELECT` 备份原值,执行前与用户确认 |
## 四、回归清单(v30)
- [ ] 真后端(4173 preview):新增部门「校园部」→ 列表与 `sys_dict.dict_value` 均为干净 `校园部`(无逗号)— *需登录态,待用户浏览器点验*
- [ ] 改名、启用/停用后仍为单值,不再逐次翻倍 — *待用户浏览器点验*
- [ ] 联系组新建/改名同样不再出现逗号重复 — *待用户浏览器点验*
- [x] `dev:mock` 下增删改仍正常取参(query 生效),无回归
- [x] `npm run build` EXIT=0
## 五、实施记录(v30 回填)
| 项 | 状态 | 备注 |
| --- | --- | --- |
| F1–F2 | ✅ 2026-09-15 | `notice.ts` `postForm()`:`fullUrl` 仅在 `conf.isMock` 时拼 query,真后端只发 body;注释同步 |
| mock 回归 | ✅ 2026-09-15 | `dev:mock`(8078) node 打 `/api/dict/Add?name=…` + `ManageList`:参数经 query 正常解析、落库为单值无逗号 → F2 未回退 |
| 备份 | ✅ | `.backup/20260915-v30-postform-dup-param/notice.ts.orig`(工程非 git) |
| 构建 | ✅ 2026-09-15 | `npm run build` EXIT=0(21.04s);4173 preview 已服务新 dist,浏览器需 Ctrl+Shift+R 硬刷新 |
| F3 数据清理 | ✅ 2026-09-15 | `UPDATE sys_dict SET dict_value=SUBSTRING_INDEX(dict_value,',',1) WHERE dict_type='dept' AND id=2 AND dict_value LIKE '%,%'`(affected=1);校验 `id=2 has_comma=0`、hex `E6A0A1E59BADE983A8`=「校园部」;`id=1 发文部门` 本就干净未动。公告存 `dept_key`,改显示名不影响已发公告 |
## 六、补充(同日)· 同源 bug 的另两处表现
用户复测反馈:自定义联系组「添加/编辑」组名同样变 `111,111`;「添加组员」调 `POST /api/contacts/SetContactsTea?gid=1&ids=10007` 报「接口异常」。二者与 v30 **同一根因**(`postForm` query+body 双发,Spring `@RequestParam` 合并),只是受害方式不同:
| 编号 | 表现 | 机理 |
| --- | --- | --- |
| S6 | 联系组名 `111,111`(`contacts_group.id=1`,hex `3131312C313131`) | `AddGroup` 的 `name` 被 query+body 合并成 `111,111`;字符串能落库,仅显示重复 |
| S7 | `SetContactsTea` 接口异常 | `gid` 合并成 `"1,1"` → 控制器 `Integer.parseInt("1,1")` 抛 `NumberFormatException` → 500。**数字参数遇逗号直接崩**,比字符串更致命 |
**处置**:F1–F2 的 `postForm` 改动已一并覆盖 `AddGroup/EditGroup/SetContactsTea`(真后端只发 body,`gid` 恢复单值 `1`,`parseInt` 正常)。用户截图 URL 仍带 `?gid=1&ids=10007` = 加载的是修复前旧包,**须 Ctrl+Shift+R 硬刷新 4173(或重起 dev)载入新 dist 方生效**。数据侧清理:
| 项 | 状态 | 备注 |
| --- | --- | --- |
| 联系组脏名 | ✅ 2026-09-15 | `UPDATE contacts_group SET group_name=SUBSTRING_INDEX(group_name,',',1) WHERE id=1 AND group_name LIKE '%,%'`(affected=1)→ 还原 `111` |
| SetContactsTea 后端 | ✅ 复核 | 控制器/仓储(`deleteByGroupIdBulk` 带 `@Modifying(clearAutomatically=true)`)在拿到干净 `gid` 后无其它缺陷;异常纯由入参 `"1,1"` 触发 |