mirror of
https://github.com/nocobase/nocobase
synced 2024-11-18 02:15:10 +00:00
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
import { Evaluator, Processor } from '..';
|
|
import { JOB_STATUS } from "../constants";
|
|
import FlowNodeModel from "../models/FlowNode";
|
|
import { Instruction } from ".";
|
|
|
|
function logicCalculate(calculation, evaluator, scope) {
|
|
if (!calculation) {
|
|
return true;
|
|
}
|
|
|
|
if (typeof calculation === 'object' && calculation.group) {
|
|
const method = calculation.group.type === 'and' ? 'every' : 'some';
|
|
return calculation.group.calculations[method](item => logicCalculate(item, evaluator, scope));
|
|
}
|
|
|
|
return evaluator(calculation, scope);
|
|
}
|
|
|
|
|
|
export default {
|
|
async run(node: FlowNodeModel, prevJob, processor: Processor) {
|
|
// TODO(optimize): loading of jobs could be reduced and turned into incrementally in processor
|
|
// const jobs = await processor.getJobs();
|
|
const { engine = 'basic', calculation, expression, rejectOnFalse } = node.config || {};
|
|
const evaluator = <Evaluator | undefined>processor.options.plugin.calculators.get(engine);
|
|
if (!evaluator) {
|
|
return {
|
|
status: JOB_STATUS.ERROR,
|
|
result: new Error('no calculator engine configured')
|
|
}
|
|
}
|
|
|
|
const scope = processor.getScope();
|
|
let result = true;
|
|
|
|
try {
|
|
result = logicCalculate(engine === 'basic' ? processor.getParsedValue(calculation) : expression, evaluator, scope);
|
|
} catch (e) {
|
|
return {
|
|
result: e.toString(),
|
|
status: JOB_STATUS.ERROR
|
|
}
|
|
}
|
|
|
|
if (!result && rejectOnFalse) {
|
|
return {
|
|
status: JOB_STATUS.FAILED,
|
|
result
|
|
};
|
|
}
|
|
|
|
const job = {
|
|
status: JOB_STATUS.RESOLVED,
|
|
result,
|
|
// TODO(optimize): try unify the building of job
|
|
nodeId: node.id,
|
|
upstreamId: prevJob && prevJob.id || null
|
|
};
|
|
|
|
const branchNode = processor.nodes
|
|
.find(item => item.upstream === node && Boolean(item.branchIndex) === result);
|
|
|
|
if (!branchNode) {
|
|
return job;
|
|
}
|
|
|
|
const savedJob = await processor.saveJob(job);
|
|
|
|
return processor.run(branchNode, savedJob);
|
|
},
|
|
|
|
async resume(node: FlowNodeModel, branchJob, processor: Processor) {
|
|
if (branchJob.status === JOB_STATUS.RESOLVED) {
|
|
// return to continue node.downstream
|
|
return branchJob;
|
|
}
|
|
|
|
// pass control to upper scope by ending current scope
|
|
return processor.end(node, branchJob);
|
|
}
|
|
} as Instruction;
|