From ce5ef5e5f0fa6628322628452fc9e537312c8abe Mon Sep 17 00:00:00 2001 From: ThearchyHelios Date: Wed, 21 Oct 2026 18:24:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=A3=E5=BE=84=E8=B4=A6=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E8=BD=AE=E6=AC=A1=E6=91=98=E8=A6=81=E5=8F=AA=E6=95=B0=E5=9B=9B?= =?UTF-8?q?=E7=A7=8D=E6=A0=87=E7=AD=BE=EF=BC=88=E6=9D=A5=E8=87=AA=E5=8F=A3?= =?UTF-8?q?=E5=BE=84=E3=80=81=E7=9B=B8=E5=85=B3=E5=8F=A3=E5=BE=84=E3=80=81?= =?UTF-8?q?=E8=BF=99=E6=AC=A1=E7=9A=84=E6=8E=A8=E7=90=86=E3=80=81=E6=B2=A1?= =?UTF-8?q?=E6=AF=94=E5=AF=B9=EF=BC=89=EF=BC=9A=E8=AE=A4=E4=B8=8D=E5=87=BA?= =?UTF-8?q?=E7=A7=8D=E7=B1=BB=E7=9A=84=E6=A0=87=E7=AD=BE=EF=BC=88=E4=B8=8D?= =?UTF-8?q?=E6=98=AF=E5=AF=B9=E8=B1=A1=E3=80=81=E6=B2=A1=E6=9C=89=E7=A7=8D?= =?UTF-8?q?=E7=B1=BB=E3=80=81=E4=B8=8D=E6=98=AF=E8=BF=99=E5=9B=9B=E7=A7=8D?= =?UTF-8?q?=EF=BC=89=E4=B8=8D=E8=AE=A1=E3=80=81=E4=B9=9F=E4=B8=8D=E7=AE=97?= =?UTF-8?q?=E8=BF=9B=E6=80=BB=E6=95=B0=EF=BC=8C=E6=91=98=E8=A6=81=E9=82=A3?= =?UTF-8?q?=E4=B8=80=E5=8F=A5=E8=AF=B4=E5=BE=97=E5=B9=B3=E3=80=81=E4=B8=8D?= =?UTF-8?q?=E5=87=BA=20NaN=E3=80=82=E5=88=86=E6=9E=90=E7=BB=93=E8=AE=BA?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E4=B8=8D=E5=92=8C=E5=8F=A3=E5=BE=84=E6=AF=94?= =?UTF-8?q?=E5=AF=B9=EF=BC=8C=E6=9C=8D=E5=8A=A1=E7=AB=AF=E4=B8=8D=E7=BB=99?= =?UTF-8?q?=E5=AE=83=E4=BB=AC=E6=A0=87=E7=AD=BE=EF=BC=8800-=E6=80=BB?= =?UTF-8?q?=E6=96=B9=E6=A1=88=20D11=EF=BC=89=EF=BC=8C=E8=BF=99=E9=87=8C?= =?UTF-8?q?=E6=98=AF=E9=98=B2=E7=9D=80=E4=BB=A5=E5=90=8E=E5=A4=9A=E5=87=BA?= =?UTF-8?q?=E5=88=AB=E7=9A=84=E7=A7=8D=E7=B1=BB=E3=80=82check-ledger=20?= =?UTF-8?q?=E7=9A=84=E4=BD=BF=E7=94=A8=E8=80=85=E4=B8=80=E8=8A=82=E6=B7=B7?= =?UTF-8?q?=E8=BF=9B=E4=B8=A4=E4=B8=AA=E8=AE=A4=E4=B8=8D=E5=87=BA=E7=A7=8D?= =?UTF-8?q?=E7=B1=BB=E7=9A=84=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/run/LedgerTurn.tsx | 15 ++++++++++++--- scripts/check-ledger.mjs | 5 ++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/frontend/src/run/LedgerTurn.tsx b/frontend/src/run/LedgerTurn.tsx index fcb7bedd..9ce300f9 100644 --- a/frontend/src/run/LedgerTurn.tsx +++ b/frontend/src/run/LedgerTurn.tsx @@ -21,13 +21,22 @@ import { ReconcileDialog, ReconcileResults } from './LedgerReconcile' * 能不能自动、不能的原因都是服务端给的;摘要只是把主报告里服务端标好的数按标签数一数、写出是哪份口径。 */ -/** 摘要的几个数:主报告里服务端标好的标签按种类数,来自口径的写出是哪几份口径(按出现的先后) */ +/** 摘要认的四种标签。服务端不给别的标签(分析结论的数不和口径比对,00-总方案 D11),以后多了也不计、不出 NaN */ +const COUNTED_KINDS = ['caliber', 'related', 'reasoning', 'unknown'] as const +type CountedKind = (typeof COUNTED_KINDS)[number] +const counted = (kind: unknown): kind is CountedKind => (COUNTED_KINDS as readonly unknown[]).includes(kind) + +/** + * 摘要的几个数:主报告里服务端标好的标签按种类数,来自口径的写出是哪几份口径(按出现的先后)。认不出种类的标签(不是对象、 + * 没有 kind、不是四种之一)不计,也不算进总数:总数要等于四种之和,摘要那一句才说得平 + */ function summaryOf(data: RunLedger) { const labels = Object.values((data.primary ? data.reports?.[data.primary]?.labels : undefined) ?? {}) - const counts = { caliber: 0, related: 0, reasoning: 0, unknown: 0 } + .filter((l) => !!l && typeof l === 'object' && counted(l.kind)) + const counts: Record = { caliber: 0, related: 0, reasoning: 0, unknown: 0 } const calibers: string[] = [] for (const l of labels) { - counts[l.kind] += 1 + counts[l.kind as CountedKind] += 1 if (l.kind === 'caliber') { const name = caliberOf(l) if (!calibers.includes(name)) calibers.push(name) diff --git a/scripts/check-ledger.mjs b/scripts/check-ledger.mjs index 7d4eb95a..7a1355ea 100644 --- a/scripts/check-ledger.mjs +++ b/scripts/check-ledger.mjs @@ -458,7 +458,9 @@ await section('使用者看到的入口照服务端的动作:不能出具的 meta: { v: 1, runId: RUN_U, runClass: 'exploratory', runStatus: 'succeeded', evidence: true } } const refused = { ...ISSUE, available: false, auto: false, reason: '这份口径没有被你能使用的应用固定,不能由你按口径出具,请搭建者出具' } delete refused.auto_reason - const LED = ledgerOf(RUN_U, { labels: WHOLE_LABELS, whole: WHOLE, actions: [refused, RECONCILE], + // 摘要只认四种标签(分析结论的数不和口径比对,服务端不给它们标签):混进来认不出的种类,不计、不出 NaN + const LED = ledgerOf(RUN_U, { labels: { ...WHOLE_LABELS, s40: { kind: 'analysis' }, s42: { reason: '没有种类' } }, + whole: WHOLE, actions: [refused, RECONCILE], // 出具过的是另一份口径(订单口径):周报口径这一项还没出具过,照服务端的原因写为什么不能出具 issued: [{ run_id: 'run-iss-u', status: 'succeeded', workflow_id: 'wf-orders', version: 1, tier: 'degraded', tier_text: '降档出具', auto: true }] }) const reply = (method, p) => { @@ -478,6 +480,7 @@ await section('使用者看到的入口照服务端的动作:不能出具的 const shown = await box.waitFor({ timeout: 12000 }).then(() => true, () => false) const text = shown ? (await box.innerText()).replace(/\s+/g, ' ') : '' check('使用者也看到摘要', text.includes('3 个数来自口径「周报口径」v2(受管)'), text) + check('……认不出种类的标签不计、不出 NaN', !text.includes('NaN') && !text.includes('undefined'), text) check('不能出具:照服务端的原因写「请搭建者出具」,不摆出具按钮', text.includes('请搭建者出具') && await page.locator('[data-ledger-issue-button]').count() === 0, text) check('能对账:照样摆对账按钮', await page.locator('[data-ledger-turn-reconcile]').count() === 1)