From 6af0749df8b2fe59c25c424d300f52075b58b325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AE=B7=E4=BA=AE=E8=BE=89?= Date: Mon, 4 Jan 2021 21:58:50 +0800 Subject: [PATCH] =?UTF-8?q?#1272=20=E5=BD=93=E5=89=8D=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E7=9A=84=E5=B7=A5=E4=BD=9C=E6=B5=81=E8=A7=84=E5=88=99=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=90=8E=EF=BC=8C=E9=9C=80=E8=A6=81=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=AF=B9=E8=B1=A1=E7=9A=84=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../objectql/src/actions/field_updates.ts | 18 +++++++++++-- .../src/actions/types/field_update_target.ts | 7 +++++ .../objectql/src/actions/workflow_rule.ts | 27 ++++++++++++++++--- 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 packages/objectql/src/actions/types/field_update_target.ts 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