feat(cost-center): 支持删除第三方卡券商品

This commit is contained in:
yml2213
2026-11-05 17:48:24 +08:00
parent f67f00a7a5
commit a6fbb43955
6 changed files with 285 additions and 19 deletions
@@ -4,7 +4,7 @@
* 商品编码固定为 `tpv:<sku>`;成本写入 `sys_third_party_voucher_cost` 的
* 商品级版本,由成本快照管道消费。
*/
import { ReloadOutlined, SyncOutlined } from '@ant-design/icons'
import { DeleteOutlined, ReloadOutlined, SyncOutlined } from '@ant-design/icons'
import {
Button,
Card,
@@ -12,6 +12,7 @@ import {
Input,
InputNumber,
Modal,
Popconfirm,
Space,
Tag,
Typography,
@@ -22,11 +23,13 @@ import { useState } from 'react'
import PercentTable from '@/components/common/PercentTable'
import {
deleteAdminVoucherProduct,
ensureVoucherChannelRules,
fetchAdminProductCatalog,
setAdminProductPrice,
} from '@/services/admin'
import type { ProductCatalogItem } from '@/types/admin'
import { formatAdminDateTime } from '@/utils/admin-time'
import { ADMIN_DEFAULT_PAGE_SIZE, buildAdminTablePagination } from '@/utils/admin-pagination'
import { useCostCenter } from './CostCenterContext'
@@ -65,6 +68,20 @@ export default function VoucherSkuPanel() {
onError: (error) => message.error(error instanceof Error ? error.message : '保存失败'),
})
const deleteMutation = useMutation({
mutationFn: (productId: number) => deleteAdminVoucherProduct(productId),
onSuccess: (response) => {
message.success(
response.data.action === 'archived'
? '该商品已有历史引用,已归档并停用后续卡券规则;历史成本已保留'
: '卡券商品及采购价配置已删除',
)
void queryClient.invalidateQueries({ queryKey: ['cost-center-voucher-products'] })
refreshAll()
},
onError: (error) => message.error(error instanceof Error ? error.message : '删除失败'),
})
async function handleEnsureRules() {
setEnsuringRules(true)
try {
@@ -99,28 +116,50 @@ export default function VoucherSkuPanel() {
title: '生效时间',
dataIndex: 'activeCostEffectiveFrom',
width: 180,
render: (value?: string | null) => value || '—',
render: (value?: string | null) =>
value ? <span style={{ whiteSpace: 'nowrap' }}>{formatAdminDateTime(value)}</span> : '—',
},
{
title: '操作',
width: 110,
width: 180,
fixed: 'right' as const,
render: (_: unknown, row: ProductCatalogItem) => (
<Button
size="small"
disabled={!canConfig}
onClick={() => {
setSelected(row)
form.setFieldsValue({
amountFen:
row.activeCostAmountFen === null || row.activeCostAmountFen === undefined
? 0
: Number((row.activeCostAmountFen / 100).toFixed(2)),
changeReason: '第三方卡券采购价调整',
})
}}
>
改价
</Button>
<Space size={4}>
<Button
size="small"
disabled={!canConfig}
onClick={() => {
setSelected(row)
form.setFieldsValue({
amountFen:
row.activeCostAmountFen === null || row.activeCostAmountFen === undefined
? 0
: Number((row.activeCostAmountFen / 100).toFixed(2)),
changeReason: '第三方卡券采购价调整',
})
}}
>
改价
</Button>
<Popconfirm
title="删除该第三方卡券商品?"
description="没有历史引用时会彻底删除;已有历史订单或成本快照时会自动归档并停用后续卡券规则,历史成本保留。"
okText="确认删除"
cancelText="取消"
okButtonProps={{ danger: true }}
onConfirm={() => deleteMutation.mutate(row.id)}
>
<Button
size="small"
danger
icon={<DeleteOutlined />}
disabled={!canConfig}
loading={deleteMutation.isPending && deleteMutation.variables === row.id}
>
删除
</Button>
</Popconfirm>
</Space>
),
},
]
@@ -555,3 +555,17 @@ export function ensureVoucherChannelRules() {
'/api/v1/admin/cost-center/voucher-products/ensure-rules',
)
}
export function deleteAdminVoucherProduct(productId: number) {
return apiDelete<{
action: 'deleted' | 'archived'
deleted: boolean
product: ProductCatalogItem
deletedCostVersionCount?: number
preserved: {
mappingCount: number
snapshotCount: number
orderItemCount: number
}
}>(`/api/v1/admin/cost-center/voucher-products/${productId}`)
}