diff --git a/deploy/sql/README.md b/deploy/sql/README.md index 406fc1eb1..c4cbee23e 100644 --- a/deploy/sql/README.md +++ b/deploy/sql/README.md @@ -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` 和后续共享溢出位迁移完整覆盖,因此不重复内联,避免每次部署无条件删除并重建同名唯一索引。 diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index 69bfac2a6..9b2ad6089 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.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 diff --git a/firstleg/src/main/resources/db/phase2-fba-pricing-migration.sql b/firstleg/src/main/resources/db/phase2-fba-pricing-migration.sql index 1d16fbacb..5024450c5 100644 --- a/firstleg/src/main/resources/db/phase2-fba-pricing-migration.sql +++ b/firstleg/src/main/resources/db/phase2-fba-pricing-migration.sql @@ -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; -- 旧索引可能缺少业务类型、船司和结束时间;用新索引名并存,避免破坏线上依赖。 diff --git a/firstleg/src/test/java/com/baiyue/firstleg/repository/PriceBookSqlContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/repository/PriceBookSqlContractTest.java index a397561f0..ba5693c0e 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/repository/PriceBookSqlContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/repository/PriceBookSqlContractTest.java @@ -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'"); } } diff --git a/iam/src/test/java/com/baiyue/iam/service/TenantCustomerExportTest.java b/iam/src/test/java/com/baiyue/iam/service/TenantCustomerExportTest.java index 0194bb403..91f10ac3f 100644 --- a/iam/src/test/java/com/baiyue/iam/service/TenantCustomerExportTest.java +++ b/iam/src/test/java/com/baiyue/iam/service/TenantCustomerExportTest.java @@ -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 diff --git a/order/src/main/resources/db/phase1-order-extension.sql b/order/src/main/resources/db/phase1-order-extension.sql index 62890d4ee..44cfc7162 100644 --- a/order/src/main/resources/db/phase1-order-extension.sql +++ b/order/src/main/resources/db/phase1-order-extension.sql @@ -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'"); diff --git a/order/src/test/java/com/baiyue/order/service/OrderIdempotencyServiceTest.java b/order/src/test/java/com/baiyue/order/service/OrderIdempotencyServiceTest.java index eb2e4cc6f..38858ccba 100644 --- a/order/src/test/java/com/baiyue/order/service/OrderIdempotencyServiceTest.java +++ b/order/src/test/java/com/baiyue/order/service/OrderIdempotencyServiceTest.java @@ -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) {