140 lines
8.2 KiB
SQL
140 lines
8.2 KiB
SQL
-- Firstleg -> Finance 费用来源事件和柜次费用模型(MySQL 8,可重复执行)
|
|
|
|
DROP PROCEDURE IF EXISTS firstleg_finance_add_column;
|
|
DELIMITER $$
|
|
CREATE PROCEDURE firstleg_finance_add_column(
|
|
IN target_table VARCHAR(64), IN target_column VARCHAR(64), IN column_definition TEXT
|
|
)
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = DATABASE() AND table_name = target_table AND column_name = target_column
|
|
) THEN
|
|
SET @ddl = CONCAT('ALTER TABLE `', target_table, '` ADD COLUMN `', target_column, '` ', column_definition);
|
|
PREPARE statement FROM @ddl;
|
|
EXECUTE statement;
|
|
DEALLOCATE PREPARE statement;
|
|
END IF;
|
|
END$$
|
|
DELIMITER ;
|
|
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'event_key',
|
|
"VARCHAR(160) NULL COMMENT '费用来源事件幂等键;历史事件允许为空' AFTER event_type");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'event_version',
|
|
"INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '事件信封版本' AFTER event_key");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'aggregate_sequence',
|
|
"INT UNSIGNED NULL COMMENT '同一费用来源的单调版本序号' AFTER event_version");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'payload_hash',
|
|
"CHAR(64) NULL COMMENT '短payload规范化JSON的SHA-256' AFTER aggregate_sequence");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'next_retry_at',
|
|
"DATETIME(3) NULL COMMENT '下一次允许投递时间' AFTER retry_count");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'published_at',
|
|
"DATETIME(3) NULL COMMENT 'Finance确认接收时间' AFTER next_retry_at");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'locked_at',
|
|
"DATETIME(3) NULL COMMENT 'Relay抢占租约时间' AFTER published_at");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'locked_by',
|
|
"VARCHAR(64) NULL COMMENT 'Relay抢占实例ID' AFTER locked_at");
|
|
CALL firstleg_finance_add_column('fl_inbound_outbox', 'last_error',
|
|
"VARCHAR(500) NULL COMMENT '最近一次投递失败摘要,不记录令牌' AFTER locked_by");
|
|
|
|
DROP PROCEDURE IF EXISTS firstleg_finance_add_index;
|
|
DELIMITER $$
|
|
CREATE PROCEDURE firstleg_finance_add_index(
|
|
IN target_table VARCHAR(64), IN target_index VARCHAR(64), IN index_definition TEXT
|
|
)
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE() AND table_name = target_table AND index_name = target_index
|
|
) THEN
|
|
SET @ddl = CONCAT('ALTER TABLE `', target_table, '` ADD ', index_definition);
|
|
PREPARE statement FROM @ddl;
|
|
EXECUTE statement;
|
|
DEALLOCATE PREPARE statement;
|
|
END IF;
|
|
END$$
|
|
DELIMITER ;
|
|
|
|
CALL firstleg_finance_add_index('fl_inbound_outbox', 'uk_inbound_outbox_event_key',
|
|
'UNIQUE KEY `uk_inbound_outbox_event_key` (`event_key`)');
|
|
CALL firstleg_finance_add_index('fl_inbound_outbox', 'idx_inbound_outbox_finance_relay',
|
|
'KEY `idx_inbound_outbox_finance_relay` (`publish_status`, `next_retry_at`, `created_at`, `id`)');
|
|
DROP PROCEDURE IF EXISTS firstleg_finance_add_index;
|
|
|
|
CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
|
|
id BIGINT UNSIGNED NOT NULL COMMENT '柜次费用来源ID',
|
|
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
|
|
loading_plan_id BIGINT UNSIGNED NOT NULL COMMENT '柜次ID,对应fl_loading_plan.id',
|
|
container_booking_id BIGINT UNSIGNED NULL COMMENT '订舱柜ID快照',
|
|
container_no VARCHAR(64) NULL COMMENT '柜号快照',
|
|
fee_item_id BIGINT UNSIGNED NOT NULL COMMENT '平台公共费用项目ID',
|
|
fee_item_code_snapshot VARCHAR(50) NOT NULL COMMENT '费用项目稳定编码快照',
|
|
fee_item_name_snapshot VARCHAR(128) NOT NULL COMMENT '费用项目名称快照',
|
|
direction VARCHAR(16) NOT NULL COMMENT '费用方向:RECEIVABLE应收、PAYABLE应付',
|
|
partner_id BIGINT UNSIGNED NULL COMMENT '应付往来单位ID快照;应收为空',
|
|
partner_name VARCHAR(200) NULL COMMENT '应付往来单位名称快照;应收为空',
|
|
business_date DATE NOT NULL COMMENT '费用业务日期',
|
|
amount DECIMAL(18,2) NOT NULL COMMENT 'CNY费用金额',
|
|
currency CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT '币种,首期固定CNY',
|
|
settlement_included TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否参与财务结算来源池',
|
|
review_status VARCHAR(16) NOT NULL DEFAULT 'PENDING' COMMENT '审核状态:PENDING待审核、APPROVED通过、REJECTED驳回',
|
|
source_status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE' COMMENT '来源状态:ACTIVE有效、VOIDED作废',
|
|
source_version INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '费用来源版本;调整递增,作废携带当前版本',
|
|
remark VARCHAR(500) NULL COMMENT '人工备注',
|
|
reviewer_id BIGINT UNSIGNED NULL COMMENT '审核人ID',
|
|
reviewer_name VARCHAR(64) NULL COMMENT '审核人名称快照',
|
|
reviewed_at DATETIME(3) NULL COMMENT '审核时间',
|
|
review_reason VARCHAR(500) NULL COMMENT '审核驳回原因',
|
|
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID',
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后更新人ID',
|
|
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '最后更新时间',
|
|
PRIMARY KEY (id),
|
|
KEY idx_container_fee_customer_plan (tenant_id, loading_plan_id, source_status),
|
|
KEY idx_container_fee_settlement (tenant_id, review_status, settlement_included, source_status),
|
|
CONSTRAINT chk_container_fee_direction CHECK (direction IN ('RECEIVABLE', 'PAYABLE')),
|
|
CONSTRAINT chk_container_fee_currency CHECK (currency = 'CNY'),
|
|
CONSTRAINT chk_container_fee_amount CHECK (amount >= 0),
|
|
CONSTRAINT chk_container_fee_review CHECK (review_status IN ('PENDING', 'APPROVED', 'REJECTED')),
|
|
CONSTRAINT chk_container_fee_source CHECK (source_status IN ('ACTIVE', 'VOIDED'))
|
|
) ENGINE=InnoDB COMMENT='柜次级人工应收应付费用来源;审核通过且参与结算后同步Finance';
|
|
|
|
CALL firstleg_finance_add_column('fl_container_fee_detail', 'partner_id',
|
|
"BIGINT UNSIGNED NULL COMMENT '应付往来单位ID快照;应收为空' AFTER direction");
|
|
CALL firstleg_finance_add_column('fl_container_fee_detail', 'partner_name',
|
|
"VARCHAR(200) NULL COMMENT '应付往来单位名称快照;应收为空' AFTER partner_id");
|
|
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'partner_id',
|
|
"BIGINT UNSIGNED NULL COMMENT '应付往来单位ID快照;应收为空' AFTER direction");
|
|
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'partner_name',
|
|
"VARCHAR(200) NULL COMMENT '应付往来单位名称快照;应收为空' AFTER partner_id");
|
|
DROP PROCEDURE IF EXISTS firstleg_finance_add_column;
|
|
|
|
DROP PROCEDURE IF EXISTS firstleg_finance_assert_schema;
|
|
DELIMITER $$
|
|
CREATE PROCEDURE firstleg_finance_assert_schema()
|
|
BEGIN
|
|
IF (SELECT COUNT(*) FROM information_schema.columns
|
|
WHERE table_schema = DATABASE() AND table_name = 'fl_inbound_outbox'
|
|
AND column_name IN ('event_key', 'event_version', 'aggregate_sequence', 'payload_hash',
|
|
'next_retry_at', 'published_at', 'locked_at', 'locked_by', 'last_error')) <> 9 THEN
|
|
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:Outbox事件信封字段不完整';
|
|
END IF;
|
|
IF NOT EXISTS (SELECT 1 FROM information_schema.tables
|
|
WHERE table_schema = DATABASE() AND table_name = 'fl_container_fee_detail') THEN
|
|
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:柜次费用表不存在';
|
|
END IF;
|
|
IF (SELECT COUNT(*) FROM information_schema.columns
|
|
WHERE table_schema = DATABASE() AND table_name = 'fl_container_fee_detail'
|
|
AND column_name IN ('partner_id', 'partner_name')) <> 2 THEN
|
|
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:柜次费用往来单位快照字段不完整';
|
|
END IF;
|
|
IF (SELECT COUNT(*) FROM information_schema.columns
|
|
WHERE table_schema = DATABASE() AND table_name = 'fl_inbound_fee_detail'
|
|
AND column_name IN ('partner_id', 'partner_name')) <> 2 THEN
|
|
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:入库费用往来单位快照字段不完整';
|
|
END IF;
|
|
END$$
|
|
DELIMITER ;
|
|
CALL firstleg_finance_assert_schema();
|
|
DROP PROCEDURE IF EXISTS firstleg_finance_assert_schema;
|