修改领取顺序,先核销

This commit is contained in:
yml2213
2026-05-31 11:58:12 +08:00
parent 11cf0e93a4
commit 904ecc9303
6 changed files with 105 additions and 39 deletions
@@ -19,7 +19,10 @@ import {
resolveKuaishouEticketShopConfig,
type KuaishouEticketShopConfig,
} from '../platforms/kuaishou-eticket/source-config-service.js'
import { queryKuaishouEticketConsumeDetail } from '../platforms/kuaishou-eticket/consume-service.js'
import {
consumeKuaishouEticket,
queryKuaishouEticketConsumeDetail,
} from '../platforms/kuaishou-eticket/consume-service.js'
import { isKuaishouEticketMockTicketCode } from '../platforms/kuaishou-eticket/mock-ticket-service.js'
import {
dispatchKuaishouCloudFulfillmentTask,
@@ -59,12 +62,26 @@ export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: Js
})
}
const persistedTicketCode = String(flow.ticket.code || '').trim()
if (flow.consume.status === 'success') {
if (!persistedTicketCode || persistedTicketCode === ticketCode) {
return getKuaishouCloudClaimDetail(token)
}
throw createHttpError('当前领取链接已完成核销,不能更换核销码', {
statusCode: 409,
errorCode: 'claim_kuaishou_cloud_ticket_already_consumed',
})
}
const mockTicketCode = isKuaishouEticketMockTicketCode(ticketCode)
let shopId = String(
flow.consume.shopId || context.order.shop_id || (mockTicketCode ? 'mock' : ''),
).trim()
let shopName = String(flow.consume.shopName || context.order.shop_name || '').trim()
let detailResult
let shopCookie = ''
let consumeBaseUrl = ''
if (mockTicketCode) {
detailResult = await queryKuaishouEticketConsumeDetail({
@@ -82,6 +99,8 @@ export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: Js
detailResult = matched.detailResult
shopId = matched.shopConfig.shopId || shopId
shopName = matched.shopConfig.kshopName || shopName
shopCookie = matched.shopConfig.cookie
consumeBaseUrl = getKuaishouEticketSourceConfig().baseUrl
}
if (!detailResult.ok || detailResult.alreadyConsumed || !detailResult.detail) {
@@ -93,6 +112,22 @@ export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: Js
})
}
const consumePayload = {
baseUrl: consumeBaseUrl,
cookie: shopCookie,
eTicketId: detailResult.eTicketId || ticketCode,
oid: String(detailResult.detail.oid || '').trim(),
formToken: String(detailResult.detail.formToken || '').trim(),
num: Number(detailResult.detail.leftCount || 0) || 1,
}
const consumeResult = await consumeKuaishouEticket(consumePayload)
if (!consumeResult.consumed) {
throw createHttpError(consumeResult.errorMessage || '核销失败,请确认核销码状态后重试', {
statusCode: 409,
errorCode: 'claim_kuaishou_cloud_consume_failed',
})
}
const taskContext = parseTaskContext(context.task)
const nextContext = {
...taskContext,
@@ -114,7 +149,11 @@ export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: Js
},
consume: {
...flow.consume,
status: 'success',
shopId,
shopName,
consumedAt: now,
errorMessage: '',
},
},
}
@@ -136,31 +175,29 @@ export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: Js
})
} else {
const preparedFlow = normalizeKuaishouCloudFlow(nextContext.kuaishouCloudFulfillment)
if (preparedFlow.binding.prepareStatus !== 'ready' || !preparedFlow.binding.bindUrl) {
await prepareKuaishouCloudFulfillmentTask(
{
...context.task,
context_json: JSON.stringify(nextContext),
},
{
source: 'claim_page_ticket_verified',
actor: { source: 'claim_page' },
},
)
} else {
await updateTask(context.task.id, {
claim_token: context.claimToken.token,
claim_expires_at: context.claimToken.expired_at,
context_json: JSON.stringify(nextContext),
last_error: '',
updated_at: now,
})
const taskWithConsumedTicket = (await updateTask(context.task.id, {
claim_token: context.claimToken.token,
claim_expires_at: context.claimToken.expired_at,
context_json: JSON.stringify(nextContext),
claimed_at: context.task.claimed_at || now,
task_status: TASK_STATUS.WAITING_BINDING,
user_action_status: 'pending_claim',
last_error: '',
updated_at: now,
})) || {
...context.task,
context_json: JSON.stringify(nextContext),
claimed_at: context.task.claimed_at || now,
task_status: TASK_STATUS.WAITING_BINDING,
user_action_status: 'pending_claim',
last_error: '',
updated_at: now,
}
if (!context.task.claimed_at) {
await updateTask(context.task.id, {
claimed_at: now,
updated_at: now,
if (preparedFlow.binding.prepareStatus !== 'ready' || !preparedFlow.binding.bindUrl) {
await prepareKuaishouCloudFulfillmentTask(taskWithConsumedTicket, {
source: 'claim_page_ticket_verified',
actor: { source: 'claim_page' },
})
}
}
@@ -174,6 +211,23 @@ export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: Js
shopName,
goodsTitle: String(detailResult.goods?.itemTitle || '').trim(),
mock: mockTicketCode,
consumedAt: now,
consumeAlreadyCompleted: consumeResult.alreadyConsumed === true,
},
now,
)
await createTaskEvent(
context.task.id,
'kuaishou_cloud_consumed',
{
source: 'claim_page_ticket_submit',
ticketCodeMasked: maskCode(detailResult.eTicketId || ticketCode),
shopId,
shopName,
consumeStatus: 'success',
consumedAt: now,
mock: mockTicketCode,
},
now,
)