This commit is contained in:
2026-08-20 19:11:43 +08:00
4 changed files with 114 additions and 1 deletions
@@ -11492,9 +11492,76 @@ CALL finance_fee_source_add_column('fin_inbox_event', 'result_resource_id',
"BIGINT UNSIGNED NULL COMMENT '成功处理生成或定位的费用来源快照ID' AFTER payload_hash");
CALL finance_fee_source_add_column('fin_inbox_event', 'error_code',
"VARCHAR(64) NULL COMMENT '处理失败时的稳定FIN错误码' AFTER result_resource_id");
CALL finance_fee_source_add_column('fin_cost', 'cost_origin',
"VARCHAR(24) NOT NULL DEFAULT 'MANUAL' COMMENT '成本来源:MANUAL人工补充、FIRSTLEG_DIRECT_PAID头程直接已付' AFTER cost_type");
CALL finance_fee_source_add_column('fin_cost', 'source_system',
"VARCHAR(32) NULL COMMENT '来源系统,头程直接已付固定FIRSTLEG' AFTER cost_origin");
CALL finance_fee_source_add_column('fin_cost', 'source_type',
"VARCHAR(32) NULL COMMENT '来源费用类型快照' AFTER source_system");
CALL finance_fee_source_add_column('fin_cost', 'source_fee_id',
"BIGINT UNSIGNED NULL COMMENT '来源费用ID' AFTER source_type");
CALL finance_fee_source_add_column('fin_cost', 'source_fee_version',
"INT UNSIGNED NULL COMMENT '来源费用版本' AFTER source_fee_id");
CALL finance_fee_source_add_column('fin_cost', 'source_hash',
"CHAR(64) NULL COMMENT '来源不可变快照SHA-256' AFTER source_fee_version");
CALL finance_fee_source_add_column('fin_cost', 'paid_at',
"DATETIME(3) NULL COMMENT '直接已付时间' AFTER voucher_file_ids");
CALL finance_fee_source_add_column('fin_cost', 'payment_method',
"VARCHAR(32) NULL COMMENT '直接已付方式' AFTER paid_at");
CALL finance_fee_source_add_column('fin_cost', 'payment_reference_no',
"VARCHAR(128) NULL COMMENT '直接已付流水号' AFTER payment_method");
DROP PROCEDURE IF EXISTS finance_fee_source_add_column;
DROP PROCEDURE IF EXISTS finance_fee_source_add_index;
DELIMITER $$
CREATE PROCEDURE finance_fee_source_add_index()
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.statistics
WHERE table_schema=DATABASE() AND table_name='fin_cost'
AND index_name='uk_fin_cost_source_version'
) THEN
ALTER TABLE fin_cost ADD UNIQUE KEY uk_fin_cost_source_version
(source_system, source_type, source_fee_id, source_fee_version);
END IF;
END$$
DELIMITER ;
CALL finance_fee_source_add_index();
DROP PROCEDURE IF EXISTS finance_fee_source_add_index;
ALTER TABLE fin_cost
MODIFY COLUMN cost_type VARCHAR(24) NOT NULL COMMENT '成本归属类型:SINGLE_ORDER单票、CONTAINER_SHARED整柜公共、SOURCE_DIRECT_PAID来源直接已付';
DROP PROCEDURE IF EXISTS finance_fee_source_replace_cost_checks;
DELIMITER $$
CREATE PROCEDURE finance_fee_source_replace_cost_checks()
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.table_constraints
WHERE constraint_schema=DATABASE() AND table_name='fin_cost' AND constraint_name='chk_fin_cost_target') THEN
ALTER TABLE fin_cost DROP CHECK chk_fin_cost_target;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.table_constraints
WHERE constraint_schema=DATABASE() AND table_name='fin_cost' AND constraint_name='chk_fin_cost_origin') THEN
ALTER TABLE fin_cost DROP CHECK chk_fin_cost_origin;
END IF;
ALTER TABLE fin_cost
ADD CONSTRAINT chk_fin_cost_target CHECK (
(cost_type='SINGLE_ORDER' AND order_id IS NOT NULL AND container_id IS NULL)
OR (cost_type='CONTAINER_SHARED' AND container_id IS NOT NULL)
OR (cost_type='SOURCE_DIRECT_PAID' AND (order_id IS NOT NULL OR inbound_id IS NOT NULL OR container_id IS NOT NULL))
),
ADD CONSTRAINT chk_fin_cost_origin CHECK (
(cost_origin='MANUAL' AND source_system IS NULL AND source_type IS NULL AND source_fee_id IS NULL AND source_fee_version IS NULL AND source_hash IS NULL)
OR (cost_origin='FIRSTLEG_DIRECT_PAID' AND source_system='FIRSTLEG' AND source_type IS NOT NULL
AND source_fee_id IS NOT NULL AND source_fee_version IS NOT NULL AND source_hash IS NOT NULL
AND status IN ('CONFIRMED','VOIDED') AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER'))
);
END$$
DELIMITER ;
CALL finance_fee_source_replace_cost_checks();
DROP PROCEDURE IF EXISTS finance_fee_source_replace_cost_checks;
-- 产品确认无历史财务数据;以下兼容值仅用于空环境重复迁移时保证结构收敛。
UPDATE fin_fee_source
SET source_type = COALESCE(source_type, 'INBOUND_FEE'),
@@ -11543,6 +11610,18 @@ BEGIN
'customer_confirmed_by_name','customer_confirmed_at')) <> 4 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Finance客户对账单确认字段不完整';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'fin_cost'
AND column_name IN ('cost_origin','source_system','source_type','source_fee_id',
'source_fee_version','source_hash','paid_at','payment_method',
'payment_reference_no')) <> 9 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Finance直接已付成本字段不完整';
END IF;
IF (SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema=DATABASE() AND table_name='fin_cost'
AND index_name='uk_fin_cost_source_version') <> 4 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Finance直接已付成本唯一索引不完整';
END IF;
END$$
DELIMITER ;
CALL finance_fee_source_assert_schema();
@@ -103,6 +103,38 @@ DELIMITER ;
CALL finance_fee_source_add_index();
DROP PROCEDURE IF EXISTS finance_fee_source_add_index;
ALTER TABLE fin_cost
MODIFY COLUMN cost_type VARCHAR(24) NOT NULL COMMENT '成本归属类型:SINGLE_ORDER单票、CONTAINER_SHARED整柜公共、SOURCE_DIRECT_PAID来源直接已付';
DROP PROCEDURE IF EXISTS finance_fee_source_replace_cost_checks;
DELIMITER $$
CREATE PROCEDURE finance_fee_source_replace_cost_checks()
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.table_constraints
WHERE constraint_schema=DATABASE() AND table_name='fin_cost' AND constraint_name='chk_fin_cost_target') THEN
ALTER TABLE fin_cost DROP CHECK chk_fin_cost_target;
END IF;
IF EXISTS (SELECT 1 FROM information_schema.table_constraints
WHERE constraint_schema=DATABASE() AND table_name='fin_cost' AND constraint_name='chk_fin_cost_origin') THEN
ALTER TABLE fin_cost DROP CHECK chk_fin_cost_origin;
END IF;
ALTER TABLE fin_cost
ADD CONSTRAINT chk_fin_cost_target CHECK (
(cost_type='SINGLE_ORDER' AND order_id IS NOT NULL AND container_id IS NULL)
OR (cost_type='CONTAINER_SHARED' AND container_id IS NOT NULL)
OR (cost_type='SOURCE_DIRECT_PAID' AND (order_id IS NOT NULL OR inbound_id IS NOT NULL OR container_id IS NOT NULL))
),
ADD CONSTRAINT chk_fin_cost_origin CHECK (
(cost_origin='MANUAL' AND source_system IS NULL AND source_type IS NULL AND source_fee_id IS NULL AND source_fee_version IS NULL AND source_hash IS NULL)
OR (cost_origin='FIRSTLEG_DIRECT_PAID' AND source_system='FIRSTLEG' AND source_type IS NOT NULL
AND source_fee_id IS NOT NULL AND source_fee_version IS NOT NULL AND source_hash IS NOT NULL
AND status IN ('CONFIRMED','VOIDED') AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER'))
);
END$$
DELIMITER ;
CALL finance_fee_source_replace_cost_checks();
DROP PROCEDURE IF EXISTS finance_fee_source_replace_cost_checks;
-- 产品确认无历史财务数据;以下兼容值仅用于空环境重复迁移时保证结构收敛。
UPDATE fin_fee_source
SET source_type = COALESCE(source_type, 'INBOUND_FEE'),
@@ -16,6 +16,8 @@ class FinanceFeeSourceMigrationContractTest {
"source_hash", "source_snapshot", "payload_hash", "result_resource_id", "error_code");
assertThat(sql).contains("settlement_mode", "paid_at", "payment_method",
"payment_reference_no", "payment_voucher_file_ids");
assertThat(sql).contains("cost_origin", "FIRSTLEG_DIRECT_PAID", "source_fee_version",
"uk_fin_cost_source_version", "Finance直接已付成本字段不完整");
assertThat(sql).contains("AVAILABLE可结算", "SUPERSEDED已被新版本替代", "VOIDED已作废");
assertThat(sql).contains("finance_fee_source_assert_schema");
}
@@ -44,7 +44,7 @@ class FinanceSqlCommentContractTest {
}
}
assertThat(tableCount).isEqualTo(17);
assertThat(columnCount).isEqualTo(248);
assertThat(columnCount).isEqualTo(257);
assertThat(missing).as("缺少中文业务注释的Finance字段").isEmpty();
}