From 00133c2ca042e0dbb50a3e9d14df30f839352eb8 Mon Sep 17 00:00:00 2001 From: xcs Date: Thu, 27 Aug 2026 01:15:44 +0800 Subject: [PATCH] =?UTF-8?q?fix(w05):=20=E4=BA=94=E5=BC=A0=E6=A8=A1?= =?UTF-8?q?=E7=89=88=E6=95=B4=E4=BB=BD=E9=87=8D=E5=81=9A=20=E2=80=94?= =?UTF-8?q?=E2=80=94=20=E9=80=90=E5=9D=97=E6=90=AC=E8=87=AA=E5=9B=9B?= =?UTF-8?q?=E4=BB=BD=E7=9B=AE=E6=A0=87=E4=BB=B6,=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E7=85=A7=20E04/I01=20=E9=82=A3=E5=A5=97=E7=89=88=E9=9D=A2?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E5=81=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户实跑截图指出:芯片主数据创建的模版样式与给的目标件对不上。病根是 brief 一边说 「版面语言逐字量自目标件」,一边让照 I01 的 prd-style.ts 当视觉底 —— 两句互相矛盾, 《HTML报告生成规范》§7 写的是「搬」不是「照着做」。 - 新增 src/views/target-style.ts:四份目标件的 -
-
-
-
${input.badge}
-
- ${input.kicker} -

${input.title}

-
收件人: · 关联任务:
-
-
- ${input.tag} - ${input.step} - ${input.state} -
-
-
${input.body}
-
${input.foot}
-
-
`; +/* ==================== 验收工单 01(差异评估结论审核):徽标别名 ==================== */ +const BIND_ACC1 = ` +/* 差异四态与推荐等级**都**落在这一屏(本活动数据面的既有约定 —— 各候选推荐等级摘要与 + 逐项差异明细同屏摆),两者取值域都含 "conditional",光认 .st 分不清是哪一列, + 加 .dst / .rec 两个字段级修饰类各自配色(**原样照抄目标件 .st.ok/.miss/.unknown/.cond + 四条声明**,只是同一份颜色现在要接两条不同的人读文案)。 */ +${badgeCss('.st.dst', [ + ['match', 'MATCH', OK], + ['mismatch', 'MISMATCH', DANGER], + ['unknown', 'UNKNOWN', AMBER], + ['conditional', 'CONDITIONAL', 'color: var(--ledger); background: var(--ledger-soft); border-color: var(--ledger-line);'], +])} +${badgeCss('.st.rec', [ + ['recommended', '推荐', OK], + ['conditional', '条件推荐', 'color: var(--ledger); background: var(--ledger-soft); border-color: var(--ledger-line);'], + ['alternate', '备选', AMBER], + ['not_recommended', '不推荐', DANGER], +])} +/* + * 风险等级(原样照抄目标件 .risk.low/.mid/.hi 三条声明)——加 critical 一档:这一屏「各候选 + * 推荐等级」摘要读的是 substitution.relation.risk_level(声明了 low/medium/high/critical + * 四档),差异明细本身的 risk_level 只有三档,共用同一族选择器,多出的第四档不会撞车。 + */ +${badgeCss('.risk', [ + ['low', '低', 'color: var(--ok);'], + ['medium', '中', 'color: #8f6a12;'], + ['high', '高', 'color: var(--danger);'], + ['critical', '危急', 'color: var(--danger); font-weight: 900;'], +])} +/* + * 约束类型(硬/软)—— 目标件的差异明细表里这一列是纯文字,没有配色(数据工单-01 的 .ct.hard/ + * .ct.soft 才是这两个值真正的徽标声明,只是它长在另一份目标件里)。这里把那两条颜色声明 + * 原样搬过来当 v- 版(数值不改,只换了外壳类名,因为这一页的样式表里从未定义过 .ct)。 + */ +.con { display: inline-block; font-size: 11px; font-weight: 700; padding: 1px 8px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap; } +${badgeCss('.con', [ + ['hard', '硬约束', DANGER], + ['soft', '软约束', MUTED], +])} +/* 替代类型 —— 目标件里也是纯文字,不配色,只补文案 */ +${badgeCss('.enumtxt', [ + ['pin_to_pin', 'Pin-to-Pin'], + ['functional', '功能替代'], + ['parametric', '参数替代'], + ['other', '其他'], +])} +`; -const part = (label: string, aside = ''): string => `

【${label}】${aside === '' ? '' : ` —— ${aside}`}

`; +/* ==================== 验收工单 02(评审放行与落账确认):徽标别名 ==================== */ +const BIND_ACC2 = ` +/* 这一屏四个枚举列(推荐等级 / 分析状态 / 需求状态 / 当前阶段)取值域两两不重叠,共用 .st 即可。 + 推荐等级、分析状态目标件里本就是 .st 徽标(原样照抄 .st.ok/.miss/.unknown/.cond 四条声明); + 需求状态 / 当前阶段目标件没有这两列,借同一套配色,不新配颜色。 */ +${badgeCss('.st', [ + ['recommended', '推荐', OK], + ['conditional', '条件推荐', 'color: var(--ledger); background: var(--ledger-soft); border-color: var(--ledger-line);'], + ['alternate', '备选', AMBER], + ['not_recommended', '不推荐', DANGER], + ['ai_draft', 'AI 草稿', AMBER], + ['fae_confirmed', 'FAE确认', OK], + ['pending_customer', '待客户验证', 'color: var(--ledger); background: var(--ledger-soft); border-color: var(--ledger-line);'], + ['customer_approved', '客户已批准', OK], + ['rejected', '不批准', DANGER], + ['void', '作废', MUTED], + ['pending', '待处理', MUTED], + ['responded', '已响应', 'color: var(--ledger); background: var(--ledger-soft); border-color: var(--ledger-line);'], + ['won', '已成交', OK], + ['abandoned', '已放弃', DANGER], + ['closed', '已关闭', MUTED], + ['assessing', '评估中', MUTED], + ['gate03', '提交 ACT-GATE-03', OK], +])} +/* 风险等级比验收 01 多一档 critical(P-11 主记录的 risk_level 声明了它,差异明细没有) */ +${badgeCss('.risk', [ + ['low', '低', 'color: var(--ok);'], + ['medium', '中', 'color: #8f6a12;'], + ['high', '高', 'color: var(--danger);'], + ['critical', '危急', 'color: var(--danger); font-weight: 900;'], +])} +/* 替代类型 —— 目标件里是纯文字,不配色,只补文案(与验收 01 同一套值域,各自页面各存一份) */ +${badgeCss('.enumtxt', [ + ['pin_to_pin', 'Pin-to-Pin'], + ['functional', '功能替代'], + ['parametric', '参数替代'], + ['other', '其他'], +])} +`; + +/** 三层壳照目标件:`
`,不再套 `.proto-root`/`.app-shell`/`.jc-stage` + * (那是 E04/I01 自己的视觉底约定,不是平台要求 —— ui-kit / view-render 从未引用过这几个类名; + * 目标件本身就是直接 `page > card`,搬版面就该原样搬这一层)。 + * 收件人 / 关联任务两格由引擎注入;目标件的「最迟交回」(`card.deadline`)本仓没有真数据源,不摆; + * 工单编号(`card.id`)换成本次评估案号 `eval_ref`。 + */ +const doc = (input: { css: string; alias: string; badge: string; hic?: string; tag: string; kicker: string; title: string; step: string; body: string; footTag: string }): string => + ` +
+
+
${input.badge}
+ ${input.hic ?? ''} +
+
${input.kicker}
+

${input.title}

+
收件人: · 关联任务:
+
+
+ ${input.tag} + ${input.step} +
+
+
${input.body}
+
+ ${input.kicker} · ${input.title} + ${input.footTag} · +
+
`; + +/* ==================== 内联 SVG 图标 —— 逐字节搬自「数据工单-01」目标件(它们是版面语言的一部分) ==================== */ +const HIC = + ''; +const ZIC_TASK = + ''; +const ZIC_TABLE = + ''; + +/* ==================== 通用绑定小工具 ==================== */ +const zone = (label: string, aside: string, icon = ''): string => `

${icon}【${label}】—— ${aside}

