后端迁移91卡券订单入口
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
import { findOrderByPlatformOrderId } from '../../repositories/order-repo.js'
|
||||
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,
|
||||
assertOpen91Signature,
|
||||
assertOpen91Timestamp,
|
||||
buildOpen91CardItem,
|
||||
buildOpen91Cards,
|
||||
buildOpen91OrderCost,
|
||||
buildOpen91OutTradeNo,
|
||||
buildOpen91SuccessResponse,
|
||||
normalizeOpen91QueryPayload,
|
||||
OPEN_91_DEFAULT_FAIL_CODE,
|
||||
OPEN_91_PLATFORM,
|
||||
OPEN_91_PROVIDER,
|
||||
resolveOpen91QueryState,
|
||||
} from './shared.js'
|
||||
|
||||
export async function queryOpen91Order(payload = {}, { requestId = '' } = {}) {
|
||||
const config = assertOpen91Config()
|
||||
const normalized = normalizeOpen91QueryPayload(payload)
|
||||
|
||||
assertOpen91QueryPayload(normalized, config)
|
||||
assertOpen91Timestamp(normalized.timestamp, config.timestampToleranceSeconds)
|
||||
assertOpen91Signature(payload, config)
|
||||
|
||||
const order = await findOrderByPlatformOrderId({
|
||||
provider: OPEN_91_PROVIDER,
|
||||
platform: OPEN_91_PLATFORM,
|
||||
shopId: config.shopId,
|
||||
platformOrderId: normalized.orderNo,
|
||||
})
|
||||
|
||||
if (!order) {
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: '',
|
||||
orderStatus: 30,
|
||||
failCode: OPEN_91_DEFAULT_FAIL_CODE,
|
||||
failReason: '订单不存在',
|
||||
})
|
||||
}
|
||||
|
||||
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 = []
|
||||
|
||||
for (const task of tasks) {
|
||||
let claimUrl = ''
|
||||
let expireTime = String(task.primary_claim_expires_at || task.claim_expires_at || '').trim()
|
||||
const primaryToken = String(task.primary_claim_token || task.claim_token || '').trim()
|
||||
|
||||
if (primaryToken) {
|
||||
claimUrl = buildClaimUrl(primaryToken)
|
||||
} else if (String(task.executor_key || '').trim() === 'kuaishou_ct_assisted') {
|
||||
try {
|
||||
const ensured = await ensureTaskClaimLink(task)
|
||||
claimUrl = String(ensured.claimUrl || '').trim()
|
||||
expireTime = String(ensured.expiredAt || expireTime).trim()
|
||||
} catch {
|
||||
claimUrl = ''
|
||||
}
|
||||
}
|
||||
|
||||
if (!claimUrl) {
|
||||
continue
|
||||
}
|
||||
|
||||
readyTaskIds.push(Number(task.id))
|
||||
cardItems.push(buildOpen91CardItem({
|
||||
claimUrl,
|
||||
expireTime,
|
||||
}))
|
||||
}
|
||||
|
||||
const queryState = resolveOpen91QueryState({
|
||||
tasks,
|
||||
readyTaskIds,
|
||||
})
|
||||
|
||||
logWebhook('[open-91/query]', '91卡券订单查询已处理', {
|
||||
requestId,
|
||||
orderNo: normalized.orderNo,
|
||||
orderId: order.id,
|
||||
taskCount: tasks.length,
|
||||
readyTaskCount: readyTaskIds.length,
|
||||
orderStatus: queryState.orderStatus,
|
||||
})
|
||||
|
||||
if (queryState.orderStatus === 30) {
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: buildOpen91OutTradeNo(order),
|
||||
orderStatus: 30,
|
||||
failCode: queryState.failCode,
|
||||
failReason: queryState.failReason,
|
||||
})
|
||||
}
|
||||
|
||||
if (queryState.orderStatus === 10) {
|
||||
return buildOpen91SuccessResponse({
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo: buildOpen91OutTradeNo(order),
|
||||
orderStatus: 10,
|
||||
failCode: 0,
|
||||
failReason: '',
|
||||
orderCost: buildOpen91OrderCost(0),
|
||||
cards: '',
|
||||
})
|
||||
}
|
||||
|
||||
const outTradeNo = buildOpen91OutTradeNo(order)
|
||||
const encryptedCards = buildOpen91Cards(cardItems, config)
|
||||
const responseData = {
|
||||
orderNo: normalized.orderNo,
|
||||
outTradeNo,
|
||||
orderStatus: 20,
|
||||
failCode: 0,
|
||||
failReason: '',
|
||||
orderCost: buildOpen91OrderCost(0),
|
||||
cards: encryptedCards,
|
||||
}
|
||||
|
||||
logWebhook('[open-91/query]', '91卡券订单查询返回 cards 已生成', {
|
||||
requestId,
|
||||
orderNo: normalized.orderNo,
|
||||
orderId: order.id,
|
||||
outTradeNo,
|
||||
cardsEncoding: config.cardsEncoding,
|
||||
cardsPlain: cardItems,
|
||||
cardsEncrypted: encryptedCards,
|
||||
responseData,
|
||||
})
|
||||
|
||||
return buildOpen91SuccessResponse(responseData)
|
||||
}
|
||||
|
||||
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