代码生成

本小节介绍的所有内容,都是在橙单生成器中配置完成的。

  • 在「工程编辑」页面,选择「支持工作流」。需要强调的是,这个选项只能从「不支持」切换到「支持」,反之是不被允许的。
  • 选择「集成工作流模块」的服务。在单体工程中,只有一个业务服务 application-webadmin,因此只能选择该服务。而微服务工程可能存在多个业务服务,那么「有且只有一个」业务服务能够集成工作流模块,并对外提供工作流的接口服务。

流程类型比对

在我们的技术支持群中,最被经常问到的一个问题就是,什么是「路由表单工作流」,什么又是「在线表单工作流」,他们有什么区别。事实上,对这个问题的解释,确实占用了我们很多时间,这里我们根据之前的问题汇总,列出以下功能比对的表格。

  路由表单工作流 在线表单工作流
在生成器中配置
便于二次开发
前端流程页面代码 每个流程独立的流程前端页面代码 (.vue) 所有流程使用在线表单公用的前端代码,不同流程的 JSON 渲染出不同的流程页面。
后台流程接口实现代码 每个流程使用自己的后台接口代码、业务服务实现类、数据访问层和实体对象等。 所有流程使用在线表单工作流公用的后台代码,根据请求接口中的「流程定义」来区分不同的流程。
在生成器的流程编辑器中配置流程 支持 不支持
在生成后工程的流程编辑器中配置流程 支持 支持
流程更新后是否需要重新部署应用 需要 不需要
运行时性能 更高 一般
适用场景 流程页面和数据操作相对复杂的流程。 流程页面和数据操作简单的流程。

路由表单工作流

路由表单工作流,需要在生成器中进行部分配置,然后生成与每个流程相关的前后端业务代码。这里需要重点说明的是,路由表单工作流的流程,在生成器中只能进行部分配置,与流程任务审批人、候选人和候选组等相关的配置,必须在生成后工程的流程编辑器中继续配置,因为用户、部门、岗位和角色等数据属于业务数据,在生成器的流程图中无法指定。最后需要说明的是,流程图中流程任务的二次配置,对生成的代码没有任何影响。

创建流程

在创建「路由表单工作流」之前,我们需要先创建该流程所需的「数据源」,以便在后续的流程配置中使用。该配置将生成与当前流程相关的后台代码 (Controller/Service/ServiceImpl/Dao/Mapper/Model/Vo/Dto)。

  • 为已经导入的服务表配置「工作流能力」。
  • 为业务表设置记录流程状态的同步字段。下图中的「流程状态字段」是粗粒度的记录,主要记录流程自身的处理状态,如:保存草稿、已提交、已完成和已终止等。而「流程审批状态字段」则记录当前流程中最新审批任务的操作状态,如:同意、拒绝、驳回、自由跳等。相对而言会更加精确。

  • 为上一步导入的服务表创建数据源。下图所示的数据源 TestFlowSubmit,就是基于上一步导入到该服务的数据表 zz_test_flow_submit。
  • 在应用管理中创建流程,该流程需要使用上一步创建的数据源,同时流程所用的「路由表单」也是在这里创建。

流程基础信息配置

  • 流程名称,中文显示名称。
  • 流程标识,等同于流程定义标识 (英文),必须全工程唯一,创建后不能修改。
  • 流程数据源,为流程提供后台接口代码,可使用前面配置的支持「工作流能力」的数据源。
  • 工单编码规则,工单表 (zz_flow_work_order) 工单编码字段 (work_order_code) 的计算规则。
  • 流程数据同步,在流程「正常审批」完成后,可将流程中使用的业务表数据,同步业务发布表中,从而实现「审批中」和「审批通过后」数据的物理隔离。

流程变量配置

  • 下图红框圈住的是两个内置流程变量,不能修改。
  • 绑定字段,在目前橙单所支持的版本中,流程变量必须与「表字段」绑定。数据源主表和所有关联表字段均可选择。
  • 变量名称,变量的中文显示名。
  • 变量标识,流程内该值必须唯一 (英文)。流程启动后,会作为流程变量名,在流程实例中传递。
  • 下图所示变量 totalAmount,会在后面的流程图中使用,比如在条件判断的表达式中。

流程审批状态配置

