From 0933b4514f01b706dc795d748bf175f0b4f0fdb3 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Wed, 5 Aug 2026 20:39:13 +0800 Subject: [PATCH] =?UTF-8?q?affiliate-dash=20=E7=BB=91=E5=AE=9A=20UID=20?= =?UTF-8?q?=E5=BC=BA=E5=88=B6=E6=A0=A1=E9=AA=8C:=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E4=B8=8E=E7=AC=AC=E4=B8=80=E6=AD=A5=E5=A1=AB?= =?UTF-8?q?=E5=86=99=20UID=20=E4=B8=8D=E4=B8=80=E8=87=B4=E6=97=B6=E7=A6=81?= =?UTF-8?q?=E6=AD=A2=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bind 时记录 expectedGameAccount(第一步 UID 权威值) - 轮询 bind-result 时本地对比 boundAccount 与 expectedGameAccount(去空白),不依赖平台 mismatch 字段 - submit 前实时拉 bind-result 二次校验,不一致 409 拒绝(前端无法绕过) - 前端:bindMismatch 时不显示提交发货按钮,提示核对后重新绑定 - 拉取失败不阻塞轮询与提交(平台侧提交仍会校验) --- .../claim/kuaishou-cloud-claim-service.ts | 44 ++++++++++++++++++- .../pages/claim/ClaimAffiliateDashSteps.tsx | 8 ++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/apps/backend/src/services/claim/kuaishou-cloud-claim-service.ts b/apps/backend/src/services/claim/kuaishou-cloud-claim-service.ts index 295c2231..834fefe2 100644 --- a/apps/backend/src/services/claim/kuaishou-cloud-claim-service.ts +++ b/apps/backend/src/services/claim/kuaishou-cloud-claim-service.ts @@ -415,6 +415,31 @@ export async function submitAffiliateDashClaim( const now = nowIso() const isMock = Boolean(flow.mock?.enabled) + + // 强制校验:绑定返回的游戏账号与第一步填写 UID 不一致时禁止提交(防止 uid 输错), + // 不依赖平台 mismatch 字段。拉取绑定结果失败时不阻塞(平台提交时仍会校验)。 + if (!isMock && flow.bindUuid) { + let mismatch = false + try { + const bindResult = await getAffiliateDashBindResult({ + orderNo: flow.orderNo, + bindUuid, + }) + const boundAccount = bindResult.gameAccount + mismatch = + Boolean(bindResult.mismatch) || + Boolean(boundAccount && normalizeUid(boundAccount) !== normalizeUid(gameAccount)) + } catch { + // 拉取失败:保持放行 + } + if (mismatch) { + throw createHttpError('绑定账号与填写 UID 不一致,请确认后重新绑定', { + statusCode: 409, + errorCode: 'affiliate_dash_bind_mismatch', + }) + } + } + const result = isMock ? { status: 'delivered', @@ -490,6 +515,7 @@ async function bindAffiliateDashClaimForTask(task: TaskRow, gameAccount: string) bindUrl: bindResult.bindUrl, qrUrl: bindResult.qrUrl, gameAccount, + expectedGameAccount: gameAccount, } const updatedTask = await updateTask(task.id, { @@ -534,12 +560,20 @@ async function refreshAffiliateDashBindState(task: TaskRow): Promise + ) : bindMismatch ? ( + ) : (