This commit is contained in:
@@ -42,6 +42,31 @@ function imageSignature(pkg: StorePackageItemDto | StorePackageViewDto) {
|
|||||||
return normalizeStorePackageImageUrls(pkg).join('|');
|
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[]) {
|
function diffPackages(live: StorePackageViewDto[], proposed: StorePackageItemDto[]) {
|
||||||
const liveMap = new Map(live.map((p, i) => [packageKey(p, i), p]));
|
const liveMap = new Map(live.map((p, i) => [packageKey(p, i), p]));
|
||||||
const proposedMap = new Map(proposed.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';
|
change: 'added' | 'removed' | 'changed' | 'unchanged';
|
||||||
live?: StorePackageViewDto;
|
live?: StorePackageViewDto;
|
||||||
proposed?: StorePackageItemDto;
|
proposed?: StorePackageItemDto;
|
||||||
|
changes?: FieldChange[];
|
||||||
}> = [];
|
}> = [];
|
||||||
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
@@ -67,7 +93,13 @@ function diffPackages(live: StorePackageViewDto[], proposed: StorePackageItemDto
|
|||||||
(l.usableTime ?? '') !== (p.usableTime ?? '') ||
|
(l.usableTime ?? '') !== (p.usableTime ?? '') ||
|
||||||
(l.otherNotes ?? '') !== (p.otherNotes ?? '') ||
|
(l.otherNotes ?? '') !== (p.otherNotes ?? '') ||
|
||||||
imageSignature(l) !== imageSignature(p);
|
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;
|
return rows;
|
||||||
@@ -84,10 +116,12 @@ function PackageDetailCard({
|
|||||||
title,
|
title,
|
||||||
pkg,
|
pkg,
|
||||||
change,
|
change,
|
||||||
|
changes,
|
||||||
}: {
|
}: {
|
||||||
title?: string;
|
title?: string;
|
||||||
pkg: StorePackageItemDto | StorePackageViewDto;
|
pkg: StorePackageItemDto | StorePackageViewDto;
|
||||||
change?: keyof typeof CHANGE_LABELS;
|
change?: keyof typeof CHANGE_LABELS;
|
||||||
|
changes?: FieldChange[];
|
||||||
}) {
|
}) {
|
||||||
const images = normalizeStorePackageImageUrls(pkg);
|
const images = normalizeStorePackageImageUrls(pkg);
|
||||||
const meta = change ? CHANGE_LABELS[change] : null;
|
const meta = change ? CHANGE_LABELS[change] : null;
|
||||||
@@ -149,6 +183,33 @@ function PackageDetailCard({
|
|||||||
) : (
|
) : (
|
||||||
<Typography.Text type="secondary">无套餐图片</Typography.Text>
|
<Typography.Text type="secondary">无套餐图片</Typography.Text>
|
||||||
)}
|
)}
|
||||||
|
{changes && changes.length ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginTop: 8,
|
||||||
|
padding: 8,
|
||||||
|
background: '#fff7e6',
|
||||||
|
border: '1px solid #ffe7ba',
|
||||||
|
borderRadius: 6,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography.Text strong style={{ fontSize: 12 }}>
|
||||||
|
变更明细
|
||||||
|
</Typography.Text>
|
||||||
|
<ul style={{ margin: '6px 0 0', paddingLeft: 18 }}>
|
||||||
|
{changes.map((c) => (
|
||||||
|
<li key={c.label} style={{ marginBottom: 4 }}>
|
||||||
|
<Typography.Text type="secondary">{c.label}:</Typography.Text>
|
||||||
|
<Typography.Text delete type="secondary">
|
||||||
|
{c.old}
|
||||||
|
</Typography.Text>
|
||||||
|
<Typography.Text type="secondary"> → </Typography.Text>
|
||||||
|
<Typography.Text strong>{c.now}</Typography.Text>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -236,6 +297,11 @@ export default function StorePackageAuditsPage() {
|
|||||||
|
|
||||||
const diffRows = detail ? diffPackages(detail.livePackages ?? [], detail.packages ?? []) : [];
|
const diffRows = detail ? diffPackages(detail.livePackages ?? [], detail.packages ?? []) : [];
|
||||||
const changeByKey = new Map(diffRows.map((row) => [row.key, row.change]));
|
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<StorePackageChangeRequestDto> = [
|
const columns: ColumnsType<StorePackageChangeRequestDto> = [
|
||||||
{ title: '门店', dataIndex: 'storeName', render: (_, row) => row.storeName || row.storeId },
|
{ title: '门店', dataIndex: 'storeName', render: (_, row) => row.storeName || row.storeId },
|
||||||
@@ -354,9 +420,17 @@ export default function StorePackageAuditsPage() {
|
|||||||
{detail.rejectReason ? (
|
{detail.rejectReason ? (
|
||||||
<Typography.Paragraph type="danger">驳回原因:{detail.rejectReason}</Typography.Paragraph>
|
<Typography.Paragraph type="danger">驳回原因:{detail.rejectReason}</Typography.Paragraph>
|
||||||
) : null}
|
) : null}
|
||||||
<Typography.Paragraph type="secondary" style={{ marginBottom: 12 }}>
|
<Space direction="vertical" size={4} style={{ marginBottom: 12 }}>
|
||||||
|
<Typography.Text type="secondary">
|
||||||
线上已审核 {detail.livePackages?.length ?? 0} 条 · 待审核 {detail.packages?.length ?? 0} 条
|
线上已审核 {detail.livePackages?.length ?? 0} 条 · 待审核 {detail.packages?.length ?? 0} 条
|
||||||
</Typography.Paragraph>
|
</Typography.Text>
|
||||||
|
<Space wrap>
|
||||||
|
<Tag color="green">新增 {addedCount}</Tag>
|
||||||
|
<Tag color="red">删除 {removedCount}</Tag>
|
||||||
|
<Tag color="orange">变更 {changedCount}</Tag>
|
||||||
|
{unchangedCount ? <Tag>未变 {unchangedCount}</Tag> : null}
|
||||||
|
</Space>
|
||||||
|
</Space>
|
||||||
<div className="admin-package-audit-cols">
|
<div className="admin-package-audit-cols">
|
||||||
<div className="admin-package-audit-col">
|
<div className="admin-package-audit-col">
|
||||||
<Typography.Title level={5} style={{ marginTop: 0 }}>
|
<Typography.Title level={5} style={{ marginTop: 0 }}>
|
||||||
@@ -386,6 +460,7 @@ export default function StorePackageAuditsPage() {
|
|||||||
title={`套餐 ${index + 1}`}
|
title={`套餐 ${index + 1}`}
|
||||||
pkg={pkg}
|
pkg={pkg}
|
||||||
change={changeByKey.get(packageKey(pkg, index))}
|
change={changeByKey.get(packageKey(pkg, index))}
|
||||||
|
changes={changesByKey.get(packageKey(pkg, index))}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Reference in New Issue
Block a user