优化快手 Cloud 主链路状态机
This commit is contained in:
@@ -6,10 +6,11 @@ import { createHttpError } from '../../utils/http.js'
|
||||
import { formatFenToAmount, normalizeFen } from '../../utils/money.js'
|
||||
import { parseTaskContext as parseTaskContextValue } from '../../utils/task-json.js'
|
||||
import { nowIso } from '../../utils/time.js'
|
||||
import { TASK_STATUS, isTaskFinalStatus } from '../../domain/task-status.js'
|
||||
import { buildClaimUrl } from './claim-service.js'
|
||||
import type { ClaimTokenRow, OrderItemRow, OrderRow, TaskRow } from '../../types/repository/rows.js'
|
||||
|
||||
export const CLAIM_TERMINAL_STATUSES = new Set(['expired', 'closed'])
|
||||
export const CLAIM_TERMINAL_STATUSES = new Set([TASK_STATUS.EXPIRED, TASK_STATUS.CLOSED])
|
||||
export const KUAISHOU_CLOUD_CLAIM_GUIDE_BASE_PATH = '/kuaishou-cloud-guide'
|
||||
|
||||
type JsonObject = Record<string, any>
|
||||
@@ -410,16 +411,16 @@ function isClaimPlaceholderSkuName(value: string) {
|
||||
async function expireClaimContext(claimToken: ClaimTokenRow, task: TaskRow) {
|
||||
const now = nowIso()
|
||||
const nextClaimToken = await updateClaimToken(claimToken.id, {
|
||||
status: 'expired',
|
||||
status: TASK_STATUS.EXPIRED,
|
||||
updated_at: now,
|
||||
})
|
||||
|
||||
let nextTask = task
|
||||
|
||||
if (!CLAIM_TERMINAL_STATUSES.has(String(task.task_status || '')) && task.task_status !== 'redeemed') {
|
||||
if (!isTaskFinalStatus(task.task_status)) {
|
||||
nextTask = await updateTask(task.id, {
|
||||
task_status: 'expired',
|
||||
user_action_status: 'expired',
|
||||
task_status: TASK_STATUS.EXPIRED,
|
||||
user_action_status: TASK_STATUS.EXPIRED,
|
||||
last_error: '领取链接已过期',
|
||||
updated_at: now,
|
||||
}) || task
|
||||
|
||||
@@ -6,6 +6,13 @@ import { createTaskEvent } from '../../repositories/task-event-repo.js'
|
||||
import { getTaskById, updateTask, updateTaskStatusIfCurrent } from '../../repositories/task-repo.js'
|
||||
import { createHttpError } from '../../utils/http.js'
|
||||
import { addHours, nowIso } from '../../utils/time.js'
|
||||
import {
|
||||
TASK_STATUS,
|
||||
canRedeemKuaishouCloudClaimStatus,
|
||||
isKuaishouCloudRedeemSettledStatus,
|
||||
isKuaishouCloudRoleConfirmSettledStatus,
|
||||
normalizeTaskStatus,
|
||||
} from '../../domain/task-status.js'
|
||||
import {
|
||||
getKuaishouEticketSourceConfig,
|
||||
listKuaishouEticketShopConfigs,
|
||||
@@ -119,7 +126,7 @@ export async function verifyKuaishouCloudClaimTicket(token: unknown, payload: Js
|
||||
kuaishouCloudFulfillment: mockFlow,
|
||||
}),
|
||||
claimed_at: context.task.claimed_at || now,
|
||||
task_status: 'waiting_binding',
|
||||
task_status: TASK_STATUS.WAITING_BINDING,
|
||||
user_action_status: 'pending_claim',
|
||||
last_error: '',
|
||||
updated_at: now,
|
||||
@@ -357,7 +364,7 @@ export async function confirmKuaishouCloudClaimRole(token: unknown) {
|
||||
})
|
||||
}
|
||||
|
||||
if (['role_confirmed', 'redeeming', 'dispatched_pending_return', 'completed', 'manual_review'].includes(String(context.task.task_status || '').trim())) {
|
||||
if (isKuaishouCloudRoleConfirmSettledStatus(context.task.task_status)) {
|
||||
return getKuaishouCloudClaimDetail(token)
|
||||
}
|
||||
|
||||
@@ -388,10 +395,10 @@ export async function confirmKuaishouCloudClaimRole(token: unknown) {
|
||||
}
|
||||
|
||||
await updateTask(context.task.id, {
|
||||
task_status: 'role_confirmed',
|
||||
task_status: TASK_STATUS.ROLE_CONFIRMED,
|
||||
role_id: flow.binding.roleId,
|
||||
role_name: flow.binding.roleName,
|
||||
user_action_status: 'role_confirmed',
|
||||
user_action_status: TASK_STATUS.ROLE_CONFIRMED,
|
||||
role_confirmed_at: now,
|
||||
last_error: '',
|
||||
updated_at: now,
|
||||
@@ -417,20 +424,20 @@ export async function redeemKuaishouCloudClaim(token: unknown) {
|
||||
})
|
||||
}
|
||||
|
||||
const currentStatus = String(context.task.task_status || '').trim()
|
||||
if (['redeeming', 'dispatched_pending_return', 'completed', 'manual_review'].includes(currentStatus)) {
|
||||
const currentStatus = normalizeTaskStatus(context.task.task_status)
|
||||
if (isKuaishouCloudRedeemSettledStatus(currentStatus)) {
|
||||
return getKuaishouCloudClaimDetail(token)
|
||||
}
|
||||
|
||||
if (currentStatus !== 'role_confirmed') {
|
||||
if (!canRedeemKuaishouCloudClaimStatus(currentStatus)) {
|
||||
throw createHttpError('请先确认角色信息', {
|
||||
statusCode: 409,
|
||||
errorCode: 'claim_kuaishou_cloud_role_not_confirmed',
|
||||
})
|
||||
}
|
||||
|
||||
const lockedTask = await updateTaskStatusIfCurrent(context.task.id, 'role_confirmed', {
|
||||
task_status: 'redeeming',
|
||||
const lockedTask = await updateTaskStatusIfCurrent(context.task.id, TASK_STATUS.ROLE_CONFIRMED, {
|
||||
task_status: TASK_STATUS.REDEEMING,
|
||||
user_action_status: 'not_required',
|
||||
last_error: '',
|
||||
updated_at: now,
|
||||
@@ -453,13 +460,13 @@ export async function redeemKuaishouCloudClaim(token: unknown) {
|
||||
})
|
||||
} catch (error) {
|
||||
const latestTask = await getTaskById(lockedTask.id)
|
||||
if (latestTask && String(latestTask.task_status || '').trim() !== 'redeeming') {
|
||||
if (latestTask && normalizeTaskStatus(latestTask.task_status) !== TASK_STATUS.REDEEMING) {
|
||||
return getKuaishouCloudClaimDetail(token)
|
||||
}
|
||||
|
||||
const message = error instanceof Error ? error.message : '兑换请求提交失败,请联系客服处理'
|
||||
await updateTask(lockedTask.id, {
|
||||
task_status: 'manual_review',
|
||||
task_status: TASK_STATUS.MANUAL_REVIEW,
|
||||
user_action_status: 'not_required',
|
||||
last_error: message,
|
||||
result_code: 'kuaishou_cloud_redeem_failed',
|
||||
@@ -569,7 +576,7 @@ async function completeMockKuaishouCloudClaimTask(task: TaskRow, timestamp: stri
|
||||
}
|
||||
|
||||
await updateTask(task.id, {
|
||||
task_status: 'completed',
|
||||
task_status: TASK_STATUS.COMPLETED,
|
||||
delivery_status: 'success',
|
||||
result_code: 'mock_success',
|
||||
result_message: '开发 mock 已模拟兑换成功',
|
||||
|
||||
Reference in New Issue
Block a user