From bc615670efb5c96f04cd4e2a3bdcd7e702d493d2 Mon Sep 17 00:00:00 2001 From: ThearchyHelios Date: Sun, 4 Oct 2026 02:52:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=9B=AE=E5=BD=95=20F2b=20/?= =?UTF-8?q?=20A2=EF=BC=9A=E8=B5=B7=E8=8D=89=E4=B8=80=E9=A1=B9=E9=83=BD?= =?UTF-8?q?=E6=B2=A1=E5=86=99=E8=BF=9B=E5=8E=BB=E6=97=B6=EF=BC=8C=E5=8F=AA?= =?UTF-8?q?=E6=9C=89=E3=80=8C=E6=A8=A1=E5=9E=8B=E7=BB=99=E4=BA=86=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E3=80=81=E5=8F=AA=E6=98=AF=E5=92=8C=E7=8E=B0=E6=9C=89?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=B8=80=E8=87=B4=E3=80=8D=E6=89=8D=E8=AF=B4?= =?UTF-8?q?=E3=80=8C=E6=B2=A1=E6=9C=89=E5=8F=98=E5=8C=96=E3=80=8D=E2=80=94?= =?UTF-8?q?=E2=80=94=E6=9C=89=E8=A1=A8=E6=B2=A1=E8=B5=B7=E8=8D=89=E3=80=81?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=9C=A8=E6=9F=90=E4=BA=9B=E8=A1=A8=E4=B8=8A?= =?UTF-8?q?=E6=B2=A1=E7=BB=99=E5=87=BA=E5=86=85=E5=AE=B9=EF=BC=88model=5Fe?= =?UTF-8?q?rror=EF=BC=89=E3=80=81=E5=8B=BE=E4=BA=86=E7=94=A8=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=8D=B4=E6=B2=A1=E6=9C=89=E4=B8=80=E5=BC=A0=E8=A1=A8?= =?UTF-8?q?=E6=8B=BF=E5=88=B0=E5=8F=AF=E7=94=A8=E5=86=85=E5=AE=B9=EF=BC=88?= =?UTF-8?q?model=5Fitems=20=E9=83=BD=E6=98=AF=200=20=E6=88=96=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=95=B4=E4=BD=93=E7=94=A8=E4=B8=8D=E4=BA=86=EF=BC=89?= =?UTF-8?q?=EF=BC=8C=E9=83=BD=E8=AF=B4=E3=80=8C=E7=9B=AE=E5=BD=95=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E6=9B=B4=E6=96=B0=EF=BC=9A=E6=A8=A1=E5=9E=8B=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E7=BB=99=E5=87=BA=E5=8F=AF=E7=94=A8=E7=9A=84=E5=86=85?= =?UTF-8?q?=E5=AE=B9=EF=BC=8C=E5=8E=9F=E5=9B=A0=E8=A7=81=E4=B8=8B=E6=96=B9?= =?UTF-8?q?=E3=80=8D=EF=BC=9B=E8=A1=A5=E6=A3=80=E6=9F=A5=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=E7=9A=84=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/catalog/DraftDialog.tsx | 26 +++++++++++++++++---- scripts/check-catalog.mjs | 27 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/catalog/DraftDialog.tsx b/frontend/src/pages/catalog/DraftDialog.tsx index ab588758..c9fba7fc 100644 --- a/frontend/src/pages/catalog/DraftDialog.tsx +++ b/frontend/src/pages/catalog/DraftDialog.tsx @@ -36,13 +36,29 @@ interface Outcome { model: string | null failure: string | null stopped: boolean + /** 这一次勾了「用模型起草」 */ + modelAsked: boolean + /** 模型给了可用内容(model_items > 0)的表有几张;服务端没给 model_items(老服务端)时 modelItemsKnown 为假 */ + modelItems: number + modelItemsKnown: boolean } -const fresh = (total: number): Outcome => ({ +const fresh = (total: number, modelAsked = false): Outcome => ({ done: 0, total, added: 0, updated: 0, removed: 0, tableErrors: [], modelErrors: [], modelSkipped: null, model: null, - failure: null, stopped: false, + failure: null, stopped: false, modelAsked, modelItems: 0, modelItemsKnown: false, }) +/** + * 一项都没写进去时怎么说。「没有变化」只在确实是「起草出了内容、和现有目录一致」时说:有表没起草、模型在某些表上 + * 没给出内容(model_error),或者勾了用模型、却没有一张表拿到模型的可用内容(模型整体用不了、model_items 都是 0), + * 都说「目录没有更新」,原因写在下面 + */ +function nothingWrittenText(out: Outcome): string { + const failed = out.modelErrors.length > 0 || out.tableErrors.length > 0 + const modelEmpty = out.modelAsked && (!!out.modelSkipped || (out.modelItemsKnown && out.modelItems === 0)) + return failed || modelEmpty ? CT.draftNothingWritten : CT.draftNoChange +} + export function DraftDialog({ sourceId, rows, visible, selected, filtered, onClose, onDrafted }: { sourceId: string /** 全部表(服务端的顺序:使用次数多的在前) */ @@ -81,7 +97,7 @@ export function DraftDialog({ sourceId, rows, visible, selected, filtered, onClo stopRef.current = false setStopping(false) setPhase('running') - const acc = fresh(tables.length) + const acc = fresh(tables.length, useModel) setOut({ ...acc }) const touched: string[] = [] let withModel = useModel @@ -96,6 +112,8 @@ export function DraftDialog({ sourceId, rows, visible, selected, filtered, onClo acc.removed += r.total.removed acc.tableErrors.push(...r.tables.filter((t) => t.error)) acc.modelErrors.push(...r.tables.filter((t) => !t.error && t.model_error)) + acc.modelItems += r.tables.filter((t) => !t.error && (t.model_items ?? 0) > 0).length + if (r.tables.some((t) => t.model_items !== undefined)) acc.modelItemsKnown = true if (r.model) acc.model = r.model // 模型整体用不了(没配置、已停用……):后面的批次不再请模型,免得每批都撞一次同样的错 if (withModel && r.model_error && !r.model_used) { acc.modelSkipped = r.model_error; withModel = false } @@ -181,7 +199,7 @@ export function DraftDialog({ sourceId, rows, visible, selected, filtered, onClo

{out.added + out.updated + out.removed === 0 && phase === 'done' && !out.failure - ? CT.draftNoChange + ? nothingWrittenText(out) : CT.draftSummary(out.added, out.updated, out.removed)}

{out.model &&

{CT.draftModelUsed(out.model)}

} diff --git a/scripts/check-catalog.mjs b/scripts/check-catalog.mjs index 1c2960dd..1b68bc84 100644 --- a/scripts/check-catalog.mjs +++ b/scripts/check-catalog.mjs @@ -761,6 +761,33 @@ await section('数据目录 · 起草', async () => { check('……写出用的是哪个模型', (await draftBox(page).innerText()).includes('模型:check-model')) await page.locator('[data-draft-close]').click() + // 一项都没写进去:只有「模型给了内容、只是和现有目录一致」才说「没有变化」,模型没给出内容要说「目录没有更新」 + const emptyReply = ({ items, modelError }) => (route, ctx) => json({ + tables: ctx.body.tables.map((n) => ({ table_name: n, added: 0, updated: 0, removed: 0, version: 1, error: null, + model_error: modelError, model_items: items })), + total: { added: 0, updated: 0, removed: 0 }, model_used: true, model: 'check-model', model_error: null, + })(route) + const draftOnce = async (reply) => { + replies.draft.push(reply, reply) + await page.locator('[data-catalog-draft]').first().click() + await draftBox(page).locator('[data-draft-model] input').check() + await page.locator('[data-draft-start]').click() + await until(async () => (await draftBox(page).getAttribute('data-draft-dialog')) === 'done', 8000) + const summary = await draftBox(page).locator('[data-draft-summary]').innerText() + const notice = await draftBox(page).locator('[data-draft-table-model-errors]').innerText().catch(() => '') + await page.locator('[data-draft-close]').click() + return { summary, notice } + } + const noContent = await draftOnce(emptyReply({ items: null, modelError: '模型没有给出这张表的可用内容' })) + check('模型没给出内容(每张表记 model_error):不说「没有变化」,说「目录没有更新」并列出原因', + noContent.summary === '目录没有更新:模型没有给出可用的内容,原因见下方' && noContent.notice.includes('模型没有给出这张表的可用内容'), + JSON.stringify(noContent)) + const zeroItems = await draftOnce(emptyReply({ items: 0, modelError: null })) + check('……模型一项可用内容都没给(model_items 都是 0):同样不说「没有变化」', zeroItems.summary === '目录没有更新:模型没有给出可用的内容,原因见下方', + JSON.stringify(zeroItems)) + const same = await draftOnce(emptyReply({ items: 3, modelError: null })) + check('……模型给了内容、只是和现有目录一致:才说「没有变化」', same.summary === '没有变化:起草出的内容与现有目录一致', JSON.stringify(same)) + // 中途停止:当前这一批做完后不再发下一批 replies.draft.push(async (route, ctx) => { await sleep(900); return draftReply(state)(route, ctx) }) await page.locator('[data-catalog-draft]').first().click()