// 由 config_export_all_20260928.sql 生成 config_export_all_20260929.sql(增量补丁)
|
// 用法:node _patch_0929.js
|
import fs from 'node:fs';
|
import path from 'node:path';
|
|
const DIR = process.cwd();
|
const SRC = path.join(DIR, 'config_export_all_20260928.sql');
|
const DST = path.join(DIR, 'config_export_all_20260929.sql');
|
const EXPORT = path.join(DIR, '_finance_bpm_export.sql');
|
|
const raw = fs.readFileSync(SRC, 'utf8');
|
const crlf = raw.includes('\r\n');
|
let sql = crlf ? raw.replace(/\r\n/g, '\n') : raw;
|
const exp = fs.readFileSync(EXPORT, 'utf8').replace(/\r\n/g, '\n');
|
|
function sub(oldStr, newStr, label) {
|
const n = sql.split(oldStr).length - 1;
|
if (n !== 1) throw new Error(`[${label}] 期望唯一匹配,实际 ${n} 次`);
|
sql = sql.replace(oldStr, newStr);
|
console.log(` OK ${label}`);
|
}
|
|
// ---------- 从部署导出文件里取 INSERT 行 ----------
|
function insertsOf(table) {
|
return exp
|
.split('\n')
|
.filter((l) => l.startsWith(`INSERT INTO \`${table}\``))
|
.map((l) => l.trim());
|
}
|
const procdefIns = insertsOf('act_re_procdef');
|
const deployIns = insertsOf('act_re_deployment');
|
const byteIns = insertsOf('act_ge_bytearray');
|
const modelIns = insertsOf('act_re_model');
|
const infoIns = insertsOf('bpm_process_definition_info');
|
if (procdefIns.length !== 1 || deployIns.length !== 1 || byteIns.length !== 3 || modelIns.length !== 1 || infoIns.length !== 1) {
|
throw new Error(`导出文件行数不符:procdef=${procdefIns.length} deploy=${deployIns.length} byte=${byteIns.length} model=${modelIns.length} info=${infoIns.length}`);
|
}
|
|
console.log('1) 文件头');
|
sub('-- 文件:config_export_all_20260928.sql', '-- 文件:config_export_all_20260929.sql', '文件名');
|
sub(
|
'-- 本次为**补丁版**:基于 0918 文件增量修改,未重跑全库导出(避免把无关表一起搅动)。',
|
'-- 本次为**补丁版**:20260929 基于 20260928 增量修改(20260928 又基于 0918),未重跑全库导出(避免把无关表一起搅动)。',
|
'补丁说明',
|
);
|
sub(
|
'-- research_fund_status(待拨付/已拨付)',
|
'-- research_fund_status(待拨付/已拨付;2026-09-29 扩为 待拨付/报销审批中/已拨付/已驳回)',
|
'头部字典说明',
|
);
|
sub(
|
'-- ⚠ 该流程的 BPMN 为手写三节点,**不是** bpm_deploy_flow_from_template 生成的单节点流程。',
|
'-- ⚠ 该流程的 BPMN 为手写三节点,**不是** bpm_deploy_flow_from_template 生成的单节点流程。\n' +
|
'-- 补丁内容(2026-09-29,课题经费拨付对接财务报销):\n' +
|
'-- ① research_fund_record 增 4 列(reimbursement_id / reimbursement_no / reject_reason / reject_time)\n' +
|
'-- + status 列注释改为「0-待拨付 15-报销审批中 20-已拨付 30-已驳回」+ idx_reimbursement_id 索引。\n' +
|
'-- **无新增表**:全库仍 427 张(finance_reimbursement 表已在 0928 版建立)。\n' +
|
'-- ② research_fund_status 字典由 2 条扩为 4 条(待拨付 0 / 报销审批中 15 / 已拨付 20 / 已驳回 30),\n' +
|
'-- system_dict_type.remark 同步改为「课题经费待拨付/报销审批中/已拨付/已驳回」。\n' +
|
'-- ③ 补 1 条 BPM 流程定义(财务报销两级审批:财务审核 → 财务主管审批),流程 key=\'finance_reimbursement_approve\',\n' +
|
'-- 分别落 act_re_procdef / act_re_deployment / act_ge_bytearray(3 条) / act_re_model /\n' +
|
'-- bpm_process_definition_info 五张表(bpm_process_definition_info.id=42)。\n' +
|
'-- form_type=20(自定义表单),form_custom_create_path=/finance/reimbursement/index、\n' +
|
'-- form_custom_view_path=/finance/reimbursement/detail/approve/index.vue。\n' +
|
'-- bpm_category(id=216, code=\'finance_reimbursement_approve\') 已存在,无需新增。\n' +
|
'-- ⚠ 该流程的 BPMN 为手写两节点,**不是** bpm_deploy_flow_from_template 生成的单节点流程。\n' +
|
'-- ④ **阶段二不动**:本次无菜单/角色/用户变更。',
|
'新增补丁段',
|
);
|
sub(
|
'-- ⚠ 本 0928 版为在其之上的补丁,**尚未在空库整份跑过**;上线/初始化前请先在可覆盖空库验证。',
|
'-- ⚠ 本 0929 版为在其之上的补丁,**尚未在空库整份跑过**;上线/初始化前请先在可覆盖空库验证。',
|
'验证说明',
|
);
|
|
console.log('2) research_fund_record 表结构');
|
sub(
|
" `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态:0-待拨付 20-已拨付',\n" +
|
" `remark` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '备注',\n" +
|
" `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',\n" +
|
' `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT \'创建时间\',\n' +
|
" `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',\n" +
|
' `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT \'更新时间\',\n' +
|
" `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',\n" +
|
' PRIMARY KEY (`id`) USING BTREE,\n' +
|
' KEY `idx_application_id` (`application_id`) USING BTREE\n' +
|
") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='课题-经费拨付记录';",
|
" `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态:0-待拨付 15-报销审批中 20-已拨付 30-已驳回',\n" +
|
" `reimbursement_id` bigint DEFAULT NULL COMMENT '关联财务报销单 ID(finance_reimbursement.id)',\n" +
|
" `reimbursement_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '关联财务报销单号',\n" +
|
" `reject_reason` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '报销驳回原因(BPM 回写)',\n" +
|
" `reject_time` datetime DEFAULT NULL COMMENT '报销驳回时间',\n" +
|
" `remark` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '备注',\n" +
|
" `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',\n" +
|
' `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT \'创建时间\',\n' +
|
" `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',\n" +
|
' `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT \'更新时间\',\n' +
|
" `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',\n" +
|
' PRIMARY KEY (`id`) USING BTREE,\n' +
|
' KEY `idx_application_id` (`application_id`) USING BTREE,\n' +
|
' KEY `idx_reimbursement_id` (`reimbursement_id`) USING BTREE\n' +
|
") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='课题-经费拨付记录';",
|
'DDL 4 列 + 注释 + 索引',
|
);
|
|
console.log('3) 字典');
|
sub(
|
"('81004', '经费拨付状态', 'research_fund_status', '0', '课题经费待拨付/已拨付', '1', '2026-09-28 20:00:00', '1', '2026-09-28 20:00:00', X'00', NULL);",
|
"('81004', '经费拨付状态', 'research_fund_status', '0', '课题经费待拨付/报销审批中/已拨付/已驳回', '1', '2026-09-29 10:00:00', '1', '2026-09-29 10:00:00', X'00', NULL);",
|
'dict_type remark',
|
);
|
const ts = '2026-09-29 10:00:00';
|
sub(
|
`('8100401', '1', '待拨付', '0', 'research_fund_status', '0', 'warning', '', '', '1', '2026-09-28 20:00:00', '1', '2026-09-28 20:00:00', X'00'),\n` +
|
`('8100402', '2', '已拨付', '20', 'research_fund_status', '0', 'success', '', '', '1', '2026-09-28 20:00:00', '1', '2026-09-28 20:00:00', X'00');`,
|
`('8100401', '1', '待拨付', '0', 'research_fund_status', '0', 'warning', '', '', '1', '${ts}', '1', '${ts}', X'00'),\n` +
|
`('8100403', '2', '报销审批中', '15', 'research_fund_status', '0', 'processing', '', '', '1', '${ts}', '1', '${ts}', X'00'),\n` +
|
`('8100402', '3', '已拨付', '20', 'research_fund_status', '0', 'success', '', '', '1', '${ts}', '1', '${ts}', X'00'),\n` +
|
`('8100404', '4', '已驳回', '30', 'research_fund_status', '0', 'danger', '', '', '1', '${ts}', '1', '${ts}', X'00');`,
|
'dict_data 4 条',
|
);
|
|
console.log('4) BPM 五张表');
|
function appendBefore(marker, lines, label) {
|
const i = sql.indexOf(marker);
|
if (i < 0) throw new Error(`[${label}] 未找到锚点`);
|
sql = sql.slice(0, i) + lines.join('\n') + '\n\n' + sql.slice(i);
|
console.log(` OK ${label}`);
|
}
|
appendBefore(
|
'-- ============ 表:act_re_deployment(导出 22 行) ============',
|
procdefIns,
|
'act_re_procdef',
|
);
|
appendBefore(
|
'-- ============ 表:act_ge_bytearray(导出 25 行) ============',
|
deployIns,
|
'act_re_deployment',
|
);
|
appendBefore('-- ============ 表:act_re_model(导出 22 行) ============', byteIns, 'act_ge_bytearray');
|
appendBefore(
|
'-- ============ 表:bpm_process_definition_info(导出 22 行) ============',
|
modelIns,
|
'act_re_model',
|
);
|
appendBefore(
|
'-- ***********************************************************************\n-- ② 协同(业务附件配置 + 分类 + 表单 + 扩展配置)',
|
infoIns,
|
'bpm_process_definition_info',
|
);
|
|
console.log('5) 表头行数');
|
sub('表:act_re_procdef(导出 22 行)', '表:act_re_procdef(导出 23 行)', 'procdef 行数');
|
sub('表:act_re_deployment(导出 22 行)', '表:act_re_deployment(导出 23 行)', 'deployment 行数');
|
sub('表:act_ge_bytearray(导出 25 行)', '表:act_ge_bytearray(导出 28 行)', 'bytearray 行数');
|
sub('表:act_re_model(导出 22 行)', '表:act_re_model(导出 23 行)', 'model 行数');
|
sub(
|
'表:bpm_process_definition_info(导出 22 行)',
|
'表:bpm_process_definition_info(导出 23 行)',
|
'procinfo 行数',
|
);
|
|
const out = crlf ? sql.replace(/\n/g, '\r\n') : sql;
|
fs.writeFileSync(DST, out, 'utf8');
|
console.log(`\n已写出 ${DST}(${sql.split('\n').length} 行,EOL=${crlf ? 'CRLF' : 'LF'})`);
|