feat(claim): 配合方案B支持买家纠错扫码UID自愈绑定,自建页面增加确认更换提示与快捷填入
This commit is contained in:
@@ -7,6 +7,8 @@ import {
|
||||
canReuseAffiliateDashBindSnapshot,
|
||||
isAffiliateDashBindSnapshotStale,
|
||||
isAffiliateDashSnapshotFresh,
|
||||
isRockAffiliateDashSku,
|
||||
shouldRefuseRockRebind,
|
||||
shouldRefreshAffiliateDashBindStateForSnapshot,
|
||||
} from './kuaishou-cloud-claim-service.js'
|
||||
|
||||
@@ -123,6 +125,81 @@ test('canReuseAffiliateDashBindSnapshot reuses verified matching bound account',
|
||||
)
|
||||
})
|
||||
|
||||
test('rock rebind is refused after mismatch or after a successful bind changes uid', () => {
|
||||
assert.equal(isRockAffiliateDashSku('rock_black_tshirt'), true)
|
||||
assert.equal(isRockAffiliateDashSku('top_black_elite_trainer'), false)
|
||||
assert.equal(
|
||||
shouldRefuseRockRebind({
|
||||
sku: 'rock_black_tshirt',
|
||||
bindUuid: 'bind-1',
|
||||
bindMismatch: true,
|
||||
}),
|
||||
true,
|
||||
)
|
||||
// 方案 B:买家改回扫码真实账号时放行自愈,改第三个账号时拒绝
|
||||
assert.equal(
|
||||
shouldRefuseRockRebind(
|
||||
{
|
||||
sku: 'rock_black_tshirt',
|
||||
bindUuid: 'bind-1',
|
||||
boundAccount: '3454648872',
|
||||
bindMismatch: true,
|
||||
},
|
||||
'3454648872',
|
||||
),
|
||||
false,
|
||||
)
|
||||
assert.equal(
|
||||
shouldRefuseRockRebind(
|
||||
{
|
||||
sku: 'rock_black_tshirt',
|
||||
bindUuid: 'bind-1',
|
||||
boundAccount: '3454648872',
|
||||
bindMismatch: true,
|
||||
},
|
||||
'9999999999',
|
||||
),
|
||||
true,
|
||||
)
|
||||
assert.equal(
|
||||
shouldRefuseRockRebind(
|
||||
{
|
||||
sku: 'rock_black_tshirt',
|
||||
bindUuid: 'bind-1',
|
||||
bound: true,
|
||||
boundAccount: '111',
|
||||
expectedGameAccount: '111',
|
||||
},
|
||||
'222',
|
||||
),
|
||||
true,
|
||||
)
|
||||
assert.equal(
|
||||
shouldRefuseRockRebind(
|
||||
{
|
||||
sku: 'rock_black_tshirt',
|
||||
bindUuid: 'bind-1',
|
||||
bound: false,
|
||||
bindMismatch: false,
|
||||
expectedGameAccount: '111',
|
||||
},
|
||||
'222',
|
||||
),
|
||||
false,
|
||||
)
|
||||
assert.equal(
|
||||
shouldRefuseRockRebind(
|
||||
{
|
||||
sku: 'skin_other',
|
||||
bindUuid: 'bind-1',
|
||||
bindMismatch: true,
|
||||
},
|
||||
'222',
|
||||
),
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
test('canReuseAffiliateDashBindSnapshot refuses mismatched bound account', () => {
|
||||
assert.equal(
|
||||
canReuseAffiliateDashBindSnapshot(
|
||||
|
||||
@@ -203,6 +203,13 @@ async function submitAffiliateDashClaimUid(
|
||||
updated_at: now,
|
||||
}
|
||||
|
||||
if (shouldRefuseRockRebind(flow, expectedUid)) {
|
||||
throw createHttpError(ROCK_CLAIM_TOKEN_LOCKED_MESSAGE, {
|
||||
statusCode: 409,
|
||||
errorCode: 'affiliate_dash_rock_token_locked',
|
||||
})
|
||||
}
|
||||
|
||||
if (!flow.orderNo) {
|
||||
await updateTask(context.task.id, {
|
||||
...baseTaskPatch,
|
||||
@@ -472,6 +479,40 @@ function resolveAffiliateDashRecordedBindUid(flow: AffiliateDashFlowSnapshot) {
|
||||
return normalizeUid(flow.expectedGameAccount || flow.gameAccount)
|
||||
}
|
||||
|
||||
export const ROCK_CLAIM_TOKEN_LOCKED_MESSAGE =
|
||||
'该订单提货链接已绑定失败,不能更换新的提货号,请联系客服处理'
|
||||
|
||||
export function isRockAffiliateDashSku(sku: unknown) {
|
||||
return String(sku || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.startsWith('rock_')
|
||||
}
|
||||
|
||||
/** Rock 一单一号:绑定失败禁止换第三方新号;但如果买家纠正为当前扫码角色的 UID,允许放行自愈。 */
|
||||
export function shouldRefuseRockRebind(flowLike: unknown, nextUid?: unknown) {
|
||||
const flow = normalizeAffiliateDashFlow(flowLike)
|
||||
if (!isRockAffiliateDashSku(flow.sku)) {
|
||||
return false
|
||||
}
|
||||
const next = normalizeUid(nextUid)
|
||||
const boundAccount = normalizeUid(flow.boundAccount)
|
||||
|
||||
// 方案 B:如果买家确认修改为当前扫码反查到的角色 UID,放行自愈
|
||||
if (flow.bindMismatch) {
|
||||
if (next && boundAccount && next === boundAccount) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if (!flow.bound) {
|
||||
return false
|
||||
}
|
||||
const current = normalizeUid(flow.boundAccount || flow.expectedGameAccount || flow.gameAccount)
|
||||
return Boolean(next && current && next !== current)
|
||||
}
|
||||
|
||||
export function isAffiliateDashBindSnapshotStale(flowLike: unknown, expectedUid: unknown): boolean {
|
||||
const flow = normalizeAffiliateDashFlow(flowLike)
|
||||
const expected = normalizeUid(expectedUid)
|
||||
@@ -577,6 +618,18 @@ async function refreshAffiliateDashBindState(task: TaskRow): Promise<TaskRow | n
|
||||
const expectedGameAccount = resolveAffiliateDashExpectedGameAccount(task, flow)
|
||||
if (isAffiliateDashBindSnapshotStale(flow, expectedGameAccount)) {
|
||||
const now = nowIso()
|
||||
if (shouldRefuseRockRebind(flow, expectedGameAccount)) {
|
||||
return (
|
||||
(await updateTask(task.id, {
|
||||
context_json: JSON.stringify({
|
||||
...taskContext,
|
||||
affiliateDash: flow,
|
||||
}),
|
||||
last_error: ROCK_CLAIM_TOKEN_LOCKED_MESSAGE,
|
||||
updated_at: now,
|
||||
})) || task
|
||||
)
|
||||
}
|
||||
return (
|
||||
(await updateTask(task.id, {
|
||||
context_json: JSON.stringify({
|
||||
|
||||
Reference in New Issue
Block a user