|
|
@ -19,7 +19,286 @@ const getAllProcesses = async (workflow,query = {}) => { |
|
|
|
return processes; |
|
|
|
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 = { |
|
|
|
module.exports = { |
|
|
|
getAllProcesses, |
|
|
|
getAllProcesses, |
|
|
|
|
|
|
|
getProcessPaths, |
|
|
|
|
|
|
|
getProcessPathsSubFlow |
|
|
|
} |
|
|
|
} |