在前面的步骤中,我们介绍了如何在生成器中配置「流程状态字段」和「流程审批状态字段」。这里我们介绍一下如何在生成器的流程编辑器中使用他们。

  • 流程状态数据,会自动同步到流程工单表 (zz_flow_work_order) 的 flow_status 和 latest_approval_status 两个固定字段中。
  • 「流程状态字段』。橙单的流程模块,会根据配置自动完成数据同步,因此无需再进行额外的配置了。
  • 「流程审批状态字段」。通常情况下,我们会为每个流程任务的「操作按钮」配置一个流程更新状态值。当按钮触发后,对应的状态标识值会同步更新到业务表的指定字段中。因此,我们可以根据业务的实际需求,为流程任务的执行状态,设置不同的「状态标识值」,以便在业务代码中可以根据不同的审批状态进行查询。至于如何与操作按钮绑定,我们会在下面的步骤中给出详细的说明。这里所述的配置,在生成后工程的流程编辑器中也可以进行编辑。

流程表单配置

  • 不同类别的流程路由表单应用场景不同,生成的代码也不同,具体差别见如下表格。
  流程页面 流程关联编辑页面 流程多对多添加页面 流程工单列表页面
功能范围 流程任务页面 编辑一对多关联从表数据的二级页面 添加多对多关联从表数据的二级页面 流程工单管理页面
数据范围 编辑和显示主表和关联表数据 编辑和显示一对多从表数据 添加多对多关联从表列表数据 工单表和主表数据显示
用于流程录入页面 可以 不可以 不可以 不可以
  • 为流程任务添加表单,可绑定的表单必须是在前面流程「基础信息」配置中,与指定「流程数据源」关联的表单。
  • 需要将所有与流程任务节点关联的表单,都绑定到当前流程。
  • 如业务数据是从流程工单发起,这里必须绑定「PC 端流程工单列表」类型的表单,如支持移动端,还需绑定「移动端流程工单列表」类型的表单,具体见下图。

流程图编辑

路由表单工作流,开始是在橙单代码生成器的流程编辑器中进行配置的。由于用户和组织机构等业务数据,在生成器中无法获悉,因此生成器中的流程编辑器无法为流程配置与审批用户和审批组织机构相关的信息。此部分配置,需要在生成后工程的流程编辑器中继续配置。

  • 为指定的流程任务选择表单,同时选择该表单是否「允许编辑」。在橙单目前的版本中,路由表单工作流没有支持精确到组件的读写控制,只是控制到表单级别。如果没有打开 「允许编辑」开关,表单内所有组件均为只读状态。

以下几步对于流程录入任务的配置非常非常重要,如配置有误,流程发起时将无法加载录入表单页面。

  • 在下图中,我们选择的流程任务是开始节点之后的「录入任务」,通常而言,录入任务关联的表单都是「允许编辑」的。

  • 对于录入任务而言,如果是从流程工单列表页面发起流程,那么「录入任务」的审批人必须为「流程发起人」。在生成器的流程编辑器中,是无法配置流程审批人的,因此这一步配置要在生成后工程的流程编辑器中进行配置,具体见下图。
  • 对于有些流程,业务数据在业务表单中已经录入完毕,而流程的发起则是在业务列表页面,通过点击业务数据的「审批」按钮发起审批流程。对于此种业务场景,第一个流程任务所对应的就是审批表单,而非上面介绍的录入表单了。
  • 如下图所示,为指定的流程任务添加「操作按钮」,在与该审批任务关联的表单中,会显示这里添加的所有「操作按钮」。
  • 按钮类型,选择一种我们内置的按钮类型即可,类型不同,功能不同。对于内置的按钮类型,也会被当成任务变量处理,并在流程中传递。比如「同意」类型的按钮,会使用内置变量 operationType,变量值为 agree。
  • 按钮名称,按钮在表单页面上的显示名。
  • 更新工单状态,下拉框中的候选项,就是在前几步中配置的「流程状态标识值」。当该按钮被触发后,就会根据该值更新工单表的 latest_approval_status 字段。以便于工单业务数据的查询和后期统计分析。如果选择「不更新」选项,就不会更新该字段值。
  • 流程有任何修改,都要点击左上角的「保存流程」按钮。
  • 点击「预览」→「预览XML」,可以预览流程的标准 BPMN XML 文件。

流程图中的按钮

