删除库存和旧回调管理

This commit is contained in:
yml
2026-05-25 23:07:19 +08:00
parent 90ad866ecc
commit 2c7464b1eb
87 changed files with 94 additions and 5794 deletions
@@ -1,14 +1,12 @@
import { createTask, listTasksByOrderId, updateTask } from '../../repositories/task-repo.js'
import {
listFulfillmentProfileRequirements,
resolveFulfillmentBinding,
} from '../../repositories/fulfillment-profile-repo.js'
import { reserveInventoryForTask } from './inventory-service.js'
import { createTaskClaimToken } from '../claim/claim-service.js'
import { notifyTaskAutoManualReview } from '../notification/domain-notifications.js'
import { nowIso } from '../../utils/time.js'
import { randomId } from '../../utils/random.js'
import type { InventoryItemRow, OrderItemRow, OrderRow, TaskRow } from '../../types/repository-rows.js'
import type { OrderItemRow, OrderRow, TaskRow } from '../../types/repository-rows.js'
type JsonObject = Record<string, unknown>
@@ -31,15 +29,6 @@ type FulfillmentBindingLike = {
[key: string]: unknown
}
type FulfillmentRequirementLike = {
role_key?: string
roleKey?: string
credential_type?: string
credentialType?: string
is_required?: boolean
[key: string]: unknown
}
type DeliveryTaskRow = TaskRow & {
skuCode?: string
skuName?: string
@@ -49,21 +38,12 @@ type DeliveryTaskDeps = {
createTask?: typeof createTask
listTasksByOrderId?: typeof listTasksByOrderId
updateTask?: typeof updateTask
listFulfillmentProfileRequirements?: (
profileId: number | string,
) => Promise<FulfillmentRequirementLike[]>
resolveFulfillmentBinding?: (input: {
skuCode: string
provider?: string
platform?: string
shopId?: string
}) => Promise<FulfillmentBindingLike | null>
reserveInventoryForTask?: (input: {
skuCode: string
taskId: number | string
credentialType?: string
roleKey?: string
}) => Promise<InventoryItemRow | null>
createTaskClaimToken?: (taskId: number | string) => Promise<ClaimTokenLike>
notifyTaskAutoManualReview?: (payload: {
task: unknown
@@ -77,18 +57,12 @@ type DeliveryTaskDeps = {
type RuntimeDeliveryTaskDeps = Required<Pick<
DeliveryTaskDeps,
'updateTask'
| 'reserveInventoryForTask'
| 'createTaskClaimToken'
| 'notifyTaskAutoManualReview'
| 'nowIso'
>>
type TaskContext = {
inventorySkuCode?: string
primaryRequirement?: {
roleKey?: string
credentialType?: string
} | null
[key: string]: unknown
}
@@ -108,9 +82,7 @@ export async function syncDeliveryTasksForOrderWithDeps(
createTask: createDeliveryTask = createTask,
listTasksByOrderId: listTasks = listTasksByOrderId,
updateTask: updateDeliveryTask = updateTask,
listFulfillmentProfileRequirements: listProfileRequirements = listFulfillmentProfileRequirements,
resolveFulfillmentBinding: resolveBinding = resolveFulfillmentBinding,
reserveInventoryForTask: reserveInventory = reserveInventoryForTask,
createTaskClaimToken: createClaimToken = createTaskClaimToken,
notifyTaskAutoManualReview: notifyManualReview = notifyTaskAutoManualReview,
nowIso: getNowIso = nowIso,
@@ -119,7 +91,6 @@ export async function syncDeliveryTasksForOrderWithDeps(
const runtimeDeps: RuntimeDeliveryTaskDeps = {
updateTask: updateDeliveryTask,
reserveInventoryForTask: reserveInventory,
createTaskClaimToken: createClaimToken,
notifyTaskAutoManualReview: notifyManualReview,
nowIso: getNowIso,
@@ -154,8 +125,6 @@ export async function syncDeliveryTasksForOrderWithDeps(
continue
}
const profile = binding
const requirements = await listProfileRequirements(profile.profile_id || profile.id)
const primaryRequirement = requirements.find((requirement) => requirement.is_required !== false) || requirements[0] || null
const quantity = Math.max(1, Number(item.quantity || 1))
const fulfillmentConfig = parseJsonObject(profile.config_json)
const cloudtentaclesConfig = parseJsonObject(fulfillmentConfig.cloudtentacles)
@@ -181,7 +150,6 @@ export async function syncDeliveryTasksForOrderWithDeps(
profileId: Number(profile.profile_id || profile.id),
executorKey: String(profile.executor_key || 'manual_dispatch'),
taskStatus: initialStatus,
inventoryStatus: profile.requires_claim ? 'pending' : 'not_required',
deliveryStatus: 'pending',
resultCode: '',
resultMessage: '',
@@ -197,13 +165,6 @@ export async function syncDeliveryTasksForOrderWithDeps(
profileName: String(profile.profile_name || profile.name || ''),
skuCode: item.sku_code,
skuName: item.sku_name,
inventorySkuCode: item.sku_code,
primaryRequirement: primaryRequirement
? {
roleKey: String(primaryRequirement.role_key || primaryRequirement.roleKey || 'primary_code'),
credentialType: String(primaryRequirement.credential_type || primaryRequirement.credentialType || 'claim_code'),
}
: null,
kuaishouCloudFulfillment: isKuaishouCloudExecutor(profile.executor_key)
? {
flowType: 'kuaishou_cloud_fulfillment',
@@ -303,16 +264,12 @@ async function preparePaidTask(
): Promise<TaskRow | DeliveryTaskRow | null> {
const {
updateTask: updateDeliveryTask = updateTask,
reserveInventoryForTask: reserveInventory = reserveInventoryForTask,
createTaskClaimToken: createClaimToken = createTaskClaimToken,
notifyTaskAutoManualReview: notifyManualReview = notifyTaskAutoManualReview,
nowIso: getNowIso = nowIso,
} = deps
const now = getNowIso()
const taskContext = parseTaskContext(task)
const primaryRequirement = taskContext.primaryRequirement || null
const inventorySkuCode = String(taskContext.inventorySkuCode || task.skuCode || '').trim()
if (['link_generated', 'claimed', 'role_confirmed', 'redeeming', 'redeemed', 'closed'].includes(task.task_status)) {
return task
@@ -344,7 +301,6 @@ async function preparePaidTask(
return updateDeliveryTask(task.id, {
task_status: 'pending_binding_prepare',
inventory_status: 'not_required',
claim_token: claimToken.token,
claim_expires_at: claimToken.expired_at,
user_action_status: 'pending_claim',
@@ -357,7 +313,6 @@ async function preparePaidTask(
const lastError = task.last_error || '当前任务需要人工履约处理'
const updatedTask = await updateDeliveryTask(task.id, {
task_status: 'manual_review',
inventory_status: 'not_required',
user_action_status: 'not_required',
last_error: lastError,
updated_at: now,
@@ -370,71 +325,7 @@ async function preparePaidTask(
return updatedTask
}
if (!inventorySkuCode) {
const lastError = '未匹配到 SKU,无法为任务分配库存凭据'
const updatedTask = await updateDeliveryTask(task.id, {
task_status: 'manual_review',
last_error: lastError,
updated_at: now,
})
await notifyManualReview({
task: updatedTask || task,
reason: lastError,
source: 'missing_sku',
})
return updatedTask
}
if (task.primary_inventory_item_id && task.primary_claim_token_id) {
return updateDeliveryTask(task.id, {
task_status: 'link_generated',
last_error: '',
updated_at: now,
})
}
if (!primaryRequirement?.credentialType) {
const lastError = '履约档案未配置库存要求,无法自动分配库存'
const updatedTask = await updateDeliveryTask(task.id, {
task_status: 'manual_review',
last_error: lastError,
updated_at: now,
})
await notifyManualReview({
task: updatedTask || task,
reason: lastError,
source: 'missing_inventory_requirement',
})
return updatedTask
}
const reserved = await reserveInventory({
skuCode: inventorySkuCode,
taskId: task.id,
credentialType: primaryRequirement.credentialType,
roleKey: primaryRequirement.roleKey || 'primary_code',
})
if (!reserved) {
return updateDeliveryTask(task.id, {
task_status: 'waiting_inventory',
inventory_status: 'pending',
last_error: '库存不足,等待可用库存凭据',
updated_at: now,
})
}
const claimToken = await createClaimToken(task.id)
return updateDeliveryTask(task.id, {
task_status: 'link_generated',
inventory_status: 'reserved',
claim_token: claimToken.token,
claim_expires_at: claimToken.expired_at,
user_action_status: 'pending_claim',
last_error: '',
updated_at: now,
})
return task
}
function resolvePaidTaskStatus(profile: FulfillmentBindingLike | null | undefined): string {