v11b-report.md 12 KB

v11b 交付报告(补交,v11c 实测)

本轮(v11c)没有改任何视觉参数。所有数字都是脚本实测(Chrome 153 headless,1440×960),复现命令在每节末尾。 上一轮只有 docs/v11b-audit.json,没有报告;本文补上,并标注哪些项在 v11c 重测过。


0. 架构落点(v11c 主任务)

中英混排 U+2009 只在两处落,不做任何事后 DOM 改写:

落点 文件 管什么
数据边界 src/services/board-service.js:61 cjkDeep(buildModel(...))(v11b 已有,未动) 模型里所有字符串字段
渲染期 各模板字符串生成处调 t()(= src/pages/shared.js 的 cjkString),另有 src/core/kfs/util.js 的 fmtDate/fmtAgo/fmtAgoText 与 cjkSpace、src/core/taxonomy/taxonomy.js 的阶段 / 上传方式 label 模板里临时拼的串:S4 ${name}、${n} 小时前、${n} 人评分、最多 ${n} 份、被 ${n} 处支撑 …

v11c 本轮为 P0 做的改动(git diff 可查):

  • shared.js:导出 t;删掉渲染后遍历的 cjk(node)(已无调用方,留着会被下一轮误用)
  • components/cjk.js:t() 的内部规则改为直接调 cjkString,与数据边界同一份 SKIP 规则
  • core/kfs/util.js:fmtDate(…, true) / fmtAgo 在生成处走 cjkSpace;新增 fmtAgoText(卡住时长)
  • core/taxonomy/taxonomy.js:STAGES 的 label、uploadMethodLabel('skill') 在生成处走 cjkSpace
  • core/library/reports.js:优先级筛选项 S 级、whenText 占位句
  • core/opportunity/opportunity.js:排序标签 优先级 S→A→B
  • 视图 / 组件 / 外壳:view-workbench、view-members、view-pool、view-ledger、view-reports、view-stages、view-report-type、view-report、filter-sheet、card-toolbar、kf-app、kf-nav、kf-opportunity-card、kf-score-panel、kf-badge 各自主持的静态文案逐个包 t() 或改到生成函数里
  • kf-app.js:删掉抽屉正文的 requestAnimationFrame + createTreeWalker 事后改写(同类做法,一并移除)

排查中修掉的两个真 bug(不是排版问题):

  1. view-reports.js 里 c.types.map((t, i) => …) 的 t 把外层的 t() 遮蔽了 —— 运行时 t is not a function,/reports 整页白屏。已把回调参数改名 ty。
  2. view-members.js 的「卡住」时长原来是 ${m.stuckHours}h(「卡住 52h」,纯英制混排),且 stuckHours 在 lastActiveAt 缺失(老数据按会话 createdAt 算)时是 0。改为从模型 stuckHours + 模型自带的 db.now 反推时刻、经 fmtAgoText 生成「62 个小时」/「2 天前」——数字仍来自模型,不从 Date.now() 现算。

仍保留的定时器:kf-app.js:79 的 setInterval(refreshMs) 是 v10 就有的数据轮询(boardService.load),不是全页 DOM 扫描,按任务书不在移除之列。MutationObserver、window.__kfCjk 全局挂载:grep 0 处(只剩注释里说明「为什么不用」)。


1. 逐项验收表(v11c 重测)

项 实测值 达标线 通过
工作台 U+2009 61 ≥ 20 ✓
8 路由合计 U+2009 679 ≥ 500 ✓
汉字↔拉丁间普通空格残留 0 = 0 ✓
S4 机会验证评估 第 3 位字符码 8201 8201 ✓
node scripts/check.mjs CHECK OK CHECK OK ✓
node --test 'test/*.test.js' 46 pass / 0 fail 46/46 ✓
32px 行盒(加 trim) 23.28px ≤ 26px ✓
12px / 20px 行盒 8.73 / 14.55px 同比例 ✓
微图表四类出现数 spark 10 · 环 71 · 对比条 6 · 热力格 5 各 ≥ 1 ✓
版式距离档数 4(8/12/16/24 在版式层;区块间 48 在令牌) ≤ 4 ✓
卡面撑高留白 > 24px 0 处 0 ✓
transition: all 源码 0 · 运行时 0 0 ✓
max-height:999px 0 0 ✓
hover translateY(-1px),150ms ≤ 2px,无放大 ✓
数字滚动 kf-roll 650ms cubic-bezier(.4,0,.2,1),1284→1301 只滚 2 位 500–750ms ✓
进场错峰 calc(var(--i) * 40ms),400ms 400ms / 40ms ✓
reduced-motion 过渡时长 1e-05s ≈ 0 ✓

