feat(fulfillment): 增加待分类订单重试接单匹配
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
PlusOutlined,
|
||||
ReloadOutlined,
|
||||
SearchOutlined,
|
||||
SyncOutlined,
|
||||
ThunderboltOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import {
|
||||
@@ -44,6 +45,7 @@ import {
|
||||
fetchInternalSkuMappings,
|
||||
fetchPendingChannelGroups,
|
||||
fetchPipelineStatus,
|
||||
retryPendingWorkOrderRouting,
|
||||
runFinancePipeline,
|
||||
type FinancePipelineStatus,
|
||||
type InternalSkuMapping,
|
||||
@@ -151,6 +153,29 @@ function PendingPanel() {
|
||||
onError: (error) => message.error(error instanceof Error ? error.message : '指定渠道失败'),
|
||||
})
|
||||
|
||||
const retryWorkOrderMutation = useMutation({
|
||||
mutationFn: (inputSku?: string) =>
|
||||
retryPendingWorkOrderRouting(inputSku ? { internalSku: inputSku } : {}),
|
||||
onSuccess: (result) => {
|
||||
const data = result.data
|
||||
const detail = [
|
||||
`重试 ${data.scanned} 个订单项`,
|
||||
`新建工单 ${data.createdWorkOrders} 个`,
|
||||
`转接单平台 ${data.assigned} 个`,
|
||||
].join(',')
|
||||
if (data.remaining > 0) {
|
||||
message.warning(`${detail},仍有 ${data.remaining} 个未匹配到接单模板`)
|
||||
} else {
|
||||
message.success(detail)
|
||||
}
|
||||
void queryClient.invalidateQueries({ queryKey: ['fulfillment-pending'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['fulfillment-rules'] })
|
||||
void queryClient.invalidateQueries({ queryKey: ['fulfillment-exceptions'] })
|
||||
},
|
||||
onError: (error) =>
|
||||
message.error(error instanceof Error ? error.message : '重新匹配接单模板失败'),
|
||||
})
|
||||
|
||||
const pipelineMutation = useMutation({
|
||||
mutationFn: () => runFinancePipeline({ days: 3 }),
|
||||
onSuccess: () => {
|
||||
@@ -253,6 +278,13 @@ function PendingPanel() {
|
||||
<Button icon={<ReloadOutlined />} onClick={() => void query.refetch()}>
|
||||
刷新
|
||||
</Button>
|
||||
<Button
|
||||
icon={<SyncOutlined />}
|
||||
loading={retryWorkOrderMutation.isPending}
|
||||
onClick={() => retryWorkOrderMutation.mutate(undefined)}
|
||||
>
|
||||
重试接单匹配
|
||||
</Button>
|
||||
<Button
|
||||
icon={<ThunderboltOutlined />}
|
||||
loading={pipelineMutation.isPending}
|
||||
@@ -267,7 +299,7 @@ function PendingPanel() {
|
||||
type="info"
|
||||
showIcon
|
||||
style={{ marginBottom: 12 }}
|
||||
message="指定渠道会写入该内部 SKU 的全局配置,并影响所有平台和店铺;系统会先确认载体创建成功,再进入商品归一与成本核算。"
|
||||
message="待分类来自真实订单,系统不提供直接删除,避免掩盖未履约收入。配置错误请修正模板/映射后点「重试接单匹配」,或通过「指定渠道」完成分流;系统会先确认载体创建成功,再进入商品归一与成本核算。"
|
||||
/>
|
||||
<PercentTable
|
||||
rowKey={(row) => rowKey(row)}
|
||||
|
||||
@@ -90,6 +90,15 @@ export type ChannelExceptionListResult = {
|
||||
|
||||
export type PipelineRunResult = Record<string, unknown>
|
||||
|
||||
export type PendingWorkOrderRetryResult = {
|
||||
scanned: number
|
||||
createdWorkOrders: number
|
||||
assigned: number
|
||||
remaining: number
|
||||
carrierFailed: number
|
||||
skipReasons: Record<string, number>
|
||||
}
|
||||
|
||||
export type FinancePipelineStatus = {
|
||||
pipeline: string
|
||||
label: string
|
||||
@@ -130,6 +139,15 @@ export function fetchChannelExceptions(
|
||||
return apiGet<ChannelExceptionListResult>('/api/v1/admin/fulfillment/exceptions', params)
|
||||
}
|
||||
|
||||
export function retryPendingWorkOrderRouting(
|
||||
payload: { internalSku?: string; limit?: number } = {},
|
||||
) {
|
||||
return apiPost<PendingWorkOrderRetryResult>(
|
||||
'/api/v1/admin/fulfillment/pending/retry-work-orders',
|
||||
payload,
|
||||
)
|
||||
}
|
||||
|
||||
export function assignChannelByInternalSku(payload: {
|
||||
internalSku: string
|
||||
channel: string
|
||||
|
||||
Reference in New Issue
Block a user