-- =============================================================================
|
-- 文件:bpm_audit_flow_02_deploy_proc.sql
|
-- 用途:BPM 审核流程「流程定义部署」段(第 2 个执行,需先执行 01 修复/分类文件)
|
-- 目标库:ruoyi-vue-pro
|
-- 要求:
|
-- * MySQL 8.0+,账号需具备 CREATE PROCEDURE 权限
|
-- * 以 mysql CLI 执行(含 DELIMITER):
|
-- mysql -u<账号> -p ruoyi-vue-pro < bpm_audit_flow_02_deploy_proc.sql
|
-- * 模板:默认从 ruoyi-vue-pro 内已有规范流程「erp-finance-payment-audit」复制,
|
-- 其 BPMN 为“发起人节点 + 提交即通过”(candidateStrategy=36) 的最简结构,
|
-- 适合所有对接单据先跑通;后续如需多级审批可在「流程模型」界面调整。
|
-- 健壮性设计:
|
-- * 幂等:目标 key 若已存在(无论激活/挂起)→ 整段跳过,不重复部署、不产生新版本。
|
-- * 事务:单流程 5 张表写入包在一个事务内,任一步失败自动回滚,不留半成品。
|
-- * 自检:procdef ID = key:1:<32位uuid>,超 64 字符直接报错中断。
|
-- * 空值规避:ENGINE_VERSION_ 不写入空串(保持 NULL),避免 Flowable 提交审批报错;
|
-- META_INFO_ 写入最小合法 JSON(含 sort/type=10),避免模型页/列表 NPE。
|
-- * 重复执行文件安全:DROP PROCEDURE IF EXISTS 保证可重复运行。
|
-- =============================================================================
|
|
SET NAMES utf8mb4;
|
|
-- 部署前自检:模板存在性(应返回 1 行)
|
SELECT KEY_, NAME_, SUSPENSION_STATE_ FROM ACT_RE_PROCDEF WHERE KEY_ = 'erp-finance-payment-audit';
|
|
DROP PROCEDURE IF EXISTS bpm_deploy_flow_from_template;
|
|
DELIMITER $$
|
|
-- 从一个“模板流程”复制部署一个新审核流程(BPMN 结构一致,仅替换 key/名称)
|
CREATE PROCEDURE bpm_deploy_flow_from_template(
|
IN p_key VARCHAR(64), -- 新流程 key(需与代码侧监听器匹配)
|
IN p_name VARCHAR(128), -- 新流程显示名
|
IN p_category VARCHAR(64), -- 归属流程分类 code
|
IN p_template VARCHAR(64) -- 复制来源模板流程 key
|
)
|
label_deploy: BEGIN
|
DECLARE v_exist INT DEFAULT 0;
|
DECLARE v_tpl_key VARCHAR(64) DEFAULT 'erp-finance-payment-audit';
|
DECLARE v_tpl_dep VARCHAR(64) DEFAULT NULL;
|
DECLARE v_tpl_name VARCHAR(255) DEFAULT NULL;
|
DECLARE v_dep VARCHAR(64);
|
DECLARE v_model_id VARCHAR(64);
|
DECLARE v_byte_id VARCHAR(64);
|
DECLARE v_procdef_id VARCHAR(64);
|
DECLARE v_meta TEXT;
|
DECLARE v_sort BIGINT;
|
DECLARE v_now DATETIME;
|
|
-- 任何异常 → 回滚并重新抛出
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
BEGIN
|
ROLLBACK;
|
RESIGNAL;
|
END;
|
|
-- 幂等:key 已存在直接跳过
|
SELECT COUNT(*) INTO v_exist FROM ACT_RE_PROCDEF WHERE KEY_ = p_key;
|
IF v_exist > 0 THEN
|
SELECT CONCAT('[SKIP] 流程已存在,跳过:', p_key) AS deploy_result;
|
LEAVE label_deploy;
|
END IF;
|
|
-- 模板定位
|
IF p_template IS NOT NULL AND p_template <> '' THEN
|
SET v_tpl_key = p_template;
|
END IF;
|
SELECT DEPLOYMENT_ID_ INTO v_tpl_dep FROM ACT_RE_PROCDEF
|
WHERE KEY_ = v_tpl_key ORDER BY VERSION_ DESC LIMIT 1;
|
SELECT NAME_ INTO v_tpl_name FROM ACT_RE_PROCDEF
|
WHERE KEY_ = v_tpl_key ORDER BY VERSION_ DESC LIMIT 1;
|
IF v_tpl_dep IS NULL THEN
|
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = CONCAT('模板流程不存在,无法复制:', v_tpl_key);
|
END IF;
|
|
SET v_now = NOW(3);
|
SET v_sort = UNIX_TIMESTAMP(v_now) * 1000;
|
SET v_dep = REPLACE(UUID(), '-', '');
|
SET v_model_id = REPLACE(UUID(), '-', '');
|
SET v_byte_id = REPLACE(UUID(), '-', '');
|
SET v_procdef_id = CONCAT(p_key, ':1:', v_dep);
|
-- procdef ID 列 VARCHAR(64) 长度守卫
|
IF CHAR_LENGTH(v_procdef_id) > 64 THEN
|
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = CONCAT('流程 key 过长,procdef ID 将超 64 字符:', p_key);
|
END IF;
|
|
START TRANSACTION;
|
|
-- 1) 部署记录(ACT_RE_DEPLOYMENT 无 REV_ 列)
|
INSERT INTO ACT_RE_DEPLOYMENT
|
(ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_)
|
VALUES
|
(v_dep, p_name, p_category, p_key, '', v_now, NULL);
|
|
-- 2) BPMN 字节(复制模板字节并替换 key 与显示名)
|
INSERT INTO ACT_GE_BYTEARRAY
|
(ID_, NAME_, DEPLOYMENT_ID_, BYTES_, GENERATED_)
|
SELECT
|
v_byte_id,
|
CONCAT(p_key, '.bpmn'),
|
v_dep,
|
CONVERT(
|
REPLACE(
|
REPLACE(CONVERT(BYTES_ USING utf8mb4), v_tpl_key, p_key),
|
v_tpl_name, p_name)
|
USING utf8mb4),
|
0
|
FROM ACT_GE_BYTEARRAY
|
WHERE DEPLOYMENT_ID_ = v_tpl_dep
|
AND NAME_ = CONCAT(v_tpl_key, '.bpmn');
|
|
-- 3) 流程定义(激活态 SUSPENSION_STATE_=1;ENGINE_VERSION_ 留 NULL)
|
INSERT INTO ACT_RE_PROCDEF
|
(ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_,
|
DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_,
|
SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_, DERIVED_VERSION_)
|
VALUES
|
(v_procdef_id, 1, p_category, p_name, p_key, 1, v_dep, CONCAT(p_key, '.bpmn'),
|
NULL, NULL, 0, 1,
|
1, '', NULL, 0);
|
|
-- 4) 流程模型(含最小合法 META_INFO_,避免模型列表 NPE)
|
SET v_meta = CONCAT(
|
'{"type":10,"formType":10,"sort":', v_sort,
|
',"visible":true,"allowCancelRunningProcess":true,"allowWithdrawTask":false',
|
',"autoApprovalType":0,"description":"","formCustomCreatePath":"","formCustomViewPath":"",',
|
'"formId":null,"managerUserIds":[],"startUserIds":[],"startDeptIds":[],"icon":null,',
|
'"processBeforeTriggerSetting":null,"processAfterTriggerSetting":null,',
|
'"taskBeforeTriggerSetting":null,"taskAfterTriggerSetting":null,',
|
'"printTemplateSetting":null,"summarySetting":null,"titleSetting":null,"processIdRule":null}');
|
INSERT INTO ACT_RE_MODEL
|
(ID_, NAME_, KEY_, CATEGORY_, CREATE_TIME_, LAST_UPDATE_TIME_, VERSION_, META_INFO_, DEPLOYMENT_ID_, TENANT_ID_)
|
VALUES
|
(v_model_id, p_name, p_key, p_category, v_now, v_now, 1, v_meta, v_dep, '');
|
|
-- 5) 流程定义扩展信息(model_type=10)
|
INSERT INTO bpm_process_definition_info
|
(process_definition_id, model_id, model_type, category, form_type, visible, sort,
|
allow_cancel_running_process, allow_withdraw_task,
|
creator, create_time, updater, update_time, deleted)
|
VALUES
|
(v_procdef_id, v_model_id, 10, p_category, 10, 1, v_sort,
|
1, 1,
|
'1', v_now, '1', v_now, 0);
|
|
COMMIT;
|
|
SELECT CONCAT('[OK] 已部署新审核流程:', p_key, ' (procdef=', v_procdef_id, ')') AS deploy_result;
|
END$$
|
|
DELIMITER ;
|
|
-- =============================================================================
|
-- ④ 按单据逐个部署缺失流程(重复执行会自动跳过已存在项)
|
-- 参数:(key, 名称, 分类code, 模板key)
|
-- =============================================================================
|
|
-- ERP 销售订单审批(代码监听 key:sale_order_approve)
|
CALL bpm_deploy_flow_from_template('sale_order_approve', '销售订单审批', 'sale_order_approve', 'erp-finance-payment-audit');
|
-- ERP 采购订单审批(代码监听 key:purchase_order_approve)
|
CALL bpm_deploy_flow_from_template('purchase_order_approve', '采购订单审批', 'purchase_order_approve', 'erp-finance-payment-audit');
|
|
-- CRM 合同审批(代码监听 key:crm-contract-audit,挂既有 contract_approve 分类)
|
CALL bpm_deploy_flow_from_template('crm-contract-audit', '合同审批', 'contract_approve', 'erp-finance-payment-audit');
|
|
-- HRM 请假审批(代码监听 key:hrm_leave)
|
CALL bpm_deploy_flow_from_template('hrm_leave', '请假审批', 'hrm_leave_approve', 'erp-finance-payment-audit');
|
-- HRM 加班审批(代码监听 key:hrm_overtime)
|
CALL bpm_deploy_flow_from_template('hrm_overtime', '加班审批', 'overtime_approve', 'erp-finance-payment-audit');
|
-- HRM 离职审批(代码监听 key:hrm_resignation)
|
CALL bpm_deploy_flow_from_template('hrm_resignation', '离职审批', 'hrm_resignation_approve', 'erp-finance-payment-audit');
|
-- HRM 调动审批(代码监听 key:hrm_transfer)
|
CALL bpm_deploy_flow_from_template('hrm_transfer', '调动审批', 'hrm_transfer_approve', 'erp-finance-payment-audit');
|
-- HRM 考勤异常审批(全量监听不挑 key,挂既有 hrm_attendance_approve 分类)
|
CALL bpm_deploy_flow_from_template('hrm_attendance_approve', '考勤异常审批', 'hrm_attendance_approve', 'erp-finance-payment-audit');
|
|
-- SRM 供应商准入审批(代码监听 key:supplier_apply_approve)
|
CALL bpm_deploy_flow_from_template('supplier_apply_approve', '供应商准入审批', 'supplier_apply_approve', 'erp-finance-payment-audit');
|
|
-- MES 仓库入库 / 出库 / 调拨审批(代码监听 key 固定,挂既有 wms_approve 分类)
|
CALL bpm_deploy_flow_from_template('wms_inbound_approve', '仓库入库审批', 'wms_approve', 'erp-finance-payment-audit');
|
CALL bpm_deploy_flow_from_template('wms_outbound_approve', '仓库出库审批', 'wms_approve', 'erp-finance-payment-audit');
|
CALL bpm_deploy_flow_from_template('wms_transfer_approve', '仓库调拨审批', 'wms_approve', 'erp-finance-payment-audit');
|
-- MES 采购收货(入库单)审批(全量监听,挂既有 item_receipt_approve 分类)
|
CALL bpm_deploy_flow_from_template('item_receipt_approve', '采购入库审批', 'item_receipt_approve', 'erp-finance-payment-audit');
|
-- MES 报工/生产工单审批(代码监听 key:mes-pro-feedback-audit)
|
CALL bpm_deploy_flow_from_template('mes-pro-feedback-audit', '报工审批', 'mes_pro_feedback_audit', 'erp-finance-payment-audit');
|
|
-- =============================================================================
|
-- ⑤ 部署结果校验(应看到 14 条新流程且 SUSPENSION_STATE_=1、model_type=10)
|
-- =============================================================================
|
SELECT p.KEY_, p.NAME_, p.VERSION_, p.SUSPENSION_STATE_ AS active_flag,
|
LENGTH(p.ID_) AS procdef_id_len,
|
i.model_type, i.category
|
FROM ACT_RE_PROCDEF p
|
LEFT JOIN bpm_process_definition_info i ON i.process_definition_id = p.ID_
|
WHERE p.KEY_ IN ('sale_order_approve','purchase_order_approve','crm-contract-audit',
|
'hrm_leave','hrm_overtime','hrm_resignation','hrm_transfer',
|
'hrm_attendance_approve','supplier_apply_approve',
|
'wms_inbound_approve','wms_outbound_approve','wms_transfer_approve',
|
'item_receipt_approve','mes-pro-feedback-audit')
|
ORDER BY p.KEY_;
|