09-10 工作台:配置收敛、复盘字段契约修复、原创选题分镜支持、榜单期号区间显示

配置收敛:
- 端口/DB名/产出根/榜单目录单源化到 mcn-work-shop/config.json,代码层统一经 load-config.js 读取
- 新增 get-port.js 供 start.bat 读端口(bat 内嵌 node -e 会被 cmd 截断,读到的是兜底值)
- start.bat 修复失效的 managed node 路径(原写死 22.22.2 已不存在),改为遍历 versions 自动探测

复盘诊断页(真 bug 修复):
- 问题清单严重度全部显示成绿色 + 修改建议不显示:模型输出 {sev:'high',fix} 与前端读取 {severity:'高',suggestion} 字段名与取值均不匹配
- 前端新增 normIssue 归一化,兼容 sev/severity/level 与中英取值,并回补所属维度显示
- 在 submit-review-tasks 与诊断/复盘 prompt 中固化 issues_json 字段契约,从源头防 schema 漂移

分镜提示词:
- 原创选题(video_id 为空)原本无生成入口(分镜按 video_id 查询)
- listStoryboards 支持按 rewrite_id 查询,前端放开入口、切版本重查,并补落库指令(此前入库靠模型自由发挥)

榜单展示:
- 期号改为显示区间「08/31 ~ 09/06」,避免被误读为单日(期号=该周周一)
- 后端新增 collectRanges,从落盘文件读真实 dateStart/dateEnd 随 API 返回(日榜 start=end 不显区间)

其他:
- 清理 dsh 环境废弃后的历史叙述类废话(16 文件约 18 处),文末变更记录区保留
- 新增 docs/工作台UI规范.md(设计 token / 布局 / 8 页面路由 / 12 类组件 / 9 条已知坑)
This commit is contained in:
maogeigei committed 2026-09-10 18:28:42 +08:00
1 parent 6cb29a9877
commit c48902f063
58 files changed
+895 -263

No files matched your search

