| 项 | 值 |
|---|---|
| 对照网址 | http://39.97.59.228:8013/hrx/mky-vent-base/compare/master...fix/audit-r3-20260921 |
| 依据文档 | tools/verify/代码审核-第三轮-mky-vent-base-20260921.md(该报告编号 B-1/B-2,对应本文档 R3-8/R3-9) |
| 分支 | fix/audit-r3-20260921(由 fix/audit-r3-bugs-20260921 与 fix/audit-r3-restore-20260921 两条施工分支按提交 cherry-pick 合成;本文件原属 bug 组分支) |
| 基线 | upstream/master = 4e311cb6(behind=0) |
| 日期 | 2026-09-21(Asia/Shanghai) |
| 交付版本 | fix/audit-r3-20260921(7 个提交:bug 组 3 + 恢复组 4) |
| 状态 | 已推 fork(origin = lizuo/mky-vent-base)用于远程构建与人工审核;未推 upstream、未推 master、未部署 |
[Fix R3-8] 恢复 resetMicroContentWH 的 onTimeout 形参(修 4 调用方失配致遮罩永久卡死)[Fix R3-9] 缩小重新生成去重删除范围(服务端时间戳基线,防误删历史同文案提问)[Docs] 第三轮审计 R3-B 批改动说明(docs/ai-changes)本清单只列提交标题,不写死 hash:本文档随分支提交,任何 amend / cherry-pick / rebase 都会让"自指 hash"失真 (第三方复核即发现旧稿引用了一个已被 amend 掉的 docs 提交 hash)。hash 一律以本分支
git log --oneline为准。
git diff --stat 4e311cb6 <R3-9 提交> -- src(基线 4e311cb6 → 两处修复后的实测输出):
src/utils/domUtils.ts | 12 ++++-
.../components/AiAssistantModal.vue | 55 +++++++++++++++++++---
2 files changed, 60 insertions(+), 7 deletions(-)
复核修正:旧稿此处为"26 +++++ / 32 insertions / 6 deletions",是 R3-9 收口前的中间态数字; 上表为复核后实测值(R3-8 单独为
domUtils.ts1 文件 +11/−1;R3-9 收口将组件改动放大到 55 行)。
另新增本说明目录:docs/ai-changes/README.md(本分支基线无该目录;规范要求仓库内补建)+ 本文件。
resetMicroContentWH 形参被删但 4 个调用方未同步7e9858ec 把签名从 (domId, callBack?, onTimeout?, maxWaitMs = 60000) 改为 (domId, callBack?, maxWaitMs = 60000) 并删掉了超时分支里的 onTimeout() 调用,但 4 个调用方(needAir.vue、ventDoc.vue、ventModal.vue、ventModal2D.vue)仍按旧签名传 3 个参数(第 3 个是错误态回调)→ 回调落进 maxWaitMs,Date.now() - start >= maxWaitMs(number 与 function 比较)恒 false → 60s 超时兜底永不触发:子应用加载失败时遮罩永久转圈、loadFailed 永不置位(MicroLoadError 错误态与重试入口成死代码)、每秒一次 setTimeout 轮询永不停止。src/utils/domUtils.ts:174 签名恢复为 (domId, callBack?: Function, onTimeout?: Function, maxWaitMs = 60000)(照我方原始实现 2eb75d33 [Fix SEC-20260913],顺序一致:超时分支先 onTimeout() 后 callBack()),并新增加固:函数开头 if (typeof maxWaitMs !== 'number') maxWaitMs = 60000;。4e311cb6(master 现状)是"恢复 + 加固"——多了一条类型防御,防止将来再出现"回调被塞进数值参数"这类失配导致兜底静默失效。removeDuplicateRegenerateUserMessage 只豁免"第一条"user 消息,凡内容同文案的历史提问("继续"、"总结一下"这类极常见)都会被 deleteMessage 静默删除。handleRegenerate 在发起重发之前取一次 getDetail 服务端快照,取其中 created_at 的最大值 baselineMs 作为基线(快照无可解析时间戳则 NaN);去重过滤条件为"内容一致 + idx > 0 + id != null + created_at 可解析 + 严格大于 baselineMs"——只删本次重发产生的那一条重复用户消息,历史同文案消息全部保留。baselineMs 为 NaN 时退化为"只删匹配项中最后一条"(本次重发产生的即最新一条),仍不删全部;created_at 缺失/不可解析的消息一律不删。src/views/ventAI/manageAssistent/api.ts 的 getDetail('/ventAI/api/chat/history/' + session_id),消息对象含 created_at 字符串字段(本组件 958 行已用 dayjs(item.created_at) 解析展示时间,格式可靠)。基线取自服务端快照而非浏览器 Date.now():前后端时钟偏差(矿内网常见分钟级)下,若用浏览器时钟比较,服务器时钟超前时历史消息会被误判为"晚于重发"而真丢数据(第一次实现有此缺陷,本次收口修正)。基线与候选消息同属服务端 created_at 时钟域,偏差被消除。用严格大于(不用 >=)是因为基线那条本身可能就是上一次的同文案提问,且 created_at 若为秒级精度,同秒的新消息宁可漏删也不能误删。created_at 缺失或无法解析的消息不删(宁留重复、不误删历史)。handleEditResend、不改后端、不改其它重发路径。handleRegenerate 里 removeDuplicateRegenerateUserMessage(userInput) → removeDuplicateRegenerateUserMessage(userInput, baselineMs)(全仓仅这一个调用点,已 grep 确认)。domId、成功回调、错误态回调),与新签名 (domId, callBack?, onTimeout?, maxWaitMs?) 逐位对齐;超时分支执行顺序与原始实现 2eb75d33 一致(onTimeout() 在前、callBack() 在后)。created_at,过滤条件只放行严格大于基线的那条(同秒同值不会被误删);快照无时间戳时走退化分支只删最后一条匹配;created_at 缺失/非法(dayjs 解析出 Invalid Date → NaN)时拦截,不删除。软链依赖 node_modules -> /root/VentAnaly60/mky-vent-base/node_modules(只读使用)。
src/utils/domUtils.ts —— @babel/parser@7.29.7(.pnpm 嵌套路径,@babel/parser 未提升,任务书给的一行命令在本环境报 MODULE_NOT_FOUND,故用嵌套真实路径,解析器版本一致):
OK src/utils/domUtils.ts
AiAssistantModal.vue —— @vue/compiler-sfc 的 parse + compileScript(script 块语法+类型检查通过):
OK src/views/ventAI/manageAssistent/components/AiAssistantModal.vue
未跑 vite build / pnpm install(任务书明令禁止);无既有 lint 报错基线对比,本次两个文件解析均通过。
关键 hunk 见 git diff(③中 stat,④中说明)。
created_at 若为秒级精度,重发新消息与基线同秒时 > 不成立会漏删一条重复(宁留重复、不误删历史,属有意取舍);② 退化分支(服务端时间戳不可得时"只删最后一条匹配")依赖消息顺序,后端若提供可靠时间戳建议切回主方案。origin = lizuo/mky-vent-base,分支 fix/audit-r3-20260921);未推 upstream、未推 master、未部署;交付合并由人工审核决定。upstream/master = 4e311cb6(behind=0,开工时已确认)。tools/verify/复核-第三轮-基座R3-8R3-9-20260921.md)结论:代码零必改;本文档原稿的"自指旧 hash + 中间态 stat 数字"两处已按复核意见修正(见 ②/③ 的修正说明)。