This commit is contained in:
2026-08-07 15:19:21 +08:00
parent b0ea1a0c5c
commit a4a03a8ae8
7 changed files with 38 additions and 148 deletions
+1
View File
@@ -5,6 +5,7 @@
- 固定入口:`头程数据库统一增量-MySQL8.sql`。文件名保留历史兼容,内容维护为当前完整数据库基线和存量环境兼容升级,不再按日期拆分发布脚本。
- 该脚本汇总一期、二期及已实现三期出仓能力的数据库基线、存量升级、IAM 权限资源和最终结构校验,适用于 MySQL 8.0。
- 正式上线前的数据库变更直接维护该文件中的当前基线、存量兼容处理和最终校验,不再创建按日期拆分的发布 SQL;正式上线后的迁移策略在生产发布规范中另行冻结。
- 当前测试环境尚未上线,船期价格表相关表、字段和索引只维护在现有初始化建表定义及本固定入口中,不向 `phase1-order-extension.sql`、`phase2-fba-pricing-migration.sql` 或新的增量脚本追加同一结构。
- 模块 `src/main/resources/db/` 下的 SQL 用于开发溯源;`deploy/sql/` 下已有日期文件全部冻结为历史记录,不再单独部署,也不得与固定入口重复执行。
- 固定入口不包含 `auth/phase1-admin-accounts.sql` 和 `warehouse/warehouse-seed.sql`,不会写入固定密码账号、演示仓库、演示快递公司或演示订单;正式平台公共仓库主数据已内联到固定入口。
- `warehouse/phase2-pallet-location-schema-migration.sql` 的有效结构已被当前 `phase2-pallet-location-schema.sql` 和后续共享溢出位迁移完整覆盖,因此不重复内联,避免每次部署无条件删除并重建同名唯一索引。
@@ -1525,7 +1525,6 @@ CALL phase1_add_column('ord_order', 'receiving_time', "VARCHAR(128) NULL COMMENT
CALL phase1_add_column('ord_order', 'channel_code', "VARCHAR(64) NULL COMMENT 'Shipping channel code'");
CALL phase1_add_column('ord_order', 'channel_name', "VARCHAR(128) NULL COMMENT 'Shipping channel snapshot'");
CALL phase1_add_column('ord_order', 'tax_mode', "VARCHAR(24) NULL COMMENT 'BUY_DECLARATION or TAX_REFUND'");
CALL phase1_add_column('ord_order', 'pricing_tax_mode', "VARCHAR(16) NULL COMMENT 'TAX_INCLUDED or TAX_EXCLUDED; independent from tax_mode'");
CALL phase1_add_column('ord_order', 'container_mode', "VARCHAR(24) NULL COMMENT 'FULL_CONTAINER or LCL'");
CALL phase1_add_column('ord_order', 'customs_inspection', "TINYINT(1) NULL COMMENT 'Whether customs inspection is required'");
CALL phase1_add_column('ord_order', 'destination_type', "VARCHAR(24) NULL COMMENT 'FBA, OVERSEAS or PRIVATE'");
@@ -2278,6 +2277,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_order (
carrier_id BIGINT UNSIGNED NULL COMMENT '计费船司逻辑ID',
carrier_name VARCHAR(128) NULL COMMENT '计费船司名称快照',
tax_mode VARCHAR(24) NULL COMMENT '买单或退税模式',
pricing_tax_mode VARCHAR(16) NULL COMMENT '报价包税维度:TAX_INCLUDED/TAX_EXCLUDED',
container_mode VARCHAR(24) NULL COMMENT '整柜或散货模式',
customs_inspection TINYINT(1) NULL COMMENT '是否商检',
destination_type VARCHAR(24) NULL COMMENT '目的仓类型',
@@ -2574,19 +2574,31 @@ CREATE TABLE IF NOT EXISTS fl_customer_charge_rule (
CREATE TABLE IF NOT EXISTS fl_carrier_fba_rate (
id BIGINT UNSIGNED NOT NULL COMMENT '船司FBA价格ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '平台价格作用域ID,船司价格固定为0',
price_book_version_id BIGINT UNSIGNED NULL COMMENT '整表价格版本ID;历史兼容价格可为空',
rate_code VARCHAR(50) NOT NULL COMMENT '平台公共价格编码',
rate_version INT UNSIGNED NOT NULL COMMENT '价格版本号',
origin_warehouse_id BIGINT UNSIGNED NULL COMMENT '确认前可为空;确认后绑定平台公共起运仓逻辑ID',
origin_warehouse_code VARCHAR(64) NULL COMMENT '起运仓稳定编码',
origin_warehouse_name VARCHAR(128) NOT NULL COMMENT '起运仓名称快照',
business_type VARCHAR(32) NOT NULL COMMENT '业务或计费类型',
channel_code VARCHAR(64) NULL COMMENT '渠道编码',
price_model VARCHAR(32) NOT NULL DEFAULT 'FBA_WAREHOUSE_RATE' COMMENT '价格模型',
carrier_id BIGINT UNSIGNED NULL COMMENT '船司逻辑ID',
carrier_name VARCHAR(128) NULL COMMENT '历史承运商名称;渠道价格可为空',
destination_type VARCHAR(16) NULL COMMENT '目的地类型:FBA或OVERSEAS;REGION_WEIGHT_TIER区域阶梯行为空',
destination_code VARCHAR(32) NULL COMMENT 'FBA目的仓编码;区域阶梯模型为空',
destination_warehouse_id BIGINT UNSIGNED NULL COMMENT '平台海外仓稳定ID;不存环境专属ID',
destination_name VARCHAR(128) NULL COMMENT '目的仓名称快照',
region_code VARCHAR(16) NULL COMMENT '区域阶梯模型区域编码',
pricing_tax_mode VARCHAR(16) NULL COMMENT '报价包税维度;独立于订单tax_mode',
weight_from_kg DECIMAL(18,6) NULL COMMENT '区域阶梯起始计费重量KG',
charge_unit VARCHAR(16) NOT NULL COMMENT '计费单位:KG或CBM',
unit_price DECIMAL(18,6) NOT NULL COMMENT '基础单价',
currency CHAR(3) NOT NULL COMMENT '币种',
additional_fee DECIMAL(18,2) NOT NULL DEFAULT 0 COMMENT '固定附加费',
source_sheet_name VARCHAR(128) NULL COMMENT '原始Excel Sheet',
source_row_number INT UNSIGNED NULL COMMENT '原始Excel行号',
source_destination_text VARCHAR(1000) NULL COMMENT '原始组合仓库或区域文本',
effective_from DATETIME(3) NOT NULL COMMENT '生效开始时间',
effective_to DATETIME(3) NULL COMMENT '生效结束时间',
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE' COMMENT '价格状态',
@@ -2599,7 +2611,10 @@ CREATE TABLE IF NOT EXISTS fl_carrier_fba_rate (
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (id),
UNIQUE KEY uk_fba_rate_version (tenant_id, rate_code, rate_version),
KEY idx_fba_rate_match (tenant_id, origin_warehouse_id, business_type, channel_code, carrier_id, destination_code, charge_unit, status, effective_from, effective_to)
KEY idx_fba_rate_match (tenant_id, origin_warehouse_id, business_type, channel_code, carrier_id, destination_type, destination_code, destination_warehouse_id, charge_unit, status, effective_from, effective_to),
KEY idx_fba_rate_book (price_book_version_id, channel_code, origin_warehouse_id, price_model, status),
KEY idx_fba_rate_destination (price_book_version_id, channel_code, origin_warehouse_id, destination_type, destination_warehouse_id, destination_code),
KEY idx_fba_rate_region (price_book_version_id, channel_code, origin_warehouse_id, region_code, weight_from_kg)
) ENGINE=InnoDB COMMENT='船司FBA目的仓价格版本';
CREATE TABLE IF NOT EXISTS fl_inbound_fee (
@@ -2617,7 +2632,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_fee (
customer_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID快照',
customer_name VARCHAR(128) NOT NULL COMMENT '客户名称快照',
business_type VARCHAR(32) NOT NULL COMMENT '业务类型快照',
tax_mode VARCHAR(24) NULL COMMENT '包税模式快照',
tax_mode VARCHAR(24) NULL COMMENT '订单买单或退税模式快照',
pricing_tax_mode VARCHAR(16) NULL COMMENT '报价包税维度快照',
rounding_scale TINYINT UNSIGNED NULL COMMENT '历史客户规则计费量保留位数快照',
rounding_mode VARCHAR(24) NULL COMMENT '历史客户规则舍入方式快照',
@@ -3064,17 +3079,14 @@ 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");
CALL phase2_fba_add_column('fl_inbound_order', 'pricing_tax_mode', "VARCHAR(16) NULL COMMENT '报价包税维度:TAX_INCLUDED/TAX_EXCLUDED' AFTER tax_mode");
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");
CALL phase2_fba_add_column('fl_inbound_fee', 'price_book_version_id', "BIGINT UNSIGNED NULL COMMENT '整表价格版本ID快照' AFTER carrier_rate_version");
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");
CALL phase2_fba_add_column('fl_inbound_fee', 'pricing_tax_mode', "VARCHAR(16) NULL COMMENT '报价包税维度快照' AFTER tax_mode");
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");
@@ -3083,61 +3095,14 @@ CALL phase2_fba_add_column('fl_inbound_fee', 'rate_code', "VARCHAR(50) NOT NULL
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");
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");
CALL phase2_fba_add_column('fl_inbound_fee', 'carrier_id', "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '船司ID快照' AFTER channel_code");
CALL phase2_fba_add_column('fl_inbound_fee', 'carrier_name', "VARCHAR(128) NOT NULL DEFAULT '' COMMENT '船司名称快照' AFTER carrier_id");
CALL phase2_fba_add_column('fl_inbound_fee', 'destination_code', "VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'FBA仓编码快照' AFTER carrier_name");
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");
CALL phase2_fba_add_column('fl_inbound_pallet_allocation', 'warehouse_resource_tenant_id',
"BIGINT UNSIGNED NULL COMMENT '平台公共仓储资源固定使用 0;tenant_id 仍是客户隔离键' AFTER warehouse_id");
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_type',
"VARCHAR(16) NULL COMMENT '目的地类型:FBA或OVERSEAS;REGION_WEIGHT_TIER区域阶梯行为空' AFTER carrier_name");
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");
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 '历史客户规则使用的换算系数快照';
-- 仓储资源是平台公共主数据;存量分配快照统一迁移到平台作用域 0,再收口非空约束。
UPDATE fl_inbound_pallet_allocation
@@ -3152,34 +3117,7 @@ SET @sql = IF(@resource_tenant_needs_modify > 0,
'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- 旧索引可能缺少业务类型、船司和结束时间;用新索引名并存,避免破坏线上依赖。
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_type, destination_code, destination_warehouse_id, charge_unit, status, effective_from, effective_to)',
'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
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_book');
SET @sql = IF(@idx_exists = 0,
'ALTER TABLE fl_carrier_fba_rate ADD INDEX idx_fba_rate_book (price_book_version_id, channel_code, origin_warehouse_id, price_model, status)',
'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
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_destination');
SET @sql = IF(@idx_exists = 0,
'ALTER TABLE fl_carrier_fba_rate ADD INDEX idx_fba_rate_destination (price_book_version_id, channel_code, origin_warehouse_id, destination_type, destination_warehouse_id, destination_code)',
'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
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_region');
SET @sql = IF(@idx_exists = 0,
'ALTER TABLE fl_carrier_fba_rate ADD INDEX idx_fba_rate_region (price_book_version_id, channel_code, origin_warehouse_id, region_code, weight_from_kg)',
'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
DROP PROCEDURE IF EXISTS phase2_fba_add_column;
CREATE TABLE IF NOT EXISTS fl_price_channel_catalog (
id BIGINT UNSIGNED NOT NULL COMMENT '渠道目录ID',
@@ -3236,9 +3174,6 @@ CREATE TABLE IF NOT EXISTS fl_price_book_version (
KEY idx_price_book_source_hash (tenant_id, source_sha256)
) ENGINE=InnoDB COMMENT='平台公共船期价格整表版本';
ALTER TABLE fl_price_book_version
MODIFY COLUMN status VARCHAR(24) NOT NULL DEFAULT 'PENDING_CONFIRMATION' COMMENT '待确认上传记录;ACTIVE/SUPERSEDED/FAILED';
CREATE TABLE IF NOT EXISTS fl_price_book_channel (
id BIGINT UNSIGNED NOT NULL COMMENT '版本渠道快照ID',
price_book_version_id BIGINT UNSIGNED NOT NULL COMMENT '整表价格版本ID',
@@ -3262,10 +3197,6 @@ CREATE TABLE IF NOT EXISTS fl_price_book_channel (
) ENGINE=InnoDB COMMENT='价格版本渠道及船期快照';
CALL phase2_fba_add_column('fl_price_book_version', 'parse_issues_json',
"JSON NULL COMMENT '上传解析问题及待确认重新校验结果' AFTER warning_count");
DROP PROCEDURE IF EXISTS phase2_fba_add_column;
INSERT INTO fl_price_channel_catalog
(id, channel_code, display_name, price_model, source_sheet_name, aliases_json, status)
VALUES
@@ -18,17 +18,14 @@ 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");
CALL phase2_fba_add_column('fl_inbound_order', 'pricing_tax_mode', "VARCHAR(16) NULL COMMENT '报价包税维度:TAX_INCLUDED/TAX_EXCLUDED' AFTER tax_mode");
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");
CALL phase2_fba_add_column('fl_inbound_fee', 'price_book_version_id', "BIGINT UNSIGNED NULL COMMENT '整表价格版本ID快照' AFTER carrier_rate_version");
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");
CALL phase2_fba_add_column('fl_inbound_fee', 'pricing_tax_mode', "VARCHAR(16) NULL COMMENT '报价包税维度快照' AFTER tax_mode");
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");
@@ -37,41 +34,14 @@ CALL phase2_fba_add_column('fl_inbound_fee', 'rate_code', "VARCHAR(50) NOT NULL
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");
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");
CALL phase2_fba_add_column('fl_inbound_fee', 'carrier_id', "BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '船司ID快照' AFTER channel_code");
CALL phase2_fba_add_column('fl_inbound_fee', 'carrier_name', "VARCHAR(128) NOT NULL DEFAULT '' COMMENT '船司名称快照' AFTER carrier_id");
CALL phase2_fba_add_column('fl_inbound_fee', 'destination_code', "VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'FBA仓编码快照' AFTER carrier_name");
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");
CALL phase2_fba_add_column('fl_inbound_pallet_allocation', 'warehouse_resource_tenant_id',
"BIGINT UNSIGNED NULL COMMENT '平台公共仓储资源固定使用 0;tenant_id 仍是客户隔离键' AFTER warehouse_id");
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");
-- 仓储资源是平台公共主数据;存量分配快照统一迁移到平台作用域 0,再收口非空约束。
UPDATE fl_inbound_pallet_allocation
@@ -86,27 +56,6 @@ SET @sql = IF(@resource_tenant_needs_modify > 0,
'SELECT 1');
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
-- 价格上传确认前,起运仓和区域阶梯目的地可以暂未绑定;确认生效时由 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 '历史客户规则使用的换算系数快照';
DROP PROCEDURE IF EXISTS phase2_fba_add_column;
-- 旧索引可能缺少业务类型、船司和结束时间;用新索引名并存,避免破坏线上依赖。
@@ -15,6 +15,8 @@ class PriceBookSqlContractTest {
void shouldProvidePriceBookTables() throws Exception {
String schema = new ClassPathResource("db/phase2-inbound-schema.sql")
.getContentAsString(StandardCharsets.UTF_8);
String migration = new ClassPathResource("db/phase2-fba-pricing-migration.sql")
.getContentAsString(StandardCharsets.UTF_8);
assertThat(schema)
.contains("CREATE TABLE IF NOT EXISTS fl_price_channel_catalog")
.contains("CREATE TABLE IF NOT EXISTS fl_price_origin_alias")
@@ -30,5 +32,9 @@ class PriceBookSqlContractTest {
.contains("destination_name VARCHAR(128)")
.contains("parse_issues_json JSON NULL")
.contains("DEFAULT 'PENDING_CONFIRMATION'");
assertThat(migration)
.doesNotContain("fl_price_book_version")
.doesNotContain("'pricing_tax_mode'")
.doesNotContain("'price_book_version_id'");
}
}
@@ -1,5 +1,6 @@
package com.baiyue.iam.service;
import com.baiyue.iam.client.AuthAccountClient;
import com.baiyue.iam.entity.IamTenant;
import com.baiyue.iam.repository.ProfileResourceRepository;
import com.baiyue.iam.repository.TenantRepository;
@@ -20,6 +21,7 @@ import static org.mockito.Mockito.when;
class TenantCustomerExportTest {
@MockBean private TenantRepository repository;
@MockBean private ProfileResourceRepository profileRepository;
@MockBean private AuthAccountClient authAccountClient;
@MockBean private TenantApprovalInitializationCoordinator approvalInitialization;
@Resource private TenantService service;
@Test
@@ -33,7 +33,6 @@ CALL phase1_add_column('ord_order', 'receiving_time', "VARCHAR(128) NULL COMMENT
CALL phase1_add_column('ord_order', 'channel_code', "VARCHAR(64) NULL COMMENT 'Shipping channel code'");
CALL phase1_add_column('ord_order', 'channel_name', "VARCHAR(128) NULL COMMENT 'Shipping channel snapshot'");
CALL phase1_add_column('ord_order', 'tax_mode', "VARCHAR(24) NULL COMMENT 'BUY_DECLARATION or TAX_REFUND'");
CALL phase1_add_column('ord_order', 'pricing_tax_mode', "VARCHAR(16) NULL COMMENT 'TAX_INCLUDED or TAX_EXCLUDED; independent from tax_mode'");
CALL phase1_add_column('ord_order', 'container_mode', "VARCHAR(24) NULL COMMENT 'FULL_CONTAINER or LCL'");
CALL phase1_add_column('ord_order', 'customs_inspection', "TINYINT(1) NULL COMMENT 'Whether customs inspection is required'");
CALL phase1_add_column('ord_order', 'destination_type', "VARCHAR(24) NULL COMMENT 'FBA, OVERSEAS or PRIVATE'");
@@ -163,17 +163,19 @@ class OrderIdempotencyServiceTest {
}
@Test
void newAndExistingDatabaseScriptsContainActualOrderWriteFields() throws Exception {
void baselineContainsCurrentOrderWriteFieldsWithoutAddingPreLaunchPricingMigration() throws Exception {
String baseline = new ClassPathResource("db/order.sql").getContentAsString(StandardCharsets.UTF_8);
String migration = new ClassPathResource("db/phase1-order-extension.sql")
.getContentAsString(StandardCharsets.UTF_8);
for (String column : new String[] {
"receiving_warehouse_address", "receiving_time", "express_company", "express_tracking_no", "pricing_tax_mode"
"receiving_warehouse_address", "receiving_time", "express_company", "express_tracking_no"
}) {
assertThat(baseline).contains(column);
assertThat(migration).contains(column);
}
assertThat(baseline).contains("pricing_tax_mode");
assertThat(migration).doesNotContain("phase1_add_column('ord_order', 'pricing_tax_mode'");
}
private OrderApplicationService service(OrderRepository repository) {