This commit is contained in:
2026-09-15 15:15:46 +08:00
parent 419950482f
commit cadc5a175e
28 changed files with 879 additions and 89 deletions
@@ -1497,7 +1497,10 @@ CREATE TABLE IF NOT EXISTS ll_warehouse_transfer_order (
estimated_arrival_at DATETIME(3) NOT NULL COMMENT '预计入仓时间', fba_shipment_no VARCHAR(128) NULL COMMENT '可选FBA货件编号',
tracking_no VARCHAR(255) NULL COMMENT '物流跟踪号', fba_box_nos VARCHAR(2000) NULL COMMENT 'FBA箱号集合', remark VARCHAR(1000) NULL COMMENT '备注',
need_relabel TINYINT NOT NULL DEFAULT 0 COMMENT '是否需要换标', relabel_application_id BIGINT NULL COMMENT '换标申请单ID', relabel_no VARCHAR(64) NULL COMMENT '换标申请单号',
status VARCHAR(32) NOT NULL DEFAULT 'PENDING_REVIEW' COMMENT '业务状态', idempotency_key VARCHAR(255) NOT NULL COMMENT '业务幂等键',
status VARCHAR(32) NOT NULL DEFAULT 'PENDING_REVIEW' COMMENT '业务状态',
review_decision VARCHAR(32) NULL COMMENT '审核决定', review_remark VARCHAR(1000) NULL COMMENT '审核备注或驳回原因',
reviewed_by VARCHAR(128) NULL COMMENT '审核人ID', reviewed_at DATETIME(3) NULL COMMENT '审核时间',
idempotency_key VARCHAR(255) NOT NULL COMMENT '业务幂等键',
allocation_idempotency_key VARCHAR(255) NULL COMMENT '库存分配幂等键',
allocation_request_hash CHAR(64) NULL COMMENT '库存分配请求哈希',
outbound_idempotency_key VARCHAR(255) NULL COMMENT '出库幂等键',
@@ -1534,6 +1537,8 @@ SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE tab
PREPARE transfer_relabel_completed_stmt FROM @ddl; EXECUTE transfer_relabel_completed_stmt; DEALLOCATE PREPARE transfer_relabel_completed_stmt;
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_warehouse_transfer_order' AND column_name='palletize_idempotency_key'), 'SELECT 1', 'ALTER TABLE ll_warehouse_transfer_order ADD COLUMN palletize_idempotency_key VARCHAR(255) NULL COMMENT ''PDA打托幂等键'', ADD COLUMN palletize_request_hash CHAR(64) NULL COMMENT ''PDA打托请求哈希'', ADD COLUMN confirmation_idempotency_key VARCHAR(255) NULL COMMENT ''客户测量确认幂等键'', ADD COLUMN confirmation_request_hash CHAR(64) NULL COMMENT ''客户测量确认请求哈希'', ADD COLUMN customer_confirmed_at DATETIME(3) NULL COMMENT ''客户确认测量时间'''));
PREPARE transfer_fulfillment_stmt FROM @ddl; EXECUTE transfer_fulfillment_stmt; DEALLOCATE PREPARE transfer_fulfillment_stmt;
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_warehouse_transfer_order' AND column_name='review_decision'), 'SELECT 1', 'ALTER TABLE ll_warehouse_transfer_order ADD COLUMN review_decision VARCHAR(32) NULL COMMENT ''审核决定'' AFTER status, ADD COLUMN review_remark VARCHAR(1000) NULL COMMENT ''审核备注或驳回原因'' AFTER review_decision, ADD COLUMN reviewed_by VARCHAR(128) NULL COMMENT ''审核人ID'' AFTER review_remark, ADD COLUMN reviewed_at DATETIME(3) NULL COMMENT ''审核时间'' AFTER reviewed_by'));
PREPARE transfer_review_fact_stmt FROM @ddl; EXECUTE transfer_review_fact_stmt; DEALLOCATE PREPARE transfer_review_fact_stmt;
CREATE TABLE IF NOT EXISTS ll_warehouse_transfer_source_order (
id BIGINT NOT NULL COMMENT '主键ID', transfer_order_id BIGINT NOT NULL COMMENT '转仓单ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户租户ID',
@@ -2468,14 +2468,14 @@ components:
remark: { type: string, nullable: true, maxLength: 1000 }
RelabelCreate:
type: object
required: [customerOrderNo, labelDeadline, contactName, contactPhone, chargeAmount, idempotencyKey, items]
required: [customerOrderNo, labelDeadline, contactName, contactPhone, idempotencyKey, items]
properties:
customerOrderNo: { type: string, maxLength: 128 }
overseasWarehouseId: { type: string, nullable: true, maxLength: 128, description: 统一目的海外仓;明细未填写目的仓时使用 }
labelDeadline: { type: string, format: date-time }
contactName: { type: string, maxLength: 128 }
contactPhone: { type: string, maxLength: 64 }
chargeAmount: { type: number, minimum: 0.01, description: 本次贴标费用(CNY) }
chargeAmount: { type: number, nullable: true, minimum: 0.01, description: 本次贴标费用(CNY);未传时不冻结或结算资金 }
remark: { type: string, nullable: true, maxLength: 1000 }
idempotencyKey: { type: string, maxLength: 255 }
deliveryMethod: { type: string, nullable: true, enum: [TRUCK, EXPRESS, TRUCK_PICKUP, EXPRESS_PICKUP, PICKUP], description: 只换箱唛或SKU与箱唛同时换时必填;只换SKU时不传 }
@@ -227,15 +227,27 @@ paths:
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
requestBody: { required: true, content: { multipart/form-data: { schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } } } }
responses: { '200': { description: OVERSEAS_RELABEL_PHOTO文件元数据, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelPhotoResponse' } } } } }
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/photos/files/{fileId}/download:
get:
summary: 读取当前操作人处理中任务的已上传照片,用于缩略图和大图预览
description: 校验 Token 绑定仓、任务认领人和文件的客户及任务归属;移除和重拍只替换待提交文件引用,不删除历史文件。
parameters:
- { name: relabelNo, in: path, required: true, schema: { type: string } }
- { name: fileId, in: path, required: true, schema: { type: integer, format: int64 } }
responses:
'200': { description: 作业照片内容, content: { 'image/*': { schema: { type: string, format: binary } } } }
'404': { description: 照片不属于当前任务或仓库 }
'409': { description: 当前操作人未认领任务或任务不在处理中 }
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/complete:
post:
summary: 提交现场任务等待复核,不提前完成申请
summary: 提交现场任务到复核池并直接等待客户确认
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelComplete' } } } }
responses: { '200': { description: WAIT_REVIEW任务, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelDetailResponse' } } } }, '409': { description: 箱数未核平、照片或版本冲突 } }
/api/pda/v1/last-leg/relabel-tasks/{relabelNo}/review:
post:
summary: 现场复核;APPROVE才完成既有换标申请,REWORK退回处理
summary: 已停用;客户确认完成复核,退回重贴由平台执行
deprecated: true
parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelReview' } } } }
responses: { '200': { description: COMPLETED或PROCESSING任务, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelDetailResponse' } } } }, '409': { description: 状态或版本冲突 } }
@@ -450,13 +462,14 @@ components:
occurredAt: { type: string, format: date-time }
RelabelCandidate:
type: object
required: [relabelNo, applicationStatus, taskStatus, itemCount, expectedPackages, relabelledPackages, skippedPackages, exceptionPackages, version, claimedByCurrentOperator]
required: [relabelNo, applicationStatus, taskStatus, operationType, itemCount, expectedPackages, relabelledPackages, skippedPackages, exceptionPackages, version, claimedByCurrentOperator]
properties:
relabelNo: { type: string }
customerOrderNo: { type: string, nullable: true }
labelDeadline: { type: string, format: date-time, nullable: true }
applicationStatus: { type: string }
taskStatus: { type: string }
operationType: { type: string, enum: [SKU_LABEL, CARTON_LABEL, CARTON_AND_SKU] }
itemCount: { type: integer }
expectedPackages: { type: integer }
relabelledPackages: { type: integer }
@@ -466,7 +479,7 @@ components:
claimedByCurrentOperator: { type: boolean }
RelabelDetail:
type: object
required: [relabelNo, applicationStatus, taskStatus, expectedPackages, relabelledPackages, skippedPackages, exceptionPackages, version, completionPhotoFileIds, items, unitFacts, history]
required: [relabelNo, applicationStatus, operationType, taskStatus, expectedPackages, relabelledPackages, skippedPackages, exceptionPackages, version, completionPhotoFileIds, items, unitFacts, history]
properties:
relabelNo: { type: string }
customerOrderNo: { type: string, nullable: true }
@@ -474,6 +487,7 @@ components:
contactName: { type: string, nullable: true }
contactPhone: { type: string, nullable: true }
applicationStatus: { type: string }
operationType: { type: string, enum: [SKU_LABEL, CARTON_LABEL, CARTON_AND_SKU] }
taskStatus: { type: string }
expectedPackages: { type: integer }
relabelledPackages: { type: integer }
@@ -513,6 +527,8 @@ components:
relabelledPackages: { type: integer }
skippedPackages: { type: integer }
exceptionPackages: { type: integer }
cartonProcessedPackages: { type: integer, description: 本轮箱唛作业已完成箱数,混合单独立计数 }
skuProcessedPackages: { type: integer, description: 本轮SKU作业已完成箱数,两项均完成才增加整箱已换标数 }
RelabelSkuItem:
type: object
required: [skuCode, newSkuCode, quantity]
@@ -723,8 +739,18 @@ components:
required: [itemId, oldLabel, newLabel, expectedVersion, idempotencyKey]
properties:
itemId: { type: string, pattern: '^[0-9]+$' }
oldLabel: { type: string, maxLength: 255 }
newLabel: { type: string, maxLength: 255 }
oldLabel: { type: string, maxLength: 255, description: 当前箱的仓库唛头,用于逐箱防重复 }
newLabel: { type: string, maxLength: 255, description: 新FBA箱唛,SKU-only不得提交SKU到此字段 }
skuVerifications:
type: array
description: SKU及组合换标必须提交该箱全部旧新SKU和件数核对结果
items:
type: object
required: [skuCode, newSkuCode, quantity]
properties:
skuCode: { type: string }
newSkuCode: { type: string }
quantity: { type: integer, minimum: 1 }
expectedVersion: { type: integer, minimum: 0 }
idempotencyKey: { type: string, maxLength: 255 }
RelabelSkip: