activiti使用心得(2) activiti的web应用 请假审批为例,bpmn文件的定义

本文详细介绍了使用Activiti实现请假审批流程的方法,包括流程定义、任务分配、排他网关的配置以及流程结束后的业务回写。通过具体代码示例,展示了如何利用TaskListener和JavaDelegate进行流程控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相关文章
activiti使用心得(1) spring 集成activiti
activiti使用心得(2) activiti的web应用 请假审批为例,bpmn文件的定义
activiti使用心得(3) 请假申请单业务
activiti使用心得(4) 请假申请单流程启动,任务列表、审批
activiti使用心得(5) activiti 对表单的使用说明
activiti使用心得(6) 请假申请单查看备注、审批结束

通过activiti designer 制作请假审批流程,如下图:
这里写图片描述

对应代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="vacation_flow7" name="My process" isExecutable="true">
    <userTask id="usertask1" name="部门领导审批">
      <extensionElements>
        <activiti:taskListener event="create" class="com.eap.activiti.taskListener.DepartManagerTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow1" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow2" name="同意" sourceRef="exclusivegateway1" targetRef="usertask2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${operateApprove == 'true'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow7" name="拒绝" sourceRef="exclusivegateway1" targetRef="usertask4">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${operateApprove == 'false'}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="usertask2" name="人事审批">
      <extensionElements>
        <activiti:taskListener event="create" class="com.eap.activiti.taskListener.PersonnelGroupVacationTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="exclusivegateway2"></sequenceFlow>
    <userTask id="usertask3" name="销假">
      <extensionElements>
        <activiti:taskListener event="create" class="com.eap.activiti.taskListener.ProcessInitiatorTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow4" name="同意" sourceRef="exclusivegateway2" targetRef="usertask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${operateApprove == 'true'}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endevent1" name="End">
      <extensionElements>
        <activiti:executionListener event="start" class="com.eap.activiti.taskListener.TaskEndDelegate"></activiti:executionListener>
      </extensionElements>
    </endEvent>
    <sequenceFlow id="flow5" sourceRef="usertask3" targetRef="endevent1">
      <extensionElements>
        <activiti:executionListener event="take" expression="${execution.setVariable('result', 'ok')}"></activiti:executionListener>
      </extensionElements>
    </sequenceFlow>
    <userTask id="usertask4" name="调整请假申请">
      <extensionElements>
        <activiti:taskListener event="create" class="com.eap.activiti.taskListener.ProcessInitiatorTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow8" name="拒绝" sourceRef="exclusivegateway2" targetRef="usertask4">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${operateApprove == 'false'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow10" name="重新申请" sourceRef="exclusivegateway3" targetRef="usertask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${operateApprove == 'true'}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow11" sourceRef="usertask4" targetRef="exclusivegateway3"></sequenceFlow>
    <sequenceFlow id="flow12" name="结束流程" sourceRef="exclusivegateway3" targetRef="endevent1">
      <extensionElements>
        <activiti:executionListener event="take" expression="${execution.setVariable('result', 'canceled')}"></activiti:executionListener>
      </extensionElements>
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${operateApprove == 'false'}]]></conditionExpression>
    </sequenceFlow>
    <startEvent id="startevent1" name="Start"></startEvent>
    <sequenceFlow id="flow13" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_vacation_flow7">
    <bpmndi:BPMNPlane bpmnElement="vacation_flow7" id="BPMNPlane_vacation_flow7">
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="210.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="360.0" y="157.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="446.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
        <omgdc:Bounds height="40.0" width="40.0" x="574.0" y="157.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
        <omgdc:Bounds height="55.0" width="105.0" x="684.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="840.0" y="160.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4">
        <omgdc:Bounds height="55.0" width="105.0" x="328.0" y="280.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway3" id="BPMNShape_exclusivegateway3">
        <omgdc:Bounds height="40.0" width="40.0" x="360.0" y="370.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="160.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="315.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="360.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="400.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="446.0" y="177.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="399.0" y="161.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
        <omgdi:waypoint x="380.0" y="197.0"></omgdi:waypoint>
        <omgdi:waypoint x="380.0" y="280.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="380.0" y="229.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="551.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="574.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="614.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="684.0" y="177.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="614.0" y="157.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
        <omgdi:waypoint x="789.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="840.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
        <omgdi:waypoint x="594.0" y="197.0"></omgdi:waypoint>
        <omgdi:waypoint x="594.0" y="307.0"></omgdi:waypoint>
        <omgdi:waypoint x="433.0" y="307.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="565.0" y="249.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
        <omgdi:waypoint x="360.0" y="390.0"></omgdi:waypoint>
        <omgdi:waypoint x="262.0" y="389.0"></omgdi:waypoint>
        <omgdi:waypoint x="262.0" y="205.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="48.0" x="243.0" y="333.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
        <omgdi:waypoint x="380.0" y="335.0"></omgdi:waypoint>
        <omgdi:waypoint x="380.0" y="370.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
        <omgdi:waypoint x="400.0" y="390.0"></omgdi:waypoint>
        <omgdi:waypoint x="857.0" y="390.0"></omgdi:waypoint>
        <omgdi:waypoint x="857.0" y="195.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="48.0" x="559.0" y="390.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
        <omgdi:waypoint x="125.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="210.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

