diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index 0826af4d1..117fbfe82 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -3139,6 +3139,8 @@ CREATE TABLE IF NOT EXISTS fl_inbound_fee ( actual_weight_kg DECIMAL(18,3) NOT NULL COMMENT '试算时实际重量kg', actual_volume_cbm DECIMAL(18,4) NOT NULL COMMENT '试算时实际体积m3', converted_quantity DECIMAL(18,4) NOT NULL COMMENT '换算后的重量或体积', + baseline_chargeable_quantity DECIMAL(18,6) NOT NULL COMMENT '系统按权威测量与生效报价计算的原始计费量', + tolerance_percent DECIMAL(5,2) NOT NULL DEFAULT 10.00 COMMENT '人工调整允许的最大偏差百分比,边界包含', chargeable_quantity DECIMAL(18,4) NOT NULL COMMENT '最终计费量', charge_unit VARCHAR(16) NOT NULL COMMENT '计费单位', currency CHAR(3) NOT NULL COMMENT '币种', @@ -3172,6 +3174,32 @@ ALTER TABLE fl_inbound_fee MODIFY COLUMN customer_id BIGINT UNSIGNED NULL COMMENT '可选业务客户快照;平台公共渠道计费不依赖该字段'; +SET @fee_baseline_quantity_sql = IF( + EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() + AND table_name='fl_inbound_fee' AND column_name='baseline_chargeable_quantity'), + 'SELECT 1', + 'ALTER TABLE fl_inbound_fee ADD COLUMN baseline_chargeable_quantity DECIMAL(18,6) NULL COMMENT ''系统按权威测量与生效报价计算的原始计费量'' AFTER converted_quantity' +); +PREPARE fee_baseline_quantity_stmt FROM @fee_baseline_quantity_sql; +EXECUTE fee_baseline_quantity_stmt; +DEALLOCATE PREPARE fee_baseline_quantity_stmt; +UPDATE fl_inbound_fee + SET baseline_chargeable_quantity = chargeable_quantity + WHERE baseline_chargeable_quantity IS NULL; +ALTER TABLE fl_inbound_fee + MODIFY COLUMN baseline_chargeable_quantity DECIMAL(18,6) NOT NULL + COMMENT '系统按权威测量与生效报价计算的原始计费量'; + +SET @fee_tolerance_percent_sql = IF( + EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() + AND table_name='fl_inbound_fee' AND column_name='tolerance_percent'), + 'SELECT 1', + 'ALTER TABLE fl_inbound_fee ADD COLUMN tolerance_percent DECIMAL(5,2) NOT NULL DEFAULT 10.00 COMMENT ''人工调整允许的最大偏差百分比,边界包含'' AFTER baseline_chargeable_quantity' +); +PREPARE fee_tolerance_percent_stmt FROM @fee_tolerance_percent_sql; +EXECUTE fee_tolerance_percent_stmt; +DEALLOCATE PREPARE fee_tolerance_percent_stmt; + CREATE TABLE IF NOT EXISTS fl_inbound_fee_item ( id BIGINT UNSIGNED NOT NULL COMMENT '费用明细ID', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键', @@ -13479,10 +13507,12 @@ CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'charge_rule_id', CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'charge_rule_version', '历史客户规则版本快照'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'charge_unit', '计费单位'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'chargeable_quantity', '最终计费量'); +CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'baseline_chargeable_quantity', '系统按权威测量与生效报价计算的原始计费量'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'confirmed_at', '确认时间'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'confirmed_by', '确认人ID'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'conversion_factor', '历史客户规则使用的换算系数快照'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'converted_quantity', '换算后的重量或体积'); +CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'tolerance_percent', '人工调整允许的最大偏差百分比,边界包含'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'created_at', '创建时间'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'currency', '币种'); CALL queue_column_comment('baiyue_firstleg', 'fl_inbound_fee', 'customer_id', '客户ID快照'); @@ -15159,6 +15189,15 @@ BEGIN 'baiyue_firstleg','baiyue_file','baiyue_audit','baiyue_event_bridge','baiyue_finance'))<>9 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '统一迁移失败:九个业务数据库未完整创建'; END IF; + IF (SELECT COUNT(*) FROM information_schema.columns + WHERE table_schema='baiyue_firstleg' AND table_name='fl_inbound_fee' + AND ((column_name='baseline_chargeable_quantity' AND is_nullable='NO' + AND numeric_precision=18 AND numeric_scale=6) + OR (column_name='tolerance_percent' AND is_nullable='NO' + AND numeric_precision=5 AND numeric_scale=2))) <> 2 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '统一迁移失败:入库费用基准计费量或容差字段不完整'; + END IF; IF (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='baiyue_iam' AND table_name='iam_tenant' AND column_name='dimension_initialization_status') <> 1 diff --git a/scripts/inbound-fee-unified-sql-contract.test.mjs b/scripts/inbound-fee-unified-sql-contract.test.mjs new file mode 100644 index 000000000..ea9f3ecd3 --- /dev/null +++ b/scripts/inbound-fee-unified-sql-contract.test.mjs @@ -0,0 +1,22 @@ +import assert from 'node:assert/strict' +import { readFileSync } from 'node:fs' +import test from 'node:test' + +const unified = readFileSync(new URL('../deploy/sql/头程数据库统一增量-MySQL8.sql', import.meta.url), 'utf8') +const firstleg = readFileSync(new URL('../firstleg/src/main/resources/db/phase2-inbound-schema.sql', import.meta.url), 'utf8') + +test('统一增量与 Firstleg 入库费用计费基准和容差字段一致', () => { + for (const source of [unified, firstleg]) { + assert.match(source, /baseline_chargeable_quantity DECIMAL\(18,6\) NOT NULL/) + assert.match(source, /tolerance_percent DECIMAL\(5,2\) NOT NULL DEFAULT 10\.00/) + assert.match(source, /SET baseline_chargeable_quantity = chargeable_quantity\s+WHERE baseline_chargeable_quantity IS NULL/) + assert.match(source, /MODIFY COLUMN baseline_chargeable_quantity DECIMAL\(18,6\) NOT NULL/) + } +}) + +test('统一增量最终检查阻止缺少入库费用计费字段的部署通过', () => { + const finalAssertion = unified.slice(unified.indexOf('CREATE PROCEDURE assert_unified_final_schema()')) + assert.match(finalAssertion, /column_name='baseline_chargeable_quantity'[\s\S]*numeric_precision=18 AND numeric_scale=6/) + assert.match(finalAssertion, /column_name='tolerance_percent'[\s\S]*numeric_precision=5 AND numeric_scale=2/) + assert.match(finalAssertion, /统一迁移失败:入库费用基准计费量或容差字段不完整/) +})