彻底重构-3
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
import { createTask, listTasksByOrderId, updateTask } from '../../repositories/task-repo.js'
|
||||
import {
|
||||
getFulfillmentProfileByKey,
|
||||
listFulfillmentProfileRequirements,
|
||||
resolveFulfillmentBinding,
|
||||
} from '../../repositories/fulfillment-profile-repo.js'
|
||||
import { reserveCdkForTask } from './cdk-service.js'
|
||||
import { createTaskClaimToken } from '../claim/claim-service.js'
|
||||
import { nowIso } from '../../utils/time.js'
|
||||
import { randomId } from '../../utils/random.js'
|
||||
|
||||
export function syncDeliveryTasksForOrder(order, orderItems) {
|
||||
const existingTasks = listTasksByOrderId(order.id)
|
||||
export async function syncDeliveryTasksForOrder(order, orderItems) {
|
||||
const existingTasks = await listTasksByOrderId(order.id)
|
||||
|
||||
if (existingTasks.length > 0) {
|
||||
if (order.pay_status !== 'paid') {
|
||||
@@ -13,47 +18,72 @@ export function syncDeliveryTasksForOrder(order, orderItems) {
|
||||
}
|
||||
|
||||
const itemMap = new Map(orderItems.map((item) => [item.id, item]))
|
||||
return existingTasks.map((task) => preparePaidTask({
|
||||
return Promise.all(existingTasks.map((task) => preparePaidTask({
|
||||
...task,
|
||||
skuCode: itemMap.get(task.order_item_id)?.sku_code || '',
|
||||
skuName: itemMap.get(task.order_item_id)?.sku_name || '',
|
||||
}))
|
||||
})))
|
||||
}
|
||||
|
||||
const tasks = []
|
||||
|
||||
for (const item of orderItems) {
|
||||
const binding = await resolveFulfillmentBinding({
|
||||
skuCode: item.sku_code,
|
||||
provider: order.provider,
|
||||
platform: order.platform,
|
||||
shopId: order.shop_id,
|
||||
})
|
||||
const profile = binding || await getFulfillmentProfileByKey('manual_review')
|
||||
if (!profile) {
|
||||
continue
|
||||
}
|
||||
const requirements = await listFulfillmentProfileRequirements(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))
|
||||
|
||||
for (let index = 0; index < quantity; index += 1) {
|
||||
const createdAt = nowIso()
|
||||
const initialStatus = order.pay_status === 'paid' ? 'paid' : 'pending_payment'
|
||||
const initialStatus = order.pay_status === 'paid'
|
||||
? resolvePaidTaskStatus(profile)
|
||||
: 'pending_payment'
|
||||
|
||||
const task = createTask({
|
||||
const task = await createTask({
|
||||
orderId: order.id,
|
||||
orderItemId: item.id,
|
||||
unitIndex: index + 1,
|
||||
provider: order.provider,
|
||||
platform: order.platform,
|
||||
shopId: order.shop_id,
|
||||
shopName: order.shop_name,
|
||||
platformOrderId: order.platform_order_id,
|
||||
taskNo: randomId('DT'),
|
||||
profileId: Number(profile.profile_id || profile.id),
|
||||
executorKey: String(profile.executor_key || 'manual_dispatch'),
|
||||
taskStatus: initialStatus,
|
||||
loginType: '',
|
||||
claimTokenId: null,
|
||||
reservedCdkId: null,
|
||||
browserSessionId: '',
|
||||
nickname: '',
|
||||
roleId: '',
|
||||
roleName: '',
|
||||
area: '',
|
||||
partitionName: '',
|
||||
inventoryStatus: profile.requires_claim ? 'pending' : 'not_required',
|
||||
deliveryStatus: initialStatus === 'redeemed' ? 'delivered' : 'pending',
|
||||
resultCode: '',
|
||||
resultMessage: '',
|
||||
screenshotPath: '',
|
||||
artifactsJson: '{}',
|
||||
claimToken: '',
|
||||
claimExpiresAt: null,
|
||||
automationMode: profile.auto_dispatch ? 'automatic' : 'manual',
|
||||
requiresClaim: Boolean(profile.requires_claim),
|
||||
userActionStatus: profile.requires_claim ? 'pending_claim' : 'not_required',
|
||||
attemptCount: 0,
|
||||
lastError: '',
|
||||
retryCount: 0,
|
||||
expiresAt: null,
|
||||
claimedAt: null,
|
||||
roleConfirmedAt: null,
|
||||
redeemedAt: null,
|
||||
contextJson: JSON.stringify({
|
||||
profileKey: String(profile.profile_key || ''),
|
||||
profileName: String(profile.profile_name || profile.name || ''),
|
||||
skuCode: item.sku_code,
|
||||
skuName: item.sku_name,
|
||||
primaryRequirement: primaryRequirement
|
||||
? {
|
||||
roleKey: String(primaryRequirement.role_key || primaryRequirement.roleKey || 'primary_code'),
|
||||
credentialType: String(primaryRequirement.credential_type || primaryRequirement.credentialType || 'tencent_code'),
|
||||
}
|
||||
: null,
|
||||
}),
|
||||
createdAt,
|
||||
updatedAt: createdAt,
|
||||
})
|
||||
@@ -70,16 +100,28 @@ export function syncDeliveryTasksForOrder(order, orderItems) {
|
||||
return tasks
|
||||
}
|
||||
|
||||
return tasks.map((task) => preparePaidTask(task))
|
||||
return Promise.all(tasks.map((task) => preparePaidTask(task)))
|
||||
}
|
||||
|
||||
function preparePaidTask(task) {
|
||||
async function preparePaidTask(task) {
|
||||
const now = nowIso()
|
||||
const taskContext = parseTaskContext(task)
|
||||
const primaryRequirement = taskContext.primaryRequirement || null
|
||||
|
||||
if (['link_generated', 'claimed', 'role_confirmed', 'redeeming', 'redeemed'].includes(task.task_status)) {
|
||||
return task
|
||||
}
|
||||
|
||||
if (!task.requires_claim || String(task.executor_key || '').trim() === 'manual_dispatch') {
|
||||
return updateTask(task.id, {
|
||||
task_status: 'manual_review',
|
||||
inventory_status: 'not_required',
|
||||
user_action_status: 'not_required',
|
||||
last_error: task.last_error || '当前任务需要人工履约处理',
|
||||
updated_at: now,
|
||||
})
|
||||
}
|
||||
|
||||
if (!task.skuCode) {
|
||||
return updateTask(task.id, {
|
||||
task_status: 'manual_review',
|
||||
@@ -88,7 +130,7 @@ function preparePaidTask(task) {
|
||||
})
|
||||
}
|
||||
|
||||
if (task.reserved_cdk_id && task.claim_token_id) {
|
||||
if (task.primary_inventory_item_id && task.primary_claim_token_id) {
|
||||
return updateTask(task.id, {
|
||||
task_status: 'link_generated',
|
||||
last_error: '',
|
||||
@@ -96,24 +138,59 @@ function preparePaidTask(task) {
|
||||
})
|
||||
}
|
||||
|
||||
const reserved = reserveCdkForTask(task.skuCode, task.id)
|
||||
if (!primaryRequirement?.credentialType) {
|
||||
return updateTask(task.id, {
|
||||
task_status: 'manual_review',
|
||||
last_error: '履约档案未配置库存要求,无法自动分配库存',
|
||||
updated_at: now,
|
||||
})
|
||||
}
|
||||
|
||||
const reserved = await reserveCdkForTask({
|
||||
skuCode: task.skuCode,
|
||||
taskId: task.id,
|
||||
credentialType: primaryRequirement.credentialType,
|
||||
roleKey: primaryRequirement.roleKey || 'primary_code',
|
||||
})
|
||||
|
||||
if (!reserved) {
|
||||
return updateTask(task.id, {
|
||||
task_status: 'waiting_inventory',
|
||||
inventory_status: 'pending',
|
||||
last_error: '库存不足,等待可用 CDK',
|
||||
updated_at: now,
|
||||
})
|
||||
}
|
||||
|
||||
const claimToken = createTaskClaimToken(task.id)
|
||||
const claimToken = await createTaskClaimToken(task.id)
|
||||
|
||||
return updateTask(task.id, {
|
||||
task_status: 'link_generated',
|
||||
reserved_cdk_id: reserved.id,
|
||||
claim_token_id: claimToken.id,
|
||||
inventory_status: 'reserved',
|
||||
claim_token: claimToken.token,
|
||||
claim_expires_at: claimToken.expired_at,
|
||||
user_action_status: 'pending_claim',
|
||||
last_error: '',
|
||||
expires_at: claimToken.expired_at,
|
||||
updated_at: now,
|
||||
})
|
||||
}
|
||||
|
||||
function resolvePaidTaskStatus(profile) {
|
||||
if (Boolean(profile?.requires_claim)) {
|
||||
return 'paid'
|
||||
}
|
||||
|
||||
if (String(profile?.executor_key || '').trim() === 'manual_dispatch') {
|
||||
return 'manual_review'
|
||||
}
|
||||
|
||||
return 'paid'
|
||||
}
|
||||
|
||||
function parseTaskContext(task) {
|
||||
try {
|
||||
return JSON.parse(String(task?.context_json || '{}'))
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user