From 7695b5e912ac1dca6ee92fd7c195764eca9f7e1a Mon Sep 17 00:00:00 2001 From: MohammadHoseinPaymard Date: Mon, 26 May 2025 16:11:04 +0330 Subject: [PATCH] update index.js and process.js --- index.js | 15 ++- process.js | 281 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 294 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index b35115d..efb168b 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ const path = require('path'); const { sleep } = require('./util'); const { getAllWorkflows } = require('./workflow'); -const { getAllProcesses } = require('./process'); +const { getAllProcesses, getProcessPaths } = require('./process'); require(path.join(process.cwd(),"..","server","dist","database.js")); @@ -39,6 +39,19 @@ require(path.join(process.cwd(),"..","server","dist","database.js")); } continue workflowsFor; } + + const { allPaths: tree, subFlowParentIds, invalidPathsWithoutEnding } = await getProcessPaths(processes, workflow); + allWorkFlowInfo[workflow.id] = { + root: { + validPaths:tree, + invalidPaths:invalidPathsWithoutEnding, + valid: tree.length, + invalid: invalidPathsWithoutEnding.length, + subFlowList: subFlowParentIds + }, + subFlow: {} + } + } console.timeEnd("WorkflowTester") diff --git a/process.js b/process.js index f1bde3f..0147c48 100644 --- a/process.js +++ b/process.js @@ -19,7 +19,286 @@ const getAllProcesses = async (workflow,query = {}) => { return processes; } +function getProcessPaths(data, workflow) { + const invalidPathsWithoutEnding = []; + + const nodesMap = data.reduce((map, node) => { + map[node.id.toString()] = node; + return map; + }, {}); + + const subFlowParentIds = []; + // const childrenMap = data.reduce((map, node) => { + // const pid = node.pid; + // if (pid !== null && pid !== undefined) { + // if (!map[pid]) map[pid] = []; + // map[pid].push(node); + // } + // return map; + // }, {}); + + const startNodes = data.filter(node => ((node.type === 0 || node.type === 1) && node.pid === null)); + + // console.log("startNodes", startNodes) + + if (startNodes?.length === 0 || !startNodes) { + invalidPathsWithoutEnding.push({ path: null, data: null, workflow: workflow.id,error:"هیچ پروسسی برای استارت این ورک فلو وجود ندارد" }); + return { + allPaths: [], + subFlowParentIds: [], + invalidPathsWithoutEnding + }; + } + + let allPaths = []; + const pathSet = new Set(); //for delete duplicated paths + function isUniquePath(path) { + const pathString = path.map(n => n.id).join(','); + if (pathSet.has(pathString)) return false; + pathSet.add(pathString); + return true; + } + + function traverse(currentNode, currentPath, visited, mergedData = []) { + // if (currentNode.type === 99) { // in bekhatere in ezaf shod ke mikhastim gozaresh ha ro nadide begirim felan + // if(isUniquePath([...currentPath])){ + // // allPaths.push({path:[...currentPath].map(n => n.id),data:mergedData}); + // invalidPathsWithoutEnding.push({path:[...currentPath].map(n => n.id),data:mergedData}); + // } + // return; + // } + // const date = Date.now(); + // console.time(date); + const newPath = [...currentPath, currentNode]; + const newVisited = { ...visited }; + + const nodeIdStr = currentNode.id.toString(); + const visitCount = newVisited[nodeIdStr] || 0; + + if (visitCount >= 2) { + // console.timeEnd(date); + return; + } + newVisited[nodeIdStr] = visitCount + 1; + + + const newMergedData = [...mergedData] + newMergedData.push({ + processId: currentNode.id.toString(), + condition: convertStringToJson(currentNode.conditions) + }); + + + if (currentNode.type === 99 || currentNode.type === 100 || currentNode.subFlowPid) { + if (currentNode.subFlowPid && !subFlowParentIds.includes(currentNode.subFlowPid)) subFlowParentIds.push(currentNode.subFlowPid) + // allPaths.push(newPath.map(n => n.id)); + if (isUniquePath(newPath)) { + allPaths.push({ path: newPath.map(n => n.id), data: newMergedData }); + } + // console.timeEnd(date); + return; + } + + const children = data.filter(node => node.pid == nodeIdStr); + // console.log("3 data:",children,nodeIdStr,data) + const linkNodes = []; + + if (currentNode.link) { + currentNode.link.split(',').forEach(id => { + const linkedNode = nodesMap[id]; + if (linkedNode) { + linkNodes.push(linkedNode); + } + }); + } + + const nextNodes = [...children, ...linkNodes]; + + // console.timeEnd(date); + if (nextNodes?.length === 0) { + if (isUniquePath(newPath)) { + // allPaths.push({path:newPath.map(n => n.id),data:newMergedData}); + invalidPathsWithoutEnding.push({ path: newPath.map(n => n.id), data: newMergedData,error:"ورک فلو در این مسیر به پایان نرسید"}); + } + return; + } + + nextNodes.forEach(nextNode => { + traverse(nextNode, newPath, newVisited, newMergedData); + }); + } + + for (let startNode of startNodes) { + traverse(startNode, [], {}); + } + + // console.log("allPaths:",allPaths.length); + + + // allPaths = [...new Set( + // allPaths.map((path,pindex)=>{ + // return path.path.join(",") + // }) + // )].map((newPath,index)=>{ + // return newPath.split(",") + // }) + + // console.log("allPaths after:",allPaths.length); + + // return allPaths.map((a,aindex)=>{ + // return a.map((b,bindex)=>{ + // return nodesMap[b.toString()].name + // }) + // }); + + return { allPaths, subFlowParentIds, invalidPathsWithoutEnding }; +} + +function getProcessPathsSubFlow(data, subFlowIdTemp, workflow) { + + const invalidSubPathsWithoutEnding = []; + + const nodesMap = data.reduce((map, node) => { + map[node.id.toString()] = node; + return map; + }, {}); + + + // const childrenMap = data.reduce((map, node) => { + // const pid = node.pid; + // if (pid !== null && pid !== undefined) { + // if (!map[pid]) map[pid] = []; + // map[pid].push(node); + // } + // return map; + // }, {}); + + let subTreePath = []; + + const startNodes = data.filter(node => ((node.type === 0 || node.type === 1) && node.pid === null) || (node.subFlowPid == subFlowIdTemp)); + + // console.log("startNodes",startNodes) + + if (startNodes?.length === 0 || !startNodes) { + // return []; + invalidSubPathsWithoutEnding.push({ path: null, data: null, workflow: workflow.id, subworkflow: subFlowIdTemp }); + return { + subTreePath: [], + invalidSubPathsWithoutEnding + }; + } + + const pathSet = new Set(); //for delete duplicated paths + function isUniquePath(path) { + const pathString = path.map(n => n.id).join(','); + if (pathSet.has(pathString)) return false; + pathSet.add(pathString); + return true; + } + + function traverse(currentNode, currentPath, visited, mergedData = []) { + // if (currentNode.type === 99) { // in bekhatere in ezaf shod ke mikhastim gozaresh ha ro nadide begirim felan + // if(isUniquePath([...currentPath])){ + // // allPaths.push({path:[...currentPath].map(n => n.id),data:mergedData}); + // invalidPathsWithoutEnding.push({path:[...currentPath].map(n => n.id),data:mergedData}); + // } + // return; + // } + // const date = `sub${subFlowIdTemp}-${Date.now()}`; + // console.time(date); + const newPath = [...currentPath, currentNode]; + const newVisited = { ...visited }; + + const nodeIdStr = currentNode.id.toString(); + const visitCount = newVisited[nodeIdStr] || 0; + + if (visitCount >= 2) { + // console.timeEnd(date); + return; + } + newVisited[nodeIdStr] = visitCount + 1; + + + const newMergedData = [...mergedData] + newMergedData.push({ + processId: currentNode.id.toString(), + condition: convertStringToJson(currentNode.conditions) + }); + + + if (currentNode.type === 99 || currentNode.type === 100 + // || currentNode.subFlowPid it will be uncommented when we want go to final subflowPid + ) { + // allPaths.push(newPath.map(n => n.id)); + if (isUniquePath(newPath)) { + subTreePath.push({ path: newPath.map(n => n.id), data: newMergedData }); + } + // console.timeEnd(date); + return; + } + + const children = data.filter(node => node.pid == nodeIdStr); + // console.log("3 data:",children,nodeIdStr,data) + const linkNodes = []; + + if (currentNode.link) { + currentNode.link.split(',').forEach(id => { + const linkedNode = nodesMap[id]; + if (linkedNode) { + linkNodes.push(linkedNode); + } + }); + } + + const nextNodes = [...children, ...linkNodes]; + + // console.timeEnd(date); + + if (nextNodes?.length === 0) { + if (isUniquePath(newPath)) { + // allPaths.push({path:newPath.map(n => n.id),data:newMergedData}); + invalidSubPathsWithoutEnding.push({ path: newPath.map(n => n.id), data: newMergedData }); + } + return; + } + + + nextNodes.forEach(nextNode => { + traverse(nextNode, newPath, newVisited, newMergedData); + }); + + + } + + for (let startNode of startNodes) { + traverse(startNode, [], {}); + } + + // console.log("allPaths:",allPaths.length); + // console.log("allPaths:",allPaths.length); + + + // allPaths = [...new Set( + // allPaths.map((path,pindex)=>{ + // return path.path.join(",") + // }) + // )].map((newPath,index)=>{ + // return newPath.split(",") + // }) + + // console.log("allPaths after:",allPaths.length); + + // return allPaths.map((a,aindex)=>{ + // return a.map((b,bindex)=>{ + // return nodesMap[b.toString()].name + // }) + // }); + + return { subTreePath, invalidSubPathsWithoutEnding }; +} + module.exports = { getAllProcesses, - + getProcessPaths, + getProcessPathsSubFlow } \ No newline at end of file