补全一些基础信息
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import { hasConfiguredOrderItems } from '../order/product-match-service.js'
|
||||
import { upsertOrderFromSource } from '../order/order-service.js'
|
||||
import { nowIso } from '../../utils/time.js'
|
||||
import { logWebhook } from '../../utils/logger.js'
|
||||
import { parseAmountToFen } from '../../utils/money.js'
|
||||
import {
|
||||
buildOpen91SourceEvent,
|
||||
upsertOpen91PendingOrder,
|
||||
} from '../platforms/ninetyone/order-service.js'
|
||||
import {
|
||||
assertOpen91Config,
|
||||
assertOpen91CreatePayload,
|
||||
@@ -14,8 +16,6 @@ import {
|
||||
normalizeOpen91CreatePayload,
|
||||
OPEN_91_COST_EXCEED_FAIL_CODE,
|
||||
OPEN_91_DEFAULT_FAIL_CODE,
|
||||
OPEN_91_PLATFORM,
|
||||
OPEN_91_PROVIDER,
|
||||
} from './shared.js'
|
||||
|
||||
export async function createOpen91Order(payload = {}, { requestId = '' } = {}) {
|
||||
@@ -26,42 +26,6 @@ export async function createOpen91Order(payload = {}, { requestId = '' } = {}) {
|
||||
assertOpen91Timestamp(normalized.timestamp, config.timestampToleranceSeconds)
|
||||
assertOpen91Signature(payload, config)
|
||||
|
||||
const now = nowIso()
|
||||
const items = [
|
||||
{
|
||||
externalItemId: normalized.productNo,
|
||||
externalSkuCode: normalized.productNo,
|
||||
externalSkuName: normalized.productNo,
|
||||
quantity: normalized.buyNum,
|
||||
spec: {
|
||||
source: OPEN_91_PROVIDER,
|
||||
},
|
||||
snapshot: {
|
||||
source: OPEN_91_PROVIDER,
|
||||
orderNo: normalized.orderNo,
|
||||
productNo: normalized.productNo,
|
||||
callbackUrl: normalized.callbackUrl,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const configured = await hasConfiguredOrderItems({
|
||||
provider: OPEN_91_PROVIDER,
|
||||
platform: OPEN_91_PLATFORM,
|
||||
shopId: config.shopId,
|
||||
items,
|
||||
})
|
||||
|
||||
if (!configured) {
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: '',
|
||||
orderStatus: 30,
|
||||
failCode: OPEN_91_DEFAULT_FAIL_CODE,
|
||||
failReason: '商品未配置或未匹配到履约规则',
|
||||
})
|
||||
}
|
||||
|
||||
if (normalized.maxAmount) {
|
||||
const maxAmountFen = parseAmountToFen(normalized.maxAmount)
|
||||
if (maxAmountFen < 0) {
|
||||
@@ -75,26 +39,8 @@ export async function createOpen91Order(payload = {}, { requestId = '' } = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
const result = await upsertOrderFromSource({
|
||||
provider: OPEN_91_PROVIDER,
|
||||
platform: OPEN_91_PLATFORM,
|
||||
shopId: config.shopId,
|
||||
shopName: config.shopName,
|
||||
platformOrderId: normalized.orderNo,
|
||||
orderStatus: 'paid',
|
||||
payStatus: 'paid',
|
||||
buyerId: '',
|
||||
buyerName: '',
|
||||
receiverContact: '',
|
||||
totalAmount: 0,
|
||||
currency: 'CNY',
|
||||
rawPayload: {
|
||||
source: OPEN_91_PROVIDER,
|
||||
...normalized,
|
||||
},
|
||||
paidAt: now,
|
||||
items,
|
||||
}, {
|
||||
const sourceEvent = buildOpen91SourceEvent(normalized, config)
|
||||
const result = await upsertOrderFromSource(sourceEvent, {
|
||||
sourceLabel: 'open91',
|
||||
})
|
||||
|
||||
@@ -103,13 +49,31 @@ export async function createOpen91Order(payload = {}, { requestId = '' } = {}) {
|
||||
orderNo: normalized.orderNo,
|
||||
productNo: normalized.productNo,
|
||||
buyNum: normalized.buyNum,
|
||||
configured,
|
||||
ignored: Boolean(result.ignored),
|
||||
ignoreReason: result.ignoreReason || '',
|
||||
orderId: result.order?.id || null,
|
||||
taskCount: Array.isArray(result.tasks) ? result.tasks.length : 0,
|
||||
})
|
||||
|
||||
if (result.ignored || !result.order || !Array.isArray(result.tasks) || result.tasks.length === 0) {
|
||||
if (result.ignored) {
|
||||
const pending = await upsertOpen91PendingOrder(normalized, config)
|
||||
logWebhook('[open-91/create]', '91卡券订单已进入待补全队列', {
|
||||
requestId,
|
||||
orderNo: normalized.orderNo,
|
||||
productNo: normalized.productNo,
|
||||
orderId: pending.order?.id || null,
|
||||
})
|
||||
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: buildOpen91OutTradeNo(pending.order),
|
||||
orderStatus: 10,
|
||||
orderCost: buildOpen91OrderCost(0),
|
||||
cards: '',
|
||||
})
|
||||
}
|
||||
|
||||
if (!result.order || !Array.isArray(result.tasks) || result.tasks.length === 0) {
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: '',
|
||||
|
||||
@@ -3,6 +3,10 @@ import { listTasksByOrderId } from '../../repositories/task-repo.js'
|
||||
import { buildClaimUrl } from '../claim/claim-service.js'
|
||||
import { ensureTaskClaimLink } from '../fulfillment/kuaishou-cloud-task-service.js'
|
||||
import { logWebhook } from '../../utils/logger.js'
|
||||
import {
|
||||
OPEN_91_MANUAL_FAILED_STATUS,
|
||||
OPEN_91_PENDING_CONFIG_STATUS,
|
||||
} from '../platforms/ninetyone/order-service.js'
|
||||
import {
|
||||
assertOpen91Config,
|
||||
assertOpen91QueryPayload,
|
||||
@@ -46,6 +50,31 @@ export async function queryOpen91Order(payload = {}, { requestId = '' } = {}) {
|
||||
}
|
||||
|
||||
const tasks = await listTasksByOrderId(order.id)
|
||||
|
||||
if (tasks.length === 0) {
|
||||
if (String(order.order_status || '').trim() === OPEN_91_PENDING_CONFIG_STATUS) {
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: buildOpen91OutTradeNo(order),
|
||||
orderStatus: 10,
|
||||
failCode: 0,
|
||||
failReason: '',
|
||||
orderCost: buildOpen91OrderCost(0),
|
||||
cards: '',
|
||||
})
|
||||
}
|
||||
|
||||
if (String(order.order_status || '').trim() === OPEN_91_MANUAL_FAILED_STATUS) {
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: buildOpen91OutTradeNo(order),
|
||||
orderStatus: 30,
|
||||
failCode: OPEN_91_DEFAULT_FAIL_CODE,
|
||||
failReason: resolveOpen91OrderFailReason(order) || '商家手动标记无法履约',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const cardItems = []
|
||||
const readyTaskIds = []
|
||||
|
||||
@@ -123,3 +152,25 @@ export async function queryOpen91Order(payload = {}, { requestId = '' } = {}) {
|
||||
cards: buildOpen91Cards(cardItems, config),
|
||||
})
|
||||
}
|
||||
|
||||
function resolveOpen91OrderFailReason(order) {
|
||||
const payload = parseJsonObject(order?.raw_payload_json)
|
||||
return String(payload.manualFailedReason || '').trim()
|
||||
}
|
||||
|
||||
function parseJsonObject(value) {
|
||||
if (!value) {
|
||||
return {}
|
||||
}
|
||||
|
||||
if (typeof value === 'object' && !Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(String(value || '{}'))
|
||||
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {}
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user