`; +const note = (items: readonly string[]): string => `
${items.map((p) => `

${p}

`).join('')}
`; const criteria = (title: string, items: readonly string[]): string => - `
${title}
    ${items.map((i) => `
  • ${i}
  • `).join('')}
`; -const flow = (text: string): string => `
${text}
`; -/** 页脚右侧「工单类型:× · <案号>」 */ -const sign = (note: string, tag: string): string => `${note}${tag} · `; + `
${title}
    ${items.map((i) => `
  • ${i}
  • `).join('')}
`; +const flow = (text: string): string => `
${text}
`; const editGate = (address: string, label: string): string => `
${label} - - - + + +
`; const gapbar = (object: string, what: string): string => `
还差 行${what}没填 —— 。按「编辑」开表,红框那几格就是要填的。补齐了才确认得了。
`; -const tag = (scope: string, col: string): string => ``; +const addrow = (address: string, label: string, hint: string): string => `
+ + ${hint} +
`; +/** 可改格:只读那一份留空,渲染器自动配孪生 ``(手写 input 会不填值,人一点编辑就是白框) */ const cell = (col: string, cls = ''): string => ``; -const ro = (col: string, cls = ''): string => ``; +/** 只读格:即便挂在可改的表里也不许被 `table.on` 藏起来 —— 目标件自己就有这条覆盖(`.jc-vcell.ro`) */ +const ro = (col: string, cls = ''): string => ``; const select = (col: string, options: ReadonlyArray, required = false): string => ``; +/** 枚举徽标(可改表里用,旁边挨着 `.jc-cell` 孪生件时要包一层 `.ro` 才不被编辑态藏起来) */ +const badge = (klass: string, col: string, wrapRo = false): string => { + const inner = ``; + return wrapRo ? `${inner}` : inner; +}; -/* ==================== 局面 0 · 数据工单 P-08 ==================== */ +/* ==================== 局面 0 · 数据工单 P-08(搬自「数据工单-01」)==================== */ -const P08_TABLE = `
+const P08_TABLE = `
- - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + +
内部料号品牌制造商规格描述封装工艺生命周期EOL / PCNDatasheet 引用Datasheet 版本适配场景标准化参数集(一行一参数:参数名 | 值 | 单位 | hard/soft | 说明)#内部料号 internal_pn全链路统一基准,不可自由文本品牌 brand_name与制造商、供应商分开制造商 manufacturer_name与品牌不一致时分开记录规格描述 specification_description按原厂资料口径封装 package影响硬约束比对工艺 process_technology硬约束比较项生命周期 lifecycle_statusActive/NRND/EOL/停产/风险EOL/PCN eol_pcn_status通知/影响/生效时间Datasheet 引用 datasheet_refDatasheet 版本 datasheet_version与引用成对适配场景 application_scenarios判断实际适用性标准化参数集 normalized_parameter_set一行一参数:参数名|值|单位|hard/soft|说明
${cell('internal_pn', 'mono')}${cell('brand_name')}${cell('manufacturer_name')}${cell('specification_description')}${cell('package', 'mono')}${cell('process_technology')}${select('lifecycle_status', [['active', 'Active'], ['nrnd', 'NRND'], ['eol', 'EOL'], ['discontinued', '停产'], ['risk', '风险']], true)}${tag('t-life', 'lifecycle_status')}${cell('eol_pcn_status')}${cell('datasheet_ref', 'mono')}${cell('datasheet_version')}${cell('application_scenarios')}${cell('internal_pn', 'mono')}${cell('brand_name')}${cell('manufacturer_name')}${cell('specification_description')}${cell('package', 'mono')}${cell('process_technology')}${badge('stx', 'lifecycle_status', true)}${select('lifecycle_status', [['active', 'Active'], ['nrnd', 'NRND'], ['eol', 'EOL'], ['discontinued', '停产'], ['risk', '风险']], true)}${cell('eol_pcn_status')}${cell('datasheet_ref', 'mono')}${cell('datasheet_version')}${cell('application_scenarios')}
`; export const P08_MASTER_CREATE = doc({ - tone: 'human', + css: P08_CSS, + alias: BIND_P08, badge: '数据', + hic: HIC, tag: '数据工单', - kicker: 'SS02 · ACT-WORK-05 差异评估 · 数据工单(P-08)', - title: '芯片主数据创建', + kicker: 'SS02 · ACT-WORK-05 差异评估 · 数据工单 1/2', + title: '芯片主数据创建(P-08)', step: '步骤 0.5 · 等待数据', - state: `待建 / 行`, + footTag: '工单类型:数据', body: - part('做什么', '批量创建 P-08 主数据记录') + - `
-

模板定位:本单是「数据工单」的实例 —— 一单一类(可多条):目标台账 = 芯片主数据(P-08); - 字段即表头、每行一条新记录;标准化参数集是这条记录的一个字段(一行一参数)。

-

触发原因:系统按内部料号查芯片主数据查无记录 —— 是「完全没有」,不是字段缺失(那归执行工单)。

-

AI 预填:上传了 datasheet 的料号 AI 已按资料预填,标着值的格子请核对;没上传的料号全部手填,同为合法路径。

-

纪律:必填列全齐才允许确认;确认后这批记录进本单草稿,放行时并入正式库并留痕(确认人 = 数据责任人);只建主数据,验证记录等事实类不在此建。

-
` + - part('创建什么', '主数据记录(每行一条,*为必填列)') + + zone('做什么', '批量创建 P-08 主数据记录', ZIC_TASK) + + note([ + '模板定位:本单是「数据工单」统一模板的实例——一单一类(可多条):目标台账 = 芯片主数据(P-08);字段即表头、每行一条新记录;标准化参数集是这条记录的一个字段(一行一参数)。', + '触发原因:系统按内部料号查芯片主数据查无记录——是「完全没有」,不是字段缺失(那归执行工单)。', + 'AI 预填:上传了 datasheet 的料号 AI 已按资料预填,标着值的格子请核对;没上传的料号全部手填,同为合法路径。', + '纪律:必填列全齐才允许确认;确认后这批记录进本单草稿,放行时并入正式库并留痕(确认人 = 数据责任人);只建主数据,验证记录等事实类不在此建。', + ]) + + zone('创建什么', '主数据记录(每行一条,*为必填列)', ZIC_TABLE) + gapbar('parts_profile', '必填') + editGate('parts.profile', `待建 条记录,点「编辑」核对预填、补齐空缺;「+ 加一行」= 再建一条`) + - `
必填列(*)全齐才允许确认;原厂未披露的参数值请直接写「未披露」,它会进入 UNKNOWN 并挂验证任务;删一行 = 该记录不建。改动只落任务草稿层,保存不等于放行。
` + P08_TABLE + - `
- - 新行的内部料号必须写(它是这一行的钥匙);其余必填列全部填写后才允许确认。 -
` + + addrow('parts.profile', '+ 加一行(再建一条记录)', '新行的内部料号必须写(它是这一行的钥匙);其余必填列全部填写后才允许确认;删一行 = 该记录不建') + flow('提交 / 确认:本工单只承载内容;确认请在对话区的【执行卡】中进行。确认后活动自动从「等待数据」唤醒。'), - foot: sign('SS02 · ACT-WORK-05 差异评估 · 数据工单 · 芯片主数据创建(P-08)', '工单类型:数据'), }); -/* ==================== 局面 0′ · 数据工单 P-10 ==================== */ +/* ==================== 局面 0′ · 数据工单 P-10(复用「数据工单-01」的样式与骨架,没有独立目标件)==================== */ -const P10_TABLE = `
+const P10_TABLE = `
- - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + +
关联料号序号资料类型品牌资料标题版本文件链接证据定位状态#关联料号 internal_pn对应 P-08 那条记录资料序号 doc_seq同一料号下 01/02… 自己续资料类型 document_type品牌 brand_name资料标题 document_title资料版本 document_version文件链接 document_ref证据定位 citation_locator页码/章节/表格资料状态 document_status
${cell('internal_pn', 'mono')}${cell('doc_seq', 'mono')}${select('document_type', [['datasheet', 'Datasheet'], ['app_note', '应用笔记'], ['reference_design', '参考设计'], ['white_paper', '白皮书'], ['sample_doc', '样片资料'], ['commitment_letter', '承诺函'], ['other', '其他']], true)}${tag('t-doc', 'document_type')}${cell('brand_name')}${cell('document_title')}${cell('document_version')}${cell('document_ref', 'mono')}${cell('citation_locator')}${select('document_status', [['valid', '有效'], ['expired', '过期'], ['pending', '待核实'], ['void', '作废']], true)}${tag('t-docst', 'document_status')}${cell('internal_pn', 'mono')}${cell('doc_seq', 'mono')}${badge('stx', 'document_type', true)}${select('document_type', [['datasheet', 'Datasheet'], ['app_note', '应用笔记'], ['reference_design', '参考设计'], ['white_paper', '白皮书'], ['sample_doc', '样片资料'], ['commitment_letter', '承诺函'], ['other', '其他']], true)}${cell('brand_name')}${cell('document_title')}${cell('document_version')}${cell('document_ref', 'mono')}${cell('citation_locator')}${badge('stx', 'document_status', true)}${select('document_status', [['valid', '有效'], ['expired', '过期'], ['pending', '待核实'], ['void', '作废']], true)}
`; export const P10_DOCUMENT_CREATE = doc({ - tone: 'human', + css: P08_CSS, + alias: BIND_P08, badge: '数据', + hic: HIC, tag: '数据工单', - kicker: 'SS02 · ACT-WORK-05 差异评估 · 数据工单(P-10)', - title: '原厂技术资料创建', + kicker: 'SS02 · ACT-WORK-05 差异评估 · 数据工单 2/2', + title: '原厂技术资料创建(P-10)', step: '步骤 0.5 · 等待数据', - state: `待建 / 行`, + footTag: '工单类型:数据', body: - part('做什么', '为本单新建的料号登记原厂资料(P-10)') + - `
-