审批受理人或审批受理组通过TaskListener进行配置,以下贴出com.eap.activiti.taskListener.DepartManagerTaskListener类的部分代码,其中一部分以伪代码的方式给出

import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.springframework.context.ApplicationContext;

import com.eap.activiti.model.BaseForm;
import com.eap.common.utils.SpringContextUtil;

@SuppressWarnings("serial")
public class DepartManagerTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        // 获取ApplicationContext  SpringContextUtil是在普通类中获取bean 的工具类
        ApplicationContext appCtx = SpringContextUtil.getApplicationContext();
        //获取RuntimeService 
        RuntimeService runtimeService = (RuntimeService) appCtx.getBean("runtimeService");
        //获得流程过程中输入的业务参数   BaseForm中 保存一些基本业务参数
        BaseForm arg = (BaseForm) runtimeService.getVariable(delegateTask.getExecutionId(), "arg");
        //获取流程启动人
        String userId = arg.getUserId();
        //通过userId,获取当前启动人所在部门部门经理,String departManager = 
        //部门经理设置为任务受理人
        delegateTask.setAssignee(departManager);

    }
}

流程结束需要对业务进行回写,继承JavaDelegate,对其进行处理,代码如下:

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.context.ApplicationContext;

import com.eap.activiti.service.ProcessBusinessService;
import com.eap.activiti.service.ProcessBusinessServiceFactory;
import com.eap.common.utils.SpringContextUtil;

public class TaskEndDelegate implements JavaDelegate{

    @Override
    public void execute(DelegateExecution execution) {
        ApplicationContext appCtx = SpringContextUtil.getApplicationContext();
        ProcessEngine processEngine = (ProcessEngine) appCtx.getBean("processEngine");

        RuntimeService runtimeService = (RuntimeService) appCtx.getBean("runtimeService");
        /** 判断流程是否结束,查询正在执行的执行对象表 */
        ProcessInstance rpi = processEngine.getRuntimeService()
                .createProcessInstanceQuery()
                .processInstanceId(execution.getProcessInstanceId()).singleResult();
        if(rpi!=null) {
            String pdi = rpi.getProcessDefinitionId();
            String key = pdi.substring(0, pdi.indexOf(":"));
            /**proEndService 是业务审批结束处理类, 想使用rpi.getProcessDefinitionKey()进行标记,但是在此处获取时,获取为空,所以从ProcessDefinitionId中截取的**/
            /** ProcessBusinessService  是获取业务bean的工厂类**/
            ProcessBusinessService proEndService = ProcessBusinessServiceFactory.builder(key);
            String status = (String) runtimeService.getVariable(execution.getId(), "operateApprove");
            System.out.println(rpi.getBusinessKey());
            proEndService.endProcess(rpi.getBusinessKey(),status);
        }


    }

}

使用排他网关对审批进行通过拒绝处理,在排他网关的流程线上,通过参数operateApprove配置处理。

部署bpmn文件代码如下:

DeploymentBuilder builder = repositoryService.createDeployment().addClasspathResource("assetRepairApply3.bpmn");
        builder.deploy();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值