1. 用户需求
假设A系统有如下员工请假审批流场景:
员工请假小于等于3天,只需主管直接审批;大于3天需要主管先审批,审批通过后再由二级主管进行审批。当员工请假审批流节后后,需要通知A系统进行业务处理(例如:如果同意,则扣除相应假期,如果拒绝,则不扣除)。
2. 需求分析
通过对用户故事的分析,需要经过如下步骤完成此需求。
- 进入流程组件,在流程组件里设计上述“员工请假审批流”。
- 在A系统内实现“员工请假审批流”结束后的业务自定义处理逻辑。
- 在A系统内实现通过流程组件API 发起“员工请假审批流”。
- 用户在A系统发起“员工请假审批流”。
3. 前置条件
已部署云巧流程组件,且服务已正常运行。
4. 服务接入
1. 流程设计
1. 设计流程图:进入流程组件,设计如下的流程图,流程编码为employee_leave。
2. 新增办理人变量:点击画布空白页,进入“流程配置”,新增如下“流程变量”,作为“主管审批”、“二级主管审批”的办理人变量。
3. 设置用户任务节点办理人:在“主管审批”节点设置办理人变量为“主管”。在“二级主管审批”节点设置办理人变量为“二级主管”。
4. 设置排他网关条件,其中approve为排他网关入口用户任务的处理结果变量(true为同意、false为拒绝),leaveDays为业务定义的请假天数变量,&&表示且的意思:
- 拒绝:${!approve}
- 同意-且小于等于3天:${approve && leaveDays<=3}
- 同意-且大于3天:${approve && leaveDays>3}
2. A系统实现流程结束后的处理逻辑
在A系统中实现流程结束后的处理逻辑B,然后订阅并消费流程组件的RocketMQ消息,消费流程组件RocketMQ消息时根据消息体内的流程实例ID、流程实例结果、...等字段调用处理逻辑B完成业务处理。
【备注】流程组件RocketMQ消息:
○ 流程事件TOPIC:为流程后端服务FLOW_NOTICE_ROCKETMQ_TOPIC_EVENT环境变量值,或flow.notice.rocketmq.topic.event配置值,默认为FLOW_EVENT。
○ 流程事件Tag:流程编码(例如:此用户故事即为employee_leave)。
○ 流程事件消息体类型:包括流程开始、流程结束、任务开始、任务结束、任务转办等事件消息。
3. A系统发起流程
- 引入流程组件API二方包。
<dependency><groupId>com.aliyun.gts</groupId><artifactId>flow-facade-api</artifactId><version>${flow.version}</version></dependency>
- 注入流程组件API类。
在A系统的Application启动类上使用如下Feign注解自动注入流程组件API类FlowProcessApi.class。
clients= {FlowProcessApi.class}) (publicclassFlowApplication { // ....}
- 当A系统和流程组件在同一个集群,且使用Nacos作为服务注册发现时,此处需要在A系统配置Nacos服务发现相关配置,如已经配置,则忽略。
- 当不在一个集群,或在一个集群但未使用Nacos作为服务注册发现时,需要在A系统新增flow.be.url配置项,即流程组件后端服务地址。
- 参考如下方式发起“员工请假审批流”:
// 员工请假审批流 流程编码finalStringemployeeLeaveProcessKey="employee_leave"; // 主管用户IDStringleaderId="xxx"; // 二级主管用户IDStringsecondaryLeaderId="yyy"; // 请假天数,应从业务系统传入,此处为了演示写为5IntegerleaveDays=5; // 请假人ID(即流程发起人ID)StringuserId="1"; // 租户ID(如果没有租户概念,默认写为1)StringtenantId="1"; // 构造流程发起请求FlowProcessStartRequestflowProcessStartRequest=newFlowProcessStartRequest(); // 设置流程编码flowProcessStartRequest.setProcessDefinitionKey("employee_leave"); // 设置流程变量,包括审批人变量和请假天数变量Map<String, Object>variables=newHashMap<>(); variables.put("leader", leaderId); variables.put("secondaryLeader", secondaryLeaderId); variables.put("leaveDays", leaveDays); flowProcessStartRequest.setVariables(variables); ResultResponse<String>response=flowProcessApi.startProcess(flowProcessStartRequest, userId, tenantId); if (response.getSuccess()) { // 发起成功// 获取此流程的流程实例IDStringprocessInstanceId=response.getData(); // 保存流程实例ID与业务系统内对象的关系,用于后续收到流程结束的通知后查询对应的业务对象// ....} else { // 发起失败// 获取失败的错误信息和错误码Stringmessage=response.getMessage(); Stringcode=response.getCode(); // 执行发起失败逻辑// ....}