简化履约匹配并支持mock订单测试

This commit is contained in:
yml
2026-05-27 12:55:44 +08:00
parent e8010728a4
commit dd6776c4e4
21 changed files with 1892 additions and 683 deletions
@@ -1,5 +1,6 @@
import { createTask, listTasksByOrderId, updateTask } from '../../repositories/task-repo.js'
import {
getFulfillmentProfileByKey,
resolveFulfillmentBinding,
} from '../../repositories/fulfillment-profile-repo.js'
import { createTaskClaimToken } from '../claim/claim-service.js'
@@ -44,6 +45,7 @@ type DeliveryTaskDeps = {
platform?: string
shopId?: string
}) => Promise<FulfillmentBindingLike | null>
getFulfillmentProfileByKey?: (profileKey: string) => Promise<FulfillmentBindingLike | null>
createTaskClaimToken?: (taskId: number | string) => Promise<ClaimTokenLike>
notifyTaskAutoManualReview?: (payload: {
task: unknown
@@ -83,6 +85,7 @@ export async function syncDeliveryTasksForOrderWithDeps(
listTasksByOrderId: listTasks = listTasksByOrderId,
updateTask: updateDeliveryTask = updateTask,
resolveFulfillmentBinding: resolveBinding = resolveFulfillmentBinding,
getFulfillmentProfileByKey: getProfileByKey = getFulfillmentProfileByKey,
createTaskClaimToken: createClaimToken = createTaskClaimToken,
notifyTaskAutoManualReview: notifyManualReview = notifyTaskAutoManualReview,
nowIso: getNowIso = nowIso,
@@ -122,10 +125,11 @@ export async function syncDeliveryTasksForOrderWithDeps(
shopId: order.shop_id,
})
if (!binding) {
const profile = binding || await resolveDynamicCloudtentaclesProfile(item, getProfileByKey)
if (!profile) {
continue
}
const profile = binding
const quantity = Math.max(1, Number(item.quantity || 1))
const fulfillmentConfig = parseJsonObject(profile.config_json)
const cloudtentaclesConfig = parseJsonObject(fulfillmentConfig.cloudtentacles)
@@ -391,6 +395,62 @@ function parseJsonObject(value: unknown): JsonObject {
}
}
async function resolveDynamicCloudtentaclesProfile(
item: OrderItemRow,
getProfileByKey: (profileKey: string) => Promise<FulfillmentBindingLike | null>,
): Promise<FulfillmentBindingLike | null> {
const snapshot = parseJsonObject(item.item_snapshot_json)
const cloudtentacles = parseJsonObject(snapshot.cloudtentacles)
const cloudSkuId = Number(cloudtentacles.cloudSkuId || 0) || 0
const cloudSkuName = String(cloudtentacles.cloudSkuName || item.sku_name || '').trim()
const cloudSourceKeys = normalizeStringArray(cloudtentacles.cloudSourceKeys)
if (!cloudSkuId || !cloudSkuName || cloudSourceKeys.length === 0) {
return null
}
const profile = await getProfileByKey('kuaishou_ct_assisted')
if (!profile) {
return null
}
return {
...profile,
profile_id: Number(profile.id || profile.profile_id || 0),
profile_key: 'kuaishou_ct_assisted',
profile_name: String(profile.profile_name || profile.name || '快手 cloud 履约').trim(),
executor_key: 'kuaishou_ct_assisted',
requires_claim: false,
auto_dispatch: false,
config_json: {
flowType: 'kuaishou_cloud_fulfillment',
configId: `cloudtentacles_name:${cloudSkuId}`,
cloudtentacles: {
cloudSourceKeys,
skuId: cloudSkuId,
skuName: cloudSkuName,
deliveryItems: [
{
cloudSkuId,
cloudSkuName,
quantity: 1,
},
],
vnKey: '1',
autoBuyEnabled: true,
minAssetReserve: 0,
autoReturnNumberAfterDispatch: true,
},
kuaishouConsume: {
shopId: '',
shopName: '',
autoConsumeAfterDispatch: false,
},
notes: '91卡券商品名自动匹配 cloudtentacles 商品',
},
}
}
function normalizeStringArray(value: unknown): string[] {
if (!Array.isArray(value)) {
return []