rustjr-account-management/migrations/002_account_model_extension.sql
tangweijie d7f81893c5 Initial commit: 完整的 Rust 账户管理系统
- 实现账户管理改进设计文档中的所有核心功能
- 三科目余额管理 (个人余额、劳动报酬、冻结余额)
- 交易状态机 (created → pending → bank_submitted → success/failed/timeout → reversed)
- 三键幂等体系 (JZTxId/BankTxId/SourceKey)
- 优先级扣款规则 (先个人后劳动)
- 在途资金管理 (可用→在途→结转/回退)
- 三账对账闭环 (总账 = 银行账 + 在途净额)
- 补偿服务域 (超时检测、重试、死信队列)
- 虚拟银行模拟器用于业务测试
- 完整的集成测试套件 (133 个测试全部通过)
- Docker 容器化部署配置
- 前端 Vue3 + TypeScript 项目结构
2026-01-05 17:56:01 +08:00

138 lines
6.5 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 账户管理模型扩展 - 数据库迁移脚本
-- 创建时间: 2026-01-05
-- 说明: 扩展三科目余额模型,增强交易状态机
-- =====================================================
-- 1. 扩展账户余额表 - 三科目模型
-- =====================================================
-- 添加三科目余额字段
ALTER TABLE account_balance
ADD COLUMN personal_balance DECIMAL(20,2) DEFAULT 0 COMMENT '个人余额(可用)' AFTER account_type,
ADD COLUMN labor_balance DECIMAL(20,2) DEFAULT 0 COMMENT '劳动报酬(可用)' AFTER personal_balance;
-- 重命名 frozen_amount 为 frozen_balance语义更清晰
ALTER TABLE account_balance
CHANGE COLUMN frozen_amount frozen_balance DECIMAL(20,2) DEFAULT 0 COMMENT '冻结余额(不可用)';
-- 数据迁移:将现有 system_balance 分配到 personal_balance
-- 注意:这是保守迁移,将全部可用余额放入个人余额
UPDATE account_balance
SET personal_balance = system_balance - COALESCE(frozen_balance, 0),
labor_balance = 0
WHERE personal_balance = 0;
-- 添加不变量校验的注释
ALTER TABLE account_balance
COMMENT = '账户余额表 - 不变量: personal_balance + labor_balance + frozen_balance = bank_balance';
-- =====================================================
-- 2. 扩展系统交易表 - 增强状态机和幂等键
-- =====================================================
-- 添加来源幂等键(用于外部入账去重)
ALTER TABLE system_transaction
ADD COLUMN source_key VARCHAR(128) COMMENT '来源幂等键(SourceKey)' AFTER bank_ref_no,
ADD COLUMN submitted_at DATETIME COMMENT '提交银行时间' AFTER confirmed_at,
ADD COLUMN version INT DEFAULT 0 COMMENT '乐观锁版本' AFTER submitted_at;
-- 创建来源幂等键的唯一索引MySQL 自动忽略 NULL 值的唯一约束)
CREATE UNIQUE INDEX idx_source_key ON system_transaction(source_key);
-- 修改状态枚举以支持新状态机
-- 注意MySQL 的 ENUM 修改需要包含所有旧值和新值
ALTER TABLE system_transaction
MODIFY COLUMN status ENUM(
'created', -- 已创建(初始状态)
'pending', -- 待处理(已建立在途)
'bank_submitted', -- 已提交银行
'success', -- 成功
'failed', -- 失败
'timeout', -- 超时
'reversed', -- 已冲正
'processing', -- 兼容旧状态
'confirmed', -- 兼容旧状态
'mismatch' -- 对账不匹配
) DEFAULT 'created' COMMENT '交易状态';
-- 数据迁移:将旧状态映射到新状态
UPDATE system_transaction SET status = 'bank_submitted' WHERE status = 'processing';
UPDATE system_transaction SET status = 'success' WHERE status = 'confirmed';
-- 添加提交时间索引(用于超时检测)
CREATE INDEX idx_submitted_at ON system_transaction(submitted_at);
CREATE INDEX idx_status_submitted ON system_transaction(status, submitted_at);
-- =====================================================
-- 3. 创建在途交易明细表(可选,用于细粒度在途管理)
-- =====================================================
CREATE TABLE IF NOT EXISTS transit_detail (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
account_id BIGINT NOT NULL COMMENT '账户ID',
txn_no VARCHAR(32) NOT NULL COMMENT '关联交易号',
amount DECIMAL(20,2) NOT NULL COMMENT '在途金额',
from_personal DECIMAL(20,2) DEFAULT 0 COMMENT '来自个人余额',
from_labor DECIMAL(20,2) DEFAULT 0 COMMENT '来自劳动报酬',
status ENUM('pending', 'settled', 'rolled_back') DEFAULT 'pending' COMMENT '状态',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
settled_at DATETIME COMMENT '结转/回退时间',
INDEX idx_account_id (account_id),
UNIQUE KEY uk_txn_no (txn_no),
INDEX idx_account_status (account_id, status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='在途交易明细表';
-- =====================================================
-- 4. 创建补偿任务表
-- =====================================================
CREATE TABLE IF NOT EXISTS compensation_task (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
txn_no VARCHAR(32) NOT NULL COMMENT '关联交易号',
task_type ENUM('timeout_check', 'reconcile', 'reverse', 'retry') NOT NULL COMMENT '任务类型',
status ENUM('pending', 'processing', 'completed', 'failed', 'dead_letter') DEFAULT 'pending' COMMENT '任务状态',
retry_count INT DEFAULT 0 COMMENT '重试次数',
max_retries INT DEFAULT 3 COMMENT '最大重试次数',
next_retry_at DATETIME COMMENT '下次重试时间',
error_message TEXT COMMENT '错误信息',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
completed_at DATETIME COMMENT '完成时间',
INDEX idx_status (status),
INDEX idx_next_retry (status, next_retry_at),
INDEX idx_txn_no (txn_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='补偿任务表';
-- =====================================================
-- 5. 创建不变量校验日志表(审计用途)
-- =====================================================
CREATE TABLE IF NOT EXISTS invariant_check_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
account_id BIGINT NOT NULL COMMENT '账户ID',
check_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '校验时间',
personal_balance DECIMAL(20,2) NOT NULL COMMENT '个人余额',
labor_balance DECIMAL(20,2) NOT NULL COMMENT '劳动报酬',
frozen_balance DECIMAL(20,2) NOT NULL COMMENT '冻结余额',
bank_balance DECIMAL(20,2) NOT NULL COMMENT '银行余额',
transit_amount DECIMAL(20,2) NOT NULL COMMENT '在途金额',
is_valid TINYINT(1) NOT NULL COMMENT '是否有效',
difference DECIMAL(20,2) COMMENT '差异金额',
trigger_source VARCHAR(100) COMMENT '触发来源',
INDEX idx_account_time (account_id, check_time),
INDEX idx_is_valid (is_valid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='不变量校验日志表';
-- =====================================================
-- 6. 扩展对账表 - 支持三账对齐
-- =====================================================
-- 添加三账对账结果字段
ALTER TABLE reconciliation_batch
ADD COLUMN bank_total DECIMAL(20,2) COMMENT '银行账汇总' AFTER mismatch_count,
ADD COLUMN transit_net DECIMAL(20,2) COMMENT '在途净额' AFTER bank_total,
ADD COLUMN ledger_total DECIMAL(20,2) COMMENT '总账汇总' AFTER transit_net,
ADD COLUMN three_account_balanced TINYINT(1) DEFAULT NULL COMMENT '三账是否平衡' AFTER ledger_total;