feat(claim): 人工履约单领取页只显示「人工处理中,请等待客服」

未命中 AFFILIATE_DASH_SKU_MAPPING 的抖音单显式回落 manual_dispatch(人工),这类单没有
自动发货通道(无 claim token、无绑定二维码),但卡券 cert_link 仍指向 /h5/<订单号> 领取页;
原页面会让买家「输 UID」,提交后没有任何自动发货动作,属于误导买家。

- 后端 kuaishou-cloud-claim-context.ts:新增 MANUAL_FULFILLMENT_MESSAGE 与
  resolveManualFulfillmentMessage(executorKey)(manual_dispatch → 等待话术,其它执行器空串);
  三个 payload builder 统一输出 manualFulfillment / manualFulfillmentMessage
- 前端 claim-snapshot.ts:输出 isManualFulfillment / manualFulfillmentMessage,
  progressText 同步显示等待话术
- 前端 ClaimPage.tsx:在「渠道已下线」之后、「输 UID」之前插入人工单卡片(只读 + 刷新状态),
  人工单不会自动轮询(无 expectedUid → 不安排下一次轮询)
- types/claim.ts:补齐两个可选字段;话术只在后端维护一份,前端只做兜底

验证:后端 npm run check(701 单测)与前端 npm run check(格式/lint/类型/143 单测/构建)全绿
This commit is contained in:
yml2213
2026-10-13 13:53:00 +08:00
parent 319e082254
commit e8fbb28cf4
5 changed files with 79 additions and 0 deletions
@@ -1,4 +1,5 @@
import {
ClockCircleOutlined,
ExclamationCircleOutlined,
LoadingOutlined,
ReloadOutlined,
@@ -301,6 +302,25 @@ export default function ClaimPage() {
<ExclamationCircleOutlined className="claim-large-icon claim-icon-error" />
<p>{snapshot.channelOfflineMessage || '该履约渠道已下线,无法继续领取'}</p>
</Card>
) : snapshot.isManualFulfillment ? (
// 人工履约单(未命中自动发货映射 → manual_dispatch):没有自动发货通道,
// 买家输 UID 也没人自动发货,这里只如实告知「等客服」,不给任何操作入口。
<Card className="claim-content-card claim-state-card">
<ClockCircleOutlined className="claim-large-icon claim-icon-info" />
<h3 style={{ marginTop: 16 }}>
{snapshot.manualFulfillmentMessage || '人工处理中,请等待客服'}
</h3>
<p style={{ color: '#64748b' }}>
该订单由人工客服处理,本页无需任何操作;处理完成后刷新本页即可查看结果。
</p>
<Button
icon={<ReloadOutlined />}
style={{ marginTop: 16 }}
onClick={() => void loadDetail()}
>
刷新状态
</Button>
</Card>
) : snapshot.currentStep === 1 ? (
<ClaimUidStep
uidInput={uidInput}
@@ -21,6 +21,9 @@ export function createClaimSnapshot(detail: ClaimDetailData | null) {
const hasExpectedUid = Boolean(expectedUid || claimIdentity?.ready)
const channelOffline = Boolean(detail?.channelOffline)
const channelOfflineMessage = String(detail?.channelOfflineMessage || '').trim()
// 人工履约单(manual_dispatch):买家无需操作,页面只显示等待客服话术
const isManualFulfillment = Boolean(detail?.manualFulfillment)
const manualFulfillmentMessage = String(detail?.manualFulfillmentMessage || '').trim()
const isAffiliateDashFlow = detail?.flowType === 'affiliate_dash'
const affiliateDashExpectedUid = String(
expectedUid || affiliateDash?.expectedGameAccount || affiliateDash?.gameAccount || '',
@@ -67,6 +70,8 @@ export function createClaimSnapshot(detail: ClaimDetailData | null) {
const progressText = resolveProgressText({
channelOffline,
channelOfflineMessage,
isManualFulfillment,
manualFulfillmentMessage,
affiliateDash,
isAffiliateDashFlow,
hasExpectedUid,
@@ -102,6 +107,8 @@ export function createClaimSnapshot(detail: ClaimDetailData | null) {
hasExpectedUid,
channelOffline,
channelOfflineMessage,
isManualFulfillment,
manualFulfillmentMessage,
roleName: '',
roleId: '',
isFeifeiFlow: false,
@@ -165,6 +172,8 @@ function resolveCurrentStep(options: {
function resolveProgressText(options: {
channelOffline: boolean
channelOfflineMessage: string
isManualFulfillment: boolean
manualFulfillmentMessage: string
affiliateDash: ClaimAffiliateDashFlowInfo | null
isAffiliateDashFlow: boolean
hasExpectedUid: boolean
@@ -175,6 +184,10 @@ function resolveProgressText(options: {
if (options.channelOffline) {
return options.channelOfflineMessage || '该履约渠道已下线'
}
// 人工履约单:买家不需要填任何信息,直接显示等待客服
if (options.isManualFulfillment) {
return options.manualFulfillmentMessage || '人工处理中,请等待客服'
}
if (!options.hasExpectedUid) {
return '请填写游戏编号'
}
+7
View File
@@ -203,6 +203,13 @@ export interface ClaimDetailData {
| (string & {})
channelOffline?: boolean
channelOfflineMessage?: string
/**
* 人工履约单(未命中自动发货映射 → `manual_dispatch`):买家在领取页**无需也不能操作**,
* 页面只展示 `manualFulfillmentMessage`,不再出现「输 UID」步骤。
*/
manualFulfillment?: boolean
/** 人工履约等待话术(如「人工处理中,请等待客服」);非人工单为空串 */
manualFulfillmentMessage?: string
claimIdentity: ClaimIdentityInfo | null
task: ClaimTaskInfo
order: ClaimOrderInfo