fix(sql): make domestic migration replay-safe

This commit is contained in:
2026-09-10 20:19:11 +08:00
parent 2b73245c96
commit 69e80a736e
5 changed files with 154 additions and 30 deletions
@@ -5485,6 +5485,7 @@ BEGIN
DECLARE source_exists INT DEFAULT 0;
DECLARE source_total_columns INT DEFAULT 0;
DECLARE source_smart_columns INT DEFAULT 0;
DECLARE source_current_columns INT DEFAULT 0;
DECLARE source_inbound_columns INT DEFAULT 0;
DECLARE target_exists INT DEFAULT 0;
DECLARE target_total_columns INT DEFAULT 0;
@@ -5529,7 +5530,45 @@ BEGIN
OR (column_name = 'updated_at' AND data_type = 'datetime' AND datetime_precision = 3 AND is_nullable = 'NO' AND LOWER(column_default) LIKE 'current_timestamp%' AND LOWER(extra) LIKE '%on update current_timestamp%')
);
IF source_total_columns = 11 AND source_smart_columns = 11 AND source_inbound_columns < 12
SELECT COUNT(*) INTO source_current_columns
FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task' AND (
(column_name = 'id' AND LOWER(column_type) = 'bigint unsigned' AND is_nullable = 'NO')
OR (column_name = 'loading_plan_id' AND LOWER(column_type) = 'bigint unsigned' AND is_nullable = 'NO')
OR (column_name = 'container_booking_id' AND LOWER(column_type) = 'bigint unsigned' AND is_nullable = 'NO')
OR (column_name = 'cabinet_no' AND LOWER(column_type) = 'varchar(64)' AND is_nullable = 'NO')
OR (column_name = 'container_no' AND LOWER(column_type) = 'varchar(64)' AND is_nullable = 'YES')
OR (column_name = 'task_status' AND LOWER(column_type) = 'varchar(24)' AND is_nullable = 'NO' AND column_default = 'LOADING')
OR (column_name = 'started_by' AND LOWER(column_type) = 'bigint unsigned' AND is_nullable = 'NO')
OR (column_name = 'started_by_name' AND LOWER(column_type) = 'varchar(64)' AND is_nullable = 'YES')
OR (column_name = 'started_at' AND data_type = 'datetime' AND datetime_precision = 3 AND is_nullable = 'NO' AND LOWER(column_default) LIKE 'current_timestamp%')
OR (column_name = 'completed_by' AND LOWER(column_type) = 'bigint unsigned' AND is_nullable = 'YES')
OR (column_name = 'completed_by_name' AND LOWER(column_type) = 'varchar(64)' AND is_nullable = 'YES')
OR (column_name = 'completed_at' AND data_type = 'datetime' AND datetime_precision = 3 AND is_nullable = 'YES')
OR (column_name = 'version' AND LOWER(column_type) = 'int unsigned' AND is_nullable = 'NO' AND CAST(column_default AS CHAR) = '0')
);
IF source_total_columns = 13 AND source_current_columns = 13
AND (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task'
AND index_name = 'uk_loading_pick_task_plan' AND non_unique = 0
AND seq_in_index = 1 AND column_name = 'loading_plan_id') = 1
AND (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task'
AND index_name = 'uk_loading_pick_task_booking' AND non_unique = 0
AND seq_in_index = 1 AND column_name = 'container_booking_id') = 1
AND (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task'
AND index_name = 'idx_loading_pick_container'
AND ((seq_in_index = 1 AND column_name = 'container_no')
OR (seq_in_index = 2 AND column_name = 'task_status')
OR (seq_in_index = 3 AND column_name = 'started_at'))) = 3
AND (SELECT COUNT(*) FROM information_schema.key_column_usage
WHERE constraint_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task'
AND column_name = 'loading_plan_id' AND referenced_table_name = 'fl_loading_plan'
AND referenced_column_name = 'id') = 1 THEN
SET source_exists = 1;
ELSEIF source_total_columns = 11 AND source_smart_columns = 11 AND source_inbound_columns < 12
AND (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema = 'baiyue_firstleg' AND table_name = 'fl_loading_pick_task'
AND index_name = 'uk_loading_pick_task_plan' AND non_unique = 0
@@ -5843,6 +5882,29 @@ DELIMITER ;
CALL repair_phase3_loading_pick_task_foreign_keys();
DROP PROCEDURE repair_phase3_loading_pick_task_foreign_keys;
-- Existing deployments may predate simulated-container channel grouping. The
-- update trigger below references this column, so upgrade it before compiling
-- the trigger rather than waiting for the later channel-container data block.
DROP PROCEDURE IF EXISTS phase3_add_container_channel_group;
DELIMITER $$
CREATE PROCEDURE phase3_add_container_channel_group()
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg'
AND table_name = 'fl_container_booking'
AND column_name = 'channel_group_code'
) THEN
ALTER TABLE fl_container_booking
ADD COLUMN channel_group_code VARCHAR(64) NULL
COMMENT '模拟柜计划渠道分组;关联真实订舱后继续保留'
AFTER merged_into_container_booking_id;
END IF;
END$$
DELIMITER ;
CALL phase3_add_container_channel_group();
DROP PROCEDURE phase3_add_container_channel_group;
DROP TRIGGER IF EXISTS trg_container_booking_before_update;
DELIMITER $$
CREATE TRIGGER trg_container_booking_before_update
@@ -6451,14 +6513,13 @@ FROM iam_role role
JOIN iam_permission permission
ON permission.tenant_id = 0
AND permission.permission_code IN (
'platform:firstleg:container:list', 'platform:firstleg:container:view',
'platform:firstleg:container:list',
'platform:firstleg:container:create',
'platform:firstleg:container:edit', 'platform:firstleg:smart-loading:list',
'platform:firstleg:smart-loading:assign', 'platform:firstleg:smart-loading:delete',
'platform:firstleg:preload:list', 'platform:firstleg:preload:view',
'platform:firstleg:preload:list',
'platform:firstleg:preload:edit', 'platform:firstleg:preload:complete',
'platform:firstleg:preload:confirm', 'platform:firstleg:loading-list:list',
'platform:firstleg:loading-list:view')
'platform:firstleg:preload:confirm', 'platform:firstleg:loading-list:list')
WHERE role.tenant_id = 0
AND role.role_code IN ('PLATFORM_ADMIN', 'ORDER_OPERATOR');
@@ -6583,13 +6644,13 @@ BEGIN
IF (SELECT COUNT(DISTINCT permission_code) FROM baiyue_iam.iam_permission
WHERE tenant_id = 0 AND app_code = 'PLATFORM' AND status = 'ACTIVE' AND deleted = 0
AND permission_code IN (
'platform:firstleg:container:list', 'platform:firstleg:container:view',
'platform:firstleg:container:list',
'platform:firstleg:container:create', 'platform:firstleg:container:edit',
'platform:firstleg:smart-loading:list', 'platform:firstleg:smart-loading:assign',
'platform:firstleg:smart-loading:delete', 'platform:firstleg:preload:list',
'platform:firstleg:preload:view', 'platform:firstleg:preload:edit',
'platform:firstleg:preload:edit',
'platform:firstleg:preload:complete', 'platform:firstleg:preload:confirm',
'platform:firstleg:loading-list:list', 'platform:firstleg:loading-list:view')) <> 14 THEN
'platform:firstleg:loading-list:list')) <> 11 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:平台权限资源未完整创建';
END IF;
IF (SELECT COUNT(DISTINCT CONCAT(role.role_code, ':', permission.permission_code))
@@ -6599,14 +6660,13 @@ BEGIN
WHERE role.tenant_id = 0 AND role.role_code IN ('PLATFORM_ADMIN', 'ORDER_OPERATOR')
AND permission.tenant_id = 0
AND permission.permission_code IN (
'platform:firstleg:container:list', 'platform:firstleg:container:view',
'platform:firstleg:container:list',
'platform:firstleg:container:create',
'platform:firstleg:container:edit', 'platform:firstleg:smart-loading:list',
'platform:firstleg:smart-loading:assign', 'platform:firstleg:smart-loading:delete',
'platform:firstleg:preload:list', 'platform:firstleg:preload:view',
'platform:firstleg:preload:list',
'platform:firstleg:preload:edit', 'platform:firstleg:preload:complete',
'platform:firstleg:preload:confirm', 'platform:firstleg:loading-list:list',
'platform:firstleg:loading-list:view')) <> 28 THEN
'platform:firstleg:preload:confirm', 'platform:firstleg:loading-list:list')) <> 22 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '智能装柜迁移失败:平台角色授权未完整写入';
END IF;
END$$
@@ -13773,6 +13833,7 @@ CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_query_operatio
CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_query_operation', 'status', '处理状态:PROCESSING处理中、SUCCESS成功');
CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_node_fact', 'id', '标准船节点事实ID');
CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_node_fact', 'query_id', '所属查询任务ID');
CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_node_fact', 'container_booking_id', '所属真实货柜ID');
CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_node_fact', 'event_key', '供应商编码与供应商事件ID组成的幂等键');
CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_node_fact', 'provider_code', '轨迹供应商编码');
CALL queue_column_comment('baiyue_firstleg', 'fl_carrier_schedule_node_fact', 'provider_event_id', '供应商稳定事件ID');
@@ -15955,6 +16016,24 @@ BEGIN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:客户四箱规尺寸配置字段不完整';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = 'baiyue_firstleg'
AND table_name = 'fl_customer_charge_rule'
AND column_name = 'initialization_key'
AND character_maximum_length = 128) <> 1 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_customer_charge_rule'
AND index_name = 'idx_charge_rule_initialization'
AND non_unique = 1
AND ((seq_in_index = 1 AND column_name = 'tenant_id')
OR (seq_in_index = 2 AND column_name = 'initialization_key'))) <> 2 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '统一迁移失败:客户默认计费规则初始化索引未完整创建';
END IF;
IF EXISTS (
SELECT tenant.id
FROM baiyue_iam.iam_tenant tenant