全部文档
文档中心工作流最佳实践多实例子流程

多实例子流程

目前多实例执行方式只有并行,执行时会根据启动多实例的数组,对数组变量中的每个成员,创建1个子流程实例,但创建子流程实例的先后顺序无法指定。

若对子流程实例内的任务/服务的处理顺序有要求,可参考如下思路,在子流程的开始节点后增加等待计时节点,以达到控制顺序的目的。

业务场景举例:主流程中利用多实例子流程节点为HR用户,生成结算各部门工资的子流程任务,但各部门间的任务处理有先后顺序。

  1. 需要存储部门的处理顺序,本例中用对象举例



  2. 启动多实例的数组:department_code



  3. 子流程中定义全局变量

定义的全局变量都基于启动参数department_code作为查询条件。



  • 定义全局变量department_name(string),初始值为查询部门名称的JS,用作任务名称:

Copy
var a = fn$queryByDeepQL(
  "select department{*} filter .department_code = <str>$department_code", 
  {"department_code":wfi$department_code});

a[0].department_name["zh-cn"]
  • 定义全局变量order(integer),初始值为查询处理顺序的JS,用作计算等待时间:

Copy
var a = fn$queryByDeepQL(
  "select department{*} filter .department_code = <str>$department_code", 
  {"department_code":wfi$department_code});

a[0].order
  • 定义全局变量cal_time(datetime),基于流程实例开始时间和order,计算等待时间,流程实例开始后需要等待order-1分钟:

Copy
// 基于流程实例的开始时间
var currentDate = new Date(wfp$start_time);
 
// 要增加的分钟数=oder-1
var minutesToAdd = (wfv$order-1);
 
// 增加分钟数后
currentDate.setMinutes(currentDate.getMinutes() + minutesToAdd)

currentDate
  1. 子流程中,在开始节点后,增加等待计时节点,基准时间设为**cal_time**



  2. 子流程中,后续任务节点的名称展示部门名称和顺序号,以备检查



  3. 效果展示

    1. 发起主流程,数组是[“PURCHASE_2”,”PURCHASE_1”,”SALES_1”,”SALES_2”]



    2. 维护好的顺序是



    3. 进入待办,查看子流程的任务开始时间:确实按照设定的顺序生成



业务场景举例:

主流程中利用多实例子流程节点发起一系列表单的预算填报,调用的子流程中仅包含一个单人任务节点,当对应预算员提交后,完成此子流程。

需求:

预算员在子流程中提交预算后,可随时撤回,一旦撤回,则全部表单重新发起,需要全部重新填报。

核心实现逻辑:

  • 子流程的UX-任务处理界面中配置按钮,关联发起消息事件(用来向主流程发送撤回消息)

  • 主流程中配置等待消息节点(用来等待撤回消息)

  • 主流程中配置发送消息节点(用来终止其他预算填报的子流程)

  • 子流程中配置等待消息节点(用来接收到消息后终止当前流程)

具体配置:

  1. 主流程设计



    1. 创建消息budget_withdraw,添加参数withdraw(boolean),用来接收撤回消息

    2. 增加全局变量submit_count(integer)、budget_withdraw(boolean),分别用来记录

      已提交的预算数量
      是否有预算员撤回

    3. (多实例子流程)预算员填报节点:增加完成时映射

      1. wfv$submit_count=如下JS表达式

Copy
var result = macr$list_of_submit_result
var result1 = result.filter(function(item) {
  return item !== null;
})
var count = result1.length
count
Copy
    2. `wfv$budget_withdraw`=如下JS表达式
Copy
!(wfv$submit_count == macp$nr_of_instances)
Copy
4. (排他网关)`是否有撤回`节点:
    1. 条件1(有人撤回):`wfv$budget_withdraw`=true(静态值)
    2. 条件1跳转至节点:重新发起预算员填报
    3. ELSE跳转至节点:更新提交状态-已填报待部门提交
5. (跳转)`重新发起预算员填报`节点:
    1. 跳转目标:重置任务状态-待提交
6. (等待消息)`等待撤回消息`节点:
    1. 订阅消息`budget_withdraw`
    2. 完成时映射`wfv$submit_count`= `true`(表达式)
7. (发送消息)`终止进行中的所有子流程`节点:
    1. 发送目标是:其他流程-预算员填报的子流程
    2. 发送消息:在子流程中定义的消息`terminate_msg`
    3. 消息参数:`true`(表达式)
    4. 发送范围:广播(因为需要所有子流程实例都终止)
8. 原本主线流程中的结束节点更改为终止节点,防止因为等待消息节点一直在进行中而无法结束流程
  1. 子流程设计



    ****

    1. 创建消息terminate_msg,添加参数terminate(boolean),用来接收终止消息(节点内编排的终止节点,用于完成整个流程实例)

    2. (等待消息)等待终止消息节点:订阅消息terminate_msg

    3. (单人任务)预算员填报节点:待办跳转界面增加跳转参数parent_proc_id=wfp$parent_proc_id,用来向主流程发送撤回消息

    4. 原本主线流程中的结束节点更改为终止节点,防止因为等待消息节点一直在进行中而无法结束流程

  2. UX-任务处理页面设计(这是子流程中单人任务预算员填报节点的待办跳转界面):

    1. 增加数据源DeepQL,QL语句中的space编码需替换:

Copy
# 仅当该流程实例中,已完成的任务、当前用户是任务处理人时、父流程还在进行中,才可以看到撤回按钮
select DFTask{*}
filter
    .process.proc_inst_id = <str>$proc_id
    and .task_status = "Completed"
    and .assignee.system_user = global spacehreevs::current_user
    and .process.parent.state = "ACTIVE"
order by .start_time desc
limit 1
```<br>![1717472280175-84c6d9ad-1881-4a49-aea3-b93d9509a75e](../media/1717472280175-84c6d9ad-1881-4a49-aea3-b93d9509a75e.png)<br>

    2. 增加`撤回`按钮
        1. 隐藏条件(条件中的数据源编码需替换):`($var.task_id == null) || ($dataSources.data_query3_EMcZ.data?.[0].task_inst_id != $var.task_id)`
        2. 事件为`发起消息事件`,向主流程发送`budget_withdraw`消息,消息参数`withdraw`赋值`true`(表达式),发送范围的流程实例ID是`$urlQuery.parent_proc_id`

**需求拓展:**

已提交过预算的预算员,在别的预算员撤回后,不被影响,无需重新提交。

**核心实现逻辑调整:**

+ 主流程中配置发送消息节点(用来终止其他预算填报的子流程)
+ 子流程中配置等待消息节点(用来接收到消息后终止当前流程)



回到顶部

咨询热线

400-821-9199

我们使用 ChatGPT,基于文档中心的内容以及对话上下文回答您的问题。

ctrl+Enter to send