该问题属于被高频提问的问题,因此我们用独立的小节进行介绍,以方便用户在文档中快速导航。对于流程图编辑中操作按钮,路由表单工作流和在线表单工作流没有任何差别,这里只是为了方便阅读,才会分别给出重复的内容。

  • 同意,默认同意操作。
  • 拒绝,默认拒绝操作。
  • 驳回,当前审批人,驳回待办任务到上一个任务节点。
  • 驳回到起点,当前审批人,驳回待办任务到流程的第一个用户任务节点,通常是录入节点。
  • 驳回到历史任务,当前审批人,驳回待办任务之前审批途径过的任务节点。不能驳回到并行网关内的任务。
  • 撤销,审批人在提交审批后,在尚未被下一个审批人审批之前,可以撤回之前的审批操作。
  • 转办,将当前任务转交给选择的用户或用户组处理,流程任务节点没有任何变化,只能更换了审批人或审批候选人组。
  • 会签,在流程图中为多实例任务。会签的指定人,需要在会签任务的上一级任务设置,用户点击会签按钮后,选择具体的审批人用户列表。在后面「实例讲解」小节,会给出专门的会签实例,并进行更为详细的说明。

  • 同意 (会签),仅用于会签任务,用户点击此按钮会使内置多实例变量 multiAgreeCount 的值加一。
  • 拒绝 (会签),仅用于会签任务,用户点击此按钮会使内置多实例变量 multiRefuseCount 的值加一。
  • 弃权 (会签),仅用于会签任务,用户点击此按钮会使内置多实例变量 multiAbstainCount 的值加一。
  • 加签,流程审批已经进入会签任务时,当前会签任务节点的上一级节点的审批人,发现需要新增会签人员时,可以通过「加签」的方式,添加新的会签人员。需要说明的是,如果会签任务已经结束,不能再进行加签了。
  • 减签,流程审批已经进入会签任务时,当前会签任务节点的上一级节点的审批人,发现需要移除某一会签人员时,可以通过「减签」的方式,移除现有的会签人员。需要说明的是,如果会签任务已经结束,不能再进行减签了。
  • 保存草稿,在流程审批数据录入节点,可以先不提交流程,而只是将当前填写的表单数据,保存到草稿中。需要额外说明的是,此操作已经启动了流程实例,流程发起人可以在「工单列表」中继续编辑草稿,并最终提交审批。
  • 终止,终止当前的流程实例。通过此方式终止的流程,工单表 flow_status 字段值为「正常结束」。
  • 自由跳,顾名思义,可以向前或向后跳转到任意用户任务。跳转过程中如果指定用户,那么该用户将为目标任务的审批人。

流程图中的变量配置

该问题属于被高频提问的问题,因此我们用独立的小节进行介绍,以方便用户在文档中快速导航。对于流程图编辑中变量设置,路由表单工作流和在线表单工作流没有任何差别,这里只是为了方便阅读,才会分别给出重复的内容。

  • 需要在上一个任务中配置流程变量。

  • 在后续的任务或流程分支中使用。

流程图中配置审批人

对于路由表单工作流而言,在生成器中「无法配置」流程任务的审批人、候选人和候选组等相关信息,必须在生成后工程的流程编辑器中继续配置,因为用户、部门、岗位和角色等数据属于业务数据,在生成器的流程图中无法指定。具体配置会在当前文档的「在线表单工作流的流程图中配置审批人」小节中给出。

工单表单绑定菜单

在上面的流程中,我们创建了三个表单,只能为「工单管理页面」类型的表单绑定菜单。

业务表单发起流程

我们内部习惯于将此种流程发起方式,称之为「主表视角」流程。该流程的业务数据录入,与普通页面没有任何差别,只是在业务数据的列表中,会多出一个流程审批的按钮,按钮显示名可自定义,该按钮触发后即可启动流程,并将所在行数据视为「流程录入数据」。「主表视角」的流程有以下几点注意事项。

  • 通常流程中的第一个任务节点不是「数据录入节点」。
  • 同一条数据,无论是新增还是修改之后,都可以进行审批。即同一条业务数据可以进行多次审批。
  • 如果同一条数据的审批流程没有结束,不能再发起针对该数据的审批流程。只有当前一个审批流程结束后,才能针对该条数据发起新的审批流程。

重点!在为业务表单配置「发起流程」操作之前,推荐先配置好「工作流」以及与其关联的「流程表单」,这里所述操作均需在「橙单生成器」中完成。

