build / build-push (push) Successful in 1m7s
★「通知公告」与既有「校园公告」是两个应用,不是同一个: · 校园公告 CampusAnnouncement → key=campusnotice、前缀 /campusnotice、按班级下发、带审批流/草稿箱(既有 notice.*) · 通知公告 NoticeFront → key=notice、前缀 /notice、按用户下发,无审批/草稿/推送范围(本次新增 notify.*) 两者路由与页面名几乎同名(/list、/list/new、已收到/已发送),极易拿错源码,故工具前缀避开已占用的 notice.*。 新增 NoticeTools(9 个工具):收件箱/详情/一键已读、发布/编辑/我发出的/阅读情况、发文部门字典、组织树。 发布表单逐项对齐 NoticeFront/src/views/notice/NewNotice.vue#doAdd: title / content / deptId / receiveList / fileIds / timingSendTime (smsFlag 在页面里没有对应控件、恒为 0,故不放出;receiveList 的「全部用户」哨兵是 all。) 配套:ToolRegistry 注册、RolePolicy 把发布闭环与两个字典工具列为教职工专属、 application.yml 补地址 http://base.yunhaixingtong.com/notice 与默认落地页 / (AgentSettings 出厂默认表也要补 notice —— 契约测试用的是 new AgentSettings(),不读 yml)。 fix(ToolExecutor): 已按 joinSeparator 拼成逗号串的字段不再被包回数组 normalizeJsonArgs 的第二个循环「数组参数给了标量 → 包成单元素数组」会作用到 刚拼好的 receiveList/fileIds 上,把 101,102 变成 [101,102], 而模块侧 NoticeRequest.receiveList 是 String ⇒ 直接判非法。 此前一直没暴露:本地 mock 的提交体是原样 JSON.stringify(args)(本来就是数组), 看不出差异,只有真实后端才走到这一步。现在 join 过的字段直接跳过该循环。 测试:ModuleFormParityTest 新增「通知公告发布字段集不与校园公告互串」+ 「代取地址带 /notice 前缀」+「提交体是逗号串、哨兵互斥、提交路径带前缀」;全量 126/126 绿。