diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index 71fe4e825..dc43fd4f9 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -5322,8 +5322,10 @@ BEGIN IF OLD.task_status = 'COMPLETED' THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '已完成PDA拣货任务不可修改'; END IF; - IF NEW.loading_plan_id <> OLD.loading_plan_id OR NOT (NEW.container_no <=> OLD.container_no) THEN - SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务归属不可修改'; + IF NEW.loading_plan_id <> OLD.loading_plan_id + OR NOT (NEW.container_booking_id <=> OLD.container_booking_id) + OR NOT (NEW.cabinet_no <=> OLD.cabinet_no) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务稳定归属不可修改'; END IF; IF NOT (OLD.task_status = 'LOADING' AND NEW.task_status IN ('LOADING', 'COMPLETED')) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务状态只允许完成'; @@ -13988,31 +13990,55 @@ DROP PROCEDURE IF EXISTS migrate_phase3_channel_containers; DELIMITER $$ CREATE PROCEDURE migrate_phase3_channel_containers() BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 + @phase3_channel_sqlstate = RETURNED_SQLSTATE, + @phase3_channel_errno = MYSQL_ERRNO, + @phase3_channel_message = MESSAGE_TEXT; + END; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_ocean_booking' AND column_name='channel_code') THEN - ALTER TABLE baiyue_firstleg.fl_ocean_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER customer_name, - ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code, - ADD COLUMN warehouse_id BIGINT UNSIGNED NULL COMMENT '国内中转仓ID快照' AFTER channel_name, - ADD COLUMN warehouse_name VARCHAR(128) NULL COMMENT '国内中转仓名称快照' AFTER warehouse_id; + ALTER TABLE baiyue_firstleg.fl_ocean_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER customer_name; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_ocean_booking' AND column_name='channel_name') THEN + ALTER TABLE baiyue_firstleg.fl_ocean_booking ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_ocean_booking' AND column_name='warehouse_id') THEN + ALTER TABLE baiyue_firstleg.fl_ocean_booking ADD COLUMN warehouse_id BIGINT UNSIGNED NULL COMMENT '国内中转仓ID快照' AFTER channel_name; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_ocean_booking' AND column_name='warehouse_name') THEN + ALTER TABLE baiyue_firstleg.fl_ocean_booking ADD COLUMN warehouse_name VARCHAR(128) NULL COMMENT '国内中转仓名称快照' AFTER warehouse_id; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_ocean_booking_container_requirement' AND column_name='capacity_cbm') THEN - ALTER TABLE baiyue_firstleg.fl_ocean_booking_container_requirement ADD COLUMN capacity_cbm DECIMAL(18,4) NULL COMMENT '柜型容量快照m3' AFTER container_kind, - ADD COLUMN max_weight_kg DECIMAL(18,3) NULL COMMENT '柜型最大承重快照kg' AFTER capacity_cbm; + ALTER TABLE baiyue_firstleg.fl_ocean_booking_container_requirement ADD COLUMN capacity_cbm DECIMAL(18,4) NULL COMMENT '柜型容量快照m3' AFTER container_kind; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_ocean_booking_container_requirement' AND column_name='max_weight_kg') THEN + ALTER TABLE baiyue_firstleg.fl_ocean_booking_container_requirement ADD COLUMN max_weight_kg DECIMAL(18,3) NULL COMMENT '柜型最大承重快照kg' AFTER capacity_cbm; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_container_booking' AND column_name='channel_code') THEN - ALTER TABLE baiyue_firstleg.fl_container_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER cabinet_no, - ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code, - ADD COLUMN ocean_booking_id BIGINT UNSIGNED NULL COMMENT '来源订舱ID' AFTER channel_name, - ADD COLUMN ocean_booking_requirement_id BIGINT UNSIGNED NULL COMMENT '来源订舱箱型需求ID' AFTER ocean_booking_id; + ALTER TABLE baiyue_firstleg.fl_container_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER cabinet_no; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_container_booking' AND column_name='channel_name') THEN + ALTER TABLE baiyue_firstleg.fl_container_booking ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_container_booking' AND column_name='ocean_booking_id') THEN + ALTER TABLE baiyue_firstleg.fl_container_booking ADD COLUMN ocean_booking_id BIGINT UNSIGNED NULL COMMENT '来源订舱ID' AFTER channel_name; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_container_booking' AND column_name='ocean_booking_requirement_id') THEN + ALTER TABLE baiyue_firstleg.fl_container_booking ADD COLUMN ocean_booking_requirement_id BIGINT UNSIGNED NULL COMMENT '来源订舱箱型需求ID' AFTER ocean_booking_id; END IF; UPDATE baiyue_firstleg.fl_container_booking c JOIN baiyue_firstleg.fl_ocean_booking_container_allocation a ON a.container_booking_id=c.id JOIN baiyue_firstleg.fl_ocean_booking b ON b.id=a.ocean_booking_id SET c.ocean_booking_id=b.id,c.ocean_booking_requirement_id=a.requirement_id,c.channel_code=COALESCE(c.channel_code,b.channel_code),c.channel_name=COALESCE(c.channel_name,b.channel_name) - WHERE c.ocean_booking_id IS NULL OR c.ocean_booking_requirement_id IS NULL OR c.channel_code IS NULL; + WHERE c.ocean_booking_id IS NULL OR c.ocean_booking_requirement_id IS NULL + OR c.channel_code IS NULL OR c.channel_name IS NULL; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_loading_pick_task' AND column_name='container_booking_id') THEN - ALTER TABLE baiyue_firstleg.fl_loading_pick_task ADD COLUMN container_booking_id BIGINT UNSIGNED NULL COMMENT '稳定柜次ID' AFTER loading_plan_id, - ADD COLUMN cabinet_no VARCHAR(64) NULL COMMENT '稳定内部柜次号快照' AFTER container_booking_id, - MODIFY COLUMN container_no VARCHAR(64) NULL COMMENT '废弃兼容字段;不得作为任务身份'; + ALTER TABLE baiyue_firstleg.fl_loading_pick_task ADD COLUMN container_booking_id BIGINT UNSIGNED NULL COMMENT '稳定柜次ID' AFTER loading_plan_id; END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_firstleg' AND table_name='fl_loading_pick_task' AND column_name='cabinet_no') THEN + ALTER TABLE baiyue_firstleg.fl_loading_pick_task ADD COLUMN cabinet_no VARCHAR(64) NULL COMMENT '稳定内部柜次号快照' AFTER container_booking_id; + END IF; + ALTER TABLE baiyue_firstleg.fl_loading_pick_task MODIFY COLUMN container_no VARCHAR(64) NULL COMMENT '废弃兼容字段;不得作为任务身份'; UPDATE baiyue_firstleg.fl_loading_pick_task t JOIN baiyue_firstleg.fl_loading_plan p ON p.id=t.loading_plan_id JOIN baiyue_firstleg.fl_container_booking c ON c.id=p.container_booking_id SET t.container_booking_id=c.id,t.cabinet_no=c.cabinet_no WHERE t.container_booking_id IS NULL OR t.cabinet_no IS NULL; IF EXISTS (SELECT 1 FROM baiyue_firstleg.fl_loading_pick_task WHERE container_booking_id IS NULL OR cabinet_no IS NULL) THEN @@ -14023,8 +14049,91 @@ BEGIN END IF; END$$ DELIMITER ; +SET @phase3_channel_sqlstate = NULL; +SET @phase3_channel_errno = NULL; +SET @phase3_channel_message = NULL; +DROP TRIGGER IF EXISTS baiyue_firstleg.trg_container_booking_before_update; +DROP TRIGGER IF EXISTS baiyue_firstleg.trg_loading_pick_task_before_update; CALL migrate_phase3_channel_containers(); DROP PROCEDURE IF EXISTS migrate_phase3_channel_containers; +DROP TRIGGER IF EXISTS baiyue_firstleg.trg_container_booking_before_update; +DELIMITER $$ +CREATE TRIGGER baiyue_firstleg.trg_container_booking_before_update +BEFORE UPDATE ON baiyue_firstleg.fl_container_booking +FOR EACH ROW +BEGIN + DECLARE current_plan_status VARCHAR(24); + SELECT MAX(plan_status) INTO current_plan_status + FROM baiyue_firstleg.fl_loading_plan WHERE container_booking_id = OLD.id; + IF current_plan_status = 'COMPLETED' THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '装柜完成后货柜全部只读,不允许修改'; + END IF; + IF current_plan_status = 'LOADING' AND ( + NOT (OLD.id <=> NEW.id) OR NOT (OLD.booking_no <=> NEW.booking_no) + OR NOT (OLD.cabinet_no <=> NEW.cabinet_no) + OR NOT (OLD.channel_code <=> NEW.channel_code) OR NOT (OLD.channel_name <=> NEW.channel_name) + OR NOT (OLD.ocean_booking_id <=> NEW.ocean_booking_id) + OR NOT (OLD.ocean_booking_requirement_id <=> NEW.ocean_booking_requirement_id) + OR NOT (OLD.warehouse_id <=> NEW.warehouse_id) OR NOT (OLD.warehouse_name <=> NEW.warehouse_name) + OR NOT (OLD.bill_of_lading_no <=> NEW.bill_of_lading_no) OR NOT (OLD.vessel_name <=> NEW.vessel_name) + OR NOT (OLD.container_type <=> NEW.container_type) + OR NOT (OLD.shipping_company_id <=> NEW.shipping_company_id) OR NOT (OLD.shipping_company_name <=> NEW.shipping_company_name) + OR NOT (OLD.departure_port_code <=> NEW.departure_port_code) OR NOT (OLD.departure_port_name <=> NEW.departure_port_name) + OR NOT (OLD.destination_port_code <=> NEW.destination_port_code) OR NOT (OLD.destination_port_name <=> NEW.destination_port_name) + OR NOT (OLD.destination_warehouse_code <=> NEW.destination_warehouse_code) OR NOT (OLD.destination_warehouse_name <=> NEW.destination_warehouse_name) + OR NOT (OLD.capacity_cbm <=> NEW.capacity_cbm) OR NOT (OLD.max_weight_kg <=> NEW.max_weight_kg) + OR NOT (OLD.terminal_trucking_company <=> NEW.terminal_trucking_company) OR NOT (OLD.loading_at <=> NEW.loading_at) + OR NOT (OLD.estimated_sailing_at <=> NEW.estimated_sailing_at) OR NOT (OLD.actual_sailing_at <=> NEW.actual_sailing_at) + OR NOT (OLD.estimated_port_arrival_at <=> NEW.estimated_port_arrival_at) OR NOT (OLD.actual_port_arrival_at <=> NEW.actual_port_arrival_at) + OR NOT (OLD.estimated_warehouse_arrival_at <=> NEW.estimated_warehouse_arrival_at) OR NOT (OLD.actual_warehouse_arrival_at <=> NEW.actual_warehouse_arrival_at) + OR NOT (OLD.created_by <=> NEW.created_by) OR NOT (OLD.created_by_name <=> NEW.created_by_name) + OR NOT (OLD.created_at <=> NEW.created_at) + ) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '装柜中仅允许修改集装箱号与航次'; + END IF; +END$$ +DELIMITER ; +DROP TRIGGER IF EXISTS baiyue_firstleg.trg_loading_pick_task_before_update; +DELIMITER $$ +CREATE TRIGGER baiyue_firstleg.trg_loading_pick_task_before_update +BEFORE UPDATE ON baiyue_firstleg.fl_loading_pick_task +FOR EACH ROW +BEGIN + IF OLD.task_status = 'COMPLETED' THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '已完成PDA拣货任务不可修改'; + END IF; + IF NEW.loading_plan_id <> OLD.loading_plan_id + OR NOT (NEW.container_booking_id <=> OLD.container_booking_id) + OR NOT (NEW.cabinet_no <=> OLD.cabinet_no) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务稳定归属不可修改'; + END IF; + IF NOT (OLD.task_status = 'LOADING' AND NEW.task_status IN ('LOADING', 'COMPLETED')) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务状态只允许完成'; + END IF; +END$$ +DELIMITER ; +DROP PROCEDURE IF EXISTS assert_phase3_channel_container_migration; +DELIMITER $$ +CREATE PROCEDURE assert_phase3_channel_container_migration() +BEGIN + DECLARE diagnostic_message VARCHAR(128); + IF @phase3_channel_sqlstate IS NOT NULL THEN + SET diagnostic_message = LEFT(CONCAT('渠道柜迁移失败 [', @phase3_channel_sqlstate, '/', + @phase3_channel_errno, ']: ', @phase3_channel_message), 128); + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = diagnostic_message; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.triggers WHERE trigger_schema='baiyue_firstleg' + AND trigger_name='trg_container_booking_before_update') THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='渠道柜迁移失败:货柜只读触发器未恢复'; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.triggers WHERE trigger_schema='baiyue_firstleg' + AND trigger_name='trg_loading_pick_task_before_update') THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='渠道柜迁移失败:PDA任务只读触发器未恢复'; + END IF; +END$$ +DELIMITER ; +CALL assert_phase3_channel_container_migration(); +DROP PROCEDURE IF EXISTS assert_phase3_channel_container_migration; CREATE TABLE IF NOT EXISTS baiyue_firstleg.fl_container_transport_history ( id BIGINT UNSIGNED NOT NULL,container_booking_id BIGINT UNSIGNED NOT NULL,before_container_no VARCHAR(64) NULL,after_container_no VARCHAR(64) NULL, before_voyage_no VARCHAR(64) NULL,after_voyage_no VARCHAR(64) NULL,reason VARCHAR(500) NULL,operator_id BIGINT UNSIGNED NOT NULL, diff --git a/firstleg/src/main/resources/db/phase3-channel-container-migration.sql b/firstleg/src/main/resources/db/phase3-channel-container-migration.sql index 4f7baa66a..a142f7761 100644 --- a/firstleg/src/main/resources/db/phase3-channel-container-migration.sql +++ b/firstleg/src/main/resources/db/phase3-channel-container-migration.sql @@ -5,33 +5,60 @@ DROP PROCEDURE IF EXISTS migrate_phase3_channel_containers; DELIMITER $$ CREATE PROCEDURE migrate_phase3_channel_containers() BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 + @phase3_channel_sqlstate = RETURNED_SQLSTATE, + @phase3_channel_errno = MYSQL_ERRNO, + @phase3_channel_message = MESSAGE_TEXT; + END; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_ocean_booking' AND column_name='channel_code') THEN - ALTER TABLE fl_ocean_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER customer_name, - ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code, - ADD COLUMN warehouse_id BIGINT UNSIGNED NULL COMMENT '国内中转仓ID快照' AFTER channel_name, - ADD COLUMN warehouse_name VARCHAR(128) NULL COMMENT '国内中转仓名称快照' AFTER warehouse_id; + ALTER TABLE fl_ocean_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER customer_name; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_ocean_booking' AND column_name='channel_name') THEN + ALTER TABLE fl_ocean_booking ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_ocean_booking' AND column_name='warehouse_id') THEN + ALTER TABLE fl_ocean_booking ADD COLUMN warehouse_id BIGINT UNSIGNED NULL COMMENT '国内中转仓ID快照' AFTER channel_name; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_ocean_booking' AND column_name='warehouse_name') THEN + ALTER TABLE fl_ocean_booking ADD COLUMN warehouse_name VARCHAR(128) NULL COMMENT '国内中转仓名称快照' AFTER warehouse_id; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_ocean_booking_container_requirement' AND column_name='capacity_cbm') THEN - ALTER TABLE fl_ocean_booking_container_requirement ADD COLUMN capacity_cbm DECIMAL(18,4) NULL COMMENT '柜型容量快照m3' AFTER container_kind, - ADD COLUMN max_weight_kg DECIMAL(18,3) NULL COMMENT '柜型最大承重快照kg' AFTER capacity_cbm; + ALTER TABLE fl_ocean_booking_container_requirement ADD COLUMN capacity_cbm DECIMAL(18,4) NULL COMMENT '柜型容量快照m3' AFTER container_kind; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_ocean_booking_container_requirement' AND column_name='max_weight_kg') THEN + ALTER TABLE fl_ocean_booking_container_requirement ADD COLUMN max_weight_kg DECIMAL(18,3) NULL COMMENT '柜型最大承重快照kg' AFTER capacity_cbm; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_container_booking' AND column_name='channel_code') THEN - ALTER TABLE fl_container_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER cabinet_no, - ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code, - ADD COLUMN ocean_booking_id BIGINT UNSIGNED NULL COMMENT '来源订舱ID' AFTER channel_name, - ADD COLUMN ocean_booking_requirement_id BIGINT UNSIGNED NULL COMMENT '来源订舱箱型需求ID' AFTER ocean_booking_id; + ALTER TABLE fl_container_booking ADD COLUMN channel_code VARCHAR(64) NULL COMMENT '订舱渠道编码快照' AFTER cabinet_no; END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_container_booking' AND column_name='channel_name') THEN + ALTER TABLE fl_container_booking ADD COLUMN channel_name VARCHAR(128) NULL COMMENT '订舱渠道名称快照' AFTER channel_code; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_container_booking' AND column_name='ocean_booking_id') THEN + ALTER TABLE fl_container_booking ADD COLUMN ocean_booking_id BIGINT UNSIGNED NULL COMMENT '来源订舱ID' AFTER channel_name; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_container_booking' AND column_name='ocean_booking_requirement_id') THEN + ALTER TABLE fl_container_booking ADD COLUMN ocean_booking_requirement_id BIGINT UNSIGNED NULL COMMENT '来源订舱箱型需求ID' AFTER ocean_booking_id; + END IF; + UPDATE fl_container_booking c JOIN fl_ocean_booking_container_allocation a ON a.container_booking_id=c.id JOIN fl_ocean_booking b ON b.id=a.ocean_booking_id SET c.ocean_booking_id=b.id,c.ocean_booking_requirement_id=a.requirement_id, c.channel_code=COALESCE(c.channel_code,b.channel_code),c.channel_name=COALESCE(c.channel_name,b.channel_name) - WHERE c.ocean_booking_id IS NULL OR c.ocean_booking_requirement_id IS NULL OR c.channel_code IS NULL; + WHERE c.ocean_booking_id IS NULL OR c.ocean_booking_requirement_id IS NULL + OR c.channel_code IS NULL OR c.channel_name IS NULL; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_loading_pick_task' AND column_name='container_booking_id') THEN - ALTER TABLE fl_loading_pick_task ADD COLUMN container_booking_id BIGINT UNSIGNED NULL COMMENT '稳定柜次ID' AFTER loading_plan_id, - ADD COLUMN cabinet_no VARCHAR(64) NULL COMMENT '稳定内部柜次号快照' AFTER container_booking_id, - MODIFY COLUMN container_no VARCHAR(64) NULL COMMENT '废弃兼容字段;不得作为任务身份'; + ALTER TABLE fl_loading_pick_task ADD COLUMN container_booking_id BIGINT UNSIGNED NULL COMMENT '稳定柜次ID' AFTER loading_plan_id; END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_loading_pick_task' AND column_name='cabinet_no') THEN + ALTER TABLE fl_loading_pick_task ADD COLUMN cabinet_no VARCHAR(64) NULL COMMENT '稳定内部柜次号快照' AFTER container_booking_id; + END IF; + ALTER TABLE fl_loading_pick_task MODIFY COLUMN container_no VARCHAR(64) NULL COMMENT '废弃兼容字段;不得作为任务身份'; UPDATE fl_loading_pick_task t JOIN fl_loading_plan p ON p.id=t.loading_plan_id JOIN fl_container_booking c ON c.id=p.container_booking_id SET t.container_booking_id=c.id,t.cabinet_no=c.cabinet_no @@ -44,9 +71,97 @@ BEGIN END IF; END$$ DELIMITER ; + +SET @phase3_channel_sqlstate = NULL; +SET @phase3_channel_errno = NULL; +SET @phase3_channel_message = NULL; +DROP TRIGGER IF EXISTS trg_container_booking_before_update; +DROP TRIGGER IF EXISTS trg_loading_pick_task_before_update; CALL migrate_phase3_channel_containers(); DROP PROCEDURE IF EXISTS migrate_phase3_channel_containers; +-- Rebuild the production guard unconditionally before surfacing a migration failure. +DROP TRIGGER IF EXISTS trg_container_booking_before_update; +DELIMITER $$ +CREATE TRIGGER trg_container_booking_before_update +BEFORE UPDATE ON fl_container_booking +FOR EACH ROW +BEGIN + DECLARE current_plan_status VARCHAR(24); + SELECT MAX(plan_status) INTO current_plan_status + FROM fl_loading_plan WHERE container_booking_id = OLD.id; + IF current_plan_status = 'COMPLETED' THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '装柜完成后货柜全部只读,不允许修改'; + END IF; + IF current_plan_status = 'LOADING' AND ( + NOT (OLD.id <=> NEW.id) OR NOT (OLD.booking_no <=> NEW.booking_no) + OR NOT (OLD.cabinet_no <=> NEW.cabinet_no) + OR NOT (OLD.channel_code <=> NEW.channel_code) OR NOT (OLD.channel_name <=> NEW.channel_name) + OR NOT (OLD.ocean_booking_id <=> NEW.ocean_booking_id) + OR NOT (OLD.ocean_booking_requirement_id <=> NEW.ocean_booking_requirement_id) + OR NOT (OLD.warehouse_id <=> NEW.warehouse_id) OR NOT (OLD.warehouse_name <=> NEW.warehouse_name) + OR NOT (OLD.bill_of_lading_no <=> NEW.bill_of_lading_no) OR NOT (OLD.vessel_name <=> NEW.vessel_name) + OR NOT (OLD.container_type <=> NEW.container_type) + OR NOT (OLD.shipping_company_id <=> NEW.shipping_company_id) OR NOT (OLD.shipping_company_name <=> NEW.shipping_company_name) + OR NOT (OLD.departure_port_code <=> NEW.departure_port_code) OR NOT (OLD.departure_port_name <=> NEW.departure_port_name) + OR NOT (OLD.destination_port_code <=> NEW.destination_port_code) OR NOT (OLD.destination_port_name <=> NEW.destination_port_name) + OR NOT (OLD.destination_warehouse_code <=> NEW.destination_warehouse_code) OR NOT (OLD.destination_warehouse_name <=> NEW.destination_warehouse_name) + OR NOT (OLD.capacity_cbm <=> NEW.capacity_cbm) OR NOT (OLD.max_weight_kg <=> NEW.max_weight_kg) + OR NOT (OLD.terminal_trucking_company <=> NEW.terminal_trucking_company) OR NOT (OLD.loading_at <=> NEW.loading_at) + OR NOT (OLD.estimated_sailing_at <=> NEW.estimated_sailing_at) OR NOT (OLD.actual_sailing_at <=> NEW.actual_sailing_at) + OR NOT (OLD.estimated_port_arrival_at <=> NEW.estimated_port_arrival_at) OR NOT (OLD.actual_port_arrival_at <=> NEW.actual_port_arrival_at) + OR NOT (OLD.estimated_warehouse_arrival_at <=> NEW.estimated_warehouse_arrival_at) OR NOT (OLD.actual_warehouse_arrival_at <=> NEW.actual_warehouse_arrival_at) + OR NOT (OLD.created_by <=> NEW.created_by) OR NOT (OLD.created_by_name <=> NEW.created_by_name) + OR NOT (OLD.created_at <=> NEW.created_at) + ) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '装柜中仅允许修改集装箱号与航次'; + END IF; +END$$ +DELIMITER ; + +DROP TRIGGER IF EXISTS trg_loading_pick_task_before_update; +DELIMITER $$ +CREATE TRIGGER trg_loading_pick_task_before_update +BEFORE UPDATE ON fl_loading_pick_task +FOR EACH ROW +BEGIN + IF OLD.task_status = 'COMPLETED' THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '已完成PDA拣货任务不可修改'; + END IF; + IF NEW.loading_plan_id <> OLD.loading_plan_id + OR NOT (NEW.container_booking_id <=> OLD.container_booking_id) + OR NOT (NEW.cabinet_no <=> OLD.cabinet_no) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务稳定归属不可修改'; + END IF; + IF NOT (OLD.task_status = 'LOADING' AND NEW.task_status IN ('LOADING', 'COMPLETED')) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务状态只允许完成'; + END IF; +END$$ +DELIMITER ; + +DROP PROCEDURE IF EXISTS assert_phase3_channel_container_migration; +DELIMITER $$ +CREATE PROCEDURE assert_phase3_channel_container_migration() +BEGIN + DECLARE diagnostic_message VARCHAR(128); + IF @phase3_channel_sqlstate IS NOT NULL THEN + SET diagnostic_message = LEFT(CONCAT('渠道柜迁移失败 [', @phase3_channel_sqlstate, '/', + @phase3_channel_errno, ']: ', @phase3_channel_message), 128); + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = diagnostic_message; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.triggers WHERE trigger_schema=DATABASE() + AND trigger_name='trg_container_booking_before_update') THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='渠道柜迁移失败:货柜只读触发器未恢复'; + END IF; + IF NOT EXISTS (SELECT 1 FROM information_schema.triggers WHERE trigger_schema=DATABASE() + AND trigger_name='trg_loading_pick_task_before_update') THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='渠道柜迁移失败:PDA任务只读触发器未恢复'; + END IF; +END$$ +DELIMITER ; +CALL assert_phase3_channel_container_migration(); +DROP PROCEDURE IF EXISTS assert_phase3_channel_container_migration; + CREATE TABLE IF NOT EXISTS fl_container_transport_history ( id BIGINT UNSIGNED NOT NULL, container_booking_id BIGINT UNSIGNED NOT NULL, before_container_no VARCHAR(64) NULL, after_container_no VARCHAR(64) NULL, diff --git a/firstleg/src/main/resources/db/phase3-smart-loading-schema.sql b/firstleg/src/main/resources/db/phase3-smart-loading-schema.sql index c0fad8087..35f20fabe 100644 --- a/firstleg/src/main/resources/db/phase3-smart-loading-schema.sql +++ b/firstleg/src/main/resources/db/phase3-smart-loading-schema.sql @@ -808,8 +808,10 @@ BEGIN IF OLD.task_status = 'COMPLETED' THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '已完成PDA拣货任务不可修改'; END IF; - IF NEW.loading_plan_id <> OLD.loading_plan_id OR NOT (NEW.container_no <=> OLD.container_no) THEN - SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务归属不可修改'; + IF NEW.loading_plan_id <> OLD.loading_plan_id + OR NOT (NEW.container_booking_id <=> OLD.container_booking_id) + OR NOT (NEW.cabinet_no <=> OLD.cabinet_no) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务稳定归属不可修改'; END IF; IF NOT (OLD.task_status = 'LOADING' AND NEW.task_status IN ('LOADING', 'COMPLETED')) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'PDA拣货任务状态只允许完成';