diff --git a/frontend/src/pages/catalog/TableDetail.tsx b/frontend/src/pages/catalog/TableDetail.tsx index f002cb24..c0168f7e 100644 --- a/frontend/src/pages/catalog/TableDetail.tsx +++ b/frontend/src/pages/catalog/TableDetail.tsx @@ -9,7 +9,7 @@ import type { } from '../../types' import { DeleteButton, EmptyState, ErrorState, Notice, Skeleton, Spinner, confirmDialog, toast } from '../../components/ui' import { useLeaveGuard } from '../../lib/leave' -import { formatDateTime, formatNumber } from '../../lib/format' +import { formatDateTime, formatNumber, formatTime } from '../../lib/format' import { CATALOG_CARDINALITY_LABEL, CATALOG_IMPACT_TEXT, CATALOG_KIND_HINT, CATALOG_KIND_LABEL, CATALOG_TABLE_FIELD_HINT, CATALOG_TABLE_FIELD_LABEL, CATALOG_TEXT as CT, CODES_TEXT as KT, @@ -326,9 +326,10 @@ export function TableDetail({ sourceId, table, rows, drafted, fillCodes, prev, n
{label && {st?.qualified ?? detail.table_name}} {CT.usage(detail.usage)} - + {/* 时间写全站统一的短格式(今天「10:05」、今年「9/27 15:21」),完整时间放在悬停里 */} + {detail.updated_at - ? (detail.updated_by ? CT.updatedBy(detail.updated_by, formatDateTime(detail.updated_at)) : CT.updatedAt(formatDateTime(detail.updated_at))) + ? (detail.updated_by ? CT.updatedBy(detail.updated_by, formatTime(detail.updated_at)) : CT.updatedAt(formatTime(detail.updated_at))) : CT.notStarted} diff --git a/frontend/src/pages/catalog/parts.tsx b/frontend/src/pages/catalog/parts.tsx index 5c90ee69..3e210979 100644 --- a/frontend/src/pages/catalog/parts.tsx +++ b/frontend/src/pages/catalog/parts.tsx @@ -6,7 +6,7 @@ import type { LucideIcon } from 'lucide-react' import clsx from 'clsx' import type { CatalogCounts, CatalogReviewAction, CatalogSource, CatalogStatus } from '../../types' import { Notice } from '../../components/ui' -import { formatDateTime, formatNumber } from '../../lib/format' +import { formatDateTime, formatNumber, formatTime } from '../../lib/format' import { CATALOG_SOURCE_LABEL, CATALOG_STATUS_HINT, CATALOG_STATUS_LABEL, CATALOG_TEXT as CT, } from '../../lib/terms' @@ -256,7 +256,9 @@ export function ItemMark({ target, compact = false, disabled = false, disabledHi {CATALOG_STATUS_HINT[status]}

{CT.itemSource(CATALOG_SOURCE_LABEL[source])}

- {target.updated_at &&

{CT.itemUpdated(formatDateTime(target.updated_at))}

} + {target.updated_at && ( +

{CT.itemUpdated(formatTime(target.updated_at))}

+ )} {target.note &&

{target.note}

}
diff --git a/scripts/check-catalog.mjs b/scripts/check-catalog.mjs index 5b3a7d9d..82b3569a 100644 --- a/scripts/check-catalog.mjs +++ b/scripts/check-catalog.mjs @@ -802,6 +802,10 @@ await section('数据目录 · 表详情与单项审阅', async () => { await openDetail(page, S1, 'visits') const head = await detail(page).locator('header').innerText() check('表头:中文名、表类型、表名、使用次数、谁改过', ['入园记录', '明细表', 'visits', '使用 42 次', '审核甲'].every((s) => head.includes(s)), head.replace(/\s+/g, ' ')) + // 时间用全站统一的短格式(formatTime:今年写「9/28 10:00」),完整时间(带秒和时区)放在悬停里 + const updated = detail(page).locator('[data-detail-updated]') + check('……修改时间写全站统一的短格式,完整时间放在悬停里', /^审核甲 于 (2026\/)?9\/28 10:00 修改$/.test(await updated.innerText()) + && !head.includes('UTC') && (await updated.getAttribute('title')) === '2026-09-28 10:00:00 (UTC+08:00)', `${await updated.innerText()} / ${await updated.getAttribute('title')}`) const grain = page.locator('[data-field="grain"]') check('表级项:粒度的值和「推断 · 模型起草」', (await grain.innerText()).includes('一张门票的一次入园') && (await grain.innerText()).includes('推断') && (await grain.innerText()).includes('模型起草')) @@ -826,6 +830,8 @@ await section('数据目录 · 表详情与单项审阅', async () => { await openMark(page, 'grain') const pt = await panel(page).innerText() check('点状态标识:弹层写位置、状态说明、来源', pt.includes('表的粒度的来源和状态') && pt.includes('只作提示,确认后才参与 SQL 检查') && pt.includes('来源:模型起草'), pt.replace(/\s+/g, ' ')) + check('……更新时间也写短格式,完整时间放在悬停里', /更新于 (2026\/)?9\/28 10:00/.test(pt) && !pt.includes('UTC') + && (await panel(page).locator('[data-item-updated]').getAttribute('title')) === '2026-09-28 10:00:00 (UTC+08:00)', pt.replace(/\s+/g, ' ')) check('……焦点落在「确认」上', await page.evaluate(() => document.activeElement?.getAttribute('data-review-action')) === 'confirm') check('……推断项已是初始状态,「恢复」不可点', await panel(page).locator('[data-review-action="reset"]').isDisabled()) await page.keyboard.press('Escape')