diff --git a/apps/backend/src/services/admin/platform-config/cloudtentacles/index.ts b/apps/backend/src/services/admin/platform-config/cloudtentacles/index.ts index 59d9db9d..f1a001cd 100644 --- a/apps/backend/src/services/admin/platform-config/cloudtentacles/index.ts +++ b/apps/backend/src/services/admin/platform-config/cloudtentacles/index.ts @@ -450,7 +450,9 @@ export async function listAdminCloudtentaclesDeliveryRecords( }); const enrichedItems = recordItems .map((record) => { - const localMatch = findBestLocalTaskForRecord(record, localTasks); + const localMatch = platformOrderId + ? findStrictLocalTaskForOrderRecord(record, localTasks) + : findBestLocalTaskForRecord(record, localTasks); return { ...record, ...(skuImageByName.get(normalizeSkuName(record.name)) || { @@ -781,6 +783,44 @@ function findBestLocalTaskForRecord( return best && best.score >= 35 ? best : null; } +function findStrictLocalTaskForOrderRecord( + record: JsonObject, + tasks: LocalCloudtentaclesTask[] = [] +) { + let best: { task: LocalCloudtentaclesTask; score: number; confidence: string } | null = null; + + for (const task of tasks) { + if (!isSameDispatchedResource(record, task)) { + continue; + } + + const score = scoreLocalTaskRecordMatch(record, task); + if (score <= 0 || (best && score <= best.score)) { + continue; + } + + best = { + task, + score, + confidence: score >= 80 ? "high" : "medium", + }; + } + + return best; +} + +function isSameDispatchedResource(record: JsonObject, task: LocalCloudtentaclesTask) { + const recordVnId = normalizeNumber(record.virtualNumberId); + const recordPhone = normalizePhone(record.phone); + const taskPhone = normalizePhone(task.vnPhone); + + if (recordVnId > 0 && task.vnId > 0 && recordVnId === task.vnId) { + return true; + } + + return Boolean(recordPhone && taskPhone && recordPhone === taskPhone); +} + function scoreLocalTaskRecordMatch(record: JsonObject, task: LocalCloudtentaclesTask) { let score = 0; const recordVnId = normalizeNumber(record.virtualNumberId); diff --git a/apps/frontend/src/views/claim/kuaishou-cloud/components/ClaimBindingStep.vue b/apps/frontend/src/views/claim/kuaishou-cloud/components/ClaimBindingStep.vue index 91e8bbaf..2e96c409 100644 --- a/apps/frontend/src/views/claim/kuaishou-cloud/components/ClaimBindingStep.vue +++ b/apps/frontend/src/views/claim/kuaishou-cloud/components/ClaimBindingStep.vue @@ -199,39 +199,37 @@ defineEmits<{ } .role-panel { - display: flex; - flex-wrap: wrap; - gap: 8px 18px; - align-items: center; - padding: 12px 14px; - border: 1px solid #bfdbfe; - border-radius: 16px; - background: #eff6ff; + display: grid; + grid-template-columns: 1fr; + gap: 6px; + padding: 2px 0; } .role-panel.pending { - border-color: #e2e8f0; - background: #f8fafc; + opacity: 0.82; } .role-panel__item { min-width: 0; - display: flex; - flex: 1 1 0; - align-items: baseline; - gap: 8px; + display: grid; + grid-template-columns: 88px minmax(0, 1fr); + align-items: center; + gap: 12px; + padding: 0; } .role-panel__item span { - flex: 0 0 auto; color: #64748b; font-size: 13px; + line-height: 1.4; + white-space: nowrap; } .role-panel__item strong { min-width: 0; color: #0f172a; font-size: 17px; + line-height: 1.45; overflow-wrap: anywhere; } @@ -300,6 +298,19 @@ defineEmits<{ padding: 7px 10px; } + .role-panel__item { + grid-template-columns: 76px minmax(0, 1fr); + gap: 10px; + } + + .role-panel__item span { + font-size: 12px; + } + + .role-panel__item strong { + font-size: 16px; + } + .action-row { width: 100%; flex-direction: column;