diff --git a/frontend/src/lib/terms.ts b/frontend/src/lib/terms.ts index b409f578..663b6329 100644 --- a/frontend/src/lib/terms.ts +++ b/frontend/src/lib/terms.ts @@ -2434,6 +2434,13 @@ export const CATALOG_DRAFT_TEXT = { // ---- 从结果、表详情回到设置:范围就是那几张表 scopeBlank: (n: number) => `有留空列的 ${formatNumber(n)} 张表`, scopeTable: (name: string) => `这张表:${name}`, + /** + * 预先选好的范围里有表已经不在表结构里(打开表详情以后别处重新探查了结构):写在那一项下面。一张都不剩时那一项 + * 照旧选着、不能开始,不退回别的范围 + */ + presetMissing: (gone: number, total: number) => (gone < total + ? `其中 ${formatNumber(gone)} 张在表结构中已没有,不会起草` + : total === 1 ? '表结构中已没有这张表,不能起草' : `表结构中已没有这 ${formatNumber(total)} 张表,不能起草`), // ---- 进行中 queued: '排队中,等待开始…', running: '正在起草…', @@ -2538,6 +2545,8 @@ export const CATALOG_DRAFT_TEXT = { redraftHint: '用模型重新起草这张表(不带补充说明,带上数据源的起草要求);人工确认、驳回过的项不会被改动', redraftBusy: '已有起草任务在进行,结束后再重新起草这张表', redraftEditing: '正在编辑这张表,保存或取消后再重新起草', + /** 表结构里已经没有的表(只剩目录):上次起草的结果照写,不给重新起草(服务端只会把它记成已跳过) */ + redraftMissing: '表结构中已没有这张表,不能重新起草', } /** 设置页「偏好设置」里「起草模型」一节(服务端 api/settings.py 的 catalog_draft 一组) */ diff --git a/frontend/src/pages/catalog/DraftDialog.tsx b/frontend/src/pages/catalog/DraftDialog.tsx index 4dafc323..3a7547fc 100644 --- a/frontend/src/pages/catalog/DraftDialog.tsx +++ b/frontend/src/pages/catalog/DraftDialog.tsx @@ -25,7 +25,8 @@ import type { DraftPreset, DraftStartBody } from './draftJob' // // 留空的列(模型列出了、中文名和含义都没给)不算没写全,表照样是已完成;结果里写合计和办法——在起草要求里补充缩写和 // 术语的含义,再重新起草这几张表。「重新起草这几张表」回到设置:范围就是那几张、勾着用模型、焦点在起草要求, -// 补完再开始。表详情里的「补充起草要求」也是这样打开(范围是那一张,见 preset)。 +// 补完再开始。表详情里的「补充起草要求」也是这样打开(范围是那一张,见 preset)。预先选好的范围里的表已经不在表结构 +// 里时不退回别的范围:那一项照旧选着、写明原因,不能开始。 // =========================================================================== type Scope = 'preset' | 'selected' | 'filtered' | 'top' | 'all' @@ -66,8 +67,9 @@ export function DraftDialog({ /** 打开时显示的任务是撞上已有任务(409)转过来的:写明 */ initialBusy?: boolean /** - * 打开设置时预先选好的范围(表详情里「补充起草要求」:只有那张表)。给了就勾上用模型、焦点放在起草要求上: - * 打开它就是为了先补起草要求再起草 + * 打开设置时预先选好的范围(表详情里「补充起草要求」:只有那张表)。给了就选它;里面有可起草的表时勾上用模型、 + * 焦点放在起草要求上(打开它就是为了先补起草要求再起草)。一张可起草的都没有(已不在表结构里)时照旧选着它、 + * 写明原因、不能开始,也不勾用模型——不退回别的范围 */ preset?: DraftPreset | null /** 点了停止、服务端还没停下来 */ @@ -88,9 +90,13 @@ export function DraftDialog({ /** 预先选好的范围:打开时给的,或者结果里点了「重新起草这几张表」 */ const [preset, setPreset] = useState(initialPreset) const scopes = useMemo(() => { - const out: { key: Scope; label: string; tables: string[] }[] = [] - const pre = preset?.tables.filter((t) => liveSet.has(t)) ?? [] - if (preset && pre.length) out.push({ key: 'preset', label: preset.label, tables: pre }) + const out: { key: Scope; label: string; tables: string[]; gone?: number }[] = [] + // 预先选好的范围总在第一项:里面的表已经不在表结构里的(打开表详情以后别处重新探查了结构)不起草、写明有几张; + // 一张都不剩也留着这一项,不退回别的范围——以为只起草那一张,实际按别的范围用模型起草了 + if (preset) { + const pre = preset.tables.filter((t) => liveSet.has(t)) + out.push({ key: 'preset', label: preset.label, tables: pre, gone: preset.tables.length - pre.length }) + } const sel = selected.filter((t) => liveSet.has(t)) if (sel.length) out.push({ key: 'selected', label: CT.scopeSelected(sel.length), tables: sel }) const vis = visible.filter((r) => r.in_schema).map((r) => r.table_name) @@ -100,11 +106,15 @@ export function DraftDialog({ return out }, [preset, selected, visible, filtered, live, liveSet]) const [scope, setScope] = useState(() => scopes[0].key) - const tables = scopes.find((s) => s.key === scope)?.tables ?? scopes[0].tables + /** 起草的就是这一项:选的那一项不在了(所选、筛选变了)就是第一项,单选框也照它勾,看得见起草的是哪些 */ + const current = scopes.find((s) => s.key === scope) ?? scopes[0] + const tables = current.tables const tooMany = tables.length > DRAFT_MAX_TABLES - const [useModel, setUseModel] = useState(!!initialPreset) + /** 打开时给的范围里有可起草的表:勾上用模型、焦点放进起草要求(打开它就是为了先补起草要求);一张都没有就都不做 */ + const presetLive = !!initialPreset && initialPreset.tables.some((t) => liveSet.has(t)) + const [useModel, setUseModel] = useState(presetLive) /** 回到设置以后把焦点放进起草要求(预先选好范围的两种入口都是为了先补起草要求) */ - const [focusGuidance, setFocusGuidance] = useState(!!initialPreset) + const [focusGuidance, setFocusGuidance] = useState(presetLive) const [guidanceText, setGuidanceText] = useState(guidance) const [note, setNote] = useState('') const guidanceLen = charCount(guidanceText) @@ -284,9 +294,16 @@ export function DraftDialog({
{scopes.map((s) => ( ))}
diff --git a/frontend/src/pages/catalog/TableDetail.tsx b/frontend/src/pages/catalog/TableDetail.tsx index 049ce6c3..61783e69 100644 --- a/frontend/src/pages/catalog/TableDetail.tsx +++ b/frontend/src/pages/catalog/TableDetail.tsx @@ -77,9 +77,12 @@ export function TableDetail({ onDetail: (d: CatalogDetail) => void /** 这个数据源有排队、进行中的起草任务:「重新起草这张表」等它结束 */ draftBusy?: boolean - /** 上次起草失败、部分完成或有留空列时的「重新起草这张表」:建只含这张表的起草任务(用模型、不带补充说明) */ + /** + * 上次起草失败、部分完成或有留空列时的「重新起草这张表」:建只含这张表的起草任务(用模型、不带补充说明)。 + * 表结构里已经没有的表不给 + */ onRedraft?: (table: string) => Promise - /** 上次起草有留空列时的「补充起草要求」:打开起草设置,范围只有这张表,先补起草要求再开始 */ + /** 上次起草有留空列时的「补充起草要求」:打开起草设置,范围只有这张表,先补起草要求再开始。表结构里已经没有的表不给 */ onDraftGuidance?: (table: string) => void }) { const [detail, setDetail] = useState(null) @@ -465,7 +468,8 @@ export function TableDetail({ // 上次起草没写全:写明原因;有留空的列:写几列、怎么办(在起草要求里补充缩写和术语的含义)。只有留空的列时是 // 提示(表照样写完了),不是失败。给「重新起草这张表」(只含这张表、用模型);有留空的列再给「补充起草要求」 // (打开起草设置,范围是这张表)。有起草任务在进行、正在编辑这张表时先不给点:起草会写进这张表,编辑中的保存 - // 就会撞上版本冲突 + // 就会撞上版本冲突。表结构里已经没有这张表(只剩目录)时上次的结果照写,不给这两个按钮、不建议重新起草, + // 写明为什么:服务端只会把它记成「已跳过」 {lastBad &&

{lastBad.status === 'failed' ? DT.lastFailed : DT.lastPartial}

} {lastBad && taskReason(lastBad) && ( @@ -474,10 +478,11 @@ export function TableDetail({ {lastBlank > 0 && ( <>

{DT.lastBlank(lastBlank)}

-

{DT.lastBlankAdvice}

+ {detail.in_schema &&

{DT.lastBlankAdvice}

} )} - {onRedraft && ( + {!detail.in_schema &&

{DT.redraftMissing}

} + {detail.in_schema && onRedraft && ( <>