@@ -6,7 +6,7 @@
## 触发链路(所有入口共用)
按钮点击 → 确认弹窗(confirmRun / confirmAiScript / confirmSaveAccount)→ `executeTask()` → `POST /api/run`(server.js 写 automations 表,scheduledAt=now+5s + next_run_at=now+5000,`skills` 数组→`skills_json` 参数级技能挂载)→ 客户端调度器拾取 → 左侧会话栏「mcn-workshop」空间后台会话执行 → 轮询 `/api/run/status`(done/error/review)→ 完成刷新页面。
按钮点击 → 确认弹窗(confirmRun / confirmAiScript / confirmSaveAccount)→ `executeTask()` → `POST /api/run`(server.js 写 automations 表,scheduledAt=now+5s + next_run_at=now+5000,`skills` 数组→`skills_json` 参数级技能挂载)→ 客户端调度器拾取 → 左侧会话栏「mcn-work-shop」空间后台会话执行(cwd = 工作台目录,由 `server.js` 从 `ROOT` 动态推导)→ 轮询 `/api/run/status`(done/error/review)→ 完成刷新页面。
## 功能入口 × 技能调用契约总表
@@ -0,0 +1,263 @@
# 短视频工作台 UI 规范
> **定位**:本文件是前端 UI 的**设计规范基线**(配色 / 字体 / 圆角 / 布局 / 组件 / 交互),供新增页面、调整样式时对照,避免重复踩坑。
---
## 1. 设计语言
亮色主题、工具类后台风格。三条主线:
1. **信息密度优先**——表格/列表是主体,行高紧凑(表格 td `7px 10px`,字号 15px)。
2. **克制配色**——蓝(`#2f6fed`)作主色承担交互反馈,橙(`#e8590c`)只用于强调数值/警示,其余靠灰度拉开层次。
3. **轻量质感**——圆角 8/12px、阴影 `0 1px 3px rgba(0,0,0,.08)`,不用重投影和渐变。
---
## 2. 设计 Token
### 2.1 色彩
| 变量 | 值 | 用途 |
|---|---|---|
| `--bg` | `#f5f6f8` | 页面底色 |
| `--panel` | `#ffffff` | 卡片/表格/弹窗面板 |
| `--border` | `#e3e6ea` | 统一描边 |
| `--text` | `#24292f` | 主文本 |
| `--dim` | `#6b7280` | 次要文本、说明、占位 |
| `--primary` | `#2f6fed` | 主色(按钮/激活态/链接 hover) |
| `--primary-soft` | `#eaf1fe` | 主色浅底(hover 行、激活 tab 底) |
| `--accent` | `#e8590c` | 强调(榜单得分、警示) |
| `--danger` | `#d93026` | 危险操作(删除) |
| `--shadow` | `0 1px 3px rgba(0,0,0,.08)` | 卡片/顶栏阴影 |
**扩展色(未进变量,直接写在规则里)**
| 场景 | 值 |
|---|---|
| 表头底色 | `#f6f8fa` |
| 链接蓝 | `#4a90e2` |
| 主色 hover 深一档 | `#2a5fd0` |
| 图标垂直微调 | `vertical-align: -0.18em` |
| 文件类型色 | md `#8250df` / json `#cf222e` / xlsx `#1a7f37` / txt·csv `#57606a` |
| 半透明主色底 | `rgba(47,111,237,.07)`(首页统计条)、`.16`(分隔线) |
**功能图标亮色映射**(未列出的跟随 currentColor):
`trending-up` 橙 · `users` 蓝 · `pen` 粉 `#ec4899` · `flask` 青 `#0ea5e9` · `lightbulb` 黄 `#d99a2b` · `refresh` 青绿 `#0f7f8f` · `chart` 玫红 `#d6336c` · `wrench` 灰 `#5b6470`
### 2.2 字体
```css
font-family: "Microsoft YaHei", "PingFang SC", "Segoe UI", sans-serif;
font-size: 16px; /* body 基准 */
```
代码/JSON 预览:`Consolas, monospace`。
**字号阶梯**(实测归纳,不是硬 token):
| 级别 | 字号 | 用例 |
|---|---|---|
| 特大 | 26px / 21px | 首页统计数字、面包屑主标题 |
| 标题 | 18px / 17px | 弹窗标题、区块标题、卡片标题 |
| 正文 | 16px / 15px | 正文、按钮、表格、输入框 |
| 次要 | 14px / 13px | 说明文字、数值列、徽章、tab(小) |
### 2.3 圆角 / 阴影 / 层级
| 类型 | 值 | 用例 |
|---|---|---|
| 圆角 | 6px | 小控件(btn-sm、侧栏切换组、树节点) |
| | **8px** | 默认(按钮、输入框、表格容器、信息卡、评分块) |
| | 10px | 徽章、榜单容器、卡片 |
| | **12px** | 大卡片(首页 data-card、func-card、统计条) |
| | 14px | 弹窗 |
| 阴影 | `var(--shadow)` | 卡片、顶栏 |
| | `0 8px 30px rgba(0,0,0,.18)` | 弹窗 |
| | `0 4px 12px rgba(47,111,237,.15)` | 卡片 hover(主色扩散) |
| z-index | 10 顶栏 / 100 弹窗遮罩 / 200 Toast | 表头 sticky 为 1 |
### 2.4 间距
没有 token 化,实际使用序列:**2 / 4 / 6 / 8 / 10 / 12 / 14 / 16 / 18 / 20 / 24px**。常用组合:
- 卡片内边距 `16px 18px`;信息卡 `14px 16px`;表格单元 `7px 10px`;表头 `8px 10px`
- 页面外边距 `20px 24px`;首页/详情内容 `24px`;区块间距 14~24px
- 工具条内部 gap 8~10px;表单行 gap 10px
---
## 3. 布局框架
```
┌─ header.topbar(55px,sticky,白底 + 底部 1px 边框 + shadow,z-index 10)
│ brand(logo) · crumbs(面包屑) · top-actions(首页/帮助/设置,右侧)
├─ main#view height: calc(100vh - 55px) overflow: auto ← 唯一滚动容器
│ .home(max-width 960) / .page(max-width 1440)
└─ 弹窗层 .modal-mask(fixed inset 0,z-index 100)
```
**滚动(坑点,勿改)**
| 规则 | 原因 |
|---|---|
| `html, body { overflow: hidden }` | 消除顶栏 1px 边框引发的第二层滚动条 |
| `main#view { height: calc(100vh - 55px) }` | **55px 是实测值**(padding 20 + 行高 34 + 边框 1)。写成 54px 底部会溢出 1px,触发第二层滚动条 |
| 长内容滚动交给内部容器(`.rw-sec-body`、`.rw-content`、`.file-tree`) | 保持页面级不滚 |
**内容宽度**:首页 `.home` max-width **960px**;功能页 `.page` max-width **1440px**(padding 20 24);弹窗 `.rw-modal` 宽 `min(1600px, 100% - 100px)`、高 `calc(100vh - 60px)`。
---
## 4. 组件规范
### 4.1 按钮
| 类 | 外观 | 用例 |
|---|---|---|
| `.btn` | 白底 + border + `6px 14px` + r8 + 15px;hover 边框/文字变 primary;`:disabled` opacity .5 | 默认 |
| `.btn-primary` | primary 底白字;hover `#2a5fd0` | 主行动 |
| `.btn-ghost` | 透明底 + border | 次要/弹窗内 |
| `.btn-danger` | danger 系 | 删除 |
| `.btn-sm` | `3px 10px` / 14px / r6 | 表格功能列 |
| `.btn-icon` | `5px 9px`,纯图标 | 图标按钮 |
| `.btn-busy` | primary-soft 底 + primary 字 + opacity .8,内含图标旋转动画 | 异步进行中 |
| `.btn-import` | 白底 + `#d0d4da` 边 + `#495057` 字 | **保存类**(浅灰底深字) |
| `.btn-view` | 白底 + primary 边 + primary 字 | **查看类** |
> 功能列成对出现时:**保存=浅灰底深字(.btn-import),查看=白底蓝字(.btn-view)**,靠底色深浅区分而非都用蓝。
顶栏三按钮用 `.ghost`(白底 + border,`6px 14px`,r8)。
### 4.2 输入框
`.input`(`6px 10px`,min-width 200px)· `.input-select`(`6px 8px`,筛选下拉更窄)。均 1px border + r8 + 15px + 白底。
### 4.3 表格
```css
.table-wrap overflow auto + 1px border + r8 + 白底
.table width 100%, border-collapse collapse, 15px
.table th sticky top 0, 背景 #f6f8fa, 8px 10px, 600, nowrap, z-index 1
.table td 7px 10px, nowrap, 底部 1px border
tbody tr:hover 背景 var(--primary-soft)
```
| 修饰类 | 作用 |
|---|---|
| `.num`(td/th) | **右对齐** + `font-size: 13px` + `font-variant-numeric: tabular-nums`(等宽数字,必须加,否则数字跳动) |
| `.th-wide` | 数值列表头 min-width 90px + 右对齐 |
| `.sortable` | cursor pointer,hover 变 primary |
| `.cell-content` | max-width 220px + 省略号 |
| `.cell-loc` | 账号定位列缩窄 110px |
| `.th-act` / `.cell-act` | 功能列居中 |
| `.title-plain` | 视频标题:默认同正文色,**hover 才变蓝+下划线**(避免整列花掉) |
| `.link` / `.link.strong` | `#4a90e2`;`.strong` 加粗 |
**列宽策略(关键)**
| 场景 | 做法 |
|---|---|
| 榜单表格 `.table-rank` | **必须 `table-layout: fixed`**——auto 布局下 100% 表格的富余空间会按比例摊薄,**min-width 压不住**;fixed 下 width 才是硬约束,账号列自动吃剩余宽度 |
| 普通数据表格 | auto 布局,靠 `.cell-content` max-width + 省略号收口 |
**行高对齐(关键)**:榜单三个 tab 的行高必须统一,否则切换时整表跳动——
- 表格 `.table-rank td { height: 42px }`(功能列 `.btn-sm` 撑到 42px,其他 tab 原本只有 34.7px)
- 首页预览 `.rank-preview-list .rank-row:not(.rank-head) { min-height: 40px }`
### 4.4 Tab(两套并存,注意覆盖)
| 位置 | 样式 |
|---|---|
| 顶栏 | 胶囊式:r8,hover 浅蓝底蓝字,active **蓝底白字 + 600** |
| 数据页(**重新定义同名 `.tabs/.tab`**) | 下划线式:无背景无圆角,`border-bottom: 2px transparent` + `margin-bottom: -1px`(压住容器分隔线),active **蓝字 + 蓝色下划线** |
> ⚠️ 同名类二次定义,**数据页规则在后会覆盖顶栏规则**。新增页面若在下划线式区域用 `.tab`,拿到的是下划线式;需要胶囊式请另起类名。
榜单 tab `.rank-tab`:r8 8px 0 0(上圆角),active 浅蓝底 + 蓝字 + 底部 2px 蓝线。
首页预览里需 `align-self: center`(全局 `.rank-tabs` 用 stretch,会让 tab 组相对兄弟控件偏上约 5px)。
### 4.5 卡片
| 类 | 规格 |
|---|---|
| `.data-card`(首页入口) | r12,`16px 18px`,shadow,hover **上浮** `translateY(-2px)` + 蓝边 + `0 4px 12px rgba(47,111,237,.15)`,transition .15s |
| `.info-card`(信息区) | r8,`14px 16px`,margin-bottom 14px;标题 15px/600 + 底部 1px 分隔线 |
| `.recent-card`(脚本快捷卡) | r10,`14px 16px`,min-height **172px**(保证网格等高),hover 蓝边 + 淡影 |
| `.func-card` | r12,`16px 18px` |
### 4.6 徽章 / 标签
`.badge`:`2px 8px`,r10,13px。
- `.badge-signed` 浅蓝底蓝字(签约/内部)
- `.badge-ext` `#fff4e5` 底 + accent 橙字
- `.rw-ver-new` primary 底白字 r9 12px(最新版本标记,附在版本条最右)
- `.recent-card-score` 12px/600 r10
### 4.7 弹窗
```css
.modal-mask fixed inset 0, rgba(0,0,0,.35), flex 居中, z-index 100
.modal 白底 r14, 22px 26px, width 520px, max-width 92vw, shadow 0 8px 30px
.req-modal 760px × min(840px, 92vh) /* AI创作 */
.rw-modal min(1600px, 100% - 100px) × calc(100vh - 60px) /* 脚本对比/查看 */
```
> ⚠️ `.modal-mask[hidden] { display: none }` **必须显式写**——`.modal-mask` 是 `display:flex`,会覆盖 HTML `hidden` 属性导致弹窗关不掉。
**对比弹窗三段式(`.rw-*`)**:`.rw-stack`(flex row, gap 12)→ `.rw-sec`(flex 1, min-width 0, r8, overflow hidden)→ 内分 `.rw-sec-head`(8px 12px,白底,底部边框)/ `.rw-sec-body`(12px 14px,overflow auto)/ `.rw-sec-foot`(**min-height 46px**,右对齐,顶部边框)。
> `.rw-sec-foot` 的 min-height 是为了**空 foot(源脚本列占位)与其他列等高**,不能删。
### 4.8 Toast
固定在底部居中(`bottom: 32px`,`translateX(-50%)`),深底 `#24292f` 白字,`10px 18px` r8,z-index 200,**显示 1.8 秒后自动消失**。用于复制成功、保存结果等轻量反馈;失败重试类提示走行内 `.toolbar-note` / `.empty`。
### 4.9 空状态
`.empty-state`:纵向居中,`padding: 56px 20px`,gap 10px——图标(dim + opacity .45)→ 标题(17px/600)→ 说明(14px/dim)→ 行动按钮(margin-top 10px)。
轻量占位可用 `.empty`(`padding: 30px`,居中,dim)。
### 4.10 分页 / 批量
`.pager` 右对齐(gap 12,`padding: 12px 4px`);`.list-footer` 用 space-between 把批量操作条放左、分页放右;批量条 `.list-batchbar` 出现时与分页同行。
### 4.11 评分条
`.score-row`:名称 `.score-name` 固定 **88px** → 进度条 `.score-bar`(flex 1,height 6px,r3,底 `#eef1f5`)→ 分值 `.score-val` 固定 **36px** 右对齐。三档宽度固定,保证多行对齐。
### 4.12 图标
```js
svgIcon(name, size = 16, color) ;生成 class="ic" 的 SVG
```
- Lucide 风格:`viewBox 0 0 24 24`,`stroke-width: 2`,`fill: none`,`stroke: currentColor`
- 静态 HTML 用 `<i data-icon="home">` 占位,`initIcons()` 统一替换
- `.ic { vertical-align: -0.18em; flex-shrink: 0 }` ——**垂直微调 -0.18em,去掉会和文字基线错开**
---
## 5. 关键交互约定
| 约定 | 说明 |
|---|---|
| **数值一律右对齐 + 等宽数字** | `text-align: right` + `font-variant-numeric: tabular-nums`,列表头同步右对齐 |
| **字段对齐用 grid 列轨道共享** | 账号信息/视频详情的多行字段,用同一个 grid 让列跨行对齐;每行独立 flex 会因内容长短把后续字段顶偏(R44/R45 教训) |
| **超宽字段移出共享网格** | 如「账号定位」整行留在网格内会把 4 条轨道撑成等宽(各 232.5px),右侧大片留白 |
| **滚动联动单向** | AI 脚本列滚动驱动分镜列对齐,**不做双向耦合**(双向会互相抖动) |
| **长文本截断三件套** | `overflow: hidden` + `text-overflow: ellipsis` + `white-space: nowrap`,并挂 `title` 显示全文 |
| **hover 才提示可点** | 列表中的标题类文本用 `.title-plain`(默认同正文色,hover 变蓝+下划线),避免整列都是蓝字 |
---
## 6. 已知坑与规避
| # | 坑 | 规避 |
|---|---|---|
| 1 | `main#view` 写成 `calc(100vh - 54px)` → 底部溢出 1px,出现第二层滚动条 | 用 **55px**(padding 20 + 行高 34 + 边框 1) |
| 2 | 榜单表格用 auto 布局 → 列宽被富余空间摊薄,`min-width` 失效 | 加 `.table-rank { table-layout: fixed }` + 显式列宽 |
| 3 | 榜单三 tab 行高不一致 → 切换时整表跳动 | 表格 td 固定 42px;首页预览行 min-height 40px |
| 4 | `.modal-mask` 的 `display:flex` 覆盖 `hidden` → 弹窗关不掉 | 显式写 `.modal-mask[hidden] { display: none }` |
| 5 | 数值列没加 `tabular-nums` → 滚动/翻页时数字左右跳 | 数值列统一加 |
| 6 | 图标与文字基线错开 | `.ic` 的 `vertical-align: -0.18em` 不能删 |
| 7 | 首页 `.rank-tabs` 相对兄弟控件偏上 ~5px | 预览场景加 `align-self: center; margin-bottom: 0` |