2026-08-04 10:07:45 +08:00
SET NAMES utf8mb4 ;
USE baiyue_firstleg ;
-- 二期 FBA 计费增量迁移。通过 information_schema 判断,允许重复部署。
DROP PROCEDURE IF EXISTS phase2_fba_add_column ;
DELIMITER $$
CREATE PROCEDURE phase2_fba_add_column ( IN p_table VARCHAR ( 64 ), IN p_column VARCHAR ( 64 ), IN p_definition TEXT )
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema . COLUMNS
WHERE TABLE_SCHEMA = DATABASE () AND TABLE_NAME = p_table AND COLUMN_NAME = p_column
) THEN
SET @ sql = CONCAT ( 'ALTER TABLE `' , p_table , '` ADD COLUMN `' , p_column , '` ' , p_definition );
PREPARE stmt FROM @ sql ; EXECUTE stmt ; DEALLOCATE PREPARE stmt ;
END IF ;
END $$
DELIMITER ;
CALL phase2_fba_add_column ( 'fl_inbound_order' , 'carrier_id' , "BIGINT UNSIGNED NULL COMMENT '计费船司逻辑ID' AFTER channel_name" );
CALL phase2_fba_add_column ( 'fl_inbound_order' , 'carrier_name' , "VARCHAR(128) NULL COMMENT '计费船司名称快照' AFTER carrier_id" );
2026-08-07 14:46:55 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_order' , 'pricing_tax_mode' , "VARCHAR(16) NULL COMMENT '报价包税维度:TAX_INCLUDED/TAX_EXCLUDED' AFTER tax_mode" );
2026-08-04 10:07:45 +08:00
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'business_type' , "VARCHAR(32) NOT NULL DEFAULT 'FBA' COMMENT '业务或计费类型' AFTER origin_warehouse_name" );
CALL phase2_fba_add_column ( 'fl_customer_charge_rule' , 'version' , "INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号' AFTER deleted" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'version' , "INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号' AFTER deleted" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rule_code' , "VARCHAR(50) NOT NULL DEFAULT '' COMMENT '客户规则编码快照' AFTER carrier_rate_version" );
2026-08-07 14:46:55 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'price_book_version_id' , "BIGINT UNSIGNED NULL COMMENT '整表价格版本ID快照' AFTER carrier_rate_version" );
2026-08-04 10:07:45 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'customer_id' , "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '客户ID快照' AFTER rule_code" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'customer_name' , "VARCHAR(128) NOT NULL DEFAULT '' COMMENT '客户名称快照' AFTER customer_id" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'business_type' , "VARCHAR(32) NOT NULL DEFAULT '' COMMENT '业务类型快照' AFTER customer_name" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'tax_mode' , "VARCHAR(24) NULL COMMENT '包税模式快照' AFTER business_type" );
2026-08-07 14:46:55 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'pricing_tax_mode' , "VARCHAR(16) NULL COMMENT '报价包税维度快照' AFTER tax_mode" );
2026-08-04 10:07:45 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rounding_scale' , "TINYINT UNSIGNED NOT NULL DEFAULT 3 COMMENT '计费量保留位数快照' AFTER tax_mode" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rounding_mode' , "VARCHAR(24) NOT NULL DEFAULT 'CEILING' COMMENT '舍入方式快照' AFTER rounding_scale" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rule_effective_from' , "DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '客户规则生效开始快照' AFTER rounding_mode" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rule_effective_to' , "DATETIME(3) NULL COMMENT '客户规则生效结束快照' AFTER rule_effective_from" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rate_code' , "VARCHAR(50) NOT NULL DEFAULT '' COMMENT '船司价格编码快照' AFTER rule_effective_to" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'origin_warehouse_id' , "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '起运仓ID快照' AFTER rate_code" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'origin_warehouse_name' , "VARCHAR(128) NOT NULL DEFAULT '' COMMENT '起运仓名称快照' AFTER origin_warehouse_id" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'channel_code' , "VARCHAR(64) NOT NULL DEFAULT '' COMMENT '渠道编码快照' AFTER origin_warehouse_name" );
2026-08-07 14:46:55 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'carrier_id' , "BIGINT UNSIGNED NULL COMMENT '历史承运商ID;渠道价格可为空' AFTER channel_code" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'carrier_name' , "VARCHAR(128) NULL COMMENT '历史承运商名称;渠道价格可为空' AFTER carrier_id" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'destination_type' , "VARCHAR(16) NULL COMMENT '目的地类型快照:FBA或OVERSEAS' AFTER carrier_name" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'destination_warehouse_id' , "BIGINT UNSIGNED NULL COMMENT '海外仓或FBA目的仓ID快照' AFTER destination_type" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'destination_name' , "VARCHAR(128) NULL COMMENT '目的仓名称快照' AFTER destination_warehouse_id" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'destination_code' , "VARCHAR(32) NULL COMMENT 'FBA仓编码快照;海外仓可为空' AFTER destination_name" );
2026-08-04 10:07:45 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rate_effective_from' , "DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '价格生效开始快照' AFTER destination_code" );
CALL phase2_fba_add_column ( 'fl_inbound_fee' , 'rate_effective_to' , "DATETIME(3) NULL COMMENT '价格生效结束快照' AFTER rate_effective_from" );
CALL phase2_fba_add_column ( 'fl_inbound_idempotency' , 'result_resource_id' , "BIGINT UNSIGNED NULL COMMENT '成功结果资源ID' AFTER result_json" );
2026-08-05 09:30:08 +08:00
CALL phase2_fba_add_column ( 'fl_inbound_pallet_allocation' , 'warehouse_resource_tenant_id' ,
2026-08-05 16:26:10 +08:00
"BIGINT UNSIGNED NULL COMMENT '平台公共仓储资源固定使用 0;tenant_id 仍是客户隔离键' AFTER warehouse_id" );
2026-08-07 14:46:55 +08:00
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'destination_type' ,
"VARCHAR(16) NULL COMMENT '目的地类型:FBA或OVERSEAS; REGION_WEIGHT_TIER区域阶梯行为空' AFTER carrier_name" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'price_book_version_id' ,
"BIGINT UNSIGNED NULL COMMENT '整表价格版本ID;历史兼容价格可为空' AFTER tenant_id" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'origin_warehouse_code' ,
"VARCHAR(64) NULL COMMENT '起运仓稳定编码' AFTER origin_warehouse_id" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'destination_warehouse_id' ,
"BIGINT UNSIGNED NULL COMMENT '平台海外仓稳定ID;不存环境专属ID' AFTER destination_code" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'destination_name' ,
"VARCHAR(128) NULL COMMENT '目的仓名称快照' AFTER destination_warehouse_id" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'price_model' ,
"VARCHAR(32) NOT NULL DEFAULT 'FBA_WAREHOUSE_RATE' COMMENT '价格模型' AFTER channel_code" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'region_code' ,
"VARCHAR(16) NULL COMMENT '区域阶梯模型区域编码' AFTER destination_code" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'pricing_tax_mode' ,
"VARCHAR(16) NULL COMMENT '报价包税维度;独立于订单tax_mode' AFTER region_code" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'weight_from_kg' ,
"DECIMAL(18,6) NULL COMMENT '区域阶梯起始计费重量KG' AFTER pricing_tax_mode" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'source_sheet_name' ,
"VARCHAR(128) NULL COMMENT '原始Excel Sheet' AFTER additional_fee" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'source_row_number' ,
"INT UNSIGNED NULL COMMENT '原始Excel行号' AFTER source_sheet_name" );
CALL phase2_fba_add_column ( 'fl_carrier_fba_rate' , 'source_destination_text' ,
"VARCHAR(1000) NULL COMMENT '原始组合仓库或区域文本' AFTER source_row_number" );
2026-08-05 09:30:08 +08:00
2026-08-05 16:26:10 +08:00
-- 仓储资源是平台公共主数据;存量分配快照统一迁移到平台作用域 0,再收口非空约束。
2026-08-05 09:30:08 +08:00
UPDATE fl_inbound_pallet_allocation
2026-08-05 16:26:10 +08:00
SET warehouse_resource_tenant_id = 0
WHERE warehouse_resource_tenant_id IS NULL OR warehouse_resource_tenant_id <> 0 ;
SET @ resource_tenant_needs_modify = ( SELECT COUNT ( * ) FROM information_schema . COLUMNS
2026-08-05 09:30:08 +08:00
WHERE TABLE_SCHEMA = DATABASE () AND TABLE_NAME = 'fl_inbound_pallet_allocation'
2026-08-05 16:26:10 +08:00
AND COLUMN_NAME = 'warehouse_resource_tenant_id'
AND ( IS_NULLABLE = 'YES' OR COLUMN_COMMENT <> '平台公共仓储资源固定使用 0;tenant_id 仍是客户隔离键' ));
SET @ sql = IF ( @ resource_tenant_needs_modify > 0 ,
"ALTER TABLE fl_inbound_pallet_allocation MODIFY COLUMN warehouse_resource_tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共仓储资源固定使用 0;tenant_id 仍是客户隔离键'" ,
2026-08-05 09:30:08 +08:00
'SELECT 1' );
PREPARE stmt FROM @ sql ; EXECUTE stmt ; DEALLOCATE PREPARE stmt ;
2026-08-04 10:07:45 +08:00
2026-08-07 14:46:55 +08:00
-- 价格上传确认前,起运仓和区域阶梯目的地可以暂未绑定;确认生效时由 Firstleg 完成映射和类型校验。
ALTER TABLE fl_carrier_fba_rate
MODIFY COLUMN origin_warehouse_id BIGINT UNSIGNED NULL COMMENT '确认前可为空;确认后绑定平台公共起运仓逻辑ID' ,
MODIFY COLUMN carrier_id BIGINT UNSIGNED NULL COMMENT '历史承运商ID;渠道价格可为空' ,
MODIFY COLUMN carrier_name VARCHAR ( 128 ) NULL COMMENT '历史承运商名称;渠道价格可为空' ,
MODIFY COLUMN destination_type VARCHAR ( 16 ) NULL COMMENT '目的地类型:FBA或OVERSEAS; REGION_WEIGHT_TIER区域阶梯行为空' ,
MODIFY COLUMN destination_code VARCHAR ( 32 ) NULL COMMENT 'FBA目的仓编码;区域阶梯模型为空' ;
ALTER TABLE fl_inbound_fee
MODIFY COLUMN charge_rule_id BIGINT UNSIGNED NULL COMMENT '历史客户计费规则ID;渠道价格可为空' ,
MODIFY COLUMN charge_rule_version INT UNSIGNED NULL COMMENT '历史客户规则版本快照' ,
MODIFY COLUMN rule_code VARCHAR ( 50 ) NULL COMMENT '历史客户规则编码快照' ,
MODIFY COLUMN rounding_scale TINYINT UNSIGNED NULL COMMENT '历史客户规则计费量保留位数快照' ,
MODIFY COLUMN rounding_mode VARCHAR ( 24 ) NULL COMMENT '历史客户规则舍入方式快照' ,
MODIFY COLUMN rule_effective_from DATETIME ( 3 ) NULL COMMENT '历史客户规则生效开始快照' ,
MODIFY COLUMN carrier_id BIGINT UNSIGNED NULL COMMENT '历史承运商ID;渠道价格可为空' ,
MODIFY COLUMN carrier_name VARCHAR ( 128 ) NULL COMMENT '历史承运商名称;渠道价格可为空' ,
MODIFY COLUMN destination_code VARCHAR ( 32 ) NULL COMMENT 'FBA仓编码快照;海外仓可为空' ,
MODIFY COLUMN charge_mode VARCHAR ( 16 ) NULL COMMENT '计费口径:KG或CBM' ,
MODIFY COLUMN conversion_factor DECIMAL ( 18 , 6 ) NULL COMMENT '历史客户规则使用的换算系数快照' ;
2026-08-04 10:07:45 +08:00
DROP PROCEDURE IF EXISTS phase2_fba_add_column ;
-- 旧索引可能缺少业务类型、船司和结束时间;用新索引名并存,避免破坏线上依赖。
SET @ idx_exists = ( SELECT COUNT ( * ) FROM information_schema . STATISTICS
WHERE TABLE_SCHEMA = DATABASE () AND TABLE_NAME = 'fl_carrier_fba_rate' AND INDEX_NAME = 'idx_fba_rate_unique_match' );
SET @ sql = IF ( @ idx_exists = 0 ,
'ALTER TABLE fl_carrier_fba_rate ADD INDEX idx_fba_rate_unique_match (tenant_id, origin_warehouse_id, business_type, channel_code, carrier_id, destination_code, charge_unit, status, effective_from, effective_to)' ,
'SELECT 1' );
PREPARE stmt FROM @ sql ; EXECUTE stmt ; DEALLOCATE PREPARE stmt ;