持久化 affiliate_dash roleName/gameChannel;免扫码授权时明确提示,有绑定链接时提交前仍可显示二维码。 Co-authored-by: Cursor <cursoragent@cursor.com>
249 lines
7.2 KiB
TypeScript
249 lines
7.2 KiB
TypeScript
import {
|
|
TASK_STATUS,
|
|
hasKuaishouCloudRedeemResultStatus,
|
|
isKuaishouCloudCompletedStatus,
|
|
normalizeTaskStatus,
|
|
} from '@/domain/task-status'
|
|
import type { ClaimAffiliateDashFlowInfo, ClaimDetailData } from '@/types/claim'
|
|
|
|
export type ResultVariant = 'success' | 'warning' | 'info'
|
|
export type ClaimSnapshot = ReturnType<typeof createClaimSnapshot>
|
|
|
|
export function createClaimSnapshot(detail: ClaimDetailData | null) {
|
|
const affiliateDash = detail?.affiliateDash || null
|
|
const order = detail?.order || null
|
|
const orderItem = detail?.orderItem || null
|
|
const product = detail?.product || null
|
|
const task = detail?.task || null
|
|
const claimIdentity = detail?.claimIdentity || null
|
|
|
|
const expectedUid = String(claimIdentity?.expectedUid || '').trim()
|
|
const hasExpectedUid = Boolean(expectedUid || claimIdentity?.ready)
|
|
const channelOffline = Boolean(detail?.channelOffline)
|
|
const channelOfflineMessage = String(detail?.channelOfflineMessage || '').trim()
|
|
const isAffiliateDashFlow = detail?.flowType === 'affiliate_dash'
|
|
const affiliateDashExpectedUid = String(
|
|
expectedUid || affiliateDash?.expectedGameAccount || affiliateDash?.gameAccount || '',
|
|
).trim()
|
|
const affiliateDashBoundAccount = String(affiliateDash?.boundAccount || '').trim()
|
|
const isAffiliateDashBound = Boolean(affiliateDash?.bound)
|
|
const isAffiliateDashUidMatched = Boolean(
|
|
isAffiliateDashBound &&
|
|
affiliateDashExpectedUid &&
|
|
affiliateDashBoundAccount &&
|
|
normalizeUid(affiliateDashExpectedUid) === normalizeUid(affiliateDashBoundAccount),
|
|
)
|
|
const isAffiliateDashBindMismatch = Boolean(
|
|
affiliateDash?.bindMismatch ||
|
|
(isAffiliateDashBound &&
|
|
affiliateDashExpectedUid &&
|
|
affiliateDashBoundAccount &&
|
|
!isAffiliateDashUidMatched),
|
|
)
|
|
const isAffiliateDashReadyToSubmit = Boolean(
|
|
isAffiliateDashBound && isAffiliateDashUidMatched && !isAffiliateDashBindMismatch,
|
|
)
|
|
const normalizedStatus = normalizeTaskStatus(task?.status)
|
|
const isRedeemFailed =
|
|
normalizedStatus === TASK_STATUS.MANUAL_REVIEW ||
|
|
normalizedStatus === TASK_STATUS.FAILED ||
|
|
normalizedStatus === TASK_STATUS.CLOSED ||
|
|
(isAffiliateDashFlow &&
|
|
['ship_failed', 'cancelled'].includes(String(affiliateDash?.orderStatus || '').trim()))
|
|
const isCompleted = isKuaishouCloudCompletedStatus(task?.status)
|
|
const hasRedeemResult =
|
|
hasKuaishouCloudRedeemResultStatus(task?.status) ||
|
|
(isAffiliateDashFlow &&
|
|
['delivered', 'ship_failed', 'cancelled'].includes(
|
|
String(affiliateDash?.orderStatus || '').trim(),
|
|
))
|
|
const currentStep = resolveCurrentStep({
|
|
channelOffline,
|
|
hasExpectedUid,
|
|
hasRedeemResult,
|
|
isAffiliateDashFlow,
|
|
isAffiliateDashReadyToSubmit,
|
|
})
|
|
const progressText = resolveProgressText({
|
|
channelOffline,
|
|
channelOfflineMessage,
|
|
affiliateDash,
|
|
isAffiliateDashFlow,
|
|
hasExpectedUid,
|
|
hasRedeemResult,
|
|
isAffiliateDashReadyToSubmit,
|
|
isAffiliateDashBindMismatch,
|
|
})
|
|
const resultTitle = resolveResultTitle({
|
|
isRedeemFailed,
|
|
isCompleted,
|
|
isAffiliateDashFlow,
|
|
affiliateDash,
|
|
})
|
|
const resultDescription = resolveResultDescription({
|
|
detail,
|
|
affiliateDash,
|
|
task,
|
|
isRedeemFailed,
|
|
isCompleted,
|
|
})
|
|
const resultVariant: ResultVariant = isRedeemFailed ? 'warning' : isCompleted ? 'success' : 'info'
|
|
|
|
return {
|
|
flow: null as null,
|
|
feifei: null as null,
|
|
affiliateDash,
|
|
order,
|
|
orderItem,
|
|
product,
|
|
task,
|
|
claimIdentity,
|
|
expectedUid,
|
|
hasExpectedUid,
|
|
channelOffline,
|
|
channelOfflineMessage,
|
|
roleName: '',
|
|
roleId: '',
|
|
isFeifeiFlow: false,
|
|
isAffiliateDashFlow,
|
|
affiliateDashExpectedUid,
|
|
affiliateDashBoundAccount,
|
|
isAffiliateDashBound,
|
|
isAffiliateDashUidMatched,
|
|
isAffiliateDashBindMismatch,
|
|
isAffiliateDashReadyToSubmit,
|
|
isBindUrlExpired: false,
|
|
isBindingPrepared: false,
|
|
isBindingPreparing: false,
|
|
isRoleReady: false,
|
|
isUidMatched: false,
|
|
confirmRoleDisabledReason: '',
|
|
isRoleConfirmed: false,
|
|
isDispatched: false,
|
|
isRedeemFailed,
|
|
isCompleted,
|
|
hasRedeemResult,
|
|
currentStep,
|
|
progressText,
|
|
resultTitle,
|
|
resultDescription,
|
|
resultVariant,
|
|
}
|
|
}
|
|
|
|
export function normalizeUid(value: unknown) {
|
|
return String(value || '')
|
|
.trim()
|
|
.replace(/\s+/g, '')
|
|
}
|
|
|
|
function resolveCurrentStep(options: {
|
|
channelOffline: boolean
|
|
hasExpectedUid: boolean
|
|
hasRedeemResult: boolean
|
|
isAffiliateDashFlow: boolean
|
|
isAffiliateDashReadyToSubmit: boolean
|
|
}) {
|
|
if (options.channelOffline) {
|
|
return 1
|
|
}
|
|
if (!options.hasExpectedUid) {
|
|
return 1
|
|
}
|
|
if (options.hasRedeemResult) {
|
|
return 4
|
|
}
|
|
if (options.isAffiliateDashFlow) {
|
|
if (!options.isAffiliateDashReadyToSubmit) {
|
|
return 2
|
|
}
|
|
return 3
|
|
}
|
|
return 2
|
|
}
|
|
|
|
function resolveProgressText(options: {
|
|
channelOffline: boolean
|
|
channelOfflineMessage: string
|
|
affiliateDash: ClaimAffiliateDashFlowInfo | null
|
|
isAffiliateDashFlow: boolean
|
|
hasExpectedUid: boolean
|
|
hasRedeemResult: boolean
|
|
isAffiliateDashReadyToSubmit: boolean
|
|
isAffiliateDashBindMismatch: boolean
|
|
}) {
|
|
if (options.channelOffline) {
|
|
return options.channelOfflineMessage || '该履约渠道已下线'
|
|
}
|
|
if (!options.hasExpectedUid) {
|
|
return '请填写游戏编号'
|
|
}
|
|
if (options.isAffiliateDashFlow) {
|
|
if (options.hasRedeemResult) {
|
|
return '发货结果已生成'
|
|
}
|
|
if (!options.affiliateDash?.bound) {
|
|
return options.affiliateDash?.bindUrl || options.affiliateDash?.qrUrl
|
|
? '请扫码绑定账号'
|
|
: '绑定链接生成中,请稍候'
|
|
}
|
|
if (options.isAffiliateDashBindMismatch) {
|
|
return '绑定 UID 不一致,请重新扫码'
|
|
}
|
|
if (!options.isAffiliateDashReadyToSubmit) {
|
|
return '绑定账号确认中,请稍候'
|
|
}
|
|
if (!(options.affiliateDash?.bindUrl || options.affiliateDash?.qrUrl)) {
|
|
return '账号已授权,请确认提交发货'
|
|
}
|
|
return '已绑定,请提交发货'
|
|
}
|
|
return '当前领取流程不可用'
|
|
}
|
|
|
|
function resolveResultTitle(options: {
|
|
isRedeemFailed: boolean
|
|
isCompleted: boolean
|
|
isAffiliateDashFlow: boolean
|
|
affiliateDash: ClaimAffiliateDashFlowInfo | null
|
|
}) {
|
|
if (options.isRedeemFailed) {
|
|
return '发货遇到问题'
|
|
}
|
|
if (options.isCompleted) {
|
|
return '兑换成功'
|
|
}
|
|
if (options.isAffiliateDashFlow && options.affiliateDash?.orderStatus === 'delivered') {
|
|
return '发货已完成'
|
|
}
|
|
return '结果已记录'
|
|
}
|
|
|
|
function resolveResultDescription(options: {
|
|
detail: ClaimDetailData | null
|
|
affiliateDash: ClaimAffiliateDashFlowInfo | null
|
|
task: ClaimDetailData['task'] | null
|
|
isRedeemFailed: boolean
|
|
isCompleted: boolean
|
|
}) {
|
|
if (options.isRedeemFailed) {
|
|
const message = String(
|
|
options.task?.lastError ||
|
|
options.affiliateDash?.failureReason ||
|
|
options.detail?.result?.resultMessage ||
|
|
'',
|
|
).trim()
|
|
return message || '当前流程需要客服处理,后续结果请以后台任务界面为准。'
|
|
}
|
|
|
|
if (options.isCompleted) {
|
|
return '当前兑换流程已经完成。'
|
|
}
|
|
|
|
if (options.affiliateDash) {
|
|
return '你的发货请求已经提交。后续结果会由系统保存在后台任务界面。'
|
|
}
|
|
|
|
return '你的兑换请求已经提交。后续结果会由系统保存在后台任务界面。'
|
|
}
|