diff --git a/activities/part-substitution-assessment/__tests__/activity.test.ts b/activities/part-substitution-assessment/__tests__/activity.test.ts index 62b95b2..390ef21 100644 --- a/activities/part-substitution-assessment/__tests__/activity.test.ts +++ b/activities/part-substitution-assessment/__tests__/activity.test.ts @@ -620,9 +620,11 @@ describe('件① 评估输入补全', () => { expect(html).toContain('data-col="param_name"'); }); - it('可改的四张表各有一道编辑闸', () => { + it('可改的四张表各有一道编辑闸 —— 查的是闸([data-edit-for] + 开钮),不是宿主:2026-08-30 换版面第一版恰好漏掉 profile 的闸,宿主在而闸不在,轨道打不开编辑,XL 的必填永远补不上(Task 7 那颗「按不下去的确认钮」同款),旧断言只查宿主没逮到', () => { for (const address of ['parts.profile', 'parts.chip_type', 'parts.type_param', 'parts.parameter']) { expect(html).toContain(`data-edit="${address}"`); + expect(html).toContain(`data-edit-for="${address}"`); + expect(html).toContain(`data-edit-open="${address}"`); } }); @@ -769,11 +771,18 @@ describe('件① 评估输入补全', () => { expect(html).toContain('.jc-typewarn.v-2{display:flex'); }); - it('**步骤圆点只按基座数点亮**:①③ 挂 _missing(v-0 档)、② 挂 distinct(v-1 档),不许模版自己判「办完了」', () => { - expect(html).toContain('class="sdot sd-m" data-class-of="parts_profile_missing"'); - expect(html).toContain('class="sdot sd-d" data-class-of="sub_eval_part_distinct_chip_type_id"'); - expect(html).toContain('class="sdot sd-m" data-class-of="parts_parameter_missing"'); - expect(html).toContain('.sdot.sd-m.v-0,.sdot.sd-d.v-1{background:var(--data)'); + it('**步骤圆点只按基座数点亮,投影挂在行外的包裹层** —— 行内 data-class-of 只认行作用域,作用域级读数在行内投不出(实测圆点永远不亮);圆点自己不许再挂 data-class-of(挂了也是死属性)', () => { + expect(html).toContain('class="pj pj-profile" data-class-of="parts_profile_missing"'); + expect(html).toContain('class="pj pj-type" data-class-of="sub_eval_part_distinct_chip_type_id"'); + expect(html).toContain('class="pj pj-param" data-class-of="parts_parameter_missing"'); + expect(html).toContain('.pj-profile.v-0 .sdot.sd-1,.pj-type.v-1 .sdot.sd-2,.pj-param.v-0 .sdot.sd-3{background:var(--data)'); + expect(html).not.toMatch(/class="sdot[^"]*" data-class-of=/); + }); + + it('**类型查名有诚实守卫**(data-by 行缺键落回外层同名字段,终审 I3):行里没真选上类型(selectCurrent 没写下 option[selected]),查名 pill 与字段行的名字都不摆', () => { + expect(html).toContain('.lane:not(:has(select[data-col="chip_type_id"] option[selected])) .idcard .tpill{display:none}'); + expect(html).toContain('.lane:not(:has(select[data-col="chip_type_id"] option[selected])) .tywrap span{display:none}'); + expect(html).toContain('class="jc-vcell tywrap"'); }); it('**新增类型面板是
,且绑定层把抽取样式的 display:none 让开** —— 少了这条让位规则,整个面板(含两道闸与两张表)永远不可见', () => { diff --git a/activities/part-substitution-assessment/src/manifest.ts b/activities/part-substitution-assessment/src/manifest.ts index 546cbc9..7298d05 100644 --- a/activities/part-substitution-assessment/src/manifest.ts +++ b/activities/part-substitution-assessment/src/manifest.ts @@ -54,7 +54,7 @@ export const manifest: ActivityManifest = { activityId: ACTIVITY_ID, name: 'ACT-WORK-05 · 差异评估', /* 重写不是改 —— 同版重装是 no-op(静默丢失,踩过) */ - packageVersion: '2.2.1', + packageVersion: '2.2.2', category: '需求分析与方案匹配', sdkVersion: '0.1.0-m5', checksum: 'dev-checksum-part-substitution-assessment', diff --git a/activities/part-substitution-assessment/src/views/report.ts b/activities/part-substitution-assessment/src/views/report.ts index 186f6fe..221daa5 100644 --- a/activities/part-substitution-assessment/src/views/report.ts +++ b/activities/part-substitution-assessment/src/views/report.ts @@ -219,8 +219,18 @@ th{white-space:nowrap} input/select 同高写的)排在 P08_CSS 之后会盖过它 —— 这里(alias 排最后)按目标件的高度要回来 */ .fld input.jc-cell,.fld select.jc-cell,.pv input.jc-cell{height:36px} @media(max-width:900px){.lanes{grid-template-columns:1fr}} -/* 步骤圆点点亮 —— 「办完了没有」全是基座数:①③ 缺格数为 0(v-0),② 不同类型恰 1 种(v-1) */ -.sdot.sd-m.v-0,.sdot.sd-d.v-1{background:var(--data);border-color:var(--data);color:#fff} +.pj{display:block} +/* 步骤圆点点亮 —— 「办完了没有」全是基座数:①③ 缺格数为 0(v-0)、② 不同类型恰 1 种(v-1)。 + 投影在行外的 .pj 包裹层上(行内 data-class-of 只认行作用域,读数投不出 —— 见 body 那段注释) */ +.pj-profile.v-0 .sdot.sd-1,.pj-type.v-1 .sdot.sd-2,.pj-param.v-0 .sdot.sd-3{background:var(--data);border-color:var(--data);color:#fff} +/* 类型查名的诚实守卫 —— data-by 在行缺键时落回外层同名字段(终审 I3 已记档的平台缺陷): + XL 还没选类型时,sub_eval.case 摊平出的 chip_type_id 会顶进来,查名 pill 摆出一个它没有的类型。 + 守卫认 selectCurrent 按**这一行自己的值**写下的 option[selected]:行里没真选上,名字不摆、摆「(未选择)」。 + 人在编辑态刚选了还没保存时守卫仍按旧值(与「基座算的数等回声」同一条纪律);保存重渲后跟上。 */ +.lane:not(:has(select[data-col="chip_type_id"] option[selected])) .idcard .tpill{display:none} +.lane:not(:has(select[data-col="chip_type_id"] option[selected])) .idcard .val:has(.tpill)::after{content:"(未选择)";font-family:Inter,ui-sans-serif,system-ui,sans-serif;font-size:14px;font-weight:400;color:var(--ink-4);letter-spacing:0} +.lane:not(:has(select[data-col="chip_type_id"] option[selected])) .tywrap span{display:none} +.lane:not(:has(select[data-col="chip_type_id"] option[selected])) .tywrap::after{content:"(未选择)";color:var(--ink-4)} /* 类型不一致护栏 —— 只在 v-2 档现身(sub_eval.part 恰两行,distinct 封顶 2;0=都没选,1=一致) */ .jc-typewarn{display:none} .jc-typewarn.v-2{display:flex;gap:8px;margin:0 0 var(--s2);padding:10px 14px;border-radius:9px;background:var(--danger-soft);border:1px solid #f3b9b5;color:var(--danger);font-size:12.5px;line-height:1.65} @@ -401,7 +411,7 @@ const LANES = `
- 1 + 1
主数据*为必填 · 在库的料现值已回填,只查漏补缺
@@ -417,12 +427,12 @@ const LANES = `
- 2 + 2
芯片类型必填 · 决定第③步比哪些参数;两颗料必须同一个类型
芯片类型
- + ${optionSelect('chip_type_id', 'parts.chip_type', 'type_id', 'type_name', true)}
类型库里没有?展开下面「新增类型」面板现场定义,保存后立刻出现在这个下拉里。
@@ -624,7 +634,7 @@ const NEWTYPE_PANEL = `
* 复制,手改会被覆盖,给输入件就是让人误以为改了算数)。 */ const PARAM_TILES = `
- 3 + 3
核心参数值一参数一格 · 值必填;查不到就留空并在说明里写明,别编一个数顶替
@@ -658,10 +668,21 @@ export const INPUT_SUPPLEMENT = doc({ 'AI 预填情况:在库的料现值已回填,只需查漏补缺;料号本身已按启动参数铺好,不必重填。纪律:查不到的参数值留空(红带会点名),不要编一个值顶替;数据工单确认后即入正式库,确认人留痕。', ]) + gateBar() + + editGate('parts.profile', '两条轨道的主数据核对 / 补齐(缺类型的在②的下拉里选),点「编辑」开卡') + + gapbar('parts_profile', '必填') + + /* + * 三层投影包裹(pj-*):步骤圆点「办完没有」的三个基座数(profile 缺格 / 类型 distinct / + * 参数缺格)都是**作用域级读数**,而行内的 data-class-of 只认行自己的键 + * (renderRows 末段 renderTemplate(…, one) 拿的是行对象,不是合并作用域 —— 实测投不出)。 + * 投影挂在行外的包裹层上,样式表用后代选择器点亮圆点;代价是两条轨道的圆点一起亮 + * (基座数本来就是表级的 —— 分到每颗料头上的数基座没有,不编)。 + */ + `
` + LANES + TYPE_WARN + NEWTYPE_PANEL + PARAM_TILES + + `
` + flow('提交 / 确认:本工单只承载内容;确认请在对话区的【执行卡】中进行。确认后活动自动从「等待数据」唤醒。'), });