生成后代码

  • 在生成器中配置的每个「路由表单工作流」,都会生成一套独立的 Controller/Service/ServiceImpl/Dao/Mapper/Model/Vo/Dto 后台代码文件。
  • 上图中 /startWithBusinessKey/${processDefinitionKey} 接口方法,会发起一个新的流程实例,其中路径参数 ${processDefinitionKey},就是在生成器中配置的 「流程标识」。
  • 在权限数据初始化文件  init-upms-data-script.sql 中,会生成与路由表单工作流相关的权限数据。
  • 在工作流数据初始化文件 flow-script.sql 中,会生成与路由表单工作流相关的初始化数据。

流程管理

上一小节的末尾,我们介绍了在 flow-script.sql 脚本文件中,会预先插入「路由表单工作流」的初始化数据,其中包含「默认流程分类」和「流程设计」等数据。

流程分类

没有任何业务功能,就是对流程进行简单的分类。

流程设计

无论是「在线表单工作流」,还是「路由表单工作流」,都需要在这里创建和维护。对于后者,生成器会生成初始化脚本,并将在生成器中配置的流程数据,全部插入到本地流程表 zz_flow_entry 中,因此,通过生成器生成的「路由表单工作流」,无需再次创建了。

  • 编辑,直接编辑流程图数据,我们会在后面的内容专门介绍,在线表单工作流的编辑功能。
  • 发布,每次编辑后,如果有任何变化,都要重新发布。
  • 版本管理,每次发布后,都需要将新发布的版本设置为「主版本」后,新启动的流程才会使用新版本流程。原先已经启动的流程,仍然继续使用之前版本,直到流程审批结束或强制终止。
  • 删除,删除流程,但是已经发布的流程,不能删除。
  • 启动,根据主版本,启动新的「流程实例」。

流程实例

当前系统中,所有已经启动过的流程实例。

  • 只要有权限访问该页面,就能看到全部流程实例数据,通常只有系统管理员有权访问该菜单。
  • 流程图,查看当前流程实例的执行流程图。
  • 流程干预,对尚未结束的流程进行强制干预。干预过程中,可以指定任意跳转节点,并为新节点指定新的审批人。
  • 流程复活,对已经结束的流程进行强制恢复。恢复过程中,可以指定任意跳转节点。
  • 终止,强制终止尚未结束的流程实例。
  • 删除,只能删除已经结束的流程实例。对于审批中的流程,可以先终止,再结束。

在线表单工作流

在线表单工作流所有配置均无需重启业务服务,配置后即可生效。

代码生成

必须在代码生成器中,选择支持「在线表单」和「岗位管理」,生成后的前后端工程中才会包含「在线表单工作流」的相关代码。否则在后面的流程配置中,将无法选择并绑定「动态表单」类型的页面。

流程基础信息配置

  • 表单类型,选择「动态表单」。
  • 流程名称,中文显示名称。
  • 流程标识,等同于流程定义标识 (英文),必须全工程唯一,创建后不能修改。
  • 流程分类,选择当前流程所在分类。该选项没有业务意义,只是便于分类显示。
  • 工单编码规则,工单表 (zz_flow_work_order) 工单编码字段 (work_order_code) 的计算规则。
  • 流程页面,这里只能选择类型为「流程类型」的在线表单页面。
  • 默认表单,设置流程任务节点默认使用的表单页面,这里不要选择工单页面。
  • 通知类型,选择流程实例的通知类型,每个流程任务进入待办状态之前都会发出该通知。另外,也可以在流程编辑中,为每个任务指定额外的通知类型,两者是并集关系。具体细节可参考 流程实例章节的待办任务通知小节
  • 级联删除业务数据,当删除流程实例的时候,是否级联删除当前实例关联的业务主表数据,以及与主表关联的从表数据。具体细节可参考 流程实例章节的级联删除业务数据小节

流程变量配置

在当前流程图的编辑中,所有用到的变量都需要在这里预先配置。

  • 下图红框圈住的是两个内置流程变量,不能修改。
  • 绑定字段,在目前橙单所支持的版本中,流程变量必须与「表字段」绑定。数据源主表和所有关联表字段均可选择。
  • 变量名称,变量的中文显示名。
  • 变量标识,流程内该值必须唯一 (英文)。流程启动后,会作为流程变量名,在流程实例中传递。
  • 下图所示变量 totalAmount,会在后面的流程图中使用,比如在条件判断的表达式中。

