This commit is contained in:
wuweihua
2026-09-20 17:12:18 +08:00
52 changed files with 3948 additions and 790 deletions
+211
View File
@@ -22,6 +22,7 @@ CREATE TABLE IF NOT EXISTS ar_bill (
written_off_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '已核销金额缓存',
unwritten_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '未核销金额缓存',
status VARCHAR(30) NOT NULL COMMENT '状态:DRAFT=草稿,CONFIRMED=已确认,PARTIAL_WRITTEN_OFF=部分核销,WRITTEN_OFF=已核销,VOID=已作废',
generation_status VARCHAR(20) NOT NULL DEFAULT 'READY' COMMENT '生成状态:GENERATING=生成中,READY=可用,FAILED=生成失败',
bill_version INT(11) NOT NULL DEFAULT 1 COMMENT '账单版本',
bank_account_name VARCHAR(100) DEFAULT NULL COMMENT '收款账户名称快照',
bank_account_no VARCHAR(128) DEFAULT NULL COMMENT '收款账号快照,应用层脱敏展示',
@@ -40,6 +41,34 @@ CREATE TABLE IF NOT EXISTS ar_bill (
KEY idx_ar_bill_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='正式应收账单主表';
CREATE TABLE IF NOT EXISTS ar_bill_generate_task (
task_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '生成任务ID',
task_no VARCHAR(50) NOT NULL COMMENT '生成任务编号',
ar_bill_id BIGINT(20) NOT NULL COMMENT '应收账单ID',
selection_mode VARCHAR(20) NOT NULL COMMENT '选择模式:EXPLICIT=手动选择,ALL_MATCHED=全选查询结果',
request_payload LONGTEXT NOT NULL COMMENT '生成请求快照JSON',
snapshot_create_time DATETIME DEFAULT NULL COMMENT '来源订单创建时间快照',
last_source_bill_id VARCHAR(36) DEFAULT NULL COMMENT '来源订单游标',
total_count INT(11) NOT NULL DEFAULT -1 COMMENT '待处理订单数,-1表示尚未统计',
processed_count INT(11) NOT NULL DEFAULT 0 COMMENT '已处理订单数',
success_count INT(11) NOT NULL DEFAULT 0 COMMENT '成功订单数',
total_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '当前生成金额',
status VARCHAR(30) NOT NULL COMMENT '任务状态:WAITING=待处理,RUNNING=生成中,SUCCESS=生成成功,FAILED=生成失败,CANCEL_REQUESTED=取消中,CANCELED=已取消',
error_message VARCHAR(1000) DEFAULT NULL COMMENT '错误信息',
request_token VARCHAR(64) NOT NULL COMMENT '请求幂等标识',
create_by VARCHAR(64) NOT NULL COMMENT '创建人',
create_time DATETIME NOT NULL COMMENT '创建时间',
started_at DATETIME DEFAULT NULL COMMENT '开始时间',
heartbeat_time DATETIME DEFAULT NULL COMMENT '最近心跳时间',
finished_at DATETIME DEFAULT NULL COMMENT '完成时间',
PRIMARY KEY (task_id),
UNIQUE KEY uk_ar_bill_generate_task_no (task_no),
UNIQUE KEY uk_ar_bill_generate_request_token (request_token),
KEY idx_ar_bill_generate_status (status, create_time),
KEY idx_ar_bill_generate_creator (create_by, status, create_time),
KEY idx_ar_bill_generate_bill (ar_bill_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应收账单异步生成任务';
CREATE TABLE IF NOT EXISTS ar_bill_detail (
detail_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '账单订单明细ID',
ar_bill_id BIGINT(20) NOT NULL COMMENT '应收账单ID',
@@ -98,13 +127,54 @@ CREATE TABLE IF NOT EXISTS ar_bill_detail_fee (
CONSTRAINT fk_ar_detail_fee_detail FOREIGN KEY (detail_id) REFERENCES ar_bill_detail (detail_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应收账单费用快照';
CREATE TABLE IF NOT EXISTS ar_export_template (
template_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '导出模板ID',
template_code VARCHAR(50) NOT NULL COMMENT '模板编码,例如 AR_CUSTOMER_BILL',
template_name VARCHAR(100) NOT NULL COMMENT '模板名称',
business_type VARCHAR(50) NOT NULL COMMENT '业务类型,例如 AR_BILL',
template_version VARCHAR(50) NOT NULL COMMENT '模板版本,已启用版本不可覆盖',
storage_type VARCHAR(20) NOT NULL DEFAULT 'CLASSPATH' COMMENT '存储类型:CLASSPATH=应用内置资源,FILE=服务器文件,OSS=对象存储,MINIO=MinIO对象存储',
storage_key VARCHAR(500) NOT NULL COMMENT '模板文件存储Key或classpath资源路径',
file_hash VARCHAR(128) DEFAULT NULL COMMENT '模板文件SHA-256校验值',
status VARCHAR(20) NOT NULL DEFAULT 'ENABLED' COMMENT '状态:ENABLED=启用,DISABLED=停用',
is_default CHAR(1) NOT NULL DEFAULT '0' COMMENT '是否默认模板:1是0否',
effective_start DATE DEFAULT NULL COMMENT '生效开始日期',
effective_end DATE DEFAULT NULL COMMENT '生效结束日期',
remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
create_by VARCHAR(64) NOT NULL COMMENT '创建人',
create_time DATETIME NOT NULL COMMENT '创建时间',
update_by VARCHAR(64) DEFAULT NULL COMMENT '更新人',
update_time DATETIME DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (template_id),
UNIQUE KEY uk_ar_export_template_code_version (business_type, template_code, template_version),
KEY idx_ar_export_template_default (business_type, status, is_default, effective_start, effective_end)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应收账单导出模板管理';
INSERT INTO ar_export_template (
template_code, template_name, business_type, template_version, storage_type, storage_key,
file_hash, status, is_default, create_by, create_time, remark
)
SELECT
'AR_CUSTOMER_BILL', '应收账单默认模板', 'AR_BILL', '1.0', 'CLASSPATH',
'templates/ar/ar_bill_template.xlsx', '735002ac3561e0579b724c0612a2c5ce2d6725bc7fd39c450b0aeff70911a45e', 'ENABLED', '1', 'system', NOW(), '系统内置默认模板'
WHERE NOT EXISTS (
SELECT 1 FROM ar_export_template
WHERE business_type = 'AR_BILL'
AND template_code = 'AR_CUSTOMER_BILL'
AND template_version = '1.0'
);
CREATE TABLE IF NOT EXISTS ar_bill_export (
export_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '导出ID',
ar_bill_id BIGINT(20) NOT NULL COMMENT '应收账单ID',
file_name VARCHAR(255) NOT NULL COMMENT '下载展示名称',
file_type VARCHAR(20) NOT NULL COMMENT 'XLSX/PDF',
template_id BIGINT(20) DEFAULT NULL COMMENT '提交导出任务时绑定的模板ID',
template_code VARCHAR(50) NOT NULL COMMENT '导出模板标识',
template_version VARCHAR(50) DEFAULT NULL COMMENT '模板版本',
template_storage_type VARCHAR(20) DEFAULT NULL COMMENT '绑定模板存储类型',
template_storage_key VARCHAR(500) DEFAULT NULL COMMENT '绑定模板存储Key',
template_hash VARCHAR(128) DEFAULT NULL COMMENT '绑定模板SHA-256校验值',
storage_key VARCHAR(500) NOT NULL COMMENT '对象存储或本地文件Key',
file_size BIGINT(20) DEFAULT NULL COMMENT '文件字节数',
file_hash VARCHAR(128) DEFAULT NULL COMMENT 'SHA-256校验值',
@@ -115,6 +185,7 @@ CREATE TABLE IF NOT EXISTS ar_bill_export (
remark VARCHAR(500) DEFAULT NULL COMMENT '失败原因或备注',
PRIMARY KEY (export_id),
KEY idx_ar_bill_export_bill (ar_bill_id, export_time),
KEY idx_ar_bill_export_template (template_id),
KEY idx_ar_bill_export_status (export_status),
CONSTRAINT fk_ar_bill_export_bill FOREIGN KEY (ar_bill_id) REFERENCES ar_bill (ar_bill_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应收账单导出文件元数据';
@@ -145,4 +216,144 @@ CREATE TABLE IF NOT EXISTS ar_bill_log (
KEY idx_ar_bill_log_request (request_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应收账单操作日志';
-- ============================================================
-- 兼容已执行旧版本脚本的增量补齐逻辑
-- 本文件是应收账单模块唯一数据库脚本,新库和存量库均可重复执行。
-- ============================================================
SET @ar_db_name := DATABASE();
-- 1. 异步生成任务依赖字段
SET @ar_has_generation_status := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'ar_bill'
AND COLUMN_NAME = 'generation_status'
);
SET @ar_sql := IF(@ar_has_generation_status = 0,
'ALTER TABLE ar_bill ADD COLUMN generation_status VARCHAR(20) NOT NULL DEFAULT ''READY'' COMMENT ''生成状态:GENERATING=生成中,READY=可用,FAILED=生成失败'' AFTER status',
'SELECT 1');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
-- 异步生成任务状态增加中文含义,便于数据库运维和排查。
-- 已存在 status 时只修改定义,不重复新增;兼容历史上已创建但字段不完整的任务表。
SET @ar_has_task_status := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'ar_bill_generate_task'
AND COLUMN_NAME = 'status'
);
SET @ar_sql := IF(@ar_has_task_status = 0,
'ALTER TABLE ar_bill_generate_task ADD COLUMN status VARCHAR(30) NOT NULL COMMENT ''任务状态:WAITING=待处理,RUNNING=生成中,SUCCESS=生成成功,FAILED=生成失败,CANCEL_REQUESTED=取消中,CANCELED=已取消'' AFTER total_amount',
'ALTER TABLE ar_bill_generate_task MODIFY COLUMN status VARCHAR(30) NOT NULL COMMENT ''任务状态:WAITING=待处理,RUNNING=生成中,SUCCESS=生成成功,FAILED=生成失败,CANCEL_REQUESTED=取消中,CANCELED=已取消''');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
UPDATE ar_bill
SET generation_status = 'READY'
WHERE generation_status IS NULL;
-- 2. 为异步游标查询补充来源订单索引。
-- 来源表可能尚未由价格模块脚本创建,因此这里做存在性判断。
SET @ar_has_source_table := (
SELECT COUNT(*)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'prc_order_bill'
);
SET @ar_has_source_cursor_index := (
SELECT COUNT(*)
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'prc_order_bill'
AND INDEX_NAME = 'idx_bill_ar_async_cursor'
);
SET @ar_sql := IF(@ar_has_source_table = 1 AND @ar_has_source_cursor_index = 0,
'ALTER TABLE prc_order_bill ADD INDEX idx_bill_ar_async_cursor (customer_id, currency, ar_bill_status, create_time, bill_id)',
'SELECT 1');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
-- 3. 兼容已存在的模板表和导出记录表,补齐模板字段、注释及索引。
ALTER TABLE ar_export_template
MODIFY COLUMN storage_type VARCHAR(20) NOT NULL DEFAULT 'CLASSPATH'
COMMENT '存储类型:CLASSPATH=应用内置资源,FILE=服务器文件,OSS=对象存储,MINIO=MinIO对象存储',
MODIFY COLUMN status VARCHAR(20) NOT NULL DEFAULT 'ENABLED'
COMMENT '状态:ENABLED=启用,DISABLED=停用';
SET @ar_has_template_id := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'ar_bill_export'
AND COLUMN_NAME = 'template_id'
);
SET @ar_sql := IF(@ar_has_template_id = 0,
'ALTER TABLE ar_bill_export ADD COLUMN template_id BIGINT(20) DEFAULT NULL COMMENT ''提交导出任务时绑定的模板ID'' AFTER file_type',
'SELECT 1');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
SET @ar_has_template_storage_type := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'ar_bill_export'
AND COLUMN_NAME = 'template_storage_type'
);
SET @ar_sql := IF(@ar_has_template_storage_type = 0,
'ALTER TABLE ar_bill_export ADD COLUMN template_storage_type VARCHAR(20) DEFAULT NULL COMMENT ''绑定模板存储类型'' AFTER template_version',
'SELECT 1');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
SET @ar_has_template_storage_key := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'ar_bill_export'
AND COLUMN_NAME = 'template_storage_key'
);
SET @ar_sql := IF(@ar_has_template_storage_key = 0,
'ALTER TABLE ar_bill_export ADD COLUMN template_storage_key VARCHAR(500) DEFAULT NULL COMMENT ''绑定模板存储Key'' AFTER template_storage_type',
'SELECT 1');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
SET @ar_has_template_hash := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'ar_bill_export'
AND COLUMN_NAME = 'template_hash'
);
SET @ar_sql := IF(@ar_has_template_hash = 0,
'ALTER TABLE ar_bill_export ADD COLUMN template_hash VARCHAR(128) DEFAULT NULL COMMENT ''绑定模板SHA-256校验值'' AFTER template_storage_key',
'SELECT 1');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
SET @ar_has_template_index := (
SELECT COUNT(*)
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = @ar_db_name
AND TABLE_NAME = 'ar_bill_export'
AND INDEX_NAME = 'idx_ar_bill_export_template'
);
SET @ar_sql := IF(@ar_has_template_index = 0,
'ALTER TABLE ar_bill_export ADD INDEX idx_ar_bill_export_template (template_id)',
'SELECT 1');
PREPARE ar_stmt FROM @ar_sql;
EXECUTE ar_stmt;
DEALLOCATE PREPARE ar_stmt;
SET FOREIGN_KEY_CHECKS = 1;