优化订单履约分流与后台筛选
This commit is contained in:
@@ -19,6 +19,7 @@ import type { JsonObject } from '../../types/json.js'
|
||||
import type { OrderItemRow, OrderRow } from '../../types/repository/rows.js'
|
||||
import { randomId } from '../../utils/random.js'
|
||||
import { nowIso } from '../../utils/time.js'
|
||||
import { logInfo, logWarn } from '../../utils/logger.js'
|
||||
import { safeParseJson } from '../admin/admin-query-utils.js'
|
||||
import { createWorkOrderMaterialAdminNotification } from '../admin/admin-notification-service.js'
|
||||
import {
|
||||
@@ -44,6 +45,7 @@ export async function syncWorkerOrdersForSourceOrder(
|
||||
const productMatchConfig = getWorkerProductMatchConfig()
|
||||
const created: WorkOrderRow[] = []
|
||||
const skipped: Array<{ orderItemId: number; reason: string }> = []
|
||||
const decisions: Array<Record<string, unknown>> = []
|
||||
|
||||
for (const item of orderItems) {
|
||||
const match = resolveMatchingProductRuleDecision(order, item, rules, mappings, {
|
||||
@@ -75,19 +77,44 @@ export async function syncWorkerOrdersForSourceOrder(
|
||||
})
|
||||
}
|
||||
if (!match.rule) {
|
||||
const reason = match.reason === 'ambiguous' ? 'rule_match_ambiguous' : 'rule_not_matched'
|
||||
skipped.push({
|
||||
orderItemId: Number(item.id),
|
||||
reason: match.reason === 'ambiguous' ? 'rule_match_ambiguous' : 'rule_not_matched',
|
||||
reason,
|
||||
})
|
||||
decisions.push(
|
||||
buildWorkerConsumerDecision(item, {
|
||||
result: 'skipped',
|
||||
reason,
|
||||
matchReason: match.reason,
|
||||
candidates: match.candidates,
|
||||
}),
|
||||
)
|
||||
continue
|
||||
}
|
||||
const rule = match.rule
|
||||
if (options.autoOnly && !rule.auto_create) {
|
||||
skipped.push({ orderItemId: Number(item.id), reason: 'auto_create_disabled' })
|
||||
decisions.push(
|
||||
buildWorkerConsumerDecision(item, {
|
||||
result: 'skipped',
|
||||
reason: 'auto_create_disabled',
|
||||
ruleId: rule.id,
|
||||
ruleKey: rule.rule_key,
|
||||
}),
|
||||
)
|
||||
continue
|
||||
}
|
||||
if (await getWorkOrderByOrderItemId(item.id)) {
|
||||
skipped.push({ orderItemId: Number(item.id), reason: 'already_exists' })
|
||||
decisions.push(
|
||||
buildWorkerConsumerDecision(item, {
|
||||
result: 'existing',
|
||||
reason: 'already_exists',
|
||||
ruleId: rule.id,
|
||||
ruleKey: rule.rule_key,
|
||||
}),
|
||||
)
|
||||
continue
|
||||
}
|
||||
// 订单号跨订单唯一:同一订单的多个 SKU 件允许共享订单号(按件建单是既有设计),
|
||||
@@ -100,6 +127,14 @@ export async function syncWorkerOrdersForSourceOrder(
|
||||
})
|
||||
) {
|
||||
skipped.push({ orderItemId: Number(item.id), reason: 'platform_order_exists' })
|
||||
decisions.push(
|
||||
buildWorkerConsumerDecision(item, {
|
||||
result: 'skipped',
|
||||
reason: 'platform_order_exists',
|
||||
ruleId: rule.id,
|
||||
ruleKey: rule.rule_key,
|
||||
}),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -161,9 +196,31 @@ export async function syncWorkerOrdersForSourceOrder(
|
||||
requirementJson: JSON.stringify({ fields }),
|
||||
now,
|
||||
})
|
||||
if (!workOrder) continue
|
||||
if (!workOrder) {
|
||||
skipped.push({ orderItemId: Number(item.id), reason: 'create_returned_empty' })
|
||||
decisions.push(
|
||||
buildWorkerConsumerDecision(item, {
|
||||
result: 'failed',
|
||||
reason: 'create_returned_empty',
|
||||
ruleId: rule.id,
|
||||
ruleKey: rule.rule_key,
|
||||
}),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
created.push(workOrder)
|
||||
decisions.push(
|
||||
buildWorkerConsumerDecision(item, {
|
||||
result: 'created',
|
||||
reason: 'rule_matched',
|
||||
ruleId: rule.id,
|
||||
ruleKey: rule.rule_key,
|
||||
workOrderId: workOrder.id,
|
||||
workOrderNo: workOrder.work_order_no,
|
||||
workOrderStatus: workOrder.status,
|
||||
}),
|
||||
)
|
||||
await createWorkOrderEvent({
|
||||
workOrderId: workOrder.id,
|
||||
actorType: 'system',
|
||||
@@ -187,10 +244,54 @@ export async function syncWorkerOrdersForSourceOrder(
|
||||
}
|
||||
}
|
||||
|
||||
logInfo('[worker-order-consumer]', '发单平台消费者处理完成', {
|
||||
source: options.source || 'source_order',
|
||||
orderId: order.id,
|
||||
platformOrderId: order.platform_order_id,
|
||||
orderItemCount: orderItems.length,
|
||||
createdCount: created.length,
|
||||
skippedCount: skipped.length,
|
||||
decisions,
|
||||
})
|
||||
|
||||
const failedDecisions = decisions.filter((decision) => decision.result === 'failed')
|
||||
if (failedDecisions.length > 0) {
|
||||
logWarn('[worker-order-consumer]', '发单平台消费者存在未成功落库的订单项', {
|
||||
source: options.source || 'source_order',
|
||||
orderId: order.id,
|
||||
platformOrderId: order.platform_order_id,
|
||||
decisions: failedDecisions,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
created: created.map((workOrder) => mapWorkOrderAdmin(workOrder)),
|
||||
skipped,
|
||||
createdCount: created.length,
|
||||
skippedCount: skipped.length,
|
||||
decisions,
|
||||
}
|
||||
}
|
||||
|
||||
function buildWorkerConsumerDecision(
|
||||
item: OrderItemRow,
|
||||
detail: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
const snapshot = safeParseJson(item.item_snapshot_json)
|
||||
const sendCode =
|
||||
snapshot.kuaishouSendCode &&
|
||||
typeof snapshot.kuaishouSendCode === 'object' &&
|
||||
!Array.isArray(snapshot.kuaishouSendCode)
|
||||
? (snapshot.kuaishouSendCode as JsonObject)
|
||||
: {}
|
||||
|
||||
return {
|
||||
orderItemId: Number(item.id),
|
||||
skuCode: item.sku_code,
|
||||
skuName: item.sku_name,
|
||||
quantity: Number(item.quantity || 1),
|
||||
sourceItemTitle: String(sendCode.itemTitle || '').trim(),
|
||||
sourceSkuNick: String(sendCode.skuNick || '').trim(),
|
||||
...detail,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user