流程状态配置

  • 在线表单流程状态字段的配置,如下图所示。
  • 流程状态数据,会自动同步到流程工单表 (zz_flow_work_order) 的 flow_status 和 latest_approval_status 两个固定字段中。
  • 流程状态字段。橙单的流程模块,会根据配置自动完成数据同步,因此无需再进行额外的配置了。需要重点说明的是,流程状态字段仅在流程实例结束时,才会由 FlowFinishedListener 监听器同步到业务表中对应的字段。
  • 流程审批状态字段。通常情况下,我们会为每个流程任务的「操作按钮」配置一个流程更新状态值。当按钮触发后,对应的状态标识值会同步更新到业务表的指定字段中。因此,我们可以根据业务的实际需求,为流程任务的执行状态,设置不同的「状态标识值」,以便在业务代码中可以根据不同的审批状态进行查询。至于如何与操作按钮绑定,我们会在下面的步骤中给出详细的说明。

流程表单配置

在流程配置中,目前并不支持在线表单的配置,如需修改,请到菜单「在线表单」→「表单管理」页面,修改与当前流程关联的在线表单配置。

流程图编辑

我们使用的是基于 BPMNjs 的流程编辑器,因此与流程图绘制相关的基础性问题,请自行百度。

  • 为指定的流程任务选择表单,同时选择该表单是否「允许编辑」。在橙单目前的版本中,在线表单工作流已支持精确到组件的读写和显隐控制。此外如果没有打开 「允许编辑」开关,表单内所有组件均为只读状态。

以下几步对于流程录入任务的配置非常非常重要,如配置有误,流程发起时将无法加载录入表单页面。

  • 在下图中,我们选择的流程任务是开始节点之后的「录入任务」,通常而言,录入任务关联的表单都是「允许编辑」的。
  • 对于录入任务而言,如果是从流程工单列表页面发起流程,那么「录入任务」的审批人必须为「流程发起人」,具体见下图。
  • 对于有些流程,业务数据在业务表单中已经录入完毕,而流程的发起则是在业务列表页面,通过点击业务数据的「审批」按钮发起审批流程。对于此种业务场景,第一个流程任务所对应的就是审批表单,而非上面介绍的录入表单了。
  • 如下图所示,为指定的流程任务添加「操作按钮」,在与该审批任务关联的表单中,会显示这里添加的所有「操作按钮」。
  • 按钮类型,选择一种我们内置的按钮类型即可,类型不同,功能不同。对于内置的按钮类型,也会被当成任务变量处理,并在流程中传递。比如「同意」类型的按钮,会使用内置变量 operationType,变量值为 agree。
  • 按钮名称,按钮在表单页面上的显示名。
  • 更新工单状态,下拉框中的候选项,就是在前几步中配置的「流程状态标识值」。当该按钮被触发后,就会根据该值更新工单表的 latest_approval_status 字段。以便于工单业务数据的查询和后期统计分析。如果选择「不更新」选项,就不会更新该字段值。
  • 任务通知,为选定的任务设置任务通知类型,可以多选。如果为当前流程也设定了任务通知,那么下图所示任务的通知,将是两者的并集。
  • 流程有任何修改,都要点击左上角的「保存流程」按钮。
  • 点击「预览」→「预览XML」,可以预览流程的标准 BPMN XML 文件。

流程图中的按钮

该问题属于被高频提问的问题,因此我们用独立的小节进行介绍,以方便用户在文档中快速导航。

  • 同意,默认同意操作。
  • 拒绝,默认拒绝操作。
  • 驳回,当前审批人,驳回待办任务到上一个任务节点。
  • 驳回到起点,当前审批人,驳回待办任务到流程的第一个用户任务节点,通常是录入节点。
  • 驳回到历史任务,当前审批人,驳回待办任务之前审批途径过的任务节点。不能驳回到并行网关内的任务。
  • 撤销,审批人在提交审批后,在尚未被下一个审批人审批之前,可以撤回之前的审批操作。
  • 转办,将当前任务转交给选择的用户或用户组处理,流程任务节点没有任何变化,只能更换了审批人或审批候选人组。
  • 会签,在流程图中为多实例任务。会签的指定人,需要在会签任务的上一级任务设置,用户点击会签按钮后,选择具体的审批人用户列表。在后面「实例讲解」小节,会给出专门的会签实例,并进行更为详细的说明。
  • 同意 (会签),仅用于会签任务,用户点击此按钮会使内置多实例变量 multiAgreeCount 的值加一。
  • 拒绝 (会签),仅用于会签任务,用户点击此按钮会使内置多实例变量 multiRefuseCount 的值加一。
  • 弃权 (会签),仅用于会签任务,用户点击此按钮会使内置多实例变量 multiAbstainCount 的值加一。
  • 加签,流程审批已经进入会签任务时,当前会签任务节点的上一级节点的审批人,发现需要新增会签人员时,可以通过「加签」的方式,添加新的会签人员。需要说明的是,如果会签任务已经结束,不能再进行加签了。
  • 减签,流程审批已经进入会签任务时,当前会签任务节点的上一级节点的审批人,发现需要移除某一会签人员时,可以通过「减签」的方式,移除现有的会签人员。需要说明的是,如果会签任务已经结束,不能再进行减签了。
  • 保存草稿,在流程审批数据录入节点,可以先不提交流程,而只是将当前填写的表单数据,保存到草稿中。需要额外说明的是,此操作已经启动了流程实例,流程发起人可以在「工单列表」中继续编辑草稿,并最终提交审批。
  • 终止,终止当前的流程实例。通过此方式终止的流程,工单表 flow_status 字段值为「正常结束」。
  • 指定审批人,为下一个流程任务指定审批人。仅当下一个流程任务的候选用户是指定审批人时,该操作才会生效。