触发原因:按内部料号查原厂技术资料库查无记录。一份资料一行;同一料号多份资料序号 01/02… 自己续。

-

为什么要它:差异明细的证据引用要指到具体资料的版本与页码 —— 没有这一行,结论就追溯不到来源。

-
` + - part('创建什么', '资料记录(每行一条,*为必填列)') + + zone('做什么', '为本单新建的料号登记原厂资料(P-10)', ZIC_TASK) + + note([ + '模板定位:与 P-08 同一套「数据工单」统一模板——目标台账 = 原厂技术资料库(P-10);一份资料一行,同一料号多份资料序号 01/02… 自己续。', + '触发原因:按内部料号查原厂技术资料库查无记录(P-08 那张先确认过,这一批料号才会走到这里)。', + '为什么要它:差异明细的证据引用要指到具体资料的版本与页码——没有这一行,结论就追溯不到来源。', + ]) + + zone('创建什么', '资料记录(每行一条,*为必填列)', ZIC_TABLE) + gapbar('parts_document', '必填') + editGate('parts.document', `待建 条资料记录,点「编辑」补齐`) + - `
资料类型、标题、版本、文件链接、状态为必填;证据定位写页码或章节。改动只落任务草稿层,保存不等于放行。
` + P10_TABLE + - `
- - 关联料号与序号是这一行的钥匙,新行都要写;必填列全齐才允许确认。 -
` + + addrow('parts.document', '+ 加一行(再登记一份资料)', '关联料号与序号是这一行的钥匙,新行都要写;必填列全齐才允许确认;删一行 = 该资料不建') + flow('提交 / 确认:本工单只承载内容;确认请在对话区的【执行卡】中进行。'), - foot: sign('SS02 · ACT-WORK-05 差异评估 · 数据工单 · 原厂技术资料创建(P-10)', '工单类型:数据'), }); -/* ==================== 局面 1 · 评估输入清单(S0/S1)==================== */ +/* ==================== 局面 1 · 评估输入清单(搬自「执行工单-01」)==================== */ -const PN_CHECK_TABLE = `
+const PN_CHECK_TABLE = `
- - - - - + + + + + - - - - - + + + + +
料号角色在库状态备注 / 放弃原因#料号角色在库状态备注 / 放弃原因
${ro('internal_pn', 'mono')}${tag('t-role', 'role')}${tag('t-exist', 'exists_status')} ${ro('internal_pn', 'mono')}${badge('st', 'exists_status', true)}${ro('note')} ${ro('abandon_reason')}
`; -const GAP_TABLE = `
+const GAP_TABLE = `
- - - - - - - + + + + + + - - - - - - - + + + + + +
键输入项来源状态绑定值 / 缺口说明补充内容#输入项来源状态绑定值 / 缺口说明补充内容
${cell('item_key', 'mono')}${cell('input_item')}${cell('source_ledger', 'mono')}${select('status', [['gap', '待补'], ['default', '默认·可改'], ['ok', '齐备']])}${tag('t-gap', 'status')}${cell('detail')}${cell('input_item')}${cell('source_ledger', 'mono')}${badge('st', 'status', true)}${cell('detail')}${cell('supplement')}
`; export const EVAL_INPUT_LIST = doc({ - tone: 'human', + css: EXEC_CSS, + alias: BIND_EXEC, badge: '执行', tag: '执行工单', kicker: 'SS02 · ACT-WORK-05 差异评估 · 执行工单 1/1', title: '评估输入与资料补齐确认', step: '步骤 1/5 · 建立评估上下文', - state: `待补 项`, + footTag: '工单类型:执行', body: - part('做什么', '启动 4 项已绑定,其余信息在工单里补齐') + - `
-

AI 已完成:系统已按启动传入的 4 项完成绑定 —— 客户、客户需求(新建 P-01 · 版本 V1)、原 PN、候选 PN(数组,逐个评估)—— 并生成输入快照。

-

需要你补齐:启动时未收的信息(应用场景、BOM 位)直接在下表补;默认值(替代类型 / 规则版本 / 负责人期限)可确认可改。本单缺口只覆盖「有而不全」;「完全没有」(料号不在库)已由数据工单创建。未补齐的缺口项将按 UNKNOWN 进入差异评估。