逐路由 U+2009(node scripts/verify-cjk.mjs):

/                    可见文本节点  143 · U+2009  61 · 普通空格残留 0
/pool                可见文本节点  368 · U+2009 166 · 普通空格残留 0
/stages              可见文本节点  555 · U+2009 100 · 普通空格残留 0
/reports             可见文本节点  337 · U+2009  64 · 普通空格残留 0
/reports/competitor  可见文本节点  302 · U+2009  41 · 普通空格残留 0
/reports/voc         可见文本节点  282 · U+2009  53 · 普通空格残留 0
/members             可见文本节点  176 · U+2009  37 · 普通空格残留 0
/ledger              可见文本节点  436 · U+2009 157 · 普通空格残留 0

S4 机会验证评估 · 13 条 → [83, 52, 8201, …, 49, 51, 8201, 26465](S4 后、13 后都是 8201)。

复现:node scripts/verify-cjk.mjs、node scripts/verify-textbox.mjs、node scripts/check.mjs、node --test 'test/*.test.js'、node scripts/verify-viz.mjs、node scripts/audit-examples.mjs --json docs/v11b-audit.json、node scripts/audit-spacing.mjs

单测改了两行期望值(与行为变更同源,不是放宽门槛):test/report.test.js:83 fmtAgo 的 3 小时前 → 3 小时前;test/model.test.js:78 阶段 label S4 机会验证评估 → S4 机会验证评估。两项都是「生成处插 U+2009」的直接后果。


2. text-box 三档对比(node scripts/verify-textbox.mjs)

inline-block,line-height: 1,文本「1284」:

字号 不加 trim 加独立长属性(trim-both / cap alphabetic) 变化 行盒 / 字号
12px 正文 12.00px 8.73px -27.2% 1.00em → 0.73em
20px 小标题 20.00px 14.55px -27.3% 1.00em → 0.73em
32px 主数值 32.00px 23.28px -27.2% 1.00em → 0.73em

关键细节(代码里保留了注释):

  • display:flex 容器里的 trim 不生效:对照实验 32px + trim-both 但容器 flex → computed 仍是 trim-both,行盒实测 32.00px。值容器必须 display:block + height:max-content。
  • 不用简写 text-box:Chrome 153 丢弃简写,只认 text-box-trim / text-box-edge 两个长属性。
  • 页面真实元素:工作台 4 个 32px KPI、报告类型页 4 个 32px KPI 全部 23.28px;S1–S5 徽标 16px、A 级 徽标 24px 均为 trim 后的 cap 高。

3. 微图表四类:出现位置 + DOM 计数(node scripts/verify-viz.mjs)

计数为 7 个路由合计。每类都满足:数字在图表旁(图表本身 aria-hidden,读屏读数字)、纯 CSS/SVG、无渐变填充、无第三方库。

类型 出现位置 DOM 计数 规格实测
sparkline 工作台 KPI 卡(4 个数字卡右下角,view-workbench.js .kpi kf-spark,7 日趋势);报告中心 5 张类型片的「份数」右侧(view-reports.js:151);报告类型页「份数」KPI(view-report-type.js:253) 10 56×16px,历史柱 .35 / 最新 .95
进度环 / 进度条 环:五阶段页每张阶段卡的「份数」环(view-stages.js:108,40px);报告类型页 4 个 KPI 环;机会卡评分面板平均分环(kf-score-panel.js:89,44px);报告卡 mini 环(report-card.js .rc .ring)。条:五阶段页每卡占比条 .ov .bar 与混合条 .ov .mix(view-stages.js:63-65) 71(环) 环 40–44px 描边 3px;条高 4px 圆角 2px 单色;环心 / 左侧印数字
对比条 报告中心「分类」区块 5 张类型片各自的 S1–S5 份数分布(view-reports.js:153 kf-bars stack);成员页「成员产出对比」前 8 位(view-members.js:91) 6 最大值占满 100%,数字右对齐(最多 N 份)
热力小格 台账页「阶段 × 层交叉分布」(view-ledger.js:178,5 行 × 若干列,每行右侧小计);台账 bar2(view-ledger.js:88)里横向的成员活跃度小格 5 12px 方形,圆角 2px,4 档不透明度

