-- ============================================================================= -- 文件: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_;