From 260616b872c2ed5fbb7c22378419e5a5472cad49 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sun, 23 Aug 2026 10:38:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E5=8D=95=E8=AE=A2=E5=8D=95=E5=8F=B7?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E5=94=AF=E4=B8=80=E6=A0=A1=E9=AA=8C=E8=A6=86?= =?UTF-8?q?=E7=9B=96Mock=E5=88=9B=E5=BB=BA=E4=B8=8E=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E8=B7=A8=E8=AE=A2=E5=8D=95=E6=9F=A5=E9=87=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin-mock-work-order-service.ts | 18 +++++++++++++++++- .../sync-worker-orders-service.ts | 13 +++++++++++++ .../pages/admin/panels/WorkOrderPanelParts.tsx | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/backend/src/services/worker-platform/admin-mock-work-order-service.ts b/apps/backend/src/services/worker-platform/admin-mock-work-order-service.ts index 56054ce0..0398d772 100644 --- a/apps/backend/src/services/worker-platform/admin-mock-work-order-service.ts +++ b/apps/backend/src/services/worker-platform/admin-mock-work-order-service.ts @@ -3,7 +3,11 @@ import { normalizeWorkOrderAcceptanceMode, normalizeWorkOrderGiftCooldownHours, } from '../../domain/work-order-acceptance-mode.js' -import { createWorkOrder, createWorkOrderEvent } from '../../repositories/worker-platform/index.js' +import { + createWorkOrder, + createWorkOrderEvent, + listWorkOrdersByPlatformOrderId, +} from '../../repositories/worker-platform/index.js' import type { JsonObject } from '../../types/json.js' import { createHttpError } from '../../utils/http.js' import { randomId } from '../../utils/random.js' @@ -46,6 +50,18 @@ export async function createAdminMockWorkOrder(payload: JsonObject = {}) { const materialComplete = payload.materialComplete === true || payload.materialComplete === 'true' const fields = normalizeRequirementFields(payload.fields) const { platformOrderId, productName, shop } = input + // 订单号全局唯一:与自动同步的真实工单也不能撞号,否则打手按单号回填资料会命中多条。 + const existingOrders = await listWorkOrdersByPlatformOrderId(platformOrderId) + if (existingOrders.length > 0) { + const existingNo = String(existingOrders[0]?.work_order_no || '').trim() + throw createHttpError( + `该订单号已存在工单${existingNo ? `(${existingNo})` : ''},请更换订单号`, + { + statusCode: 409, + errorCode: 'mock_work_order_platform_order_exists', + }, + ) + } const material = { ...(materialComplete ? { diff --git a/apps/backend/src/services/worker-platform/sync-worker-orders-service.ts b/apps/backend/src/services/worker-platform/sync-worker-orders-service.ts index e0f26980..5799acd7 100644 --- a/apps/backend/src/services/worker-platform/sync-worker-orders-service.ts +++ b/apps/backend/src/services/worker-platform/sync-worker-orders-service.ts @@ -9,6 +9,7 @@ import { createWorkOrder, createWorkOrderEvent, getWorkOrderByOrderItemId, + listWorkOrdersByPlatformOrderId, listWorkProductRuleMappings, listWorkProductRules, type WorkOrderRow, @@ -88,6 +89,18 @@ export async function syncWorkerOrdersForSourceOrder( skipped.push({ orderItemId: Number(item.id), reason: 'already_exists' }) continue } + // 订单号跨订单唯一:同一订单的多个 SKU 件允许共享订单号(按件建单是既有设计), + // 但订单号已挂在其他订单下时跳过,避免自动同步产生撞号工单。 + const samePlatformOrders = await listWorkOrdersByPlatformOrderId(order.platform_order_id) + if ( + samePlatformOrders.some((existing) => { + const existingOrderId = Number(existing.order_id || 0) + return existingOrderId > 0 && existingOrderId !== Number(order.id) + }) + ) { + skipped.push({ orderItemId: Number(item.id), reason: 'platform_order_exists' }) + continue + } const fields = normalizeRequirementFields(safeParseJson(rule.requirement_json).fields) const skuQuantity = resolveSkuNameQuantity(item.sku_name) diff --git a/apps/frontend/src/pages/admin/panels/WorkOrderPanelParts.tsx b/apps/frontend/src/pages/admin/panels/WorkOrderPanelParts.tsx index 598b83af..609ac2d2 100644 --- a/apps/frontend/src/pages/admin/panels/WorkOrderPanelParts.tsx +++ b/apps/frontend/src/pages/admin/panels/WorkOrderPanelParts.tsx @@ -111,6 +111,7 @@ export function MockWorkOrderForm({ onCreated }: { onCreated: () => Promise