Files
dsh_shenxian/dsh-server-docs/04-调整方案/143-MCN工作台入口失效与语言切换显示修复.md
admin e6207aa691
build / build-and-scan (push) Waiting to run
chore(仓库对齐): 文档库结构治理 + IM/插件线落地
文档库:目录改为编号制(01-规范/02-架构设计/03-数据库/04-调整方案/
05-交接单/06-ops/07-scripts/08-skills/09-archive),顶层散文件归入 01-规范/;
INDEX.md 与 docs-manifest.json 重刷(档案 146 篇);旧目录名引用全量对齐。

IM 线:src/im/**(SDK / hub / store / presence / ws / gateway-token)、
src/web/routes/im.ts、src/db/plugin-data/**、src/supervisor/plugin-assembly.ts
及对应 test/**。

插件线:poc/{im-agent-bridge,im-connection-gateway,im-conversation-tabs,
business-plugins-im,carbon-mcp-probe}、src/web/routes/{sessions,overlay-device}.ts、
src/net/relay/{device-grant,instance-credential}.ts。

仓库卫生:清出 40 个历史误入库 / 已改名文件(34 个交接单归档 + 6 个旧结构,
本地均有副本);dsh-server-docs/.gitignore 补 tmp/;交接单不入库(政策)。
2026-09-24 07:25:16 +08:00

9.6 KiB
Raw Permalink Blame History

143 · MCN工作台入口"点了没反应" + 用户设置里切语言"没反应"

  • 日期:2026-09-20
  • 触发:用户「admin账号dsh会话 点击左侧 MCN工作台入口 没有反应,找到原因修复后把MCN任务会话入口的位置改到MCN工作台 header区域(用图标即可)」+「设置选项中 用户设置里面切换 语言还是不起做用」
  • 对象:dsh-plugin-mcn-suite 0.3.10 → 0.3.11(客户端源 = dsh-plugin-mcn/lib/client.js)· @dsh-local/portal-entry 0.5.5 → 0.5.6
  • 状态:✅ 已落地,真机浏览器实测通过(admin 实例,47)

TL;DR|两条都是 dsh 0.1.5-rc.1 与插件里写死的老契约不一致,不是用户操作问题: ① 对话区槽位名从 conversation 改成 main.conversation ⇒ 插件 querySelector('[data-slot="conversation"]') 实测恒为 null ⇒ 工作台面板根本不挂载(面板宿主 pageHost 一直 null,portal 不渲染)="点了没反应"。 ② ctx.locale.getLocale() 由"返回 id 字符串"变成返回快照对象 {active,locales,revision} ⇒ String(obj).split("-")[0] 恒为 "[object Object]" ⇒ 受控 <select> 匹配不上任何 option, 浏览器只显示第一项(English) ⇒ 选「中文」时界面看着毫无变化(其实本来就是中文,是显示错)。 同时按用户要求把「MCN任务会话」入口从左侧栏独立一行搬进工作台 header(图标按钮)。


一、取证(先证后改,全部为实测)

# 结论 证据
1 线上插件客户端代码 = 本地源码(不是改不生效) 实例内 dsh-plugin-mcn-suite/lib/client.js md5 = 本地 dsh-plugin-mcn/lib/client.js 拼装产物 md5(f1a3cf7c…)
2 实例跑的是 dsh 0.1.5-rc.1(插件按 0.1.2-rc.1 写) /usr/local/bin/dsh --version = 0.1.5-rc.1
3 槽位名已改名 浏览器实测 document.querySelector('[data-slot="conversation"]') = null;页面上 29 个 data-slot 里是 main.conversation(父 main、祖父 .centerCol,两者都是 display:contents 透明容器,与旧结构同形)
4 语言取值形态已变 官方 dsh-client-locale/lib/client.js:getLocale() return this.snapshot(={active,locales,revision})
5 语言下拉"显示错"可复现 用户设置里 select 的 DOM value="en"/selectedIndex=0,而 document.documentElement.lang = zh-CN(即界面本来就是中文)

取证手段:mksess.cjs(admin 临时会话)+ agent-browser(set headers 无效 ⇒ 改用 eval document.cookie='sid=…; domain=.ai1net.com' 注入)+ eval 探针。用完删会话(user_agent='poc-curl2')。


二、改动

2.1 dsh-plugin-mcn-suite 0.3.10 → 0.3.11

源改在 dsh-plugin-mcn/lib/client.js(该包是整合包的源,构建脚本按序拼接;整合产物 dsh-plugin-mcn-suite/lib/client.js 由脚本重生成,勿手改):

  1. 槽位自适应:新增 CONVERSATION_SLOT_SELECTORS = ['[data-slot="main.conversation"]', '[data-slot="conversation"]']
    • findConversationSlot(),conversation 的取值改为调用它(两个名字都认 ⇒ 跨 dsh 版本都能挂载)。
  2. 配套 CSS 同步:.mcnNav_split>[data-slot='conversation'] 与 …>div{…} 两条规则各补 ,….mcnNav_split>[data-slot='main.conversation']…。
  3. 入口搬家:删除侧栏独立入口组件 AiSessionsTrigger 与其注册(id: mcn-sessions, order: 61); McnPage 新增 openAiSessions()(setEntryParams(null); setView("ai-sessions"))并在 header(面包屑右侧工具条) 增加图标按钮(新增 V1_ICON_INNER.chat = Lucide messages-square),面包屑补 ai-sessions → 「MCN任务会话」。

2.2 @dsh-local/portal-entry 0.5.5 → 0.5.6

currentLocale() 兼容两种形态(对象取 .active,并兜底 getSnapshot().active;字符串形态照旧)。pickLocale / setLocale 不动。

2.3 构建链上顺带修掉的两处负向回归(同轮,属"随手一构建就会把已删功能装回去")

# 问题 处置
A build-mcn-suite.cjs 的 CLIENT_SOURCES / HOST_SYNC 仍列着 dsh-plugin-mcn-schedule,而 v0.3.10 已按用户指令摘除计划任务(HOST_PARTS 只剩 mcn+voxemw,线上产物 lib/host/ 无 schedule)⇒ 一构建就把「计划任务」装回去 两处同步删掉该条目(与 lib/index.js 的 HOST_PARTS 对齐)
B dsh-plugin-mcn/lib/client.js 里 v0.3.10 的「更多功能 → 自动任务」摘除编辑丢了(线上产物是注释、源文件里还是死链按钮 openEntry("entry:mcn-schedule")) 源文件补回同一处编辑(改成说明注释)
C pack 未排除 tgz ⇒ 历史散落在 suite 根的 dsh-plugin-mcn-suite-0.3.10.tgz(1.9 MB)会被打进新包 --exclude=*.tgz + 若命中即抛错;历史 tgz 移到 dist/

A/B/C 都是为了满足**「新产物 = 线上产物 + 本次修复」**这一可核验性质:重打包后与线上 0.3.10 的 diff = 9 个 hunk / 51 行,全部是本次改动。


三、验收

# 口径 结果
A 语法 / 构建 ✅ 两个源文件 node --check 通过;build-mcn-suite.cjs client 自检全绿(load=1 / collect=5 / exports.default=0)
B 产物核验 ✅ dist/dsh-plugin-mcn-suite-0.3.11.tgz(436 条目 / 1.90 MB / md5 0b84b3bc…);顶层只有 package/,无 .bak/node_modules/tgz;portal-entry-0.5.6.tgz(4 文件,两个半边都在)
C 与线上旧产物的差异面 ✅ 仅 9 hunk / 51 行,全部为本次改动(见 §二 2.3 注)
D 投放 ✅ admin:pnpm add 实装 0.3.11(bundles=7 含本包)· portal-entry 实装 0.5.6;旧产物归档 business-plugins/.bak/dsh-plugin-mcn-suite-0.3.10.tgz
E 浏览器实测(三段式) ✅ ① 点「MCN工作台」⇒ hash=#/mcn、[data-mcn-split] 与 [data-mcn-panel] 均出现、面板正文为「MCN 工作台 / 热点数据 / 账号列表 / AI写脚本 / 脚本诊断」;② 点 header 的「MCN任务会话」图标 ⇒ 面包屑「MCN 工作台 / MCN任务会话」、页标题与计数正常;③ 左侧栏已无独立「MCN任务会话」行;④ 语言:初始 select=zh(修前是 en,界面却是中文)、选 English ⇒ lang=en 且整站变英文、选 中文 ⇒ lang=zh-CN 且回中文;⑤ 持久化:<home>/settings.yaml 出现 locale: preference: zh
F 平台侧校验 ✅ scripts/verify-portal-entry.mjs 全绿(28 条)(本轮把「快照对象取 .active」补成断言,防回退)
G 收尾 ✅ 测试会话已删(PG sessions where user_agent='poc-curl2' = 0);服务器 /tmp 暂存件已清

四、边界 / 未覆盖

  1. ✅ guest(实例在 w-106)已补齐(2026-09-20 09:1x–09:3x,同一会话内追加):106 上 @dsh-local/portal-entry 已从 0.5.5 → 0.5.6(pnpm add 成功、dsh.profile.bundles 含本包、包内 client.js 命中 v = v.active), 实例停过后由平台按需拉起;浏览器实测:初始态 document.documentElement.lang = zh-CN 且下拉 = zh(修前恒显示 en), 切 English ⇒ lang=en + 下拉 en(一致)⇒ 修复在 guest 同样生效。 ⚠️ dsh-plugin-mcn-suite 在 106 上仍未安装 —— 它本来只有 admin 装(MCN 工作台是 admin 的自研插件),不是遗漏。 手段 = 新脚本 scripts/install-plugin-for-user.cjs(见档案 144 §二:把"给某个用户装某个 tgz"收敛成机器无关的原子动作)。
  2. dsh 版本契约(槽位名 / locale API)属跨版本耦合点:这次是"改名"型破坏,插件侧已做成双名兼容; 若 0.1.6 再改名,CONVERSATION_SLOT_SELECTORS 是唯一落点(一处集中维护)。

五、可复用结论(跨会话)

  • 🔴 「点了没反应」先查宿主契约:MCN 工作台靠 document.querySelector('[data-slot="…"]') 找宿主 ⇒ 槽位名是外部契约, dsh 升级后必须用浏览器确认名字(本次 conversation → main.conversation)。判据:[data-mcn-panel] 是否出现。
  • 🔴 官方 locale 是"两形态"API:getLocale() 在 0.1.5-rc.1 返回快照对象;凡读当前语言必须取 .active。 表现具有欺骗性:下拉显示 English 但界面是中文 ⇒ 别按"界面语言对不对"判断,要看 document.documentElement.lang + select 的 value。
  • 🔴 重打包前先做"产物差异面"核验:把新产物与线上在跑的那份做 diff,确认差异只含本次改动 —— 本次正是靠它抓到 A/B/C 三处"一构建就负向回归"(计划任务复活 / 死链菜单项 / 历史 tgz 打进包)。
  • 🔧 浏览器实测的可行姿势:mksess.cjs 造 admin 会话 → agent-browser:set headers 注 Cookie 不生效, 改用 open https://ai1net.com/login.html + eval document.cookie='sid=…; domain=.ai1net.com; path=/' → 再 open 实例子域。 另注:agent-browser 在本机前台会被沙箱杀(SIGTERM),用 run_in_background 起一次(守护进程常驻)后,后续命令加 > 文件 2>&1(不走管道)即可前台跑。
  • 🔧 手动跑平台脚本要带运行环境:/etc/dshs.env + dshs.service.d/*.conf 的 Environment=(否则 DSH_PLATFORM_DIR 缺省, artifactDir() 会落到 /root/.dshs/platform/artifacts)。脚本模板见 .workbuddy/tmp/run-with-platform-env.sh。