| HANDOFF.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| emergency-repair-web/src/utils/sensitive.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
HANDOFF.md
@@ -1,7 +1,8 @@ # HANDOFF:临抢修软件需求与第一版实现 > 交接日期:2026-08-25(2026-08-26 晚 / 2026-09-07 / 2026-09-08 / 2026-09-09 核对 / 2026-09-10 / 2026-09-11 / 2026-09-14 / 2026-09-16 / 2026-09-17 / 2026-09-28 新会话准备 / 2026-09-28 专业配置与故障编号自动生成 / 2026-09-29 代码入库公司 Git 更新)| 用途:新开会话时先读本文件,即可无缝接续 > 项目目录:`C:\Users\jcxiong\Documents\Codex\MyProject\EmergencyRepair` > 交接日期:2026-08-25(2026-08-26 晚 / 2026-09-07 / 2026-09-08 / 2026-09-09 核对 / 2026-09-10 / 2026-09-11 / 2026-09-14 / 2026-09-16 / 2026-09-17 / 2026-09-28 新会话准备 / 2026-09-28 专业配置与故障编号自动生成 / 2026-09-29 代码入库公司 Git 更新 / 2026-10-02 本机环境迁移与前后端启动)| 用途:新开会话时先读本文件,即可无缝接续 > 项目目录(2026-10-02 起为本机 `D:\projectJava\lqx`;行内旧路径 `C:\Users\jcxiong\Documents\Codex\MyProject\EmergencyRepair` 为上一台机器) > 注意:2026-10-02 本机工具链与旧记录不同,构建、启动与工作方式约定以第 16 节为准。 ## 0. 最新交接(2026-09-28 新会话准备,优先阅读) @@ -660,3 +661,39 @@ 2. 决策表 B6–B10 待用户答复(`requirement\工程状态机设计.md` 第 4 节 + `requirement\决策表_待确认项.md` B 组),答完固化为正式设计。 3. AXU15 剩余待确认:字段来源与可改性(待确认清单第 13 条)、完工验收各环节角色与打印输出、修后质量评级与 AXU14 T员评分字段的关系。 4. 后续改动完成后直接推送到公司 Git 仓库 `main` 分支。 ## 16. 收尾快照(2026-10-02 周五,本机环境迁移与前后端启动) **环境迁移(重要,与第 0 节旧记录不同)** - 代码已在本机重新拉取,工作目录改为 `D:\projectJava\lqx`,不再是 `D:\Codex\MyProject\EmergencyRepair`。 - 仓库:`http://61.183.254.94:3000/r/EmergencyRepair.git`,分支 `main`,本地 HEAD `5d015d7`(docs: add shutdown snapshot for 2026-09-29),与 `origin/main` 一致。 - 克隆时远端 HEAD 指向不存在的 ref,不会自动检出,需手动 `git checkout main`。凭据已存入 Windows 凭据管理器,`.git/config` 中不再有明文密码。 - 本机工具链与旧机器不同,**第 0.9 节和第 8 节里“`apply_patch` 不可用、必须用 Python 读改写、不能用 `Start-Process`”的约定只适用于上一台机器**,本机 `apply_patch` 与 `Start-Process` 均可正常使用。 - JDK:`C:\Program Files\Java\jdk1.8.0_172`。PATH 里的 java 是 JRE 1.8.0_481(没有 javac),构建前必须显式设置 `JAVA_HOME`。 - Maven:`D:\solidDir\apache-maven-3.6.1\bin\mvn.cmd`(不在 PATH,需绝对路径调用)。 - Node/npm:`C:\Program Files\nodejs`(Node v14.8.0 / npm 6.14.7,不在 PATH,需绝对路径调用)。 - 达梦驱动 `dm.jdbc:DmJdbcDriver18:1.0` 在默认本地仓库缺失(只有下载失败标记),已从 `D:\solidDir\repo` 同名构件安装进 `C:\Users\Lenovo\.m2`;属环境准备,未改项目文件。 - DM8:服务 `DmServiceDMSERVER` 运行中,监听 `127.0.0.1:5236`(PID 5692),账号 `SYSDBA/SYSDBA`,schema `LX`。 **本次完成的构建与运行** - 后端 `mvn -B -DskipTests clean package` 通过,产物 `emergency-repair-server\target\emergency-repair-server-1.0.0-SNAPSHOT.jar`(约 27MB)。 - 前端 `npm install` + `npm run build` 通过,产物 `emergency-repair-web\dist`,仅两个既有包体积告警。 - 后端用 `java -jar target\emergency-repair-server-1.0.0-SNAPSHOT.jar` 后台运行,监听 `8091`(PID 61648);前端用 `node node_modules\@vue\cli-service\bin\vue-cli-service.js serve` 后台运行,监听 `8082`(PID 57052)。日志为项目根的 `backend.log` / `frontend.log`(`*.log` 已被 `.gitignore` 忽略)。 - HTTP 验证:`POST /api/auth/login`(`admin/admin123`)返回 `code=200`;`GET http://localhost:8082/` 返回 200;前端 `/api` 代理到 8091 链路通。登录 `admin / admin123`。 **本次唯一代码改动(已获用户确认)** - `emergency-repair-web\src\utils\sensitive.js`:敏感词运行时替换改为跳过表格数据单元格。 - 口径:`<td>` 内的文本与属性保持代称;`<th>` 表头、页面标题、筛选标签、placeholder 照常替换。 - 实现:新增 `isInsideTableCell()`(`closest('td')`),接入文本遍历、属性替换、`MutationObserver` 字符变化回调,以及 `replaceDom()` 直接收到文本节点的分支。 - 验证:向运行页面注入探针表格(表头与数据格均写 `X号`),结果为 `<th>县号</th>`、`<td>X号</td>`;`npm run build` 通过。 - 效率影响:表格场景通常更快;没有表格且高频更新普通文本时,仅增加 `closest('td')` 的少量判断开销。 **用户本次明确的工作方式要求(务必遵守)** - 用户问“可不可以……”时只是要调查结论和方案,**不要直接改代码**;只有用户明确要求实施时才动文件。 - 改动前先说明要改什么,口径不明确时先问清楚。 **下次接续** 1. 先确认 `5236 / 8091 / 8082` 是否在监听,不在再按上面的命令重启(本机启动需显式设置 `JAVA_HOME`,Maven / Node 用绝对路径)。 2. `sensitive.js` 改动已获确认并随本次提交推送;`requirement\~$原始需求.docx` 是 Word 锁文件,不要提交。 3. 需求侧待确认项不变:决策表 B6–B10、AXU15 字段来源与可改性、完工验收各环节角色与打印输出、修后质量评级与 AXU14 T员评分字段的关系。 4. 后续改动完成后推送到公司 Git 仓库 `main` 分支。 emergency-repair-web/src/utils/sensitive.js
@@ -12,6 +12,16 @@ !(realName.startsWith('[') && realName.endsWith(']')) } // Table body cells render stored data, so they keep the codenames from the // source instead of being rewritten like headers, labels and placeholders. function isInsideTableCell(node) { const element = node && node.nodeType === 1 ? node : node && node.parentElement if (!element || !element.closest) { return false } return !!element.closest('td') } function replaceAsciiCodename(value, codename, realName) { const pattern = new RegExp('(^|[^A-Za-z0-9])' + codename + '(?=$|[^A-Za-z0-9])', 'g') return value.replace(pattern, function (match, prefix) { @@ -57,11 +67,16 @@ return } if (root.nodeType === 1) { attributes.forEach(function (attribute) { replaceAttribute(root, attribute) }) if (!isInsideTableCell(root)) { attributes.forEach(function (attribute) { replaceAttribute(root, attribute) }) } } root.querySelectorAll('[placeholder], [title], [aria-label]').forEach(function (element) { if (isInsideTableCell(element)) { return } attributes.forEach(function (attribute) { replaceAttribute(element, attribute) }) @@ -74,7 +89,9 @@ } if (root.nodeType === 3) { replaceTextNode(root) if (!isInsideTableCell(root)) { replaceTextNode(root) } return } @@ -85,9 +102,10 @@ { acceptNode: function (node) { const parent = node.parentElement return parent && !SKIPPED_TAGS[parent.tagName] ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT if (!parent || SKIPPED_TAGS[parent.tagName] || isInsideTableCell(parent)) { return NodeFilter.FILTER_REJECT } return NodeFilter.FILTER_ACCEPT } } ) @@ -107,7 +125,9 @@ observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.type === 'characterData') { replaceTextNode(mutation.target) if (!isInsideTableCell(mutation.target)) { replaceTextNode(mutation.target) } return } mutation.addedNodes.forEach(function (node) {