流程图中的变量配置

该问题属于被高频提问的问题,因此我们用独立的小节进行介绍,以方便用户在文档中快速导航。

  • 需要在上一个任务中配置流程变量。
  • 在后续的任务或流程分支中使用。

流程图中配置审批人

为流程任务配置审批人、候选人和候选组。如果指定的是审批人,该任务只能由指定用户审批。如果指定的是候选人组 (一组候选人) 和候选组 (部门、角色和岗位),那么所有符合身份的用户都可以看到待办任务,并完成任务的审批。

  • 处理用户,该选项设置的是「指派人」,因此只能指定一个用户。对于该选项,「处理用户」一定不要选择「使用指定审批人」,因为指定后的 ${appointedAssignee} 变量,在运行时可以指定多人,而处理用户是设置给指派人 Assignee 的,该值不能使用多人。
  • 候选用户组,该选项设置的是「审批候选人组」。可以指定多个候选人,通常设置「指定审批人」时,需要使用该选项。
  • 角色,当前系统中指定角色的用户。
  • 部门,当前系统中指定部门的用户。
  • 岗位,当前系统中指定岗位的用户。因为岗位和部门是存在多对多关联关系的,所以岗位的选择,相比于「角色」和「部门」要复杂一点儿,具体见下图及文字注释。
  • 流程发起人部门领导,流程发起人所在部门的岗位中,被标记为领导岗位的用户组。
  • 流程发起人上级部门领导,流程发起人所在部门的上级部门的岗位中,被标记为领导岗位的用户组。

流程图中配置抄送人

当前流程达到某一审批任务时,在流程图中为该任务设置的抄送用户和抄送组中的用户,都会收到流程审批的消息通知,但是「被抄送用户」不能参与流程的审批,只能查看审批内容。另外需要说明的是,可以选择多个类型的抄送组,所有抄送组中的用户都会收到抄送消息。

工单表单绑定菜单

  • 在线表单的类型必须是「流程页面」。
  • 必须包含「工单列表」类型的在线表单。
  • 绑定菜单,其中菜单绑定的表单类型,必须为「工单列表」。

业务表单发起流程

我们内部习惯于将此种流程发起方式,称之为「主表视角」流程。该流程的业务数据录入,与普通页面没有任何差别,只是在业务数据的列表中,会多出一个流程审批的按钮,按钮显示名可自定义,该按钮触发后即可启动流程,并将所在行数据视为「流程录入数据」。「主表视角」的流程有以下几点注意事项。

  • 通常流程中的第一个任务节点不是「数据录入节点」。
  • 同一条数据,无论是新增还是修改之后,都可以进行审批。即同一条业务数据可以进行多次审批。
  • 如果同一条数据的审批流程没有结束,不能再发起针对该数据的审批流程。只有当前一个审批流程结束后,才能针对该条数据发起新的审批流程。

重点!在为业务表单配置「发起流程」操作之前,推荐先配置好「工作流」以及与其关联的「流程表单」。其中与流程关联的表单必须为「流程类型」的在线表单。

接下来我们需要创建「非流程类型」的业务表单,在本例中,我们以橙单在线演示工程中的「文章管理」表单为例,具体配置过程见以下几张截图。

工单打印