截图:docs/screenshots/v11b/viz-*.png。


4. 间距分级与「我的推进」框

  • 四档:卡内 padding 16 / 卡内 gap 12 / 卡片之间 24 / 区块之间 48(src/styles/tokens.js 的 --kf-space-card / --kf-space-in / --kf-space-card-gap / --kf-space-section)。
  • node scripts/audit-spacing.mjs:版式层实测值 8px×2、12px×2、16px×22、24px×4 —— 4 种(报警线 > 6),四档外 0 种。48 用在区块之间(.p-sec margin)。
  • 25% 缩放截图:docs/screenshots/v11b/spacing-25-*.png(7 页),块与块之间的缝肉眼可分出层级。
  • 「我的推进」虚线占位框:数据来自 forMe,有数据放阶段完成度,.grid2 { align-items: start } + .grid2 > kf-glass-card { align-self: start }(view-workbench.js:40,42),卡收缩到内容高。
  • stretch 扫描(audit-spacing.mjs 的「撑高留白」):卡面内容外空白 > 24px 的 0 处(.grid2 上一轮 220px 的问题已不在)。

5. 字数复核(v11c 实测)

口径:可见文本节点里的中文字符 + 中文标点([一-龥 -〿＀-￯],即汉字、CJK 标点、全角符号),排除 SVG 内文本(textNodesIn 本来只收 HTML 文本节点,且跳过 svg 子树)、aria-label(属性不算文本节点)、隐藏元素(用与 verify-cjk 相同的 visible 判定),另排除含 URL / 文件名的节点;页外的导航与顶栏不计。

页面 上限 实测 通过
工作台 / 350 422 ✗
报告类型页 /reports/voc 300 780 ✗
报告中心 /reports 200 818 ✗

(参考:/stages 1676、/pool 1190、/ledger 786、/members 293,这三页任务书没给上限。)

未达成:三页都超。工作台超 72;报告中心 / 类型页超得多,是因为卡片自带来源行(谁 · Agent · 方式 · 时间)、筛选条、每个类型的阶段条旁都有文字。压缩到上限要删信息或改卡片结构,属于视觉改版,v11c 不做,如实列在这里。


6. 未达成 / 没验到的

  1. 字数:工作台 422/350、报告类型页 780/300、报告中心 818/200,均超(见第 5 节)。未调低口径凑数。
  2. 反例 #3(玻璃用在所有卡片):内容卡还是玻璃(白面 + blur)。改成实白面是视觉改版,本轮不做;详见 docs/v11b-audit.md 第 3 条。
  3. 反例 #13(圆角 > 16px):圆形头像 / 进度环 50px,判定可接受,未改。
  4. 「进度条」单列计数:verify-viz.mjs 的 KIND 只点了 spark / ring / bars / heat 四类,阶段卡上的 4px 进度条是 kf-bars 之外的 .ov .bar(纯 CSS),没有独立 DOM 计数;本文给的是源码位置,不是脚本数字。规格(高 4px / 圆角 2px)是源码读出来的。
  5. sparkline 尺寸:任务书写宽 64–80px,实测 56×16px(--h: 16px)。v11b 定的,本轮不改视觉,如实记录不一致。
  6. 数据轮询定时器:kf-app.js:79 的 setInterval 仍在(v10 起的数据刷新,不是全页扫描)。
  7. 滚动条 / 25% 截图的人工确认:截图已生成,但「能看出块在呼吸」是肉眼判断,没有一个可自动化的阈值指标。
  8. scripts/v11b-patch.mjs:文件仍在磁盘上(未删除),但源码里 0 处引用;按「我提交」的约定没动它,建议你提交前一并删掉。
  9. verify-viz 的 阶段 × 类型交叉:任务书写的热力格位置之一是「阶段 × 类型交叉」,落地的是「阶段 × 层」(台账页)。类型维度没有做热力格。