alphaH 7d7b0470d6 feat(汇安融转译): 16 前端转译为「超时关闭」,下游文档同步告知 5 дней назад
..
README.md 7d7b0470d6 feat(汇安融转译): 16 前端转译为「超时关闭」,下游文档同步告知 5 дней назад
har-status16-harness.mjs 7d7b0470d6 feat(汇安融转译): 16 前端转译为「超时关闭」,下游文档同步告知 5 дней назад

README.md

汇安融 trade_status=16「超时关闭」前端转译 —— 执行级验证台

这台子回答哪一句话

上游把长时间未付的单关掉、trade_status 回来是 "16" —— 收银台、订单列表、 订单详情这三块屏幕上,会不会出现一个裸的「16」?

「源码里 HAR_TRADE_STATUS_TEXT 加了 "16": "超时关闭"」不是答案。这页有 16 条 断言,答案是数出来的:真模板渲染出的文本 + el-tag / el-option 每次渲染 记下的一对对读数。

怎么跑

cd .claude/plan/2026-10-10-har-status16-harness
node har-status16-harness.mjs

不带参数、不联网、不碰库、不写任何东西。只认最后那行 SUMMARY —— 失败也 exit 0(与同目录各台一致),别拿 exit code 当判据。

它怎么做到「真」

环节 真的还是假的
har.ts(映射表) 真:本仓那份原样转译求值,HAR_TRADE_STATUS_TEXT/TAG 直接从它取出
订单页 SFC 真:@vue/compiler-sfc 解析 + compileScript + 单独 compileTemplate,真模板挂载渲染
收银台 SFC 真:compileScript 编译本仓那个 index.vue(只驱动绑定,模板不渲染)
vue 真:frontend/node_modules 里那份 vue(createRenderer 挂载)
页面函数 真:loadOrderList() 是本台真实调用;详情靠直接改 detail/detailVisible 再渲染
DOM 假:createRenderer 接一套内存节点(patchProp/insertStaticContent 都要给它)
el-table / el-tag / el-option / el-dialog 假:会转发插槽或记账的桩(el-table 按 data 逐行把 row 塞进列插槽;el-tag 记 {type,text};el-option 记 {label,value};el-dialog 只在 modelValue 时渲染);其余 el-* 直通默认插槽
接口 假:HarAPI 换成记账桩,orderList 喂夹具四行、orderDetail 喂 16 那行

「假」的那几样与要证的那句话无关:本台问的是屏幕上写出什么字,不是像素长什么样。

16 条断言

# 读数 它钉的是什么
A1 列表 16 行渲染出「超时关闭」 转译发生
A2 全页文本不含裸 "16" 负向:没有任何一处漏转译
A3 正控:8 行仍「交易关闭」 老文案没被碰坏
A4 正控:表外值 99 仍原样显示 「表外不猜」的兜底没被谁顺手删掉
A5 el-tag 配对 {info, 超时关闭} 颜色与文字都对
A5b TAG 表里 16 显式给了 "info" ★ 见坑②:这格在渲染层是隐形的,只能直接钉表值
A6 正控:1 行仍 {success, 支付成功} 已知状态的 tag 没动
A7 筛选下拉出现 {16 → 超时关闭} 下拉吃的是 TEXT 表(v-for),这条路也得亮
A8 正控:下拉里 8 仍「交易关闭」 下拉没被改坏
B1 详情弹层里的状态 tag 同款转译 列表与详情是模板里两处独立的映射点,测一处不代表另一处
B2 打开详情后全页文本仍不含裸 "16" 弹层打开后复核负向
C1 收银台 result:16 → 超时关闭 / muted / detail 含「没有收到钱」 不再落进「表外状态原样显示」的兜底
C2 正控:1 → 收款成功 + money
C3 正控:8 → 交易关闭
C4 正控:表外值 99 仍原样 兜底没被删(收银台这一侧)
C5 apply(16) 停轮询进 done 现状行为回归:16 不在收银台 PENDING 里

A1/A2/A5/A5b/A7/B1/B2/C1 是「必须转译」侧,A3/A4/A6/A8/C2/C3/C4 是正控。 只有转译侧的话,把映射表整个换成恒返回「超时关闭」也能全绿。

两向变异(读数在 logs/_t-status16-fe-mut*.txt / -green-final.txt)

变异 期望 实读
M1:删掉 TEXT 表的 "16" 格 必须红 SUMMARY FAIL 断言=16 不符=6:A1 A2 A5 A7 B1 B2
M2:删掉 TAG 表的 "16" 格 必须红 SUMMARY FAIL 断言=16 不符=1:只 A5b(★ 见坑②)
M3:删掉收银台 RESULT 的 "16" 格 必须红 SUMMARY FAIL 断言=16 不符=1:只 C1
M4:无害改动(TEXT 表 0/1 两行调序) 必须仍绿 SUMMARY PASS 断言=16 不符=0

四次变异还原后复量 sha256,与变异前逐字节一致: har.ts = 1c62324eb7a2…,cashier/index.vue = d63c00b9d4be…。 实现前的红灯(_t-status16-fe-red-1.txt,当时台子 13 条断言)红在 A1 A2 A5 B1 B2 C1 —— 恰好是「没转译」那一撮。

踩过的坑

  1. bindingMetadata 必须带。 compileScript 出来的 setup 结果带 __isScriptSetup 旗子,runtime 的 hasSetupBinding 见到它就拒绝走 _ctx 代理 ⇒ 模板里每个绑定都 undefined,槽函数一渲染就 TypeError: _ctx.searchForm。 把 script.bindings 传进 compileTemplate 的 compilerOptions,模板才编成 $setup.xx 直取。2026-10-10 实测踩过一次。
  2. TAG 那一格在渲染层是隐形的。 两处 el-tag 都写成 TAG[st] || 'info' —— 「TAG 表缺格」与「给了 info」渲染成同一个样子。实测:只加渲染断言时 M2(删掉 这格)全绿(_t-status16-fe-mut2-tag.txt,SUMMARY PASS 断言=13)。所以 台子补了 A5b 直接钉表值 + A7/A8 下拉(下拉吃 TEXT 不吃 TAG)。设计保留这格: 显式表态 + 表风格一致,A5b 钉着它。
  3. 夹具纪律:非状态字段全都避开子串 "16"。 行号用 A1~A4 后缀,否则 order_no: "…16…" 会污染 A2/B2 的负向断言 —— 负向断言只有在「其余字段都干净」 时才是有判别力的。
  4. process.exit(0) 不设 exitCode。 判据是 SUMMARY 那行,不是退出码 —— 否则「台子崩了」与「断言不符」在 CI 里分不开。

与另外两张表的关系

「16」这个值同一天写进了三个地方,各写一遍、各钉各的:

位置 形态 钉它的量具
前端映射表 har.ts TEXT/TAG + 收银台 RESULT 本台
后端分类 HarOrderStatus.TIMEOUT_CLOSED(FINAL 成员,不进 PENDING/PAY_RECORDED) HarOrderStatusTest(含两向变异 J1/J2)
下游文档 har-openapi.md 10.3/10.4/10.5/§11 + 对接 docx 词普查回读

值的传递原则:本地不转义、逐字入库、逐字出网 —— 中文文案分别由前端转译与 下游文档各自承担,上游回了什么就存什么、发什么。