1) dsh-server-docs/ 从工作区(原 E:\...\aliyun-dsh-server\dsh-server-docs)**整体并入本仓**,
保留目录名 ⇒ 仓库内 dsh-server-docs/... 的相对引用天然继续有效;旧目录(含其 .git)已归档到
工作区 _中间产物_待清理/,未随本提交带入。
2) .gitattributes:新增 `dsh-server-docs/** -text` —— 原文档库是 `* -text` + autocrlf=false,
必须保持纯 LF,否则会被本仓的 CRLF 规则翻掉。
3) 活引用里的绝对路径已全部改到新位置(docs 的 INDEX / README / scripts / skills + 用户级 skills
+ ~/.workbuddy/settings.json 的 hooks);历史档案(04-调整方案/、archive/)按「只增不改」未动。
⚠️ hooks 路径改动需「完全重启会话」才生效(配置是会话启动快照)。
4) 交接单/T08:新增 §16「生产整体切换执行记录」(形态 / 落地动作 / **4 个只有真上线才暴露的真 bug** /
验收证据 / 回滚命令 / 残留项);台账 T08 行 → 已完成并归档;03-路线图 §二 登记 T08 收尾项。
5) 统一称谓:**「本机」只指跑 WorkBuddy 的开发机**,47 / 106 一律写「远程服务器」。
6.1 KiB
60 · 设置面板分区改名:功能插件 → 功能管理
- 日期:2026-09-12
- 状态:✅ 已实施并验证(服务器已生效;本地待提交)
- 触发:用户「平台管理改为用户管理放到功能插件下面,将功能插件改为功能管理」
- 关联:档案 57(「平台管理」→「用户管理」+ 移到功能插件下方 —— 本次需求的前两项)、38(术语统一「业务插件」→「功能插件」)、36(功能插件分区诞生)、18 v3(同一设置面板的另一个 section)
一、需求拆解与状态核实
用户这次说了三件事,前两件在档案 57 已做完,本次是第三件。先把实例里实际加载的内容查清(而不是看文档):
| 需求 | 实例内实际状态(改动前实测) | 结论 |
|---|---|---|
| ① 平台管理 → 用户管理 | portal-entry v0.5.1,section id: user-management,label: 用户管理 |
✅ 已生效(档案 57) |
| ② 放到功能插件下面 | portal-entry order: 102 > business-plugins order: 101 |
✅ 已生效(档案 57) |
| ③ 功能插件 → 功能管理 | business-plugins v0.2.1,section.label: 功能插件 |
❌ 本次要做 |
用户重复提① ②,多半是浏览器缓存:设置面板的 section 名由客户端 bundle 运行时注册,页面不硬刷新就还是旧的 JS。已在上线说明里明确"需硬刷新"。
二、改动
只改一个东西:分区标题。 poc/business-plugins/(代码库内,真源)→ @dsh-local/business-plugins v0.2.1 → v0.2.2。
| 位置 | 改动 |
|---|---|
lib/client.js 第 61 行 |
"section.label": "功能插件" → "功能管理" |
lib/client.js 第 89 行 |
"section.label": "Feature plugins" → "Feature management"(中英同步,否则切英文界面会不一致) |
package.json |
version 0.2.1 → 0.2.2 + description 记录本次变更 |
刻意没有改的地方
同一份 locale 字典里还有几处「功能插件」字样,都保留了:
empty:「暂无功能插件(需管理员在门户投放)」confirm:「确认应用功能插件更改?…」rejected.title:「以下插件与实例不兼容,已自动禁用」
理由:这些句子描述的是「插件」这个事物,不是分区名 —— 分区叫「功能管理」,里面管理的对象仍然叫「功能插件」。全文替换会让文案变成「确认应用功能管理更改?」这类不通顺的说法。 同理,文档与代码注释里的「功能插件」术语一律不动(档案 38b 已把术语统一到「功能插件」,本次只动 UI 分区标题这一个字符串)。
三、安装与验证
| 步骤 | 做法 / 结果 |
|---|---|
| 打包 | cp -r 整目录复制 → npm pack → /opt/dsh/artifacts/business-plugins-0.2.2.tgz;包内清单与源清单 diff 一致(4 文件:package.json / cordis.patch.yml / lib/client.js / lib/index.js) |
| 同步源码 | /root/bp-build/business-plugins/. → /opt/dshs/poc/business-plugins/(仓库内真源) |
| 全员升级 | node scripts/ensure-biz-plugins.cjs --all --restart → admin、guest 均 版本落后(0.2.1 → 0.2.2),升级中… → ✓ bundles=5(含 @dsh-local/business-plugins: true) |
| 文件校验 | 两个用户 node_modules/@dsh-local/business-plugins 版本 = 0.2.2,label=section.label": "功能管理" |
| 编码校验 | grep -o 功能管理 | od -c → 345 212 237 350 203 275 347 256 241 347 220 206 = UTF-8 双字 12 字节(排除被写成 GBK / 转义序列的常见事故) |
| 生效判定 | 升级时报「已停 0 个实例 scope」→ 其后由访问触发全新启动 → 必然加载 0.2.2(无需再重启) |
为什么没做浏览器渲染验证:section 名在运行时由 client bundle 注册,curl 抓不到渲染结果;/plugins/??<pkg>/client.js 直取返回 401(该组合加载端点不接受独立请求)。文件 + 版本 + 编码 + 加载时机四者已闭环,渲染机制沿用 v0.2.x 生产验证过的实现。请硬刷新会话页确认。
踩坑:pack 必须整目录复制
档案 57 已经栽过一次 —— 手工逐个 cp 漏了 lib/index.js,导致全实例崩溃循环。本次沿用「cp -r <src>/. <build>/ + 打包后强制 diff 清单校验」的流程,清单一致才继续。
清理
ensure-biz-plugins.cjs 用的是旧姿势(把 tgz 复制进 ws + HOME=<ws> 跑 pnpm,无 store 隔离)→ 会在 ws 留下安装残留。本次移入 <userRoot>/trash/2026-09-12-ws-installer-residue/(移走不删除,30 天后由 purge-trash.sh 真删):
- admin:
business-plugins-0.2.1.tgz、business-plugins-0.2.2.tgz、portal-entry-0.4.3.tgz、workspace-scoped-picker-0.1.4.tgz(4 个) - guest:3 个(其余不存在)
保留 .local/、.cache/:那是 pnpm 的 store / metadata 目录,删掉会让下次 pnpm add 重新下载全部依赖(且会再次触发档案 57 记录的 ERR_PNPM_UNEXPECTED_STORE),副作用大于收益。
四、遗留(与本次相关)
ensure-biz-plugins.cjs的旧安装姿势(档案 57 §五.2 已记):它用HOME=<ws>且不隔离 store → 每次都会污染 ws(本次 4 个残留即由此而来),且升级已有 node_modules 时同样会撞ERR_PNPM_UNEXPECTED_STORE(本次侥幸没撞,因为它的 store 恰好仍是 ws 内路径,与.modules.yaml记录一致)。 建议:与ensure-portal-entry.cjs对齐 —— 暂存到<home>/.dsh-stage/、读.modules.yaml沿用 storeDir、setpriv以用户身份安装。web/wake.html双端不一致(档案 59 §四已记):本机 4708 B / 服务器 4591 B,待核对同步。
五、回滚
# 退回 0.2.1(旧包仍在 artifacts 里)
NODE_OPTIONS= node /opt/dshs/scripts/ensure-biz-plugins.cjs --all --restart # 需先把 artifacts 里的新包挪走
# 或直接改回源码字符串后重打 0.2.3 再铺
回滚后需重启实例(bundle 在实例启动时加载)。