仅当支持打印报表模块时,该功能可用!

数据集配置详解

  • 本小节将以合同审批流程为例,详细介绍一下工单打印的完整配置步骤。
  • 下面是上图中的 SQL 语句。需要说明的是,这里是以 MySQL 为例的。
SELECT 
    -- 为了避免两个表出现同名字段的冲突,这里推荐明确列出工单表中所需的字段。
    a.work_order_id, 
    a.work_order_code, 
    a.process_definition_key, 
    a.process_definition_name, 
    a.task_name, 
    a.submit_username, 
    a.dept_id, 
    a.latest_approval_status,
    a.flow_status,
    b.* 
FROM 
    -- 工单表和业务表的一对一内连接。
    zz_flow_work_order a, zz_test_flow_contract b 
WHERE 
    -- 下面的${workOrderId},是SQL结果集的变量参数。 参数名推荐这里的命名方式。
    -- 但是需要说明的是,必须要针对工单表主键字段 work_order_id 进行过滤。
    a.work_order_id = ${workOrderId} 
    AND a.deleted_flag = 1
    -- 工单表的business_key是字符型字段,而业务的主键,可能是字符型也可能是数值型,
    -- 不同类型的字段数据进行关联,会产生自动的隐式转换,这种转换对于不同的数据库有
    -- 不同的依赖,有时候甚至会抑制业务表主键的索引。
    AND a.business_key = b.contract_id

流程工单配置

  • 在下图中配置的打印模板输入参数「workOrderId」,会被传递给上一步创建的 SQL 结果集参数 ${workOrderId}。
  • 配置打印 Excel 模板并创建打印段落,为新建的打印段落选择上面配置的 SQL 数据集,作为该段落的数据源。同时配置结果集参数,并指定为上一步创建的模板输入参数 workOrderId。
  • 配置打印 Word 模板并添加数据集,本例需要选择上面配置的 SQL 数据集,同时配置结果集参数,并指定为上一步创建的模板输入参数 workOrderId。关于 Word 打印模板的编写可参考 统计报表章节的 Word 打印模板小节
  • 配置流程工单的在线表单,并进行如下图所示的配置。

技术实现

  • 在线表单工作流的工单打印接口为 FlowOperationController 类的 printWorkOrder 方法。见如下代码及关键性注释。
// 该方法并不进行实际的打印工作,而是对当前请求的工单参数数据进行合法性验证。通过验证后,会为本次调用生成
// 唯一的打印令牌,并存入与session关联的缓存中,再将实际打印接口及生成的打印令牌返回给前端。前端收到应答后,
// 会调用返回的实际打印接口完成打印。
@PostMapping("/printWorkOrder")
public ResponseResult<String> printWorkOrder(
       @MyRequestBody(required = true) Long workOrderId,
       @MyRequestBody(required = true) Long printId,
       @MyRequestBody(required = true) List<JSONArray> printParams) throws IOException {
       
   // 这里忽略打印数据验证的相关代码 ... ...

   // 为本次打印请求生成唯一的打印令牌。
   String token = MyCommonUtil.generateUuid();
   // 将本次请求的打印令牌和打印参数,均存入会话关联的缓存中。出于安全考虑,仅返回打印令牌。
   sessionCacheHelper.putSessionPrintTokenAndInfo(token, new MyPrintInfo(printId, printParams));
   // 将打印令牌作为url参数返回给前端。
   return ResponseResult.success(onlineProperties.getPrintUrlPath() + "?printToken=" + token);
}
  • 实际打印方法的实现。该接口为 ReportPrintController 的 print 方法。
@GetMapping("/print")
public void print(@RequestParam String printToken) throws IOException {
   // 根据打印令牌参数printToken,从会话关联的缓存中读取实际的打印数据。
   // 如果不存在则视为无效调用。
   MyPrintInfo printInfo = sessionCacheHelper.getSessionPrintInfoByToken(printToken);
   if (printInfo == null) {
       ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.error(ErrorCodeEnum.NO_ACCESS_PERMISSION));
       return;
   }
   // 将请求参数转换为打印服务所需的参数对象。
   List<ReportPrintParam> reportPrintParams = new LinkedList<>();
   for (JSONArray printParam : printInfo.getPrintParams()) {
       ReportPrintParam reportPrintParam = new ReportPrintParam();
       if (CollUtil.isNotEmpty(printParam)) {
           reportPrintParam = new ReportPrintParam();
           for (int i = 0; i < printParam.size(); ++i) {
               ReportPrintParam.FilterInfo filterInfo =
                       printParam.getJSONObject(i).toJavaObject(ReportPrintParam.FilterInfo.class);
               reportPrintParam.add(filterInfo);
           }
       }
       reportPrintParams.add(reportPrintParam);
   }
   // 执行实际的打印,并将打印结果作为应答数据流,直接返回给前端。
   if (CollUtil.isNotEmpty(reportPrintParams)) {
        ReportPrint print = reportPrintService.getById(printInfo.getPrintId());
        int renderType = print.getPrintType() == ReportPrintType.EXCEL ? PrintRenderType.EXCEL : PrintRenderType.WORD;
        reportOperationHelper.print(printInfo.getPrintId(), reportPrintParams, renderType);
   }
}

