diff --git a/apps/admin-web/src/pages/StorePackageAuditsPage.tsx b/apps/admin-web/src/pages/StorePackageAuditsPage.tsx index f728ce1..ecdcd9f 100644 --- a/apps/admin-web/src/pages/StorePackageAuditsPage.tsx +++ b/apps/admin-web/src/pages/StorePackageAuditsPage.tsx @@ -42,6 +42,31 @@ function imageSignature(pkg: StorePackageItemDto | StorePackageViewDto) { return normalizeStorePackageImageUrls(pkg).join('|'); } +type FieldChange = { label: string; old: string; now: string }; + +/** 逐字段比较套餐内容,返回发生变化的字段明细(用于“变动的地方详细列出”) */ +function fieldChanges( + live: StorePackageItemDto | StorePackageViewDto, + proposed: StorePackageItemDto | StorePackageViewDto, +): FieldChange[] { + const changes: FieldChange[] = []; + const text = (v: string | number | null | undefined) => (v ?? '').toString().trim(); + const pushIf = (label: string, oldV: string, newV: string) => { + if (oldV !== newV) changes.push({ label, old: oldV || '(空)', now: newV || '(空)' }); + }; + pushIf('价格', `¥${text(live.price)}`, `¥${text(proposed.price)}`); + pushIf('套餐名称', text(live.name), text(proposed.name)); + pushIf('菜品内容', text(live.dishes), text(proposed.dishes)); + pushIf('可用时间', text(live.usableTime), text(proposed.usableTime)); + pushIf('其他说明', text(live.otherNotes), text(proposed.otherNotes)); + const liveImgs = normalizeStorePackageImageUrls(live); + const proposedImgs = normalizeStorePackageImageUrls(proposed); + if (imageSignature(live) !== imageSignature(proposed)) { + changes.push({ label: '图片', old: `${liveImgs.length} 张`, now: `${proposedImgs.length} 张` }); + } + return changes; +} + function diffPackages(live: StorePackageViewDto[], proposed: StorePackageItemDto[]) { const liveMap = new Map(live.map((p, i) => [packageKey(p, i), p])); const proposedMap = new Map(proposed.map((p, i) => [packageKey(p, i), p])); @@ -51,6 +76,7 @@ function diffPackages(live: StorePackageViewDto[], proposed: StorePackageItemDto change: 'added' | 'removed' | 'changed' | 'unchanged'; live?: StorePackageViewDto; proposed?: StorePackageItemDto; + changes?: FieldChange[]; }> = []; for (const key of keys) { @@ -67,7 +93,13 @@ function diffPackages(live: StorePackageViewDto[], proposed: StorePackageItemDto (l.usableTime ?? '') !== (p.usableTime ?? '') || (l.otherNotes ?? '') !== (p.otherNotes ?? '') || imageSignature(l) !== imageSignature(p); - rows.push({ key, change: changed ? 'changed' : 'unchanged', live: l, proposed: p }); + rows.push({ + key, + change: changed ? 'changed' : 'unchanged', + live: l, + proposed: p, + changes: changed ? fieldChanges(l, p) : undefined, + }); } } return rows; @@ -84,10 +116,12 @@ function PackageDetailCard({ title, pkg, change, + changes, }: { title?: string; pkg: StorePackageItemDto | StorePackageViewDto; change?: keyof typeof CHANGE_LABELS; + changes?: FieldChange[]; }) { const images = normalizeStorePackageImageUrls(pkg); const meta = change ? CHANGE_LABELS[change] : null; @@ -149,6 +183,33 @@ function PackageDetailCard({ ) : ( 无套餐图片 )} + {changes && changes.length ? ( +
+ + 变更明细 + + +
+ ) : null} ); } @@ -236,6 +297,11 @@ export default function StorePackageAuditsPage() { const diffRows = detail ? diffPackages(detail.livePackages ?? [], detail.packages ?? []) : []; const changeByKey = new Map(diffRows.map((row) => [row.key, row.change])); + const changesByKey = new Map(diffRows.map((row) => [row.key, row.changes])); + const addedCount = diffRows.filter((r) => r.change === 'added').length; + const removedCount = diffRows.filter((r) => r.change === 'removed').length; + const changedCount = diffRows.filter((r) => r.change === 'changed').length; + const unchangedCount = diffRows.filter((r) => r.change === 'unchanged').length; const columns: ColumnsType = [ { title: '门店', dataIndex: 'storeName', render: (_, row) => row.storeName || row.storeId }, @@ -354,9 +420,17 @@ export default function StorePackageAuditsPage() { {detail.rejectReason ? ( 驳回原因:{detail.rejectReason} ) : null} - - 线上已审核 {detail.livePackages?.length ?? 0} 条 · 待审核 {detail.packages?.length ?? 0} 条 - + + + 线上已审核 {detail.livePackages?.length ?? 0} 条 · 待审核 {detail.packages?.length ?? 0} 条 + + + 新增 {addedCount} + 删除 {removedCount} + 变更 {changedCount} + {unchangedCount ? 未变 {unchangedCount} : null} + +
@@ -386,6 +460,7 @@ export default function StorePackageAuditsPage() { title={`套餐 ${index + 1}`} pkg={pkg} change={changeByKey.get(packageKey(pkg, index))} + changes={changesByKey.get(packageKey(pkg, index))} /> )) ) : (