客户领取页 ui与逻辑优化

This commit is contained in:
yml
2026-05-04 01:53:35 +08:00
parent dd842c165a
commit a914b7b828
15 changed files with 2124 additions and 349 deletions
@@ -11,6 +11,12 @@ import {
resolveKuaishouEticketShopConfig,
} from '../platforms/kuaishou-eticket/source-config-service.js'
import { queryKuaishouEticketConsumeDetail } from '../platforms/kuaishou-eticket/consume-service.js'
import {
dispatchKuaishouCloudFulfillmentTask,
normalizeKuaishouCloudFlow,
prepareKuaishouCloudFulfillmentTask,
refreshKuaishouCloudTaskRoleInfo,
} from '../fulfillment/kuaishou-cloud-task-service.js'
import { getClaimContext, getClaimDetail } from './claim-session-service.js'
const KUAISHOU_CLOUD_GUIDE_DIR = path.resolve(PROJECT_ROOT, '../../tems/imgs')
@@ -28,12 +34,6 @@ export async function verifyKuaishouCloudClaimTicket(token, payload = {}) {
}
const flow = normalizeKuaishouCloudFlow(parseTaskContext(context.task).kuaishouCloudFulfillment)
if (!flow.binding.bindUrl || flow.binding.prepareStatus !== 'ready') {
throw createHttpError('当前任务还没有准备好绑定资源,请联系客服稍后重试', {
statusCode: 409,
errorCode: 'claim_kuaishou_cloud_binding_not_ready',
})
}
const ticketCode = String(payload.ticketCode || payload.eTicketId || '').trim()
if (!ticketCode) {
@@ -96,7 +96,7 @@ export async function verifyKuaishouCloudClaimTicket(token, payload = {}) {
},
}
await updateTask(context.task.id, {
const updatedTask = await updateTask(context.task.id, {
claim_token: context.claimToken.token,
claim_expires_at: context.claimToken.expired_at,
claimed_at: context.task.claimed_at || now,
@@ -112,6 +112,14 @@ export async function verifyKuaishouCloudClaimTicket(token, payload = {}) {
goodsTitle: String(detailResult.goods?.itemTitle || '').trim(),
}, now)
const preparedFlow = normalizeKuaishouCloudFlow(nextContext.kuaishouCloudFulfillment)
if (preparedFlow.binding.prepareStatus !== 'ready' || !preparedFlow.binding.bindUrl) {
await prepareKuaishouCloudFulfillmentTask(updatedTask, {
source: 'claim_page_ticket_verified',
actor: { source: 'claim_page' },
})
}
return getClaimDetail(token, { includeQrImage: false })
}
@@ -135,47 +143,6 @@ export async function getKuaishouCloudClaimGuideAssetPath(filename) {
return filePath
}
function normalizeKuaishouCloudFlow(value) {
const source = value && typeof value === 'object' ? value : {}
const binding = source.binding && typeof source.binding === 'object' ? source.binding : {}
const consume = source.consume && typeof source.consume === 'object' ? source.consume : {}
const ticket = source.ticket && typeof source.ticket === 'object' ? source.ticket : {}
return {
...source,
ticket: {
code: String(ticket.code || '').trim(),
status: String(ticket.status || 'pending').trim() || 'pending',
capturedAt: ticket.capturedAt || null,
capturedBy: ticket.capturedBy || null,
verifiedAt: ticket.verifiedAt || null,
oid: String(ticket.oid || '').trim(),
formToken: String(ticket.formToken || '').trim(),
leftCount: Number(ticket.leftCount || 0) || 0,
goodsTitle: String(ticket.goodsTitle || '').trim(),
},
binding: {
prepareStatus: String(binding.prepareStatus || 'pending').trim() || 'pending',
cloudSourceKey: String(binding.cloudSourceKey || '').trim(),
skuId: Number(binding.skuId || 0) || 0,
skuName: String(binding.skuName || '').trim(),
vnKey: String(binding.vnKey || '').trim(),
vnId: Number(binding.vnId || 0) || 0,
vnPhone: String(binding.vnPhone || '').trim(),
bindUrl: String(binding.bindUrl || '').trim(),
bindPreparedAt: binding.bindPreparedAt || null,
},
consume: {
status: String(consume.status || 'pending').trim() || 'pending',
shopId: String(consume.shopId || '').trim(),
shopName: String(consume.shopName || '').trim(),
autoConsumeEnabled: consume.autoConsumeEnabled === true,
consumedAt: consume.consumedAt || null,
errorMessage: String(consume.errorMessage || '').trim(),
},
}
}
function parseTaskContext(task) {
const rawValue = task?.context_json
if (!rawValue) {
@@ -193,11 +160,84 @@ function parseTaskContext(task) {
}
}
function maskCode(value) {
const normalized = String(value || '').trim()
if (normalized.length <= 6) {
return normalized
export async function confirmKuaishouCloudClaimRole(token) {
const context = await getClaimContext(token)
const now = nowIso()
if (String(context.task.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
throw createHttpError('当前领取链接不是快手 Cloud 客户领取流程', {
statusCode: 409,
errorCode: 'claim_not_kuaishou_cloud',
})
}
return `${normalized.slice(0, 3)}***${normalized.slice(-3)}`
if (['role_confirmed', 'dispatched_pending_return', 'completed'].includes(String(context.task.task_status || '').trim())) {
return getClaimDetail(token, { includeQrImage: false })
}
const refreshed = await refreshKuaishouCloudTaskRoleInfo(context.task, {
source: 'claim_page_role_confirm',
actor: { source: 'claim_page' },
recordEvent: false,
})
const flow = normalizeKuaishouCloudFlow(parseTaskContext(refreshed.task).kuaishouCloudFulfillment)
if (flow.ticket.status !== 'verified') {
throw createHttpError('请先验证核销码', {
statusCode: 409,
errorCode: 'claim_kuaishou_cloud_ticket_not_verified',
})
}
if (!flow.binding.vnPhone || !flow.binding.roleName || !flow.binding.roleId) {
throw createHttpError('角色信息还未刷新到系统,请完成绑定后稍等片刻再试', {
statusCode: 409,
errorCode: 'claim_kuaishou_cloud_role_not_ready',
})
}
await updateTask(context.task.id, {
task_status: 'role_confirmed',
role_id: flow.binding.roleId,
role_name: flow.binding.roleName,
user_action_status: 'role_confirmed',
role_confirmed_at: now,
last_error: '',
updated_at: now,
})
await createTaskEvent(context.task.id, 'kuaishou_cloud_role_confirmed', {
vnPhone: flow.binding.vnPhone,
roleName: flow.binding.roleName,
roleId: flow.binding.roleId,
}, now)
return getClaimDetail(token, { includeQrImage: false })
}
export async function redeemKuaishouCloudClaim(token) {
const context = await getClaimContext(token)
const now = nowIso()
if (String(context.task.executor_key || '').trim() !== 'kuaishou_ct_assisted') {
throw createHttpError('当前领取链接不是快手 Cloud 客户领取流程', {
statusCode: 409,
errorCode: 'claim_not_kuaishou_cloud',
})
}
if (context.task.task_status !== 'role_confirmed') {
throw createHttpError('请先确认角色信息', {
statusCode: 409,
errorCode: 'claim_kuaishou_cloud_role_not_confirmed',
})
}
await dispatchKuaishouCloudFulfillmentTask(context.task, {
source: 'claim_page_redeem',
actor: { source: 'claim_page' },
autoFinalize: true,
})
return getClaimDetail(token, { includeQrImage: false })
}