- 前后端接入 ESLint 10 扁平配置(typescript-eslint 类型感知检查 + react-hooks/react-refresh),新增 lint / lint:check / lint:fix 脚本并纳入 check 链路 - 清理全部 no-unused-vars 与 no-useless-assignment 警告,修复 floating promises、正则转义等问题 - 删除确认无引用的死代码(markKuaishouCloudBindUrlRefreshFailed、未使用 helper 等)
329 lines
9.6 KiB
TypeScript
329 lines
9.6 KiB
TypeScript
export const TASK_STATUS = {
|
||
PENDING_PAYMENT: 'pending_payment',
|
||
PAID: 'paid',
|
||
LINK_GENERATED: 'link_generated',
|
||
CLAIMED: 'claimed',
|
||
PENDING_BINDING_PREPARE: 'pending_binding_prepare',
|
||
WAITING_BINDING: 'waiting_binding',
|
||
ROLE_CONFIRMED: 'role_confirmed',
|
||
REDEEMING: 'redeeming',
|
||
DISPATCHED_PENDING_RETURN: 'dispatched_pending_return',
|
||
COMPLETED: 'completed',
|
||
REDEEMED: 'redeemed',
|
||
RETRY_PENDING: 'retry_pending',
|
||
MANUAL_REVIEW: 'manual_review',
|
||
FAILED: 'failed',
|
||
EXPIRED: 'expired',
|
||
CLOSED: 'closed',
|
||
} as const
|
||
|
||
export type KnownTaskStatus = (typeof TASK_STATUS)[keyof typeof TASK_STATUS]
|
||
export type TaskStatus = KnownTaskStatus | (string & {})
|
||
|
||
const TASK_TRANSITIONS: Record<KnownTaskStatus, readonly KnownTaskStatus[]> = {
|
||
[TASK_STATUS.PENDING_PAYMENT]: [
|
||
TASK_STATUS.PAID,
|
||
TASK_STATUS.PENDING_BINDING_PREPARE,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.PAID]: [
|
||
TASK_STATUS.LINK_GENERATED,
|
||
TASK_STATUS.PENDING_BINDING_PREPARE,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.LINK_GENERATED]: [
|
||
TASK_STATUS.CLAIMED,
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.CLAIMED]: [
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.PENDING_BINDING_PREPARE]: [
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.WAITING_BINDING]: [
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.REDEEMING,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.ROLE_CONFIRMED]: [
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.REDEEMING,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.REDEEMING]: [
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
],
|
||
[TASK_STATUS.DISPATCHED_PENDING_RETURN]: [
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
],
|
||
[TASK_STATUS.RETRY_PENDING]: [
|
||
TASK_STATUS.PENDING_BINDING_PREPARE,
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.REDEEMING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.MANUAL_REVIEW]: [
|
||
TASK_STATUS.PENDING_BINDING_PREPARE,
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.REDEEMING,
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.CLOSED,
|
||
],
|
||
[TASK_STATUS.FAILED]: [TASK_STATUS.RETRY_PENDING, TASK_STATUS.MANUAL_REVIEW, TASK_STATUS.CLOSED],
|
||
[TASK_STATUS.COMPLETED]: [],
|
||
[TASK_STATUS.REDEEMED]: [],
|
||
[TASK_STATUS.EXPIRED]: [],
|
||
[TASK_STATUS.CLOSED]: [],
|
||
}
|
||
|
||
const FINAL_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
])
|
||
|
||
const OPEN_91_FAILED_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.FAILED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.CLOSED,
|
||
])
|
||
|
||
const CLAIM_INACTIVE_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.FAILED,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
])
|
||
|
||
const PAID_PREPARATION_STABLE_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.LINK_GENERATED,
|
||
TASK_STATUS.CLAIMED,
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.REDEEMING,
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.EXPIRED,
|
||
TASK_STATUS.CLOSED,
|
||
])
|
||
|
||
const KUAISHOU_CLOUD_CLAIM_LINK_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.PENDING_BINDING_PREPARE,
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.FAILED,
|
||
])
|
||
|
||
const KUAISHOU_CLOUD_ROLE_CONFIRM_SETTLED_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.REDEEMING,
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
])
|
||
|
||
const KUAISHOU_CLOUD_REDEEM_SETTLED_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.REDEEMING,
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
])
|
||
|
||
const CLAIM_LINK_REGENERATABLE_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.LINK_GENERATED,
|
||
TASK_STATUS.CLAIMED,
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
])
|
||
|
||
const KUAISHOU_CLOUD_RESULT_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.FAILED,
|
||
])
|
||
|
||
const FULFILLMENT_COMPLETED_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.DISPATCHED_PENDING_RETURN,
|
||
TASK_STATUS.COMPLETED,
|
||
TASK_STATUS.REDEEMED,
|
||
])
|
||
|
||
const RETRYABLE_TASK_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.RETRY_PENDING,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
])
|
||
|
||
const KUAISHOU_CLOUD_PREPARABLE_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.PENDING_BINDING_PREPARE,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.FAILED,
|
||
])
|
||
|
||
const KUAISHOU_CLOUD_REBINDABLE_STATUSES = new Set<TaskStatus>([
|
||
TASK_STATUS.WAITING_BINDING,
|
||
TASK_STATUS.ROLE_CONFIRMED,
|
||
TASK_STATUS.MANUAL_REVIEW,
|
||
TASK_STATUS.RETRY_PENDING,
|
||
])
|
||
|
||
export function normalizeTaskStatus(value: unknown): TaskStatus {
|
||
return String(value || '').trim() as TaskStatus
|
||
}
|
||
|
||
export function canTaskTransition(from: unknown, to: unknown): boolean {
|
||
const current = normalizeTaskStatus(from) as KnownTaskStatus
|
||
const next = normalizeTaskStatus(to) as KnownTaskStatus
|
||
if (!current || !next || current === next) {
|
||
return Boolean(current && next)
|
||
}
|
||
|
||
return Boolean(TASK_TRANSITIONS[current]?.includes(next))
|
||
}
|
||
|
||
export function getTaskNextStatuses(status: unknown): readonly KnownTaskStatus[] {
|
||
return TASK_TRANSITIONS[normalizeTaskStatus(status) as KnownTaskStatus] || []
|
||
}
|
||
|
||
export function isTaskFinalStatus(status: unknown): boolean {
|
||
return FINAL_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function isOpen91FailedTaskStatus(status: unknown): boolean {
|
||
return OPEN_91_FAILED_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function isClaimInactiveTaskStatus(status: unknown): boolean {
|
||
return CLAIM_INACTIVE_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function isPaidPreparationStableStatus(status: unknown): boolean {
|
||
return PAID_PREPARATION_STABLE_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function shouldEnsureKuaishouCloudClaimLink(status: unknown): boolean {
|
||
return KUAISHOU_CLOUD_CLAIM_LINK_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function isKuaishouCloudRoleConfirmSettledStatus(status: unknown): boolean {
|
||
return KUAISHOU_CLOUD_ROLE_CONFIRM_SETTLED_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function isKuaishouCloudRedeemSettledStatus(status: unknown): boolean {
|
||
return KUAISHOU_CLOUD_REDEEM_SETTLED_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function canRedeemKuaishouCloudClaimStatus(status: unknown): boolean {
|
||
const normalized = normalizeTaskStatus(status)
|
||
// 允许 WAITING_BINDING:UID 匹配后可一键确认+兑换
|
||
return normalized === TASK_STATUS.ROLE_CONFIRMED || normalized === TASK_STATUS.WAITING_BINDING
|
||
}
|
||
|
||
export function canRegenerateClaimLinkStatus(status: unknown): boolean {
|
||
return CLAIM_LINK_REGENERATABLE_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function hasKuaishouCloudRedeemResultStatus(status: unknown): boolean {
|
||
return KUAISHOU_CLOUD_RESULT_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function isTaskFulfillmentCompletedStatus(status: unknown): boolean {
|
||
return FULFILLMENT_COMPLETED_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function canRetryTaskStatus(status: unknown): boolean {
|
||
return RETRYABLE_TASK_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function canMarkManualReviewTaskStatus(status: unknown): boolean {
|
||
const normalized = normalizeTaskStatus(status)
|
||
return normalized !== TASK_STATUS.MANUAL_REVIEW && !isTaskFinalStatus(normalized)
|
||
}
|
||
|
||
export function canCompleteManualDispatchTaskStatus(status: unknown): boolean {
|
||
return !isTaskFinalStatus(status)
|
||
}
|
||
|
||
export function canPrepareKuaishouCloudFulfillmentStatus(status: unknown): boolean {
|
||
return KUAISHOU_CLOUD_PREPARABLE_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function canRebindKuaishouCloudRoleStatus(status: unknown): boolean {
|
||
return KUAISHOU_CLOUD_REBINDABLE_STATUSES.has(normalizeTaskStatus(status))
|
||
}
|
||
|
||
export function canDispatchKuaishouCloudFulfillmentStatus(status: unknown): boolean {
|
||
return normalizeTaskStatus(status) === TASK_STATUS.WAITING_BINDING
|
||
}
|
||
|
||
export function canReturnKuaishouCloudFulfillmentStatus(status: unknown): boolean {
|
||
return normalizeTaskStatus(status) === TASK_STATUS.DISPATCHED_PENDING_RETURN
|
||
}
|
||
|
||
export function resolveInitialPaidTaskStatus(
|
||
profile:
|
||
| {
|
||
requires_claim?: boolean
|
||
executor_key?: unknown
|
||
}
|
||
| null
|
||
| undefined,
|
||
): TaskStatus {
|
||
if (profile?.requires_claim) {
|
||
return TASK_STATUS.PAID
|
||
}
|
||
|
||
if (String(profile?.executor_key || '').trim() === 'kuaishou_ct_assisted') {
|
||
return TASK_STATUS.PENDING_BINDING_PREPARE
|
||
}
|
||
|
||
if (String(profile?.executor_key || '').trim() === 'manual_dispatch') {
|
||
return TASK_STATUS.MANUAL_REVIEW
|
||
}
|
||
|
||
return TASK_STATUS.PAID
|
||
}
|