请假流程示例,设计流程

发表时间:2018-05-05 16:55:15 浏览量( 14 ) 留言数( 0 )

学习目标:

1、了解Java的历史

2、为什么要学习Java语言

3、端正学习态度


学习过程:

一、流程业务说明

下面我们可以做一个请假流程的实例。首先先简单说一下流程的业务逻辑:

1、申请人填写请假原因、天数、请假的日期然后发起流程,提交给项目负责人审核

2、项目负责人审核请假,如果同意就会发给部门负责人审核,如果不同意就会发回给申请人修改,申请人可以放弃申请,也可以修改后重启提交。

3、部门负责人审核请假,如果不同意就会返回给项目负责人,如果同意且天数少于3天,那么就通知申请人,并结束流程,如果大于3天就要给部门总监审核

4、部门总监审核,如果同意且天数少于10天,那么就通知申请人,并结束流程,如果大于10天就要给部门和人事联合审核.

5、部门和人事联合审核必须全部同意,就通知申请人,并结束流程,只要有一个人不同意都会返回给上一步骤,也就是部门总监审核。


二、流程的设计

我们一起来画一下这个流程图,下面给出一些要点,其他大家可以自己参考流程图和源代码。

1、开始节点设置流程的发起人变量

图形化设计

attcontent/4bd665dc-2d93-450f-be71-de842d2a9d5d.png

对应代码:

 <startEvent id="startevent1" name="请假申请" activiti:initiator="applyUser"></startEvent>

配合代码

identityService.setAuthenticatedUserId("kafeitu");  

作用就是设置当前的用户ID

在启动流程的时候会判断有没有activiti:initiator属性,如果有把属性activiti:initiator的值作为一个变量添加到流程实例中,也就是applyUser,不要以为applyUser是一个特殊的变量,它就是一个普通的变量而已。后面可以使用表单式直接引用的。

和其他变量的使用一样,比如项目负责人的办理人我们设置为

activiti:assignee="${projectManager}"

而重新申请的办理人就是申请人,所以我们设置为

activiti:assignee="${applyUser}"


2、条件表单式

attcontent/475cc974-e7cb-49db-af22-ea68a71110e1.png

对应代码

    <sequenceFlow id="flow10" name="不通过" sourceRef="usertask1" targetRef="usertask7">

      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${apply==false}]]></conditionExpression>

    </sequenceFlow>

其他的条件表单式自行设置就可以了。


3、会签

attcontent/78548d2a-53d7-4d10-8832-364bb54d2993.png


attcontent/a0bf3e29-1a71-4c03-b9ef-cabd43e3c5e8.png

<userTask id="usertask4" name="部门和人事联合审批" activiti:assignee="${user}">
      <extensionElements>
        <activiti:taskListener event="complete" delegateExpression="${leaveCounterListener}"></activiti:taskListener>
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user">
        <completionCondition>${notApply&gt;0}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </userTask>


分配给users变量列表, isSequential="false" 非串行,就是所有人都会并行审批,退出条件是只要有一个人不同意。

activiti:collection:执行该会签环节的参与人,此处是使用的一个名叫users的流程变量

activiti:elementVariable:表示的是每一个分支都有一个名叫user的流程变量,和上方的activiti:assignee结合。

还绑定一个监听器,用于累计不同意的人数,因为使用了spring代理,所以选择delegateExpression,并且时再完成后才触发。具体的实现逻辑如下:

public class LeaveCounterListener implements TaskListener {

    private static final long serialVersionUID = 1L;

    @Override
    public void notify(DelegateTask delegateTask) {
        String apply = (String) delegateTask.getVariable("apply");
        if (apply.equals("false")) {
            int notApply = (Integer) delegateTask.getVariable("notApply");
            delegateTask.setVariable("notApply", notApply+1);
        }
    }

}



完整的流程图
attcontent/18d85686-e975-492d-8367-5f0eafe89ffb.png


对应的代码:

<process id="leave" name="leave" isExecutable="true">
    <startEvent id="startevent1" name="请假申请" activiti:initiator="applyUser"></startEvent>
    <userTask id="usertask1" name="项目负责人审核" activiti:assignee="${projectManager}"></userTask>
    <sequenceFlow id="flow1" name="to 项目负责人审核" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <userTask id="usertask2" name="部门负责人" activiti:assignee="${deptManager}"></userTask>
    <sequenceFlow id="flow2" name="提交部门负责人审核" sourceRef="usertask1" targetRef="usertask2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${apply==true}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="usertask3" name="部门总监审核" activiti:assignee="${deptBoss}"></userTask>
    <sequenceFlow id="flow3" name="大于3天" sourceRef="exclusivegateway2" targetRef="usertask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days>3}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="usertask4" name="部门和人事联合审批" activiti:assignee="${user}">
      <extensionElements>
        <activiti:taskListener event="complete" delegateExpression="${leaveCounterListener}"></activiti:taskListener>
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${users}" activiti:elementVariable="user">
        <completionCondition>${notApply&gt;0}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </userTask>
    <sequenceFlow id="flow4" name="大于10天" sourceRef="exclusivegateway3" targetRef="usertask4">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days>10}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow5" sourceRef="usertask4" targetRef="exclusivegateway1"></sequenceFlow>
    <scriptTask id="scripttask1" name="全部通过通知申请人" scriptFormat="groovy" activiti:autoStoreVariables="false">
      <script>out.println("hello");</script>
    </scriptTask>
    <sequenceFlow id="flow8" name="全部同意通知申请人" sourceRef="exclusivegateway1" targetRef="scripttask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${notApply==0}]]></conditionExpression>
    </sequenceFlow>
    <userTask id="usertask7" name="重新填写" activiti:assignee="${applyUser}"></userTask>
    <sequenceFlow id="flow10" name="不通过" sourceRef="usertask1" targetRef="usertask7">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${apply==false}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endevent1" name="结束"></endEvent>
    <sequenceFlow id="flow11" name="结束" sourceRef="scripttask1" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow12" name="放弃申请" sourceRef="exclusivegateway4" targetRef="endevent1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply==false}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow13" name="重新提交" sourceRef="exclusivegateway4" targetRef="usertask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply==true}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow14" name="同意,通知申请人" sourceRef="exclusivegateway2" targetRef="scripttask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days<=3}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow15" name="不同意" sourceRef="usertask2" targetRef="usertask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${apply==false}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow16" name="同意申请" sourceRef="usertask3" targetRef="exclusivegateway3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${apply==true}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow18" name="同意" sourceRef="usertask2" targetRef="exclusivegateway2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${apply==true}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow19" name="不同意" sourceRef="usertask3" targetRef="usertask2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${apply==false}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow20" name="同意,通知申请人" sourceRef="exclusivegateway3" targetRef="scripttask1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days<=10}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow21" name="有人不同意" sourceRef="exclusivegateway1" targetRef="usertask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${notApply>0}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="exclusivegateway4" name="Exclusive Gateway"></exclusiveGateway>
    <sequenceFlow id="flow22" sourceRef="usertask7" targetRef="exclusivegateway4"></sequenceFlow>
  </process>