From eeb087e453b04f7f9b654de30c7f60e14697b7a8 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Tue, 8 Sep 2026 00:11:31 +0800 Subject: [PATCH] fix: make terminal drayage migration restartable --- deploy/sql/头程数据库统一增量-MySQL8.sql | 78 ++++++++++++++----- .../TerminalDrayageSqlContractTest.java | 10 +++ 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index 30d910930..ac44ef196 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -18022,14 +18022,14 @@ DROP PROCEDURE IF EXISTS assert_wallet_event_schema; -- 目的港码头拖车、提柜与还空闭环(模块来源:phase3-terminal-drayage-schema.sql) USE baiyue_firstleg; CREATE TABLE IF NOT EXISTS fl_terminal_drayage ( - id BIGINT UNSIGNED NOT NULL, container_booking_id BIGINT UNSIGNED NOT NULL, - fleet_supplier_id BIGINT UNSIGNED NOT NULL, fleet_supplier_name VARCHAR(128) NOT NULL, - pickup_appointment_at DATETIME(3) NULL, actual_pickup_at DATETIME(3) NULL, - estimated_empty_return_at DATETIME(3) NULL, actual_empty_return_at DATETIME(3) NULL, - version INT UNSIGNED NOT NULL DEFAULT 1, created_by BIGINT UNSIGNED NOT NULL, - created_by_name VARCHAR(64) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), - updated_by BIGINT UNSIGNED NOT NULL, updated_by_name VARCHAR(64) NULL, - updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), + id BIGINT UNSIGNED NOT NULL COMMENT '目的港码头拖车聚合ID', container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '唯一归属物理货柜ID', + fleet_supplier_id BIGINT UNSIGNED NOT NULL COMMENT 'Warehouse ACTIVE/TRUCKING供应商ID快照', fleet_supplier_name VARCHAR(128) NOT NULL COMMENT 'Warehouse供应商名称快照', + pickup_appointment_at DATETIME(3) NULL COMMENT '预约提柜时间', actual_pickup_at DATETIME(3) NULL COMMENT '实际提柜时间', + estimated_empty_return_at DATETIME(3) NULL COMMENT '服务端按卸柜完成时间加72小时计算的预计还柜时间', actual_empty_return_at DATETIME(3) NULL COMMENT '实际还空柜时间', + version INT UNSIGNED NOT NULL DEFAULT 1 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 '更新时间', PRIMARY KEY(id), UNIQUE KEY uk_terminal_drayage_container(container_booking_id), KEY idx_terminal_drayage_warning(actual_empty_return_at,estimated_empty_return_at), CONSTRAINT fk_terminal_drayage_container FOREIGN KEY(container_booking_id) REFERENCES fl_container_booking(id), @@ -18038,27 +18038,69 @@ CREATE TABLE IF NOT EXISTS fl_terminal_drayage ( AND (actual_empty_return_at IS NULL OR actual_empty_return_at >= actual_pickup_at)) ) ENGINE=InnoDB COMMENT='目的港货柜级码头拖车与还空事实'; CREATE TABLE IF NOT EXISTS fl_terminal_drayage_history ( - id BIGINT UNSIGNED NOT NULL, drayage_id BIGINT UNSIGNED NOT NULL, - container_booking_id BIGINT UNSIGNED NOT NULL, action VARCHAR(32) NOT NULL, - from_status VARCHAR(32) NOT NULL, to_status VARCHAR(32) NOT NULL, - from_version INT UNSIGNED NOT NULL, to_version INT UNSIGNED NOT NULL, - reason VARCHAR(500) NULL, operator_id BIGINT UNSIGNED NOT NULL, operator_name VARCHAR(64) NULL, - created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), PRIMARY KEY(id), + id BIGINT UNSIGNED NOT NULL COMMENT '历史ID', drayage_id BIGINT UNSIGNED NOT NULL COMMENT '码头拖车聚合ID', + container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '货柜ID快照', action VARCHAR(32) NOT NULL COMMENT '业务动作', + from_status VARCHAR(32) NOT NULL COMMENT '操作前状态', to_status VARCHAR(32) NOT NULL COMMENT '操作后状态', + from_version INT UNSIGNED NOT NULL COMMENT '操作前版本', to_version INT UNSIGNED NOT NULL COMMENT '操作后版本', + reason VARCHAR(500) NULL COMMENT '操作说明', operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID', operator_name VARCHAR(64) NULL COMMENT '操作人名称快照', + created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间', PRIMARY KEY(id), KEY idx_terminal_drayage_history(container_booking_id,created_at,id), CONSTRAINT fk_terminal_drayage_history FOREIGN KEY(drayage_id) REFERENCES fl_terminal_drayage(id), CONSTRAINT chk_terminal_drayage_history_action CHECK(action IN ('SELECT_FLEET','SCHEDULE_PICKUP','RECORD_PICKUP','RECORD_EMPTY_RETURN')) ) ENGINE=InnoDB COMMENT='目的港码头拖车不可变操作历史'; CREATE TABLE IF NOT EXISTS fl_terminal_drayage_operation ( - id BIGINT UNSIGNED NOT NULL, container_booking_id BIGINT UNSIGNED NOT NULL, - operation VARCHAR(32) NOT NULL, idempotency_key VARCHAR(255) NOT NULL, - request_hash CHAR(64) NOT NULL, result_version INT UNSIGNED NOT NULL, - operator_id BIGINT UNSIGNED NOT NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + id BIGINT UNSIGNED NOT NULL COMMENT '幂等操作ID', container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '货柜ID', + operation VARCHAR(32) NOT NULL COMMENT '业务动作', idempotency_key VARCHAR(255) NOT NULL COMMENT '客户端幂等键', + request_hash CHAR(64) NOT NULL COMMENT '请求载荷SHA-256', result_version INT UNSIGNED NOT NULL COMMENT '成功结果版本', + operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '完成时间', PRIMARY KEY(id), UNIQUE KEY uk_terminal_drayage_operation(container_booking_id,idempotency_key), KEY idx_terminal_drayage_operation(container_booking_id,created_at), CONSTRAINT fk_terminal_drayage_operation_container FOREIGN KEY(container_booking_id) REFERENCES fl_container_booking(id) ) ENGINE=InnoDB COMMENT='目的港码头拖车成功幂等操作'; +-- MySQL DDL 会隐式提交;如果前次执行在末段校验失败,重跑时需把已创建表的列注释收敛到当前基线。 +ALTER TABLE fl_terminal_drayage + MODIFY COLUMN id BIGINT UNSIGNED NOT NULL COMMENT '目的港码头拖车聚合ID', + MODIFY COLUMN container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '唯一归属物理货柜ID', + MODIFY COLUMN fleet_supplier_id BIGINT UNSIGNED NOT NULL COMMENT 'Warehouse ACTIVE/TRUCKING供应商ID快照', + MODIFY COLUMN fleet_supplier_name VARCHAR(128) NOT NULL COMMENT 'Warehouse供应商名称快照', + MODIFY COLUMN pickup_appointment_at DATETIME(3) NULL COMMENT '预约提柜时间', + MODIFY COLUMN actual_pickup_at DATETIME(3) NULL COMMENT '实际提柜时间', + MODIFY COLUMN estimated_empty_return_at DATETIME(3) NULL COMMENT '服务端按卸柜完成时间加72小时计算的预计还柜时间', + MODIFY COLUMN actual_empty_return_at DATETIME(3) NULL COMMENT '实际还空柜时间', + MODIFY COLUMN version INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观锁版本号', + MODIFY COLUMN created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID', + MODIFY COLUMN created_by_name VARCHAR(64) NULL COMMENT '创建人名称快照', + MODIFY COLUMN created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', + MODIFY COLUMN updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后更新人ID', + MODIFY COLUMN updated_by_name VARCHAR(64) NULL COMMENT '最后更新人名称快照', + MODIFY COLUMN updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间'; + +ALTER TABLE fl_terminal_drayage_history + MODIFY COLUMN id BIGINT UNSIGNED NOT NULL COMMENT '历史ID', + MODIFY COLUMN drayage_id BIGINT UNSIGNED NOT NULL COMMENT '码头拖车聚合ID', + MODIFY COLUMN container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '货柜ID快照', + MODIFY COLUMN action VARCHAR(32) NOT NULL COMMENT '业务动作', + MODIFY COLUMN from_status VARCHAR(32) NOT NULL COMMENT '操作前状态', + MODIFY COLUMN to_status VARCHAR(32) NOT NULL COMMENT '操作后状态', + MODIFY COLUMN from_version INT UNSIGNED NOT NULL COMMENT '操作前版本', + MODIFY COLUMN to_version INT UNSIGNED NOT NULL COMMENT '操作后版本', + MODIFY COLUMN reason VARCHAR(500) NULL COMMENT '操作说明', + MODIFY COLUMN operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID', + MODIFY COLUMN operator_name VARCHAR(64) NULL COMMENT '操作人名称快照', + MODIFY COLUMN created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间'; + +ALTER TABLE fl_terminal_drayage_operation + MODIFY COLUMN id BIGINT UNSIGNED NOT NULL COMMENT '幂等操作ID', + MODIFY COLUMN container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '货柜ID', + MODIFY COLUMN operation VARCHAR(32) NOT NULL COMMENT '业务动作', + MODIFY COLUMN idempotency_key VARCHAR(255) NOT NULL COMMENT '客户端幂等键', + MODIFY COLUMN request_hash CHAR(64) NOT NULL COMMENT '请求载荷SHA-256', + MODIFY COLUMN result_version INT UNSIGNED NOT NULL COMMENT '成功结果版本', + MODIFY COLUMN operator_id BIGINT UNSIGNED NOT NULL COMMENT '操作人ID', + MODIFY COLUMN created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '完成时间'; + DROP PROCEDURE IF EXISTS assert_terminal_drayage_schema; DELIMITER $$ CREATE PROCEDURE assert_terminal_drayage_schema() diff --git a/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/mapper/TerminalDrayageSqlContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/mapper/TerminalDrayageSqlContractTest.java index 28da7a5b2..41c95d782 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/mapper/TerminalDrayageSqlContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/mapper/TerminalDrayageSqlContractTest.java @@ -24,4 +24,14 @@ class TerminalDrayageSqlContractTest { assertThat(mapper).contains("WHERE b.id=#{containerBookingId} FOR UPDATE", "WHERE container_booking_id=#{value.containerBookingId} AND version=#{expectedVersion}"); } + + @Test + void unifiedMigrationRepairsColumnsAfterAPartialDdlRun() throws Exception { + String sql = Files.readString(Path.of("../deploy/sql/头程数据库统一增量-MySQL8.sql")); + assertThat(sql).contains( + "ALTER TABLE fl_terminal_drayage", + "ALTER TABLE fl_terminal_drayage_history", + "ALTER TABLE fl_terminal_drayage_operation", + "MODIFY COLUMN estimated_empty_return_at DATETIME(3) NULL COMMENT '服务端按卸柜完成时间加72小时计算的预计还柜时间'"); + } }