添加快手 Cloud 换绑角色功能

This commit is contained in:
yml
2026-05-30 11:23:52 +08:00
parent 681ff44cbc
commit 1c50569ea9
22 changed files with 1537 additions and 953 deletions
@@ -4,10 +4,7 @@ import {
parseTaskContext as parseTaskContextValue,
parseTaskState as parseTaskStateValue,
} from '../../utils/task-json.js'
import {
canRegenerateClaimLinkStatus,
isTaskFinalStatus,
} from '../../domain/task-status.js'
import { canRegenerateClaimLinkStatus, isTaskFinalStatus } from '../../domain/task-status.js'
import type { AdminViewerSessionInput } from '../../types/admin/read-inputs.js'
import type { OrderItemRow, TaskRow } from '../../types/repository/rows.js'
@@ -51,16 +48,19 @@ export function mapManualDispatchContext(
return {
outcome: String(record.outcome || '').trim(),
deliveryReference: String(record.deliveryReference || '').trim(),
deliveredCredential: viewerContext.canViewSensitiveTaskData ? String(record.deliveredCredential || '').trim() : '',
deliveredCredential: viewerContext.canViewSensitiveTaskData
? String(record.deliveredCredential || '').trim()
: '',
resultMessage: String(record.resultMessage || '').trim(),
completedAt: record.completedAt || null,
completedBy: record.completedBy && typeof record.completedBy === 'object'
? {
userId: Number(record.completedBy.userId || 0) || 0,
username: String(record.completedBy.username || '').trim(),
role: String(record.completedBy.role || '').trim(),
}
: null,
completedBy:
record.completedBy && typeof record.completedBy === 'object'
? {
userId: Number(record.completedBy.userId || 0) || 0,
username: String(record.completedBy.username || '').trim(),
role: String(record.completedBy.role || '').trim(),
}
: null,
}
}
@@ -78,7 +78,8 @@ export function mapKuaishouCloudFulfillmentContext(
const role = record.role && typeof record.role === 'object' ? record.role : {}
const purchase = record.purchase && typeof record.purchase === 'object' ? record.purchase : {}
const dispatch = record.dispatch && typeof record.dispatch === 'object' ? record.dispatch : {}
const returnNumber = record.returnNumber && typeof record.returnNumber === 'object' ? record.returnNumber : {}
const returnNumber =
record.returnNumber && typeof record.returnNumber === 'object' ? record.returnNumber : {}
const consume = record.consume && typeof record.consume === 'object' ? record.consume : {}
const cloudSourceKeys = Array.isArray(binding.cloudSourceKeys)
? binding.cloudSourceKeys.map((value: unknown) => String(value || '').trim()).filter(Boolean)
@@ -156,6 +157,7 @@ export function mapKuaishouCloudFulfillmentContext(
consumedAt: consume.consumedAt || null,
errorMessage: String(consume.errorMessage || '').trim(),
},
rebind: mapKuaishouCloudRebindContext(record.rebind),
notes: String(record.notes || '').trim(),
}
}
@@ -204,9 +206,13 @@ export function mapKuaishouCloudTaskStateProjection(
binding: {
prepareStatus: task.kuaishou_bind_url ? 'ready' : 'pending',
cloudSourceKeys: sourceKey ? [sourceKey] : [],
cloudSourceLabels: sourceKey ? [resolveCloudSourceLabel(sourceKey, options.cloudSourceLabelMap)] : [],
cloudSourceLabels: sourceKey
? [resolveCloudSourceLabel(sourceKey, options.cloudSourceLabelMap)]
: [],
resolvedSourceKey: sourceKey,
resolvedSourceLabel: sourceKey ? resolveCloudSourceLabel(sourceKey, options.cloudSourceLabelMap) : '',
resolvedSourceLabel: sourceKey
? resolveCloudSourceLabel(sourceKey, options.cloudSourceLabelMap)
: '',
skuId: 0,
skuName: '',
vnKey: '',
@@ -255,6 +261,10 @@ export function mapKuaishouCloudTaskStateProjection(
consumedAt: null,
errorMessage: '',
},
rebind: {
currentAttempt: 0,
history: [],
},
notes: '',
}
}
@@ -263,13 +273,67 @@ function resolveCloudSourceLabel(sourceKey: string, labelMap: CloudSourceLabelMa
const key = String(sourceKey || '').trim()
if (!key) return ''
const label = labelMap instanceof Map
? labelMap.get(key)
: labelMap?.[key]
const label = labelMap instanceof Map ? labelMap.get(key) : labelMap?.[key]
return String(label || key).trim() || key
}
function mapKuaishouCloudRebindContext(value: unknown): JsonRecord {
const record = value && typeof value === 'object' ? (value as JsonRecord) : {}
const history = Array.isArray(record.history) ? record.history : []
return {
currentAttempt: Math.max(0, Number(record.currentAttempt || 0) || 0),
history: history.map((item) => mapKuaishouCloudRebindHistoryItem(item)).filter(Boolean),
}
}
function mapKuaishouCloudRebindHistoryItem(value: unknown): JsonRecord | null {
if (!value || typeof value !== 'object') {
return null
}
const record = value as JsonRecord
const oldBinding =
record.oldBinding && typeof record.oldBinding === 'object'
? (record.oldBinding as JsonRecord)
: {}
const newBinding =
record.newBinding && typeof record.newBinding === 'object'
? (record.newBinding as JsonRecord)
: null
return {
attempt: Math.max(1, Number(record.attempt || 1) || 1),
source: String(record.source || '').trim(),
requestedAt: record.requestedAt || null,
requestedBy:
record.requestedBy && typeof record.requestedBy === 'object' ? record.requestedBy : null,
status: String(record.status || '').trim(),
errorMessage: String(record.errorMessage || '').trim(),
oldBinding: {
vnKey: String(oldBinding.vnKey || '').trim(),
vnId: Number(oldBinding.vnId || 0) || 0,
vnPhone: String(oldBinding.vnPhone || '').trim(),
bindUrl: String(oldBinding.bindUrl || '').trim(),
bindPreparedAt: oldBinding.bindPreparedAt || null,
bindExpiresAt: oldBinding.bindExpiresAt || null,
roleName: String(oldBinding.roleName || '').trim(),
roleId: String(oldBinding.roleId || '').trim(),
},
newBinding: newBinding
? {
vnKey: String(newBinding.vnKey || '').trim(),
vnId: Number(newBinding.vnId || 0) || 0,
vnPhone: String(newBinding.vnPhone || '').trim(),
bindUrl: String(newBinding.bindUrl || '').trim(),
bindPreparedAt: newBinding.bindPreparedAt || null,
bindExpiresAt: newBinding.bindExpiresAt || null,
}
: null,
}
}
export function mapRedeemResolutionContext(value: unknown): JsonRecord | null {
if (!value || typeof value !== 'object') {
return null
@@ -278,8 +342,8 @@ export function mapRedeemResolutionContext(value: unknown): JsonRecord | null {
const record = value as JsonRecord
const attempts = Array.isArray(record.attempts)
? record.attempts
.map((attempt) => mapRedeemResolutionAttempt(attempt))
.filter((attempt): attempt is RedeemResolutionAttempt => Boolean(attempt))
.map((attempt) => mapRedeemResolutionAttempt(attempt))
.filter((attempt): attempt is RedeemResolutionAttempt => Boolean(attempt))
: []
return {
@@ -296,7 +360,9 @@ export function getTaskPrimaryClaimTokenId(task: TaskLike | null | undefined): n
return Number.isFinite(value) && value > 0 ? value : null
}
export function createAdminViewerContext(session: AdminViewerSessionInput | null = null): AdminViewerContext {
export function createAdminViewerContext(
session: AdminViewerSessionInput | null = null,
): AdminViewerContext {
const role = normalizeAdminRole(session?.role)
return {
@@ -326,7 +392,11 @@ export function canViewerCloseTask(task: TaskLike, viewerContext: AdminViewerCon
return !isTaskFinalStatus(task?.task_status)
}
export function resolveDisplayShopName(provider: unknown, shopId: unknown, shopName: unknown): string {
export function resolveDisplayShopName(
provider: unknown,
shopId: unknown,
shopName: unknown,
): string {
const normalizedShopName = String(shopName || '').trim()
if (normalizedShopName) {
return normalizedShopName
@@ -367,8 +437,13 @@ export function resolveOrderItemTitle(item: Partial<OrderItemRow> | null | undef
])
}
export function resolveOrderItemDeliveryMode(tasks: TaskLike[] | null | undefined, orderItemId: number | string): string {
const task = (Array.isArray(tasks) ? tasks : []).find((item) => item.order_item_id === orderItemId)
export function resolveOrderItemDeliveryMode(
tasks: TaskLike[] | null | undefined,
orderItemId: number | string,
): string {
const task = (Array.isArray(tasks) ? tasks : []).find(
(item) => item.order_item_id === orderItemId,
)
if (!task) {
return ''
@@ -382,7 +457,12 @@ export function resolveOrderItemDeliveryMode(tasks: TaskLike[] | null | undefine
return 'kuaishou_cloud'
}
if (task.requires_claim || getTaskPrimaryClaimTokenId(task) || task.primary_claim_token || task.claim_token) {
if (
task.requires_claim ||
getTaskPrimaryClaimTokenId(task) ||
task.primary_claim_token ||
task.claim_token
) {
return 'claim_link'
}
@@ -393,7 +473,10 @@ export function isManualDispatchTask(task: TaskLike | null | undefined): boolean
return String(task?.executor_key || '').trim() === 'manual_dispatch'
}
export function canRegenerateClaimLinkForViewer(task: TaskLike, viewerContext: AdminViewerContext): boolean {
export function canRegenerateClaimLinkForViewer(
task: TaskLike,
viewerContext: AdminViewerContext,
): boolean {
if (isManualDispatchTask(task)) {
return false
}