From 6ec72d863516f79595ccaa863bf4536138f36d07 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Thu, 23 Jul 2026 11:55:21 +0800 Subject: [PATCH] fix: normalize publish snapshot diff to ignore audit and date noise Co-authored-by: Cursor --- src/utils/publishSnapshotDiff.ts | 64 ++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/src/utils/publishSnapshotDiff.ts b/src/utils/publishSnapshotDiff.ts index 6e10f31..1c7bc1a 100644 --- a/src/utils/publishSnapshotDiff.ts +++ b/src/utils/publishSnapshotDiff.ts @@ -6,11 +6,58 @@ function canonicalKey(key: string): string { return key.charAt(0).toLowerCase() + key.slice(1) } +const AUDIT_KEYS = new Set([ + 'createtime', + 'updatetime', + 'createby', + 'updateby', + 'createtimeutc', + 'updatetimeutc', +]) + +function isDefaultDateString(value: string): boolean { + return /^0001-01-01[ T]00:00:00/.test(value.trim()) +} + +function normalizeScalar(value: unknown): unknown { + if (typeof value !== 'string') return value + if (isDefaultDateString(value)) return undefined + if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}/.test(value)) { + return value.replace('T', ' ').slice(0, 19) + } + return value +} + +function sortArrayItems(items: unknown[]): unknown[] { + if (items.length === 0) return items + const first = items[0] + if (first == null || typeof first !== 'object' || Array.isArray(first)) { + return items + } + const record = first as Record + if ('id' in record) { + return [...items].sort( + (a, b) => Number((a as Record)?.id ?? 0) - Number((b as Record)?.id ?? 0) + ) + } + if ('serialNumber' in record) { + return [...items].sort( + (a, b) => + Number((a as Record)?.serialNumber ?? 0) + - Number((b as Record)?.serialNumber ?? 0) + ) + } + return items +} + /** 递归规范化快照对象,便于语义对比 */ export function normalizeSnapshotForDiff(input: unknown): unknown { - if (input === null || input === undefined) return input + if (input === null || input === undefined) return undefined if (Array.isArray(input)) { - return input.map((item) => normalizeSnapshotForDiff(item)) + const normalized = input + .map((item) => normalizeSnapshotForDiff(item)) + .filter((item) => item !== undefined) + return sortArrayItems(normalized) } if (typeof input === 'object') { const record = input as Record @@ -19,11 +66,15 @@ export function normalizeSnapshotForDiff(input: unknown): unknown { ) const out: Record = {} for (const key of keys) { - out[canonicalKey(key)] = normalizeSnapshotForDiff(record[key]) + const ck = canonicalKey(key) + if (AUDIT_KEYS.has(ck)) continue + const val = normalizeSnapshotForDiff(record[key]) + if (val === undefined) continue + out[ck] = val } return out } - return input + return normalizeScalar(input) } export function parseSnapshotJson(raw: unknown): unknown { @@ -86,6 +137,11 @@ export function computeSnapshotDiff( try { const original = normalizeSnapshotForDiff(parseSnapshotJson(originalRaw)) const modified = normalizeSnapshotForDiff(parseSnapshotJson(modifiedRaw)) + const originalText = JSON.stringify(original) + const modifiedText = JSON.stringify(modified) + if (originalText === modifiedText) { + return { length: 0, rows: [] } + } const diff = diffJson(original, modified) const rows = flattenDiffParts(diff) const length = diff.filter((item) => item.added || item.removed).length