feat: complete dropship palletization workflow

This commit is contained in:
2026-09-08 17:24:48 +08:00
parent e9182e8cfe
commit 6c2d169798
61 changed files with 1242 additions and 1358 deletions
@@ -2860,6 +2860,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_carton_label (
cargo_item_no INT UNSIGNED NOT NULL COMMENT '订单货物明细序号快照',
cargo_name VARCHAR(255) NULL COMMENT '货物名称快照',
sku_code VARCHAR(128) NULL COMMENT '箱唛绑定的SKU快照;二维码内容不变',
units_per_carton INT UNSIGNED NULL COMMENT '每箱SKU数量快照;一件代发必须为正数',
detail_package_count INT UNSIGNED NOT NULL COMMENT '该订单货物明细箱数快照',
inbound_code VARCHAR(40) NOT NULL COMMENT '入仓码快照',
box_code VARCHAR(80) NOT NULL COMMENT '固定二维码内容:入仓码#总箱数-箱下标',
@@ -2877,7 +2878,6 @@ CREATE TABLE IF NOT EXISTS fl_inbound_carton_label (
PRIMARY KEY (id),
UNIQUE KEY uk_carton_label_box_code (tenant_id, box_code),
UNIQUE KEY uk_carton_label_index (tenant_id, inbound_id, label_version, carton_index),
KEY idx_carton_label_active (tenant_id, inbound_id, batch_status, label_version),
KEY idx_carton_label_detail (tenant_id, inbound_id, inbound_detail_id),
CONSTRAINT fk_carton_label_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order (id)
) ENGINE=InnoDB COMMENT='首次打印前冻结的实际箱号与订单货物明细映射';
@@ -5190,6 +5190,10 @@ CREATE TABLE IF NOT EXISTS fl_loading_plan_item (
product_image_url VARCHAR(1000) NULL COMMENT '产品图片访问地址快照',
package_count INT UNSIGNED NOT NULL COMMENT '本次装柜箱数',
product_quantity INT UNSIGNED NULL COMMENT '产品总数量',
unit_type VARCHAR(24) NOT NULL DEFAULT 'PACKAGE' COMMENT '分配单元:PACKAGE普通箱、SEALED_PALLET一件代发封托',
pallet_id BIGINT UNSIGNED NULL COMMENT '一件代发封托ID;普通箱为空',
pallet_no VARCHAR(32) NULL COMMENT '一件代发系统托盘码快照',
indivisible TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否为不可拆整托单元',
units_per_carton INT UNSIGNED NULL COMMENT '每箱产品数',
pallet_count INT UNSIGNED NULL COMMENT '托盘数',
gross_weight_kg DECIMAL(18,3) NULL COMMENT '本次装柜毛重kg',
@@ -5210,24 +5214,23 @@ CREATE TABLE IF NOT EXISTS fl_loading_plan_item (
removed_by_name VARCHAR(64) NULL COMMENT '推送前逻辑删除操作人名称快照',
removed_at DATETIME(3) NULL COMMENT '推送前逻辑删除时间',
deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '推送前逻辑删除标记;冻结后不可修改',
active_inbound_detail_id BIGINT UNSIGNED GENERATED ALWAYS AS (
CASE WHEN deleted = 0 THEN inbound_detail_id ELSE NULL END
) STORED COMMENT '未删除明细唯一锁;删除后返回NULL释放分配资格',
active_inbound_detail_id BIGINT UNSIGNED GENERATED ALWAYS AS (CASE WHEN deleted = 0 THEN inbound_detail_id ELSE NULL END) STORED COMMENT '未删除明细查询键;删除后返回NULL',
active_assignment_key VARCHAR(96) GENERATED ALWAYS AS (CASE WHEN deleted = 0 THEN CONCAT(CASE WHEN pallet_id IS NULL THEN 'D:0' ELSE CONCAT('P:', pallet_id) END, ':', inbound_detail_id) ELSE NULL END) STORED COMMENT '普通明细或已封托托盘明细的有效唯一锁',
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
created_by_name VARCHAR(64) NULL COMMENT '创建人名称快照',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID',
updated_by_name VARCHAR(64) NULL COMMENT '最后修改人名称快照',
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
COMMENT '装柜明细最后更新时间',
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '装柜明细最后更新时间',
version INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id),
UNIQUE KEY uk_loading_item_plan_detail (loading_plan_id, active_inbound_detail_id),
UNIQUE KEY uk_loading_item_plan_assignment (loading_plan_id, active_assignment_key),
KEY idx_loading_item_active_detail (account_id, active_inbound_detail_id),
KEY idx_loading_item_plan (loading_plan_id, deleted, load_sequence, id),
KEY idx_loading_item_account (account_id, created_at, id),
KEY idx_loading_item_inbound (account_id, inbound_id, deleted),
KEY idx_loading_item_candidate (account_id, inbound_id, inbound_detail_id, deleted),
KEY idx_loading_item_pallet (pallet_id, deleted),
KEY idx_loading_item_order (account_id, order_id, deleted),
CONSTRAINT fk_loading_item_plan FOREIGN KEY (loading_plan_id) REFERENCES fl_loading_plan (id),
CONSTRAINT chk_loading_item_account CHECK (account_id > 0),
@@ -5555,65 +5558,7 @@ CREATE TABLE IF NOT EXISTS fl_loading_pick_history (
CONSTRAINT fk_loading_pick_history_item FOREIGN KEY (pick_item_id) REFERENCES fl_loading_pick_item (id)
) ENGINE=InnoDB COMMENT='PDA拣货幂等和操作审计历史';
CREATE TABLE IF NOT EXISTS fl_loading_work_pallet (
id BIGINT UNSIGNED NOT NULL COMMENT '一件代发现场作业托盘ID',
pick_task_id BIGINT UNSIGNED NOT NULL COMMENT 'PDA装柜拣货任务ID',
loading_plan_id BIGINT UNSIGNED NOT NULL COMMENT '装柜计划ID快照',
warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '作业仓库ID',
warehouse_pallet_id BIGINT UNSIGNED NULL COMMENT '仓库实物托盘ID;未绑定仓库资源时为空',
pallet_code VARCHAR(64) NOT NULL COMMENT '现场托盘号',
open_operation_id VARCHAR(128) NOT NULL COMMENT '开托幂等操作号',
seal_operation_id VARCHAR(128) NULL COMMENT '封托幂等操作号',
pallet_status VARCHAR(16) NOT NULL DEFAULT 'OPEN' COMMENT '托盘状态:OPEN打托中、SEALED已封托、CANCELLED已取消',
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建操作人ID',
created_by_name VARCHAR(64) NULL COMMENT '创建操作人名称快照',
sealed_by BIGINT UNSIGNED NULL COMMENT '封托操作人ID',
sealed_by_name VARCHAR(64) NULL COMMENT '封托操作人名称快照',
sealed_at DATETIME(3) NULL COMMENT '封托时间',
version INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (id),
UNIQUE KEY uk_loading_work_pallet_code (pick_task_id, pallet_code),
UNIQUE KEY uk_loading_work_pallet_open_operation (open_operation_id),
UNIQUE KEY uk_loading_work_pallet_seal_operation (seal_operation_id),
KEY idx_loading_work_pallet_plan (loading_plan_id, pallet_status, id),
CONSTRAINT fk_loading_work_pallet_task FOREIGN KEY (pick_task_id) REFERENCES fl_loading_pick_task (id),
CONSTRAINT fk_loading_work_pallet_plan FOREIGN KEY (loading_plan_id) REFERENCES fl_loading_plan (id),
CONSTRAINT chk_loading_work_pallet_status CHECK (pallet_status IN ('OPEN','SEALED','CANCELLED'))
) ENGINE=InnoDB COMMENT='一件代发PDA现场实际托盘;允许同托盘承载多个客户订单';
CREATE TABLE IF NOT EXISTS fl_loading_work_pallet_carton (
id BIGINT UNSIGNED NOT NULL COMMENT '一件代发现场托盘箱唛绑定ID',
pick_task_id BIGINT UNSIGNED NOT NULL COMMENT 'PDA装柜拣货任务ID',
work_pallet_id BIGINT UNSIGNED NOT NULL COMMENT '现场作业托盘ID',
loading_plan_item_id BIGINT UNSIGNED NOT NULL COMMENT '装柜计划货物明细ID',
pick_item_id BIGINT UNSIGNED NOT NULL COMMENT 'PDA拣货明细ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '箱唛所属客户ID',
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '来源入仓单ID',
inbound_detail_id BIGINT UNSIGNED NOT NULL COMMENT '来源入仓货物明细ID',
carton_label_id BIGINT UNSIGNED NOT NULL COMMENT '稳定箱唛记录ID',
box_code VARCHAR(80) NOT NULL COMMENT '稳定箱唛箱码快照',
sku_code VARCHAR(128) NOT NULL COMMENT 'SKU编码快照',
units_per_carton INT UNSIGNED NULL COMMENT '每箱产品数量快照',
bound_by BIGINT UNSIGNED NOT NULL COMMENT '最后绑定操作人ID',
bound_by_name VARCHAR(64) NULL COMMENT '最后绑定操作人名称快照',
operation_id VARCHAR(128) NOT NULL COMMENT '最近一次绑定或移托幂等操作号',
version INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '首次上托时间',
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '最后移托时间',
PRIMARY KEY (id),
UNIQUE KEY uk_loading_work_carton_task_label (pick_task_id, carton_label_id),
UNIQUE KEY uk_loading_work_carton_operation (operation_id),
KEY idx_loading_work_carton_pallet (work_pallet_id, sku_code, id),
KEY idx_loading_work_carton_plan_item (loading_plan_item_id, id),
CONSTRAINT fk_loading_work_carton_task FOREIGN KEY (pick_task_id) REFERENCES fl_loading_pick_task (id),
CONSTRAINT fk_loading_work_carton_pallet FOREIGN KEY (work_pallet_id) REFERENCES fl_loading_work_pallet (id),
CONSTRAINT fk_loading_work_carton_plan_item FOREIGN KEY (loading_plan_item_id) REFERENCES fl_loading_plan_item (id),
CONSTRAINT fk_loading_work_carton_pick_item FOREIGN KEY (pick_item_id) REFERENCES fl_loading_pick_item (id),
CONSTRAINT fk_loading_work_carton_label FOREIGN KEY (carton_label_id) REFERENCES fl_inbound_carton_label (id),
CONSTRAINT chk_loading_work_carton_units CHECK (units_per_carton IS NULL OR units_per_carton > 0)
) ENGINE=InnoDB COMMENT='一件代发PDA逐箱上托事实;客户订单不合并但实际托盘可混托';
DROP PROCEDURE IF EXISTS repair_phase3_loading_pick_task_foreign_keys;
DELIMITER $$
@@ -6276,12 +6221,13 @@ BEGIN
'destination_warehouse_name', 'product_name_zh', 'product_name_en',
'product_image_file_id', 'pallet_count', 'net_weight_kg',
'dimensional_weight_kg', 'product_quantity', 'units_per_carton',
'fba_tracking_no', 'shipment_no', 'shipping_mark', 'version')) <> 17 THEN
'unit_type', 'pallet_id', 'pallet_no', 'indivisible', 'active_assignment_key',
'fba_tracking_no', 'shipment_no', 'shipping_mark', 'version')) <> 22 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:明细归属、清单快照或冻结字段缺失';
END IF;
IF (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_plan_item'
AND index_name = 'uk_loading_item_plan_detail' AND non_unique = 0) <> 2 THEN
AND index_name = 'uk_loading_item_plan_assignment' AND non_unique = 0) <> 2 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:计划内唯一活动明细锁缺失';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
@@ -17393,7 +17339,9 @@ CREATE TABLE IF NOT EXISTS fl_dropship_pallet_task (
warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '作业仓库ID',
task_status VARCHAR(24) NOT NULL COMMENT '任务状态:PENDING待领取、CLAIMED已领取、COMPLETED已完成',
total_cartons INT UNSIGNED NOT NULL COMMENT '测量确认总箱数',
counted_cartons INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已逐箱确认实收数量的箱数',
allocated_cartons INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已上托箱数',
discrepancy_cartons INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已确认差异箱数',
assignee_id BIGINT UNSIGNED NULL COMMENT '任务领取人ID',
assignee_name VARCHAR(64) NULL COMMENT '任务领取人姓名快照',
claimed_at DATETIME(3) NULL COMMENT '任务领取时间',
@@ -17406,7 +17354,7 @@ CREATE TABLE IF NOT EXISTS fl_dropship_pallet_task (
KEY idx_dropship_task_operator (task_status,assignee_id,warehouse_id,created_at),
CONSTRAINT fk_dropship_task_inbound FOREIGN KEY (inbound_id) REFERENCES fl_inbound_order(id),
CONSTRAINT chk_dropship_task_status CHECK (task_status IN ('PENDING','CLAIMED','COMPLETED')),
CONSTRAINT chk_dropship_task_cartons CHECK (allocated_cartons<=total_cartons)
CONSTRAINT chk_dropship_task_cartons CHECK (allocated_cartons<=counted_cartons AND counted_cartons<=total_cartons)
) ENGINE=InnoDB COMMENT='一件代发测量后PDA合托任务';
CREATE TABLE IF NOT EXISTS fl_dropship_pallet (
@@ -17415,8 +17363,8 @@ CREATE TABLE IF NOT EXISTS fl_dropship_pallet (
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户隔离键',
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '一件代发入仓单ID',
warehouse_id BIGINT UNSIGNED NOT NULL COMMENT '作业仓库ID',
pallet_no VARCHAR(32) NULL COMMENT '封托时生成的DP托盘号',
pallet_status VARCHAR(16) NOT NULL COMMENT '托盘状态:OPEN合托中、COMPLETED已封托',
pallet_no VARCHAR(32) NOT NULL COMMENT '现场扫描的系统DP托盘码',
pallet_status VARCHAR(16) NOT NULL COMMENT '托盘状态:OPEN组托中、SEALED已封托',
open_operation_id VARCHAR(128) NOT NULL COMMENT '创建托盘幂等操作ID',
seal_operation_id VARCHAR(128) NULL COMMENT '封托幂等操作ID',
created_by BIGINT UNSIGNED NOT NULL COMMENT '托盘创建人ID',
@@ -17433,7 +17381,7 @@ CREATE TABLE IF NOT EXISTS fl_dropship_pallet (
UNIQUE KEY uk_dropship_pallet_seal_op (seal_operation_id),
KEY idx_dropship_pallet_inbound (tenant_id,inbound_id,pallet_status),
CONSTRAINT fk_dropship_pallet_task FOREIGN KEY (task_id) REFERENCES fl_dropship_pallet_task(id),
CONSTRAINT chk_dropship_pallet_status CHECK (pallet_status IN ('OPEN','COMPLETED'))
CONSTRAINT chk_dropship_pallet_status CHECK (pallet_status IN ('OPEN','SEALED'))
) ENGINE=InnoDB COMMENT='一件代发合托形成的可打印托盘';
CALL queue_column_comment('baiyue_firstleg','fl_loading_cabinet_evidence','id','柜次证据记录ID');
@@ -17500,23 +17448,33 @@ DROP TEMPORARY TABLE IF EXISTS tmp_table_comment_target;
CREATE TABLE IF NOT EXISTS fl_dropship_pallet_carton (
id BIGINT UNSIGNED NOT NULL COMMENT '托盘箱明细ID',
task_id BIGINT UNSIGNED NOT NULL COMMENT '所属合托任务ID',
pallet_id BIGINT UNSIGNED NOT NULL COMMENT '所属合托托盘ID',
pallet_id BIGINT UNSIGNED NULL COMMENT '所属组托托盘ID;已清点待绑托时为空',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户隔离键',
inbound_id BIGINT UNSIGNED NOT NULL COMMENT '一件代发入仓单ID',
inbound_detail_id BIGINT UNSIGNED NOT NULL COMMENT '入仓货物明细ID',
carton_label_id BIGINT UNSIGNED NOT NULL COMMENT '稳定箱唛记录ID',
sku_code VARCHAR(128) NOT NULL COMMENT '箱唛冻结SKU编码',
cargo_name VARCHAR(255) NULL COMMENT '货物名称快照',
box_code VARCHAR(64) NOT NULL COMMENT '稳定箱码',
operation_id VARCHAR(128) NOT NULL COMMENT '上托幂等操作ID',
bound_by BIGINT UNSIGNED NOT NULL COMMENT '上托操作人ID',
box_code VARCHAR(80) NOT NULL COMMENT '稳定箱码',
expected_sku_quantity INT UNSIGNED NOT NULL COMMENT '箱唛冻结的应收SKU数量',
actual_sku_quantity INT UNSIGNED NOT NULL COMMENT 'PDA确认的实收SKU数量',
discrepancy_status VARCHAR(24) NOT NULL COMMENT '差异状态:MATCH或ACCEPTED_VARIANCE',
discrepancy_remark VARCHAR(500) NULL COMMENT '差异接受说明',
count_operation_id VARCHAR(128) NOT NULL COMMENT '逐箱清点幂等操作ID',
bind_operation_id VARCHAR(128) NULL COMMENT '批量绑托幂等操作ID',
last_operation_id VARCHAR(128) NOT NULL COMMENT '最后一次绑托或换托操作幂等号',
counted_by BIGINT UNSIGNED NOT NULL COMMENT '清点操作人ID',
counted_by_name VARCHAR(64) NULL COMMENT '清点操作人姓名快照',
counted_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '清点时间',
bound_by BIGINT UNSIGNED NULL COMMENT '上托操作人ID',
bound_by_name VARCHAR(64) NULL COMMENT '上托操作人姓名快照',
bound_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '上托时间',
bound_at DATETIME(3) NULL COMMENT '上托时间',
PRIMARY KEY (id),
UNIQUE KEY uk_dropship_carton_task_label (task_id,carton_label_id),
KEY idx_dropship_carton_pallet_sku (pallet_id,sku_code,id),
KEY idx_dropship_carton_inbound (tenant_id,inbound_id,pallet_id),
KEY idx_dropship_carton_operation (operation_id),
UNIQUE KEY uk_dropship_carton_count_operation (count_operation_id),
KEY idx_dropship_carton_bind_operation (task_id,bind_operation_id),
CONSTRAINT fk_dropship_carton_task FOREIGN KEY (task_id) REFERENCES fl_dropship_pallet_task(id),
CONSTRAINT fk_dropship_carton_pallet FOREIGN KEY (pallet_id) REFERENCES fl_dropship_pallet(id),
CONSTRAINT fk_dropship_carton_label FOREIGN KEY (carton_label_id) REFERENCES fl_inbound_carton_label(id)