-
` + - part('已绑定', '启动时冻结,工单内不可改 —— 绑错请退回启动人重新启动') + - `
- 客户 - 客户需求 · V1 · - 原内部料号 - 规则版本 -
` + + zone('做什么', '启动 4 项已绑定,其余信息在工单里补齐') + + note([ + 'AI 已完成:系统已按启动传入的 4 项完成绑定——客户、客户需求(新建 P-01 · 版本 V1)、原 PN、候选 PN(数组,逐个评估)——并生成输入快照。', + '需要你补齐:启动时未收的信息(应用场景、BOM 位)直接在下表补;默认值(替代类型 / 规则版本 / 负责人期限)可确认可改。本单缺口只覆盖「有而不全」;「完全没有」(料号不在库)已由数据工单创建。未补齐的缺口项将按 UNKNOWN 进入差异评估。', + ]) + + zone('料号存在性核对', '只读参考 · 与下表「补充内容」互不冲突') + PN_CHECK_TABLE + - part('交回什么', '评估输入清单(已绑定项只读核对,缺口项补齐,*为必填)') + + zone('交回什么', '评估输入清单(已绑定项照实核对,缺口项补齐,*为必填)') + gapbar(`${D}_input_gap`, '补充内容') + - editGate(`${D}.input_gap`, `还有 项待补 / 待确认,点「编辑」在「补充内容」列填入`) + - `
加一行 = 补充 AI 未列出的资料项(新行的「输入项」与「补充内容」必填);删一行 = 该输入项不适用;补不了的写「留 UNKNOWN」或「挂验证任务」—— 那也是一个答案。改动只落任务草稿层,保存不等于放行。
` + + editGate(`${D}.input_gap`, `还有 项待补 / 待确认,点「编辑」在「补充内容」列填入 —— 已绑定那几行的「输入项/来源/绑定值」抄的是启动入参,发现记录本身有误请退回触发方重新启动,不要在这里改`) + GAP_TABLE + - `
- - 键写一个英文短名(如 thermal_note);「绑定值 / 缺口说明」栏写清这项资料是什么、AI 为什么拿不到。 -
` + - flow('审批 / 提交:本工单只承载内容;「提交」请在对话区的【执行卡】中进行。提交后去向:进入步骤 2 · AI 读取与标准化,仍缺失的项将按 UNKNOWN 进入差异评估。'), - foot: sign('SS02 · ACT-WORK-05 差异评估 · 执行工单 1/1 · 评估输入与资料补齐确认', '工单类型:执行'), + addrow(`${D}.input_gap`, '+ 加一行(补充资料项)', '新加行的「输入项」与「补充内容」为必填;删一行 = 该输入项不适用;补不了的写「留 UNKNOWN」或「挂验证任务」') + + flow( + '审批 / 提交:本工单只承载内容;「提交」请在对话区的【执行卡】中进行。提交后去向:进入步骤 2 · AI 读取与标准化,仍缺失的项将按 UNKNOWN 进入差异评估。注意:启动参数如有误,需退回触发方修订后重新触发,本单不可改。', + ), }); -/* ==================== 局面 2 · 差异评估结论审核(S2/S3/S4,只读)==================== */ +/* ==================== 局面 2 · 差异评估结论审核(搬自「验收工单-01」)==================== */ -const RELATION_TABLE = `
+const RELATION_SUMMARY_TABLE = `
- - - - - - - - - + + + + + + + - - - - - - - - - + + + + + + +
候选料号替代类型推荐等级推荐理由差异摘要风险验证要求置信度#候选料号替代类型推荐等级风险等级推荐理由差异摘要
${ro('candidate_internal_pn', 'mono')}${tag('t-sub', 'substitution_type')}${tag('t-rec', 'recommendation_level')}${ro('recommendation_reason')}${ro('difference_summary')}${tag('t-risk', 'risk_level')}${ro('verification_requirement')}${ro('confidence_score', 'mono')}${badge('st rec', 'recommendation_level')}${badge('risk', 'risk_level')}
`; -const ITEM_TABLE = `
- - - - - - - - - - - - - - - +const DIFFERENCE_ITEM_TABLE = `
关系参数项原 PN 值候选 PN 值单位约束类型结论风险证据引用影响说明UNKNOWN 去向置信度
+ - - - - - - - - - - - - - + + + + + + + + + +
#参数项 parameter_name原 PN 值 original_value候选 PN 值 candidate_value单位 parameter_unit约束类型 constraint_type结论 difference_status风险等级证据引用 evidence_refAI 置信度
${ro('substitution_relation_id', 'mono')}${ro('original_value', 'mono')}${ro('candidate_value', 'mono')}${ro('parameter_unit')}${tag('t-con', 'constraint_type')}${tag('t-diff', 'difference_status')}${tag('t-risk', 'risk_level')}${ro('evidence_ref', 'mono')}${ro('impact_statement')}${ro('unknown_disposition')}${ro('confidence', 'mono')}${badge('st dst', 'difference_status')}${badge('risk', 'risk_level')}
`; export const DIFFERENCE_REVIEW = doc({ - tone: 'ledger', + css: ACC1_CSS, + alias: BIND_ACC1, badge: '验收', tag: '验收工单', kicker: 'SS02 · ACT-WORK-05 差异评估 · 验收工单 1/2', title: '差异评估结论审核', step: '步骤 3~4/5 · 逐项差异评估 + FAE/RI 审核', - state: `共 个候选 · 条比对`, + footTag: '工单类型:验收', body: - part('AI 结论说明', '结论是怎么算出来的') + - `
-

AI 已完成的计算:按 GOV 评估规则(锁定版本 ),对原 PN - 与每个候选逐项比对,四态结论 —— MATCH / - MISMATCH / - UNKNOWN / - CONDITIONAL ,并给出风险等级、证据引用与置信度。 - 差异明细 = P-11 差异明细子表(一条参数一条记录);当前为 AI 草稿,审核通过前不落账。本单数据工单创建的主数据,其参数证据标注「人工录入」。

-
` + - part('验收判据', '你据此判断「通过 / 驳回」') + + zone('AI 结论说明', '结论是怎么算出来的') + + note([ + 'AI 已完成的计算:按 GOV 评估规则(锁定版本 ),对原 PN 与每个候选逐项比对,产出四态结论——MATCH / MISMATCH / UNKNOWN / CONDITIONAL,并给出风险等级、证据引用与置信度。差异明细 = P-11 差异明细子表(一条参数差异一条记录);当前为 AI 草稿,FAE 审核通过前不落账。评估参数可能含本次数据工单创建的主数据(确认人背书;未附 datasheet 的参数项会显式标注「人工录入」)。', + ]) + criteria('判断这份差异评估结论是否可信,请逐项核对', [ '关键参数差异均有明确状态:逐项结论无漏项,每个参数都有四态之一的判定;', 'UNKNOWN 项均有去向:每个 UNKNOWN 都挂了验证任务或补来源动作,不允许悬空;', - '证据链完整:每项结论可追溯至 P-08 / P-10 / P-06 的具体记录,或本单数据工单的创建记录(人工录入);', + '证据链完整:每项结论可追溯至 P-08 / P-10 / P-06 的具体记录,或本单数据工单的创建记录(标注:人工录入);', '硬约束项未被自动判 MATCH:封装 / 工艺等硬约束未经证据支持不得判 MATCH。', ]) + - part('各候选推荐等级', '只读展示 · 每个候选一条 P-11 主记录草稿') + - RELATION_TABLE + - part('AI 产出的差异明细', '只读展示 · P-11 差异明细子表草稿') + - ITEM_TABLE + - flow('审批:本工单只承载内容;「通过 / 驳回」请在对话区的【验收卡】中进行。审核意见与补充条件写入 P-06(验证要求);通过后去向:进入步骤 5 · 评审放行与落账确认。'), - foot: sign('SS02 · ACT-WORK-05 差异评估 · 验收工单 1/2 · 差异评估结论审核', '工单类型:验收'), + zone('各候选推荐等级', '只读展示(P-11 主记录草稿,一个候选一条)') + + RELATION_SUMMARY_TABLE + + zone('AI 产出的差异明细', '只读展示(P-11 差异明细子表草稿 · 一条参数一条记录 difference_item_id)') + + DIFFERENCE_ITEM_TABLE + + flow( + '审批:本工单只承载内容;「通过 / 驳回」请在对话区的【验收卡】中进行。审核意见与补充条件写入 P-06(验证要求 verification_requirement);通过后去向:进入步骤 5 · 评审放行与落账确认。', + ), }); -/* ==================== 局面 3 · 评审放行与落账确认(S5/T_release,只读)==================== */ +/* ==================== 局面 3 · 评审放行与落账确认(搬自「验收工单-02」)==================== */ -const P11_TABLE = `
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/** 字段:值 两列表 —— 逐字节搬自目标件「拟写 P-11」「拟回写 P-01」的版式(一行一个字段), + * 用 `data-rows` 包一整张小表当行模版,一个候选 / 一条需求各重复出一份,天然支持多候选。 */ +const P11_FIELD_TABLE = `
替代关系ID替代类型原内部料号候选内部料号推荐等级推荐理由差异摘要替代分析报告分析状态客户批准状态风险验证要求证据可信度规则版本
${ro('substitution_relation_id', 'mono')}${tag('t-sub', 'substitution_type')}${ro('original_internal_pn', 'mono')}${ro('candidate_internal_pn', 'mono')}${tag('t-rec', 'recommendation_level')}${ro('recommendation_reason')}${ro('difference_summary')}${ro('analysis_report_ref', 'mono')}${tag('t-anal', 'analysis_status')}未提交 由审批流程维护,本活动不产生${tag('t-risk', 'risk_level')}${ro('verification_requirement')}${ro('confidence_score', 'mono')}${ro('rule_version', 'mono')}
+ + + + + + + + + + + + + + + +
#字段拟写入值
替代类型 substitution_type
原内部料号 original_internal_pn
候选内部料号 candidate_internal_pn
推荐等级 recommendation_level${badge('st', 'recommendation_level')} (枚举:推荐 / 条件推荐 / 备选 / 不推荐,四态之一)
推荐理由 recommendation_reason
差异摘要 difference_summary
替代分析报告 analysis_report_ref
分析状态 analysis_status${badge('st', 'analysis_status')} (枚举:AI草稿 / FAE确认 / 待客户验证 / 客户已批准 / 不批准 / 作废)
客户批准状态 customer_approval_status未提交 (由审批流程维护,本活动不产生)
风险等级 risk_level${badge('risk', 'risk_level')}
验证要求 verification_requirement
证据可信度 confidence_score
差异规则版本 rule_version
`; -const P01_TABLE = `
- - - - - - - - - - - - - - - - - - - - +const P01_FIELD_TABLE = `
需求编号风险等级验证要求输出链接下一步动作当前阶段需求状态
${ro('request_id', 'mono')}${tag('t-risk', 'risk_level')}${ro('verification_requirement')}${ro('output_ref', 'mono')}${ro('next_action')}${tag('t-stage', 'current_stage')}${tag('t-reqstat', 'request_status')}
+ + + + + + + + +
#字段拟写入值
风险等级 risk_level${badge('risk', 'risk_level')}
验证要求 verification_requirement
输出链接 output_ref
下一步动作 next_action
当前阶段 current_stage${badge('st', 'current_stage')}
需求状态 request_status${badge('st', 'request_status')}
`; export const LANDING_CONFIRM = doc({ - tone: 'ledger', + css: ACC2_CSS, + alias: BIND_ACC2, badge: '验收', tag: '验收工单', kicker: 'SS02 · ACT-WORK-05 差异评估 · 验收工单 2/2', title: '评审放行与落账确认', step: '步骤 5/5 · 提交 ACT-GATE-03', - state: `拟落账 条 P-11`, + footTag: '工单类型:验收', body: - part('AI 结论说明', '本单确认什么') + - `
-

本活动以 ACT-GATE-03 评审放行为终点。本单确认拟落账内容:评估结论层写 P-11 替代关系主记录(每个候选一条)与差异明细子表,需求状态回写 P-01(风险等级 / 验证要求 / 输出链接 / 下一步动作 / 当前阶段)。 - 客户批准不属于本活动 —— 客户批准状态由审批流程维护,本单只写分析层(分析状态 = FAE 确认)。

-
` + - part('验收判据', '你据此判断「通过 / 驳回」') + + zone('AI 结论说明', '本单确认什么') + + note([ + '本活动以 ACT-GATE-03 评审放行为终点。本单确认拟落账内容:评估结论层写 P-11 替代关系主记录(替代类型 / 原内部料号 / 候选内部料号 / 推荐等级 / 推荐理由 / 差异摘要 / 替代分析报告 / 分析状态 / 风险等级 / 验证要求 / 证据可信度 / 差异规则版本),需求状态回写 P-01(风险等级 / 验证要求 / 输出链接 / 下一步动作 / 当前阶段)。客户批准不属于本活动——客户批准状态由审批流程维护,本单只写分析层(分析状态 = FAE 确认),customer_approval_status 保持「未提交」,不由差异评估产生。', + ]) + criteria('放行与落账前,请逐项核对', [ - '推荐等级与差异明细一致:存在 UNKNOWN / CONDITIONAL 的候选,推荐等级不得给「推荐」;', - '分析状态与客户批准状态分离:本单只写分析层(FAE 确认),客户批准状态保持「未提交」;', + '推荐等级与差异明细一致:差异明细中存在 UNKNOWN / CONDITIONAL 时,推荐等级不得给「推荐」;', + '分析状态与客户批准状态分离:本单只写分析层(分析状态 = FAE 确认),客户批准状态保持「未提交」;', 'GOV 规则版本已锁定:规则版本随结论一并落账;', '回写 P-01 字段完整:风险等级、验证要求、输出链接、下一步动作、当前阶段五项齐全。', ]) + - part('拟写 P-11 · 替代关系主记录', '只读展示') + - P11_TABLE + - part('拟回写 P-01 · 需求状态', '只读展示') + - P01_TABLE + - flow('审批:本工单只承载内容;「通过 / 驳回」请在对话区的【验收卡】中进行。通过后去向:P-11 落账、P-01 回写、放行;结论供 ACT-WORK-08 证据归集消费。'), - foot: sign('SS02 · ACT-WORK-05 差异评估 · 验收工单 2/2 · 评审放行与落账确认', '工单类型:验收'), + zone('拟写 P-11 · 替代关系主记录', '只读展示') + + P11_FIELD_TABLE + + zone('拟回写 P-01 · 需求状态', '只读展示') + + P01_FIELD_TABLE + + flow( + '审批:本工单只承载内容;「通过 / 驳回」请在对话区的【验收卡】中进行。通过后去向:在对话区卡提交 ACT-GATE-03 评审放行;放行后结论供 ACT-WORK-08 证据归集消费。', + ), }); diff --git a/activities/part-substitution-assessment/src/views/target-style.ts b/activities/part-substitution-assessment/src/views/target-style.ts new file mode 100644 index 0000000..3026657 --- /dev/null +++ b/activities/part-substitution-assessment/src/views/target-style.ts @@ -0,0 +1,336 @@ +/** + * ACT-WORK-05 差异评估的四份目标件样式表 —— **机械抽取,一个数值都不许改** + * (《HTML报告生成规范》§7:有目标件时「搬」,不要「照着做」;样式表整段搬,标记逐块搬)。 + * + * 来源(`docs/SS02-ACT-WORK-05-html/`): + * · `P08_CSS` ← `ACT-WORK-05-数据工单-01-芯片主数据创建.html` 的两段 `` 之间的原文,再拿抽出来的内容包回 + * `` 与源文件同一行区间做 `diff`,四份全部「零差异」——过程写在 + * task-5-report.md,这里不重复贴证据。 + * + * 这份文件只装**目标件自己的样式**,不装平台绑定用的开关(三态占位、缺项红带、 + * `data-class-of` 的 `v-*` 别名这类)——那些是本活动自己加出来的东西,活在 + * `report.ts` 的 `BIND_CSS_*` 常量里,两处不要混。 + */ + +export const P08_CSS = ` +:root{ + --ink:#1f2329; --ink-2:#41464e; --ink-3:#646a73; --ink-4:#8f959e; + --line:#dee0e3; --line-soft:#e8eaed; --soft:#f8f9fb; + --brand:#3370ff; --brand-deep:#245bdb; --brand-soft:#e1eaff; --brand-wash:#f0f4ff; + --data:#3370ff; --data-soft:#e1eaff; --data-line:#c3d6ff; + --ok:#278717; --ok-soft:#e8f8e4; --danger:#d83931; --danger-soft:#feeae9; + --mono:"SF Mono",Menlo,Consolas,monospace; +} +*{box-sizing:border-box} +html,body{margin:0;padding:0} +body{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:#eef1f6;color:var(--ink);font-size:14px;line-height:1.7;-webkit-font-smoothing:antialiased} +.page{margin:0;padding:0} +.card{background:#fff;overflow:hidden;border:0;border-radius:0;box-shadow:none} +.card-head{display:flex;align-items:center;gap:14px;padding:18px 22px;border-bottom:2px solid var(--ink);background:linear-gradient(120deg,#f0f5ff 0%,#fff 55%,#eef4ff 100%)} +.badge{flex:none;width:44px;height:44px;border-radius:10px;display:grid;place-items:center;background:var(--data);color:#fff;font-weight:800;font-size:13px;box-shadow:0 6px 16px rgba(51,112,255,.25)} +.tit{flex:1;min-width:0} +.tit .kick{font-size:11px;letter-spacing:.08em;color:var(--ink-4);font-weight:700} +.tit h1{margin:2px 0 0;font-size:19px;font-weight:800;line-height:1.3} +.tit .sub{font-size:12px;color:var(--ink-3);margin-top:3px} +.side{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none} +.tag{font-size:11px;font-weight:800;padding:2px 10px;border-radius:999px;color:var(--data);background:var(--data-soft);border:1px solid var(--data-line)} +.step{font-size:12px;color:var(--ink-3)} +.deadline{font-size:12px;color:var(--ink-3)} +.deadline b{color:var(--danger)} +.card-bd{padding:20px 22px} +.zone{font-size:11px;font-weight:800;letter-spacing:.12em;color:var(--ink-4);margin:0 0 8px} +.zone b{color:var(--ink-3)} +.note{border:1px solid var(--line);border-left:3px solid var(--data);border-radius:8px;background:var(--soft);padding:14px 16px;margin-bottom:16px} +.note p{margin:0 0 6px;font-size:13px;color:var(--ink-2)} +.note p:last-child{margin-bottom:0} +.note b{color:var(--ink)} +.note .done{color:var(--ok);font-weight:700} +.note .need{color:var(--data);font-weight:700} +.jc-editgate{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:14px 0 10px;padding:9px 12px;border-radius:9px;background:var(--soft);border:1px solid var(--line-soft);font-size:12px;color:var(--ink-3)} +.jc-editgate-t{flex:1 1 auto;min-width:0} +.jc-editgate-t b{color:var(--ink-2);font-weight:700} +.jc-egbtn{flex:none;display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:1px solid var(--line);border-radius:7px;padding:6px 13px;font:inherit;font-size:12px;font-weight:700;color:var(--ink-2);background:#fff;transition:border-color .16s,color .16s,background .16s} +.jc-egbtn:hover{border-color:var(--brand);color:var(--brand)} +.jc-egbtn.save{color:#fff;background:var(--data);border-color:var(--data)} +.jc-egbtn.save:hover{filter:brightness(1.06);color:#fff} +.jc-editgate .eg-cancel,.jc-editgate .eg-save{display:none} +.jc-editgate.on{background:var(--brand-wash);border-color:var(--data-line);color:#1e40af} +.jc-editgate.on .eg-open{display:none} +.jc-editgate.on .eg-cancel,.jc-editgate.on .eg-save{display:inline-flex} +.tbl-wrap{border:1px solid var(--line-soft);border-radius:10px;overflow:hidden} +table{width:100%;border-collapse:collapse;font-size:12.5px} +th{text-align:left;background:var(--soft);font-size:11px;letter-spacing:.03em;font-weight:800;color:var(--ink-3);padding:9px 10px;border-bottom:1px solid var(--line)} +th.req::after{content:" *";color:var(--danger);font-size:11px} +td{padding:8px 10px;border-bottom:1px solid var(--line-soft);vertical-align:middle} +tr:last-child td{border-bottom:0} +td.rn{position:relative;width:38px;white-space:nowrap;font-family:var(--mono);font-size:11px;color:var(--ink-4);text-align:center} +.jc-vcell{display:block;font-size:12.5px;color:var(--ink);line-height:1.5;overflow-wrap:anywhere} +.jc-vcell.mono{font-family:var(--mono);font-size:11.5px;color:var(--ink-2)} +.jc-cell{display:none;width:100%;min-width:60px;border:1px solid var(--line);border-radius:6px;padding:6px 8px;font:inherit;font-size:12.5px;color:var(--ink);background:#fff} +.jc-cell.mono{font-family:var(--mono);font-size:11.5px} +.jc-cell:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-wash);outline:none} +table.on td>.jc-vcell{display:none} +table.on td>.jc-cell{display:block} +td.rn .jc-rowdel{display:none;width:22px;height:22px;margin:0 auto;cursor:pointer;border:1px solid var(--line);border-radius:6px;padding:0;font:inherit;font-size:14px;line-height:1;color:var(--ink-3);background:#fff} +td.rn .jc-rowdel:hover{border-color:var(--danger);color:var(--danger);background:var(--danger-soft)} +table.on td.rn .jc-rn-num{display:none} +table.on td.rn .jc-rowdel{display:block} +.jc-addrow{display:none;margin:8px 0 0;padding:8px 12px;border-radius:9px;background:var(--soft);border:1px dashed var(--line);font-size:12px;color:var(--ink-3)} +.jc-addrow.show{display:flex;align-items:center;gap:8px} +.jc-addrow button{cursor:pointer;border:1px solid var(--brand-soft);border-radius:7px;padding:5px 12px;font:inherit;font-size:12px;font-weight:700;color:var(--brand-deep);background:var(--brand-wash)} +.jc-addrow button:hover{background:var(--brand-soft)} +.jc-addrow em{font-style:normal;font-size:11.5px;color:var(--ink-4)} +.flow{margin-top:16px;padding:9px 12px;border-radius:8px;background:var(--soft);border:1px dashed var(--line);font-size:12px;color:var(--ink-3)} +.flow b{color:var(--ink)} +.card-foot{padding:13px 22px;border-top:1px solid var(--line-soft);font-size:11.5px;color:var(--ink-4);display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px} +@media(max-width:600px){.card-head{flex-wrap:wrap}.side{align-items:flex-start}} +/* 补充:数据工单专用标识(仅追加,不改动基件样式) */ +.mono{font-family:var(--mono);font-size:12px;color:var(--ink-2)} +.pre{font-style:normal;font-size:10.5px;font-weight:800;color:var(--data);background:var(--data-soft);border:1px solid var(--data-line);border-radius:999px;padding:0 7px;margin-left:6px;white-space:nowrap} +table.on td>.pre{display:none} +.ct{display:inline-block;font-size:11px;font-weight:700;padding:1px 8px;border-radius:999px;border:1px solid transparent;white-space:nowrap} +.ct.hard{color:var(--danger);background:var(--danger-soft);border-color:#f3b9b5} +.ct.soft{color:var(--ink-3);background:#eef1f6;border-color:var(--line)} +.tbl-gap{margin-top:18px} +/* ===== 视觉补充段 v3(通用批量模板:字段即表头、每行一条;不改基件样式与 JS 钩子) ===== */ +.hic{flex:none;width:26px;height:26px;color:var(--data)} +.zic{width:14px;height:14px;color:var(--ink-3);vertical-align:-2px;margin-right:3px} +/* 表头内字段说明(第二行小字) */ +.thd{display:block;font-size:10px;font-weight:600;color:var(--ink-4);letter-spacing:0;margin-top:1px;line-height:1.4} +/* 表 1:字段即表头,内容多列,允许横向滚动 */ +#tbl1{min-width:1240px} +#tbl1 .jc-vcell{display:inline} +/* 表 2 列宽 */ +#tbl2 th:nth-child(2){width:150px} +#tbl2 th:nth-child(3){width:18%} +#tbl2 th:nth-child(4){width:14%} +#tbl2 th:nth-child(5){width:8%;text-align:center;white-space:nowrap} +#tbl2 th:nth-child(6){width:13%;text-align:center;white-space:nowrap} +#tbl2 td:nth-child(5),#tbl2 td:nth-child(6){text-align:center;white-space:nowrap} +/* 说明列(只读注释,编辑态保持可见) */ +.desc{color:var(--ink-3);font-size:12px;line-height:1.5} +table.on td>.jc-vcell.ro{display:block} +.tbl-wrap{overflow-x:auto} +@media (prefers-reduced-motion: reduce){*{animation:none!important;transition:none!important}} +`; + +export const EXEC_CSS = ` +:root{ + --ink:#1f2329; --ink-2:#41464e; --ink-3:#646a73; --ink-4:#8f959e; + --line:#dee0e3; --line-soft:#e8eaed; --soft:#f8f9fb; + --brand:#3370ff; --brand-deep:#245bdb; --brand-soft:#e1eaff; --brand-wash:#f0f4ff; + --human:#a9711e; --human-soft:#f6ecd8; --human-line:#e6d3a8; + --ok:#278717; --ok-soft:#e8f8e4; --danger:#d83931; --danger-soft:#feeae9; + --mono:"SF Mono",Menlo,Consolas,monospace; +} +*{box-sizing:border-box} +html,body{margin:0;padding:0} +body{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:#eef1f6;color:var(--ink);font-size:14px;line-height:1.7;-webkit-font-smoothing:antialiased} +.page{margin:0;padding:0} +.card{background:#fff;overflow:hidden;border:0;border-radius:0;box-shadow:none} +.card-head{display:flex;align-items:center;gap:14px;padding:18px 22px;border-bottom:2px solid var(--ink);background:linear-gradient(120deg,#fffaf1 0%,#fff 55%,#fbf6ea 100%)} +.badge{flex:none;width:44px;height:44px;border-radius:10px;display:grid;place-items:center;background:var(--human);color:#fff;font-weight:800;font-size:13px;box-shadow:0 6px 16px rgba(169,113,30,.25)} +.tit{flex:1;min-width:0} +.tit .kick{font-size:11px;letter-spacing:.08em;color:var(--ink-4);font-weight:700} +.tit h1{margin:2px 0 0;font-size:19px;font-weight:800;line-height:1.3} +.tit .sub{font-size:12px;color:var(--ink-3);margin-top:3px} +.side{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none} +.tag{font-size:11px;font-weight:800;padding:2px 10px;border-radius:999px;color:var(--human);background:var(--human-soft);border:1px solid var(--human-line)} +.step{font-size:12px;color:var(--ink-3)} +.deadline{font-size:12px;color:var(--ink-3)} +.deadline b{color:var(--danger)} +.card-bd{padding:20px 22px} +.zone{font-size:11px;font-weight:800;letter-spacing:.12em;color:var(--ink-4);margin:0 0 8px} +.zone b{color:var(--ink-3)} +.note{border:1px solid var(--line);border-left:3px solid var(--human);border-radius:8px;background:var(--soft);padding:14px 16px;margin-bottom:16px} +.note p{margin:0;font-size:13px;color:var(--ink-2)} +.note b{color:var(--ink)} +.note .done{color:var(--ok);font-weight:700} +.note .need{color:var(--human);font-weight:700} +.jc-editgate{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:14px 0 10px;padding:9px 12px;border-radius:9px;background:var(--soft);border:1px solid var(--line-soft);font-size:12px;color:var(--ink-3)} +.jc-editgate-t{flex:1 1 auto;min-width:0} +.jc-editgate-t b{color:var(--ink-2);font-weight:700} +.jc-egbtn{flex:none;display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:1px solid var(--line);border-radius:7px;padding:6px 13px;font:inherit;font-size:12px;font-weight:700;color:var(--ink-2);background:#fff;transition:border-color .16s,color .16s,background .16s} +.jc-egbtn:hover{border-color:var(--brand);color:var(--brand)} +.jc-egbtn.save{color:#fff;background:var(--human);border-color:var(--human)} +.jc-egbtn.save:hover{filter:brightness(1.06);color:#fff} +.jc-editgate .eg-cancel,.jc-editgate .eg-save{display:none} +.jc-editgate.on{background:var(--human-soft);border-color:var(--human-line);color:#7c4a12} +.jc-editgate.on .eg-open{display:none} +.jc-editgate.on .eg-cancel,.jc-editgate.on .eg-save{display:inline-flex} +.tbl-wrap{border:1px solid var(--line-soft);border-radius:10px;overflow:hidden} +table{width:100%;border-collapse:collapse;font-size:12.5px} +th{text-align:left;background:var(--soft);font-size:11px;letter-spacing:.03em;font-weight:800;color:var(--ink-3);padding:9px 10px;border-bottom:1px solid var(--line)} +th.req::after{content:" *";color:var(--danger);font-size:11px} +td{padding:8px 10px;border-bottom:1px solid var(--line-soft);vertical-align:middle} +tr:last-child td{border-bottom:0} +td.rn{position:relative;width:38px;white-space:nowrap;font-family:var(--mono);font-size:11px;color:var(--ink-4);text-align:center} +.jc-vcell{display:block;font-size:12.5px;color:var(--ink);line-height:1.5;overflow-wrap:anywhere} +.jc-vcell.mono{font-family:var(--mono);font-size:11.5px;color:var(--ink-2)} +.jc-cell{display:none;width:100%;min-width:60px;border:1px solid var(--line);border-radius:6px;padding:6px 8px;font:inherit;font-size:12.5px;color:var(--ink);background:#fff} +.jc-cell.mono{font-family:var(--mono);font-size:11.5px} +.jc-cell:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-wash);outline:none} +table.on td>.jc-vcell{display:none} +table.on td>.jc-cell{display:block} +td.rn .jc-rowdel{display:none;width:22px;height:22px;margin:0 auto;cursor:pointer;border:1px solid var(--line);border-radius:6px;padding:0;font:inherit;font-size:14px;line-height:1;color:var(--ink-3);background:#fff} +td.rn .jc-rowdel:hover{border-color:var(--danger);color:var(--danger);background:var(--danger-soft)} +table.on td.rn .jc-rn-num{display:none} +table.on td.rn .jc-rowdel{display:block} +.jc-addrow{display:none;margin:8px 0 0;padding:8px 12px;border-radius:9px;background:var(--soft);border:1px dashed var(--line);font-size:12px;color:var(--ink-3)} +.jc-addrow.show{display:flex;align-items:center;gap:8px} +.jc-addrow button{cursor:pointer;border:1px solid var(--brand-soft);border-radius:7px;padding:5px 12px;font:inherit;font-size:12px;font-weight:700;color:var(--brand-deep);background:var(--brand-wash)} +.jc-addrow button:hover{background:var(--brand-soft)} +.jc-addrow em{font-style:normal;font-size:11.5px;color:var(--ink-4)} +.flow{margin-top:16px;padding:9px 12px;border-radius:8px;background:var(--soft);border:1px dashed var(--line);font-size:12px;color:var(--ink-3)} +.flow b{color:var(--ink)} +.card-foot{padding:13px 22px;border-top:1px solid var(--line-soft);font-size:11.5px;color:var(--ink-4);display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px} +@media(max-width:600px){.card-head{flex-wrap:wrap}.side{align-items:flex-start}} +/* 补充:评估输入清单状态标识(仅追加,不改动基件样式) */ +.mono{font-family:var(--mono);font-size:12px;color:var(--ink-2)} +.st{display:inline-block;font-size:11px;font-weight:700;padding:1px 8px;border-radius:999px;border:1px solid transparent;white-space:nowrap} +.st.bound{color:var(--ink-3);background:#eef1f6;border-color:var(--line)} +.st.ok{color:var(--ok);background:var(--ok-soft);border-color:#c9ecc2} +.st.miss{color:var(--human);background:var(--human-soft);border-color:var(--human-line)} +.st.def{color:var(--brand-deep);background:var(--brand-wash);border-color:var(--brand-soft)} +tr.ro td{background:var(--soft)} +table.on td>.jc-vcell.ro{display:block} +`; + +export const ACC1_CSS = ` +:root{ + --ink:#1f2329; --ink-2:#41464e; --ink-3:#646a73; --ink-4:#8f959e; + --line:#dee0e3; --line-soft:#e8eaed; --soft:#f8f9fb; + --brand:#3370ff; --brand-deep:#245bdb; --brand-soft:#e1eaff; --brand-wash:#f0f4ff; + --ledger:#b23a2e; --ledger-soft:#f7e4e0; --ledger-line:#ecc5bd; + --ok:#278717; --ok-soft:#e8f8e4; --danger:#d83931; --danger-soft:#feeae9; + --mono:"SF Mono",Menlo,Consolas,monospace; +} +*{box-sizing:border-box} +html,body{margin:0;padding:0} +body{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:#eef1f6;color:var(--ink);font-size:14px;line-height:1.7;-webkit-font-smoothing:antialiased} +.page{margin:0;padding:0} +.card{background:#fff;overflow:hidden;border:0;border-radius:0;box-shadow:none} +.card-head{display:flex;align-items:center;gap:14px;padding:18px 22px;border-bottom:2px solid var(--ink);background:linear-gradient(120deg,#fdf3f1 0%,#fff 55%,#fbf2f0 100%)} +.badge{flex:none;width:44px;height:44px;border-radius:10px;display:grid;place-items:center;background:var(--ledger);color:#fff;font-weight:800;font-size:13px;box-shadow:0 6px 16px rgba(178,58,46,.25)} +.tit{flex:1;min-width:0} +.tit .kick{font-size:11px;letter-spacing:.08em;color:var(--ink-4);font-weight:700} +.tit h1{margin:2px 0 0;font-size:19px;font-weight:800;line-height:1.3} +.tit .sub{font-size:12px;color:var(--ink-3);margin-top:3px} +.side{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none} +.tag{font-size:11px;font-weight:800;padding:2px 10px;border-radius:999px;color:var(--ledger);background:var(--ledger-soft);border:1px solid var(--ledger-line)} +.step{font-size:12px;color:var(--ink-3)} +.deadline{font-size:12px;color:var(--ink-3)} +.deadline b{color:var(--danger)} +.card-bd{padding:20px 22px} +.zone{font-size:11px;font-weight:800;letter-spacing:.12em;color:var(--ink-4);margin:0 0 8px} +.zone b{color:var(--ink-3)} +.note{border:1px solid var(--line);border-left:3px solid var(--ledger);border-radius:8px;background:var(--soft);padding:14px 16px;margin-bottom:16px} +.note p{margin:0;font-size:13px;color:var(--ink-2)} +.note b{color:var(--ink)} +.criteria{border:1px solid var(--ledger-line);border-radius:10px;background:var(--ledger-soft);padding:13px 16px;margin-bottom:18px} +.criteria .c-title{font-size:11px;font-weight:800;letter-spacing:.08em;color:var(--ledger);margin-bottom:7px} +.criteria ul{margin:0;padding-left:18px;font-size:12.5px;color:var(--ink-2)} +.criteria li{margin:4px 0} +.criteria b{color:var(--ink)} +.tbl-wrap{border:1px solid var(--line-soft);border-radius:10px;overflow:hidden} +table{width:100%;border-collapse:collapse;font-size:13px} +th{text-align:left;background:var(--soft);font-size:11px;letter-spacing:.05em;font-weight:800;color:var(--ink-3);padding:9px 12px;border-bottom:1px solid var(--line)} +td{padding:11px 12px;border-bottom:1px solid var(--line-soft);vertical-align:top} +tr:last-child td{border-bottom:0} +.num{font-family:var(--mono);color:var(--ink-4);white-space:nowrap} +.cust{font-weight:700} +.prio{font-family:var(--mono);font-weight:800} +.prio.hi{color:var(--danger)} +.prio.mid{color:var(--ink-2)} +.reason{font-size:12.5px;color:var(--ink-2)} +.flow{margin-top:16px;padding:9px 12px;border-radius:8px;background:var(--soft);border:1px dashed var(--line);font-size:12px;color:var(--ink-3)} +.flow b{color:var(--ink)} +.card-foot{padding:13px 22px;border-top:1px solid var(--line-soft);font-size:11.5px;color:var(--ink-4);display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px} +@media(max-width:600px){.card-head{flex-wrap:wrap}.side{align-items:flex-start}} +/* 补充:四态结论 pill 与风险等级(仅追加,不改动基件样式) */ +.st{display:inline-block;padding:1px 9px;border-radius:999px;font-size:11px;font-weight:800;letter-spacing:.04em;font-family:var(--mono);white-space:nowrap;border:1px solid transparent} +.st.ok{color:var(--ok);background:var(--ok-soft);border-color:#bfe6b4} +.st.miss{color:var(--danger);background:var(--danger-soft);border-color:#f3b9b5} +.st.unknown{color:#8f6a12;background:#fdf3d7;border-color:#ecd9a0} +.st.cond{color:var(--ledger);background:var(--ledger-soft);border-color:var(--ledger-line)} +.risk{font-weight:800;font-size:12.5px} +.risk.low{color:var(--ok)} +.risk.mid{color:#8f6a12} +.risk.hi{color:var(--danger)} +.mono{font-family:var(--mono);font-size:12px;color:var(--ink-2)} +`; + +export const ACC2_CSS = ` +:root{ + --ink:#1f2329; --ink-2:#41464e; --ink-3:#646a73; --ink-4:#8f959e; + --line:#dee0e3; --line-soft:#e8eaed; --soft:#f8f9fb; + --brand:#3370ff; --brand-deep:#245bdb; --brand-soft:#e1eaff; --brand-wash:#f0f4ff; + --ledger:#b23a2e; --ledger-soft:#f7e4e0; --ledger-line:#ecc5bd; + --ok:#278717; --ok-soft:#e8f8e4; --danger:#d83931; --danger-soft:#feeae9; + --mono:"SF Mono",Menlo,Consolas,monospace; +} +*{box-sizing:border-box} +html,body{margin:0;padding:0} +body{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:#eef1f6;color:var(--ink);font-size:14px;line-height:1.7;-webkit-font-smoothing:antialiased} +.page{margin:0;padding:0} +.card{background:#fff;overflow:hidden;border:0;border-radius:0;box-shadow:none} +.card-head{display:flex;align-items:center;gap:14px;padding:18px 22px;border-bottom:2px solid var(--ink);background:linear-gradient(120deg,#fdf3f1 0%,#fff 55%,#fbf2f0 100%)} +.badge{flex:none;width:44px;height:44px;border-radius:10px;display:grid;place-items:center;background:var(--ledger);color:#fff;font-weight:800;font-size:13px;box-shadow:0 6px 16px rgba(178,58,46,.25)} +.tit{flex:1;min-width:0} +.tit .kick{font-size:11px;letter-spacing:.08em;color:var(--ink-4);font-weight:700} +.tit h1{margin:2px 0 0;font-size:19px;font-weight:800;line-height:1.3} +.tit .sub{font-size:12px;color:var(--ink-3);margin-top:3px} +.side{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none} +.tag{font-size:11px;font-weight:800;padding:2px 10px;border-radius:999px;color:var(--ledger);background:var(--ledger-soft);border:1px solid var(--ledger-line)} +.step{font-size:12px;color:var(--ink-3)} +.deadline{font-size:12px;color:var(--ink-3)} +.deadline b{color:var(--danger)} +.card-bd{padding:20px 22px} +.zone{font-size:11px;font-weight:800;letter-spacing:.12em;color:var(--ink-4);margin:0 0 8px} +.zone b{color:var(--ink-3)} +.note{border:1px solid var(--line);border-left:3px solid var(--ledger);border-radius:8px;background:var(--soft);padding:14px 16px;margin-bottom:16px} +.note p{margin:0;font-size:13px;color:var(--ink-2)} +.note b{color:var(--ink)} +.criteria{border:1px solid var(--ledger-line);border-radius:10px;background:var(--ledger-soft);padding:13px 16px;margin-bottom:18px} +.criteria .c-title{font-size:11px;font-weight:800;letter-spacing:.08em;color:var(--ledger);margin-bottom:7px} +.criteria ul{margin:0;padding-left:18px;font-size:12.5px;color:var(--ink-2)} +.criteria li{margin:4px 0} +.criteria b{color:var(--ink)} +.tbl-wrap{border:1px solid var(--line-soft);border-radius:10px;overflow:hidden} +table{width:100%;border-collapse:collapse;font-size:13px} +th{text-align:left;background:var(--soft);font-size:11px;letter-spacing:.05em;font-weight:800;color:var(--ink-3);padding:9px 12px;border-bottom:1px solid var(--line)} +td{padding:11px 12px;border-bottom:1px solid var(--line-soft);vertical-align:top} +tr:last-child td{border-bottom:0} +.num{font-family:var(--mono);color:var(--ink-4);white-space:nowrap} +.cust{font-weight:700} +.prio{font-family:var(--mono);font-weight:800} +.prio.hi{color:var(--danger)} +.prio.mid{color:var(--ink-2)} +.reason{font-size:12.5px;color:var(--ink-2)} +.flow{margin-top:16px;padding:9px 12px;border-radius:8px;background:var(--soft);border:1px dashed var(--line);font-size:12px;color:var(--ink-3)} +.flow b{color:var(--ink)} +.card-foot{padding:13px 22px;border-top:1px solid var(--line-soft);font-size:11.5px;color:var(--ink-4);display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px} +@media(max-width:600px){.card-head{flex-wrap:wrap}.side{align-items:flex-start}} +/* 补充:推荐等级 pill 与状态强调(仅追加,不改动基件样式) */ +.st{display:inline-block;padding:1px 9px;border-radius:999px;font-size:11px;font-weight:800;letter-spacing:.04em;font-family:var(--mono);white-space:nowrap;border:1px solid transparent} +.st.ok{color:var(--ok);background:var(--ok-soft);border-color:#bfe6b4} +.st.miss{color:var(--danger);background:var(--danger-soft);border-color:#f3b9b5} +.st.unknown{color:#8f6a12;background:#fdf3d7;border-color:#ecd9a0} +.st.cond{color:var(--ledger);background:var(--ledger-soft);border-color:var(--ledger-line)} +.risk{font-weight:800;font-size:12.5px} +.risk.mid{color:#8f6a12} +.mono{font-family:var(--mono);font-size:12px;color:var(--ink-2)} +.tbl-gap{margin-top:18px} +`;