流程运行

路由表单工作流和在线表单工作流的操作步骤是完全一致的。

启动流程

  • 在「流程设计」页面启动流程。通常是流程的管理和配置用户,在编辑流程之后,通过该方式启动流程,进行必要的流程调试和验证。
  • 在指定流程的「工单管理」页面启动流程。系统的业务用户,通常使用该方式启动流程。
  • 对于「路由表单工作流」,可以配置为在业务页面中,针对指定业务数据发起流程审批。具体配置方式可参考当前文档「路由表单工作流的业务表单发起流程」小节。

待办任务

  • 启动后的流程,流程任务的审批人可以在「待办任务」列表中看到自己的审批任务。
  • 点击上图的「办理」按钮,将进入任务处理页面。下图为表单数据主页面,右上角的两个按钮,都是在流程图中,为该审批任务配置的,点击后,都能完成当前任务的审批。
  • 抄送设置,与在流程图中配置的「抄送」是相同的功能。这里可以选择抄送人和抄送用户组。在当前任务审批通过后,下一个流程任务进入「待办」状态时,被抄送的用户也将收到流程任务的审批通知,不同的是,被抄送人只能查看流程任务中的审批数据,不能指定审批操作。
  • 流程图,显示当前审批流程的审批进度。绿框标记的任务是已完成任务,蓝框标记的是待办任务,其他的是未执行任务。点击指定任务,可以弹框显示该任务的审批人记录。
  • 审批记录,显示当前审批流程的已审批记录。
  • 审批人,显示当前待办任务的审批人列表。如果候选组是指定部门,那么该部门下的所有用户都会被列出。

已办任务

显示当前用户已审批过的,所有流程的任务。可以点击「详情」按钮查看任务的业务数据和审批信息。

历史任务

显示当前用户发起的,已结束流程的审批任务。

工单管理

通常是当前用户查看自己所发起流程的列表页面。或者是部门领导,在配置数据权限后,也可以查看本部门用户的流程工单列表数据。

  • 新建,点击后可创建当前流程的新工单。
  • 详情,点击后可查看当前工单的数据和审批详情数据。
  • 催办,点击后会给当前的流程待办人发送一条催办消息,会在页面的右上角给出「新消息」提示。
  • 撤销,只有流程发起人可以撤销当前审批任务。如果有任何审批用户提交了审批记录,该任务不能再被撤销。

流程权限配置

本小节主要介绍工作流与权限相关的内容。

路由表单工作流

路由表单工作流是在生成器中配置的,生成后工程的 init-upms-data-script.sql 脚本文件中,会包含与所有路由表单工作流相关的权限数据。

本小节所有的文字和截图都是为了说明,路由表单工作流的权限数据是「开箱即用」的,不再需要任何手动的配置了。

  • 下面一组图是路由表单工作流「报销审批」基础权限配置的截图,这些数据都是由 init-upms-data-script.sql 脚本自动初始化的,无需额外的手动配置。
  • 「报销审批」流程的工单菜单配置。
  • 上图中「报销审批」工单菜单设置的「权限字列表」配置值,会与下图的后台接口关联。使用该注解 @SaCheckPermission("testFlowSubmit.workflow.flowSubmit") 标记的接口,均为流程发起和工单查看接口,其余流程审批接口,如审批、拒绝、驳回以及查看任务信息等接口均为白名单接口,这些接口内部会进行操作人员的合法性校验。

在线表单工作流

在线表单工作流,直接将工单配置绑定到菜单即可,无需再做任何额外配置。

结语

赠人玫瑰,手有余香,感谢您的支持和关注,选择橙单,效率乘三,收入翻番。