From 71912ef5d0057fc3ef018d3a4f55a30dc5869ecf Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 12 Sep 2026 16:44:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(worker-platform):=20=E6=8E=A5=E5=8D=95?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E5=85=A8=E9=9D=A2=E6=94=B9=E7=94=A8=E5=86=85?= =?UTF-8?q?=E9=83=A8=E7=BB=9F=E4=B8=80=E5=B7=A5=E5=8D=95=E5=8F=B7=EF=BC=8C?= =?UTF-8?q?=E9=9A=90=E8=97=8F=E7=AC=AC=E4=B8=89=E6=96=B9=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E5=8D=95=E5=8F=B7=E9=98=B2=E6=B3=84=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增业务工单单号生成器 generateWorkOrderNo(),生成 WO+年月日+时分+随机数的统一内部单号(如 WO26091216358821); 2. 接单平台抢单大厅、订单列表、详情抽屉、模态弹窗及售后全面切换为展示 workOrderNo,彻底屏蔽拼多多/快手等第三方平台来源标识; 3. 打手资金明细补充关联内部工单号 relatedWorkOrderNo,避免打手在账单中识别原平台; 4. 管理后台工单面板升级为双单号清晰展示(高亮内部工单号 + 辅助可复制平台单号),兼顾打手对单与官方平台售后溯源。 --- .../src/repositories/worker-platform/types.ts | 1 + .../worker-platform/worker-wallet-repo.ts | 2 +- .../admin-mock-work-order-service.ts | 4 ++-- .../sync-worker-orders-service.ts | 4 ++-- .../worker-platform/worker-finance-mappers.ts | 1 + apps/backend/src/utils/random.ts | 14 +++++++++++ .../pages/admin/panels/WorkOrdersPanel.tsx | 24 +++++++++++++++++-- .../admin/panels/work-order-panel-utils.tsx | 4 ++-- .../src/pages/worker/WorkerAfterSalesPage.tsx | 4 ++-- .../src/pages/worker/WorkerHallPage.tsx | 4 ++-- .../pages/worker/WorkerOrderDetailDrawer.tsx | 2 +- .../src/pages/worker/WorkerProfileRecords.tsx | 4 ++-- .../src/pages/worker/worker-order-utils.tsx | 4 ++-- .../worker/worker-profile-view-utils.tsx | 4 ++-- apps/frontend/src/types/worker-platform.ts | 1 + 15 files changed, 57 insertions(+), 20 deletions(-) diff --git a/apps/backend/src/repositories/worker-platform/types.ts b/apps/backend/src/repositories/worker-platform/types.ts index ad82a106..b672e491 100644 --- a/apps/backend/src/repositories/worker-platform/types.ts +++ b/apps/backend/src/repositories/worker-platform/types.ts @@ -152,6 +152,7 @@ export type WorkerWalletLedgerRow = { note: string payload_json: string | Record created_at: string + related_work_order_no?: string | null related_platform_order_id?: string | null } diff --git a/apps/backend/src/repositories/worker-platform/worker-wallet-repo.ts b/apps/backend/src/repositories/worker-platform/worker-wallet-repo.ts index 420ec853..06fe2a0b 100644 --- a/apps/backend/src/repositories/worker-platform/worker-wallet-repo.ts +++ b/apps/backend/src/repositories/worker-platform/worker-wallet-repo.ts @@ -34,7 +34,7 @@ export async function listWorkerWalletLedgers({ const offset = (page - 1) * pageSize params.push(pageSize, offset) const itemsResult = await query( - `SELECT wwl.*, wo.platform_order_id AS related_platform_order_id + `SELECT wwl.*, wo.work_order_no AS related_work_order_no, wo.platform_order_id AS related_platform_order_id FROM worker_wallet_ledgers wwl LEFT JOIN work_orders wo ON wo.id = wwl.related_work_order_id ${whereClause} 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 cef3bbd5..1a48e5ec 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 @@ -12,7 +12,7 @@ import { } 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' +import { generateWorkOrderNo, randomId } from '../../utils/random.js' import { nowIso } from '../../utils/time.js' import { getKuaishouIndustrySourceConfig, @@ -103,7 +103,7 @@ export async function createAdminMockWorkOrder(payload: JsonObject = {}) { }, } const workOrder = await createWorkOrder({ - workOrderNo: randomId('WO'), + workOrderNo: generateWorkOrderNo(), platformOrderId, productName, categoryId, 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 e2bd8f2a..c28b1f66 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 @@ -17,7 +17,7 @@ import { } from '../../repositories/worker-platform/index.js' import type { JsonObject } from '../../types/json.js' import type { OrderItemRow, OrderRow } from '../../types/repository/rows.js' -import { randomId } from '../../utils/random.js' +import { generateWorkOrderNo, randomId } from '../../utils/random.js' import { nowIso } from '../../utils/time.js' import { logInfo, logWarn } from '../../utils/logger.js' import { safeParseJson } from '../admin/admin-query-utils.js' @@ -173,7 +173,7 @@ export async function syncWorkerOrdersForSourceOrder( const now = nowIso() const materialComplete = fields.every((field) => !field.required) const workOrder = await createWorkOrder({ - workOrderNo: randomId('WO'), + workOrderNo: generateWorkOrderNo(), productRuleId: Number(rule.id), orderId: Number(order.id), orderItemId: Number(item.id), diff --git a/apps/backend/src/services/worker-platform/worker-finance-mappers.ts b/apps/backend/src/services/worker-platform/worker-finance-mappers.ts index e560828a..7499c8a3 100644 --- a/apps/backend/src/services/worker-platform/worker-finance-mappers.ts +++ b/apps/backend/src/services/worker-platform/worker-finance-mappers.ts @@ -272,6 +272,7 @@ export function mapWalletLedger(ledger: WorkerWalletLedgerRow | null | undefined balanceAfter: Number(ledger.balance_after || 0), frozenAfter: Number(ledger.frozen_after || 0), relatedWorkOrderId: ledger.related_work_order_id ? Number(ledger.related_work_order_id) : null, + relatedWorkOrderNo: String(ledger.related_work_order_no || '').trim() || null, relatedPlatformOrderId: String(ledger.related_platform_order_id || '').trim() || null, auditStatus: ledger.audit_status || '', note: ledger.note || '', diff --git a/apps/backend/src/utils/random.ts b/apps/backend/src/utils/random.ts index 18781e8e..35ceb06c 100644 --- a/apps/backend/src/utils/random.ts +++ b/apps/backend/src/utils/random.ts @@ -7,3 +7,17 @@ export function randomToken(bytes = 24): string { export function randomId(prefix: string, bytes = 6): string { return `${prefix}${crypto.randomBytes(bytes).toString('hex')}` } + +/** + * Generate formatted internal work order number + * 生成系统标准内部工单号,如:WO26091216358821 (WO + 年月日 + 4位时分 + 4位随机) + */ +export function generateWorkOrderNo(date: Date = new Date()): string { + const yy = String(date.getFullYear()).slice(-2) + const mm = String(date.getMonth() + 1).padStart(2, "0") + const dd = String(date.getDate()).padStart(2, "0") + const hh = String(date.getHours()).padStart(2, "0") + const min = String(date.getMinutes()).padStart(2, "0") + const rand = Math.floor(1000 + Math.random() * 9000) + return `WO${yy}${mm}${dd}${hh}${min}${rand}` +} diff --git a/apps/frontend/src/pages/admin/panels/WorkOrdersPanel.tsx b/apps/frontend/src/pages/admin/panels/WorkOrdersPanel.tsx index 398c0d63..1d5e7e1a 100644 --- a/apps/frontend/src/pages/admin/panels/WorkOrdersPanel.tsx +++ b/apps/frontend/src/pages/admin/panels/WorkOrdersPanel.tsx @@ -942,6 +942,20 @@ export default function WorkOrdersPanel() { 创建时间 {formatAdminDateTime(row.createdAt)} + + 工单号: + + {row.workOrderNo || getDisplayOrderNo(row)} + + + {row.platformOrderId ? ( + + 平台号: + + {row.platformOrderId} + + + ) : null} {shopName || provider ? ( {provider ? `来源:${provider}` : ''} @@ -949,7 +963,6 @@ export default function WorkOrdersPanel() { {shopName ? `店铺:${shopName}` : ''} ) : null} - {getDisplayOrderNo(row)} ) }, @@ -1531,8 +1544,15 @@ export default function WorkOrdersPanel() {
+ + + {detailOrder.workOrderNo || '-'} + + - {getDisplayOrderNo(detailOrder)} + + {detailOrder.platformOrderId || '-'} + {detailOrder.orderId || '-'} diff --git a/apps/frontend/src/pages/admin/panels/work-order-panel-utils.tsx b/apps/frontend/src/pages/admin/panels/work-order-panel-utils.tsx index 9b17c58e..9acaa539 100644 --- a/apps/frontend/src/pages/admin/panels/work-order-panel-utils.tsx +++ b/apps/frontend/src/pages/admin/panels/work-order-panel-utils.tsx @@ -49,9 +49,9 @@ export function renderWorkOrderWorkers(order: WorkOrder) { } export function getDisplayOrderNo( - order: Pick | null | undefined, + order: Pick | null | undefined, ): string { - return String(order?.platformOrderId || '').trim() || '-' + return String(order?.workOrderNo || order?.platformOrderId || '').trim() || '-' } /** 用户付款金额(分);未知返回 null(不参与超价提示) */ diff --git a/apps/frontend/src/pages/worker/WorkerAfterSalesPage.tsx b/apps/frontend/src/pages/worker/WorkerAfterSalesPage.tsx index 8f787763..9484b94f 100644 --- a/apps/frontend/src/pages/worker/WorkerAfterSalesPage.tsx +++ b/apps/frontend/src/pages/worker/WorkerAfterSalesPage.tsx @@ -264,8 +264,8 @@ function WorkerAfterSalesItem({
- - {item.platformOrderId || item.workOrderNo || item.caseNo} + + 工单号 {item.workOrderNo || item.caseNo} | null | undefined): string { - return String(order?.platformOrderId || '').trim() || '-' +function getDisplayOrderNo(order: Pick | null | undefined): string { + return String(order?.workOrderNo || order?.platformOrderId || '').trim() || '-' } function formatMoney(value: number | undefined) { diff --git a/apps/frontend/src/pages/worker/WorkerOrderDetailDrawer.tsx b/apps/frontend/src/pages/worker/WorkerOrderDetailDrawer.tsx index 461dc0de..59dbef2e 100644 --- a/apps/frontend/src/pages/worker/WorkerOrderDetailDrawer.tsx +++ b/apps/frontend/src/pages/worker/WorkerOrderDetailDrawer.tsx @@ -96,7 +96,7 @@ export function WorkerOrderDetailDrawer({ {order.productName || '-'} {order.categoryName || '-'} - {getDisplayOrderNo(order)} + {getDisplayOrderNo(order)} {getOrderStatusDisplay(order).label} diff --git a/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx b/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx index 4061ef4f..0cf35b12 100644 --- a/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx +++ b/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx @@ -141,8 +141,8 @@ export function WorkerProfileMobileLedgerRecords({ {row.note ?
说明: {row.note}
: null} - {row.relatedPlatformOrderId ? ( -
订单号 {row.relatedPlatformOrderId}
+ {row.relatedWorkOrderNo || row.relatedPlatformOrderId ? ( +
工单号 {row.relatedWorkOrderNo || row.relatedPlatformOrderId}
) : null}
{formatDateTime(String(row.createdAt || ''))} diff --git a/apps/frontend/src/pages/worker/worker-order-utils.tsx b/apps/frontend/src/pages/worker/worker-order-utils.tsx index 48f9b64e..ff0d21a5 100644 --- a/apps/frontend/src/pages/worker/worker-order-utils.tsx +++ b/apps/frontend/src/pages/worker/worker-order-utils.tsx @@ -164,9 +164,9 @@ export function hasSubmittedAcceptance(order: WorkOrder) { } export function getDisplayOrderNo( - order: Pick | null | undefined, + order: Pick | null | undefined, ): string { - return String(order?.platformOrderId || '').trim() || '-' + return String(order?.workOrderNo || order?.platformOrderId || '').trim() || '-' } export function getRequirementFields(order: WorkOrder | null): CollectField[] { diff --git a/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx b/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx index e8864b5a..46e2ce8a 100644 --- a/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx +++ b/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx @@ -199,8 +199,8 @@ export const workerLedgerColumns: TableColumnsType = [ render: (_, row) => (
{row.note || '-'} - {row.relatedPlatformOrderId ? ( - 订单号 {row.relatedPlatformOrderId} + {row.relatedWorkOrderNo || row.relatedPlatformOrderId ? ( + 工单号 {row.relatedWorkOrderNo || row.relatedPlatformOrderId} ) : null}
), diff --git a/apps/frontend/src/types/worker-platform.ts b/apps/frontend/src/types/worker-platform.ts index 38503551..a0098f46 100644 --- a/apps/frontend/src/types/worker-platform.ts +++ b/apps/frontend/src/types/worker-platform.ts @@ -97,6 +97,7 @@ export type WorkerWalletLedger = { balanceAfter: number frozenAfter: number relatedWorkOrderId: number | null + relatedWorkOrderNo?: string | null relatedPlatformOrderId: string | null auditStatus: string note: string