# 插件接入验收(静态面·用 MCN 插件)+ MCN 工作台移动端独占屏幕(2026-09-25) > **一句话**:① 拿**真插件**(`dsh-plugin-mcn`)走了一遍接入的**静态面验收** —— 声明过校验、库名换算正确、 > DDL 正确,同时抓出**两条会让人返工的实测结论**;② 修掉"MCN 工作台在移动端一半会话一半插件、没法用" > —— 窄屏改为**独占**;③ `08-插件开发与对接规范` 新增 **§4-补 移动端 / 窄屏兼容(硬要求)**。 > **两件都未部署**(本机无 PG、无容器 ⇒ 真机验收与部署合并为下一棒)。 --- ## 一、接入验收(静态面)—— 用真插件跑平台真校验器 **跑法(可复现)**: ```bash node 交付物/插件接入验收-静态面-20260925.mjs # 默认插件 = D:/dshworkspace/plugin_package/dsh-plugin-mcn node 交付物/插件接入验收-静态面-20260925.mjs <插件包目录> # 换插件 ``` 判据来源**不是**本仓库单测,而是**平台真实现** `lib/db/plugin-data/schema.js`(与门户「检测第 3 项」同一个函数) ⇒ 这就是"插件会话照文档做"会遇到的同一套校验。脚本**只读**:不建库、不连 PG、不改插件包、不上传。 ### 验收结果(全绿) ``` 声明来源 origin = yaml-file ← 必须由 package.json 的 dsh.data.schema 指向 ✅ 声明通过校验:3 张表 · schemaVersion=1 · source=./dsh.data.yaml ✅ hot_accounts scope=user · 12 列 · 2 索引 · 物理名 p_dsh_plugin_mcn_hot_accounts ✅ account_videos scope=user · 15 列 · 2 索引 · 物理名 p_dsh_plugin_mcn_account_videos ✅ account_analysis scope=user · 5 列 · 1 索引 · 物理名 p_dsh_plugin_mcn_account_analysis ✅ 库名换算:dsh-plugin-mcn ⇒ dshs_pl_dsh_plugin_mcn(过白名单 ^dshs_pl_[a-z][a-z0-9_]{0,40}$) ✅ 声明自算库名与换算一致(运行时「库名不一致即拒」判据的正面用例) ✅ 每张表都是「(归属列, 声明第一列)」复合主键 —— ⛔ 无代理自增 id ✅ 归属列已由内核补齐(scope:user ⇒ user_id) ``` **建库后库内 DDL(8 条)**:3 张表 + 5 个索引,形如 ```sql CREATE TABLE IF NOT EXISTS "p_dsh_plugin_mcn_hot_accounts" ( "user_id" TEXT NOT NULL, "created_at" BIGINT NOT NULL, "updated_at" BIGINT NOT NULL, "account_key" TEXT NOT NULL, … , PRIMARY KEY ("user_id", "account_key")); CREATE UNIQUE INDEX IF NOT EXISTS "p_dsh_plugin_mcn_hot_accounts_account_key_uq_1" ON … ("account_key"); ``` ### 🔴 验收抓出的两条实测结论(**会让人返工,已回写文档**) 1. **只把 `dsh.data.yaml` 放进包里 = 不生效**。本次第一跑 `origin = none` —— 因为没有 `package.json` 的 `dsh.data.schema` 指向。平台**不自动探测**该文件名(`schema.ts:701-746` 现读)。 ⇒ `08 规范 §3-1` 已写这条(**我这次是没先读文档才踩的,反证该条写得对**);同时提醒:`files` 字段 也要带上 `dsh.data.yaml`,否则 `npm pack` 不打包它。 2. **存量表的自增 `id` 不能照搬**。数据面主键 = `(归属列, 声明第一列)`,**没有代理 id 列** ⇒ MCN 原有的 `id INTEGER PRIMARY KEY` 必须换成**业务键**(本次声明用 `account_key` / `aweme_id` / `analysis_key`,取值规则 = `<账号名>` 或 `<账号名>:<时间戳>`)。这是"存量插件接入"最先撞的一堵墙。 ### 验收同时得到的"接入前置条件"读数 **红线扫描(`DB-03 §二`)命中 21 处**,全在 `lib/db.js`(`CREATE TABLE` × 11 + 迁移语句等) ⇒ **MCN 当前形态不合规**(DB-03 红线 6:⛔ 不得以实例本地库为权威)。接入路径 = 把 `db.js` 的读写 换成经内核 API(`/api/im/data/*` 或 SDK)⇒ 属**插件侧改造**,工作量大,需单独排棒。 --- ## 二、MCN 工作台 · 移动端独占屏幕 ### 病象与根因 **病象**(用户实测):手机上点开 MCN 工作台 ⇒ **一半会话窗口、一半插件窗口**,两侧都不可用。 **根因**(代码级,`dsh-plugin-mcn/lib/client.js`): 工作台把宿主的会话区搬进一个 `flex-direction:row` 的容器(`.mcnNav_split`), 再追加一个宽度 **50%**(`.mcnNav_panel`,行内 `style.width`)的面板 ⇒ **窄屏上两栏各半**,而面板内表格内容宽 **720px**、操作按钮也摆不下 ⇒ 不可用。 插件此前**没有任何视口断点**(只有主题判断)。 ### 改法(纯样式 · 单文件 · 独立成段) 新增一段独立样式 `data-plugin-css="mcn-mobile"`(⛔ 不碰既有三段样式),一条 `@media (max-width:900px)` 内含四组规则: | 组 | 规则 | 为什么必须这么写 | |---|---|---| | ① **独占** | `.mcnNav_split{display:block}`|会话区与 `.mcnNav_resizer` `display:none!important`|面板 `width:100%!important` | 面板宽度是**行内 style** ⇒ 只有 `!important` 盖得住;宿主给会话区设了 `display:contents` ⇒ 隐藏也必须 `!important` | | ② 触摸目标 | 按钮/标签 ≥44px;图标按钮 44×44 | WCAG 2.5.5 / iOS HIG | | ③ 输入字号 | input/select/textarea `font-size:16px` | <16px 时 iOS Safari 聚焦会**放大整页** | | ④ 窄屏适配 | 弹窗 `width:calc(100vw-32px)`、`min-width:0`|宽弹窗与对比面板改竖排|统计条换行、字号收小|表格单元格间距放宽 | 原先 `min-width:320px` +固定宽度在 320px 视口上必然横向溢出 | **为什么取 900px**(而非"手机断点"768):≤900px 时两栏各 <450px,表格/表单都不成立 ⇒ 桌面窄窗口与平板共享同一条判据,不维护第二套阈值。 **宽屏(>900px)行为逐字不变** ⇒ 只做正向迭代。 **退出路径**:复用面包屑上既有的关闭按钮(已放大到 ≥44px 触摸目标)⇒ 关掉即恢复会话区, ⛔ 不新增控件、⛔ 不动 React 结构(改动面 = 一段 CSS 数组,可单独回滚)。 ### 本轮做过的校验(**不是**真实浏览器验收) ``` node --check lib/client.js → ✅ 语法通过(改动前后均过) mcn-mobile 段存在 / @media 规则 1 条 → ✅ ``` ⚠️ **未做**:真实浏览器/真机视觉验收(见下)。 --- ## 三、文档(同批) | 文件 | 变更 | |---|---| | `01-规范/08-插件开发与对接规范.md` | **新增 §4-补 移动端 / 窄屏兼容(硬要求)**(断点表 + 四条硬判据 + 三条 ⛔ + 六条自测 + 参考实现指针)|`§7` 自测清单补「移动端专项」|头部状态块补一行|`§11` 变更记录补 2026-09-25 | | 同上(上一轮同批) | `§3-4` 数据面取数链路重写 + `§6` 错误码 + `§7` 取数自测 | --- ## 四、未做(⛔ 不许看成已闭环) 1. 🔴 **未部署、未真机验收**(本机无 PG、无容器 ⇒ 数据面建库/取数在本机跑不了)。合并成一棒: **部署 47 → 数据面真机自测(四拒一空 + insert/find 回读)→ MCN 工作台移动端视觉验收 (375×667 独占 / 能退出 / 无横向溢出 / 聚焦不缩放 / 横屏可用)**。 2. **MCN 插件未改造为"数据面接入"**:仅补了**声明 + package.json 指向**(`dsh.data.yaml`、`dsh.data` 键、 `files` 带上该文件)—— 读写仍走本地 SQLite(红线扫描 21 处)。⚠️ **未上传、未投放** ⇒ 在线用户零影响。⚠️ **注意**:一旦把带声明的版本传到共享层,平台检测会判它"有数据面" ⇒ **未建库前所有用户都无法启用**(门禁 ②)。**顺序必须是:先建库 ⇒ 再投放**。 3. **移动端改动只覆盖 MCN 工作台**。其它"占用宿主区域"型插件(如门户入口/会话标签页) 是否同样有窄屏问题 ⇒ **未普查**(§4-补 已把判据写成硬要求,可用于逐个复查)。