diff --git a/packages/objectql/src/actions/field_updates.ts b/packages/objectql/src/actions/field_updates.ts index 328d646836..c9c664475c 100644 --- a/packages/objectql/src/actions/field_updates.ts +++ b/packages/objectql/src/actions/field_updates.ts @@ -1,6 +1,7 @@ import { getObject, computeFormula, SteedosError } from '../index'; import { runQuotedByObjectFieldFormulas } from '../formula'; import { runQuotedByObjectFieldSummaries } from '../summary'; +import { FieldUpdateTarget } from './types/field_update_target'; const _ = require('underscore'); const getFieldValue = async (action: any, recordId: string, userSession: any)=>{ @@ -19,7 +20,8 @@ const getFieldValue = async (action: any, recordId: string, userSession: any)=>{ export async function runFieldUpdateAction(action: any, recordId: any, userSession: any){ const record = await getObject(action.object_name).findOne(recordId, null); let mainObjectName = null; - let recordIdToUpdate; + let recordIdToUpdate: string; + let previousRecord: any; if(action.target_object && action.target_object != action.object_name){ mainObjectName = getObject(action.object_name).getField(action.target_object).reference_to; if(!_.isString(mainObjectName)){ @@ -27,11 +29,13 @@ export async function runFieldUpdateAction(action: any, recordId: any, userSessi } recordIdToUpdate = record[action.target_object]; const fieldValue = await getFieldValue(action, recordId, userSession); + previousRecord = await getObject(mainObjectName).findOne(recordIdToUpdate, null); await getObject(mainObjectName).directUpdate(recordIdToUpdate, {[action.field_name]: fieldValue}); }else{ mainObjectName = action.object_name; recordIdToUpdate = record._id; const fieldValue = await getFieldValue(action, recordId, userSession); + previousRecord = record; await getObject(mainObjectName).directUpdate(recordIdToUpdate, {[action.field_name]: fieldValue}); } @@ -43,11 +47,19 @@ export async function runFieldUpdateAction(action: any, recordId: any, userSessi await runQuotedByObjectFieldSummaries(mainObjectName, recordIdToUpdate, null, userSession, { fieldNames: [action.field_name] }); + + return { + object_name: mainObjectName, + record_id: recordIdToUpdate, + field_name: action.field_name, + previous_record: previousRecord + }; } export async function runFieldUpdateActions(ids: Array, recordId: any, userSession: any){ const filters = []; + let targets: Array = []; if(!_.isEmpty(ids)){ filters.push(['_id', 'in', ids]) @@ -56,7 +68,9 @@ export async function runFieldUpdateActions(ids: Array, recordId: any, u if(!_.isEmpty(filters)){ const actions = await getObject("action_field_updates").find({filters: filters}) for (const action of actions) { - await runFieldUpdateAction(action, recordId, userSession) + const target:FieldUpdateTarget = await runFieldUpdateAction(action, recordId, userSession); + targets.push(target); } } + return targets; } \ No newline at end of file diff --git a/packages/objectql/src/actions/types/field_update_target.ts b/packages/objectql/src/actions/types/field_update_target.ts new file mode 100644 index 0000000000..d1c4b3f072 --- /dev/null +++ b/packages/objectql/src/actions/types/field_update_target.ts @@ -0,0 +1,7 @@ +export type FieldUpdateTarget = { + record_id: string, + object_name: string, + field_name: string, + from_rule_id: string, + previous_record: any +} \ No newline at end of file diff --git a/packages/objectql/src/actions/workflow_rule.ts b/packages/objectql/src/actions/workflow_rule.ts index 38b6b7895a..d664d49e23 100644 --- a/packages/objectql/src/actions/workflow_rule.ts +++ b/packages/objectql/src/actions/workflow_rule.ts @@ -3,15 +3,21 @@ import { computeFormula } from '../formula' import { WorkflowRule } from './types/workflow_rule'; import { JsonMap } from "@salesforce/ts-types"; import { runFieldUpdateActions } from './field_updates' +import { FieldUpdateTarget } from './types/field_update_target'; import _ = require('underscore'); -export async function runObjectWorkflowRules(objectName, event, record, userSession, previousRecord) { +export async function runObjectWorkflowRules(objectName, event, record, userSession, previousRecord, fromRuleId?) { if(!_.include(['insert', 'update'], event) || !record){ return ; } let filters = [['object_name', '=', objectName], ['space', '=', record.space], ['active', '=', true]]; + if(fromRuleId){ + // 如果是级联触发的工作流规则,则要排除掉其原本来自的工作流规则,避免死循环 + filters.push(['_id', '<>', fromRuleId]); + } + switch (event) { case 'insert': filters.push([['trigger_type', '=', 'onCreateOnly'], 'or', ['trigger_type', '=', 'onAllChanges'], 'or', ['trigger_type', '=', 'onCreateOrTriggeringUpdate']]) @@ -23,14 +29,25 @@ export async function runObjectWorkflowRules(objectName, event, record, userSess break; } + let allTargets: Array = []; + let tempTargets: Array = []; const wfRules = await getObject('workflow_rule').find({ filters: filters}); for (const wfRule of wfRules) { if(wfRule.trigger_type === 'onCreateOrTriggeringUpdate'){ - await runWFRule(wfRule, record, userSession, previousRecord) + tempTargets = await runWFRule(wfRule, record, userSession, previousRecord) }else{ - await runWFRule(wfRule, record, userSession) + tempTargets = await runWFRule(wfRule, record, userSession) } + tempTargets.forEach((target) => { + target.from_rule_id = wfRule._id; + }); + allTargets = allTargets.concat(tempTargets); } + allTargets.forEach(async (target)=>{ + // 因为工作流操作可能更改记录字段值,所以这里只能根据id重新取record + const targetRecord = await getObject(target.object_name).findOne(target.record_id, null); + await runObjectWorkflowRules(target.object_name, event, targetRecord, userSession, target.previous_record, target.from_rule_id); + }); } // export async function runObjectWorkflowRulesOnCreateOnly(objectName, record, userSession) { @@ -56,6 +73,7 @@ export async function runObjectWorkflowRules(objectName, event, record, userSess async function runWFRule(rule: WorkflowRule, record: JsonMap, userSession, previousRecord?: JsonMap) { let previousIsTrue = false; + let targets: Array = []; if(previousRecord){ previousIsTrue = await computeFormula(rule.formula, rule.object_name, previousRecord, userSession.userId, userSession.spaceId); @@ -64,7 +82,8 @@ async function runWFRule(rule: WorkflowRule, record: JsonMap, userSession, previ if(!previousIsTrue){ let isTrue = await computeFormula(rule.formula, rule.object_name, record, userSession.userId, userSession.spaceId) if (isTrue) { - runFieldUpdateActions(rule.updates_field_actions, record._id, userSession) + targets = await runFieldUpdateActions(rule.updates_field_actions, record._id, userSession); } } + return targets; } \ No newline at end of file