DELIMITER // CREATE OR REPLACE PROCEDURE bpmm01_spread ( IN p_uuid VARCHAR(100) ) /* 功能 : 配合 vue+jsplumb 的 bpm, 將 flow 的 json 轉為可用的 table 內容 描述 : 本程式可能會在 bpm_list 的 update Trugger 被呼叫(TBD) 建立日期 : 2022/10/30 修改歷史 項目 誰 日期 修改說明 ==== ========== ========== ================================================ 1 michael 2022-10-30 測試 2 Michael 2022-11-01 新增 stepName 欄位 3 Michael 2022-12-03 刪除已經存在的前次內容(防錯, 並可於修改 flow 後重新產生) */ BEGIN DECLARE v_json LONGTEXT; DECLARE v_col LONGTEXT; DECLARE v_type VARCHAR(10); DECLARE v_count INT; DECLARE v_group1 INT; DECLARE v_now INT; DECLARE v_pos INT; DECLARE v_rowid INT; DECLARE v_loop INT; DECLARE v_flow_id VARCHAR(100); DECLARE v_elementId VARCHAR(100); DECLARE v_stepId VARCHAR(100); DECLARE v_filterSet VARCHAR(1000); DECLARE v_nextStep VARCHAR(1000); DECLARE v_nextStep2 VARCHAR(1000); DECLARE v_nextStep_false VARCHAR(100); DECLARE v_switchStep VARCHAR(1000); DECLARE v_stepName VARCHAR(100); DECLARE v_typeName VARCHAR(100); DECLARE v_roleName VARCHAR(100); DECLARE v_max INT; DECLARE v_currid INT; DECLARE v_done INT DEFAULT FALSE; -- 臨時表用於存儲解析的JSON數據 DROP TEMPORARY TABLE IF EXISTS temp_data; CREATE TEMPORARY TABLE temp_data ( rowid INT AUTO_INCREMENT PRIMARY KEY, col LONGTEXT, group1 INT DEFAULT NULL ); -- 獲取流程JSON SELECT flow_json INTO v_json FROM bpm_list WHERE flow_id = p_uuid; -- 防止重複寫入 DELETE FROM bpm_setup WHERE flow_id = p_uuid; -- 分割JSON字串並存入臨時表 SET @sql = CONCAT('INSERT INTO temp_data (col) VALUES ', REPLACE(REPLACE(REPLACE(v_json, CHAR(10), CONCAT('''),(', '''')), '\\', '\\\\'), '\"', '\\\"'), ');'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- 計算總行數 SELECT COUNT(*) INTO v_max FROM temp_data; SET v_currid = 1; -- 標記elementId所在的行組 SET v_type = ''; SET v_count = 1; WHILE (v_currid <= v_max) DO SELECT col INTO v_col FROM temp_data WHERE rowid = v_currid; IF LOCATE('"elementId"', v_col) > 0 THEN UPDATE temp_data SET group1 = v_count WHERE rowid = v_currid; SET v_count = v_count + 1; END IF; SET v_currid = v_currid + 1; END WHILE; -- 填充組標記 SET v_now = 0; SET v_currid = 1; WHILE (v_currid <= v_max) DO SELECT IFNULL(group1, 0) INTO v_group1 FROM temp_data WHERE rowid = v_currid; IF v_group1 = 0 AND v_now > 0 THEN UPDATE temp_data SET group1 = v_now WHERE rowid = v_currid; ELSE SET v_now = v_group1; END IF; SET v_currid = v_currid + 1; END WHILE; -- 處理每個組 SET v_currid = 1; WHILE (v_currid <= v_now) DO -- 識別節點類型 SELECT col INTO v_col FROM temp_data WHERE group1 = v_currid AND LOCATE('elementId', col) > 0; IF LOCATE('startNode', v_col) > 0 THEN SET v_elementId = 'startNode'; ELSEIF LOCATE('nodeNode', v_col) > 0 THEN SET v_elementId = 'nodeNode'; ELSEIF LOCATE('conditionNode', v_col) > 0 THEN SET v_elementId = 'conditionNode'; ELSEIF LOCATE('switchNode', v_col) > 0 THEN SET v_elementId = 'switchNode'; ELSEIF LOCATE('stopNode', v_col) > 0 THEN SET v_elementId = 'stopNode'; END IF; -- 提取stepId SELECT col INTO v_col FROM temp_data WHERE group1 = v_currid AND LOCATE('stepId', col) > 0; SET v_pos = LOCATE(':', v_col); SET v_stepId = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_stepId); SET v_stepId = SUBSTRING(v_stepId, 1, v_pos-1); -- 提取nextStep IF v_elementId <> 'stopNode' THEN SELECT col INTO v_col FROM temp_data WHERE group1 = v_currid AND LOCATE('nextStep', col) > 0; SET v_pos = LOCATE(':', v_col); SET v_nextStep = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_nextStep); SET v_nextStep = SUBSTRING(v_nextStep, 1, v_pos-1); END IF; -- 處理條件節點的過濾器和分支 IF v_elementId = 'conditionNode' THEN SELECT col INTO v_col FROM temp_data WHERE group1 = v_currid AND LOCATE('filterSet', col) > 0; IF v_col IS NOT NULL THEN SET v_pos = LOCATE(':', v_col); SET v_filterSet = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_filterSet); SET v_filterSet = SUBSTRING(v_filterSet, 1, v_pos-1); -- 提取"是"分支的下一步 SELECT rowid INTO v_rowid FROM temp_data WHERE group1 = v_currid AND LOCATE('"name": "是"', col) > 0; SELECT col INTO v_col FROM temp_data WHERE rowid = v_rowid - 1; SET v_pos = LOCATE(':', v_col); SET v_nextStep = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_nextStep); SET v_nextStep = SUBSTRING(v_nextStep, 1, v_pos-1); -- 提取"否"分支的下一步 SELECT rowid INTO v_rowid FROM temp_data WHERE group1 = v_currid AND LOCATE('"name": "否"', col) > 0; SELECT col INTO v_col FROM temp_data WHERE rowid = v_rowid - 1; SET v_pos = LOCATE(':', v_col); SET v_nextStep_false = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_nextStep_false); SET v_nextStep_false = SUBSTRING(v_nextStep_false, 1, v_pos-1); END IF; END IF; -- 處理switch節點的多分支 IF v_elementId = 'switchNode' THEN SET v_loop = 1; SET v_switchStep = ''; WHILE (v_loop <= 10) DO SELECT rowid, col INTO v_rowid, v_col FROM temp_data WHERE group1 = v_currid AND LOCATE(CONCAT('"name": "', v_loop, '"'), col) > 0; IF v_col IS NOT NULL THEN SELECT col INTO v_col FROM temp_data WHERE rowid = v_rowid - 1; SET v_pos = LOCATE(':', v_col); SET v_nextStep2 = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_nextStep2); SET v_nextStep2 = SUBSTRING(v_nextStep2, 1, v_pos-1); SET v_switchStep = CONCAT(v_switchStep, v_nextStep2, '^'); ELSE SET v_loop = 100; -- 退出循環 END IF; SET v_loop = v_loop + 1; END WHILE; IF LENGTH(v_switchStep) > 0 THEN SET v_switchStep = SUBSTRING(v_switchStep, 1, LENGTH(v_switchStep)-1); END IF; END IF; -- 提取其他節點屬性 IF v_elementId NOT IN ('stopNode', 'startNode') THEN -- stepName SELECT col INTO v_col FROM temp_data WHERE group1 = v_currid AND LOCATE('stepName', col) > 0; SET v_pos = LOCATE(':', v_col); SET v_stepName = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_stepName); SET v_stepName = SUBSTRING(v_stepName, 1, v_pos-1); -- typeName SELECT col INTO v_col FROM temp_data WHERE group1 = v_currid AND LOCATE('typeName', col) > 0; SET v_pos = LOCATE(':', v_col); SET v_typeName = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_typeName); SET v_typeName = SUBSTRING(v_typeName, 1, v_pos-1); -- roleName SELECT col INTO v_col FROM temp_data WHERE group1 = v_currid AND LOCATE('roleName', col) > 0; SET v_pos = LOCATE(':', v_col); SET v_roleName = SUBSTRING(v_col, v_pos+3, LENGTH(v_col)); SET v_pos = LOCATE('"', v_roleName); SET v_roleName = SUBSTRING(v_roleName, 1, v_pos-1); END IF; -- 根據節點類型設置預設值 IF v_elementId = 'startNode' THEN SET v_filterSet = ''; SET v_nextStep_false = ''; SET v_stepName = ''; SET v_typeName = ''; SET v_roleName = ''; ELSEIF v_elementId = 'stopNode' THEN SET v_filterSet = ''; SET v_nextStep = ''; SET v_nextStep_false = ''; SET v_stepName = ''; SET v_typeName = ''; SET v_roleName = ''; ELSEIF v_elementId = 'switchNode' THEN SET v_filterSet = ''; SET v_nextStep = v_switchStep; SET v_nextStep_false = ''; ELSEIF v_elementId = 'conditionNode' THEN SET v_typeName = ''; ELSEIF v_elementId = 'nodeNode' THEN SET v_filterSet = ''; SET v_nextStep_false = ''; END IF; -- 插入結果到bpm_setup表 INSERT INTO bpm_setup (flow_id, elementId, stepId, filterSet, nextStep, nextStep_false, stepName, typeName, roleName) VALUES (p_uuid, v_elementId, v_stepId, v_filterSet, v_nextStep, v_nextStep_false, v_stepName, v_typeName, v_roleName); SET v_currid = v_currid + 1; END WHILE; -- 清理臨時表 DROP TEMPORARY TABLE IF EXISTS temp_data; END // DELIMITER ;