SpringBoot+Activiti6+JPA+Vue+ElementUi--完整小案例--3

1. 说明

在案例2的基础上进行完善,案例2,点击打开

2. 案例3

2.1 对比案例2,增加的内容(后台IDEA)


流程驳回–测试
场景:请假不通过,审批人进行驳回。
流程图:
在这里插入图片描述
测试类:ActivitiJpaTest03

package com.yb;

import com.yb.dao.ActRuIdentitylinkDao;
import com.yb.domain.ActRuIdentitylink;
import com.yb.domain.User;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;

/**
 * @author liangjie@itcast.cn
 * @version 1.0
 * @date 2020/8/5
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiJpaTest03 {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;

    @Resource
    private HttpServletRequest request;
    /**
     * 部署流程,测试审批驳回功能
     */
    @Test
    public void repositoryDeploy(){
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("processes/activiti_leave.bpmn")
                .addClasspathResource("processes/activiti_leave.png")
                .name("测试审批驳回功能-1")
                .deploy();
        System.out.println("部署ID:"+deploy.getId());
        System.out.println("部署名称"+deploy.getName());
    }

    /**
     * 发布流程
     */
    @Test
    public void runtimeRelease(){
//        User user = (User) request.getServletContext().getAttribute("user");
//        模拟登录用户,进行指定任务人
        User user = new User(1, "jack", "1234");
        HashMap<String, Object> map = new HashMap<>();
        map.put("inputUser",user.getUsername());
        ProcessInstance pi = runtimeService.startProcessInstanceByKey("leave",map);
        System.out.println("流程实例ID:"+pi.getId());
        System.out.println("流程定义ID:"+pi.getProcessDefinitionId());
    }

    /**
     * 查询及完成任务
     */
    @Test
    public void taskQueryComplete(){
        //        User user = (User) request.getServletContext().getAttribute("user");
        //        模拟登录用户,获取到任务人,进行任务的查询和提交
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee("jack")
                .list();
        for (Task task : list) {
            System.out.println("--------------------------------------------");
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
            //完成任务,这里测试请假3天触发一个角色多个审批人
            HashMap<String, Object> map = new HashMap<>();
            map.put("day",3);
            taskService.complete(task.getId(),map);
        }
    }

    @Resource
    private ActRuIdentitylinkDao actRuIdentitylinkDao;
    /**
     * 测试通过待办任务获取到属于该任务角色id的审批人都有哪些
     */
    @Test
    public void testMultiple(){
        //Approval approval
        //模拟获取到前台传来的待办任务的id,这里是5005
        //获取到运行时act_ru_identitylink中的数据
//        List<IdentityLink> taskList = taskService.getIdentityLinksForTask("17505");

        //遍历取出数据
//        for (IdentityLink identityLink : taskList) {
//            System.out.println("==审批人名称:"+identityLink.getUserId()
//                    +"==对应审批角色的ID"+identityLink.getTaskId());
//        }
        List<ActRuIdentitylink> list = actRuIdentitylinkDao.findByUserId("王一");
        for (ActRuIdentitylink actRuIdentitylink : list) {
            System.out.println(actRuIdentitylink);
        }
    }

    /**
     *为审批人拾取任务,这样才能提交任务
     */
    @Test
    public void claimTask(){
        //上面获取到的
        String taskId="5005";
        String userId="王一";
        //拾取任务
        taskService.claim(taskId,userId);
        //任务拾取以后, 可以回退给组
//        taskService.setAssignee(taskId, null);
        //任务拾取以后,可以转给别人去处理(别人可以是组成员也可以不是)
        //taskService.claim(taskId, "wangliu");
    }

    /**
     * 查询及完成任务+驳回功能
     */
    @Test
    public void taskQueryComplete2(){
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee("王一")
                .list();
        for (Task task : list) {
            System.out.println("--------------------------------------------");
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
            //完成任务,王一进行审批,0==不同意,驳回,1==同意,放行。
            HashMap<String, Object> map = new HashMap<>();
            map.put("status",0);
            taskService.complete(task.getId(),map);
        }
    }
}

数据库:
审批不通过驳回到填写请假单
在这里插入图片描述


流程驳回加入案例
流程图同上。
相比于案例2来说,增加了申请时的请假理由,查询状态时未通过进行重新申请,审批人增加审批意见,不通过时进行驳回到填写请假单。
Bpmn文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1596608849637" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="leave" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_2" name="开始"/>
    <userTask activiti:assignee="${inputUser}" activiti:exclusive="true" id="_3" name="填写请假单"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="_4" name="排他网关"/>
    <userTask activiti:assignee="王大" activiti:exclusive="true" id="_5" name="总经理审批"/>
    <userTask activiti:candidateUsers="王一,王二,王三" activiti:exclusive="true" id="_6" name="项目经理审批"/>
    <endEvent id="_7" name="结束"/>
    <sequenceFlow id="_8" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="_9" sourceRef="_3" targetRef="_4"/>
    <sequenceFlow id="_10" name="大于三天" sourceRef="_4" targetRef="_5">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day>3}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_11" name="小于三天" sourceRef="_4" targetRef="_6">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day<=3}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_12" sourceRef="_5" targetRef="_7"/>
    <sequenceFlow id="_13" sourceRef="_6" targetRef="_7"/>
    <sequenceFlow id="_14" name="不同意" sourceRef="_5" targetRef="_3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${status==0}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_15" name="不同意" sourceRef="_6" targetRef="_3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${status==0}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#000000;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="leave">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="345.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <omgdc:Bounds height="55.0" width="85.0" x="90.0" y="335.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="250.0" y="345.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
        <omgdc:Bounds height="55.0" width="85.0" x="375.0" y="280.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
        <omgdc:Bounds height="55.0" width="85.0" x="370.0" y="415.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7">
        <omgdc:Bounds height="32.0" width="32.0" x="555.0" y="350.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_13" id="BPMNEdge__13" sourceElement="_6" targetElement="_7">
        <omgdi:waypoint x="455.0" y="442.5"/>
        <omgdi:waypoint x="555.0" y="366.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_5" targetElement="_7">
        <omgdi:waypoint x="460.0" y="307.5"/>
        <omgdi:waypoint x="555.0" y="366.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_15" id="BPMNEdge__15" sourceElement="_6" targetElement="_3">
        <omgdi:waypoint x="412.5" y="470.0"/>
        <omgdi:waypoint x="225.0" y="495.0"/>
        <omgdi:waypoint x="132.5" y="390.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_14" id="BPMNEdge__14" sourceElement="_5" targetElement="_3">
        <omgdi:waypoint x="417.5" y="280.0"/>
        <omgdi:waypoint x="135.0" y="250.0"/>
        <omgdi:waypoint x="135.0" y="335.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_2" targetElement="_3">
        <omgdi:waypoint x="32.0" y="361.0"/>
        <omgdi:waypoint x="90.0" y="362.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_3" targetElement="_4">
        <omgdi:waypoint x="175.0" y="362.5"/>
        <omgdi:waypoint x="250.0" y="361.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="_4" targetElement="_6">
        <omgdi:waypoint x="282.0" y="361.0"/>
        <omgdi:waypoint x="370.0" y="442.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_4" targetElement="_5">
        <omgdi:waypoint x="282.0" y="361.0"/>
        <omgdi:waypoint x="375.0" y="307.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

审批未通过,重新提交

controller
/**
     * 审批未通过-重新提交
     * @param leave
     * @return
     */
    @PostMapping("/reapply")
    public BaseResult FillInAgain(@RequestBody Leave leave){
        BaseResult baseResult =  leaveApproval.FillInAgain(leave);
        return baseResult;
    }
serviceImpl
/**
     * 未通过重新提交请假单
     * @param leave
     * @return
     */
    @Override
    public BaseResult FillInAgain(Leave leave) {
        //重新提交更新当前申请人信息
        leaveRepository.updateLeaveByName(leave.getDays(),leave.getReason(),leave.getName());

        User user = (User) request.getServletContext().getAttribute("user");
        //查看请假任务,获取任务id
        String taskId = taskQueryComplete(user.getUsername());
        //请假任务重新提交
        HashMap<String, Object> map = new HashMap<>();
        map.put("day",leave.getDays());
        taskService.complete(taskId,map);
        return BaseResult.ok("已重新提交");
    }

审批通过和未通过及更新申请人状态
不通过进行驳回,驳回变量status,0驳回,1通过。

 /**
     * 审批-多人审批
     * @param approval
     * @return
     */
    @Override
    public BaseResult Approval(Approval approval) {
        List<ActRuTask> byAssignee = actRuTaskDao.findByAssignee(approval.getName());
        if(byAssignee.size()>0){
            for (ActRuTask actRuTask : byAssignee) {
                if(approval.getOpinion().equals("同意")){

                    //通过,更改申请人状态和设置审批人意见
                    Adopt(actRuTask.getProcInstId(),approval);
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("status",1);
                    taskService.complete(actRuTask.getId(),map);
                    return BaseResult.ok("已审批");
                }else {
                    //未通过,更改申请人状态和设置审批人意见
                    Failed(actRuTask.getProcInstId(),approval);
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("status",0);
                    taskService.complete(actRuTask.getId(),map);
                    return BaseResult.error("该流程未通过审批,已通知该员工");
                }
            }
        }
        List<ActRuIdentitylink> byUserId = actRuIdentitylinkDao.findByUserId(approval.getName());
        if(byUserId.size()>0){
            for (ActRuIdentitylink actRuIdentitylink : byUserId) {
                if(actRuIdentitylink.getTaskId()!=null){
                    taskService.claim(actRuIdentitylink.getTaskId(),actRuIdentitylink.getUserId());
                    if(approval.getOpinion().equals("同意")){

                        //通过,更改申请人状态和设置审批人意见
                        Adopt(actRuIdentitylink.getProcInstId(),approval);
                        HashMap<String, Object> map = new HashMap<>();
                        map.put("status",1);
                        taskService.complete(actRuIdentitylink.getTaskId(),map);
                        return BaseResult.ok("已审批");
                    }else {
                        //未通过,更改申请人状态和设置审批人意见
                        Failed(actRuIdentitylink.getProcInstId(),approval);
                        HashMap<String, Object> map = new HashMap<>();
                        map.put("status",0);
                        taskService.complete(actRuIdentitylink.getTaskId(),map);

                        return BaseResult.error("该流程未通过审批,已通知该员工");
                    }
                }
            }
        }
        return BaseResult.error("服务器繁忙,请稍后再试");
    }

    /**
     * 通过
     */
    public void Adopt(String procInstId,Approval approval){
        Map<String, Object> variables = runtimeService.getVariables(procInstId);
        //inputUser是办理请假单任务的人,获取到的信息存进请假单业务类中返回
        for (Map.Entry<String, Object> entry : variables.entrySet()) {
            if(entry.getKey().equals("inputUser")){
                String value = (String) entry.getValue();
                //已审批通过更改申请人状态,1==通过,默认0==未审批
                Integer i =  leaveRepository.updateStateByName(1,approval.getProposal(),value);
                //已审批通过,把审批人意见设置进申请人信息中进行前台的一个回显

            }

        }
    }

    /**
     * 未通过
     */
    public void Failed(String procInstId,Approval approval){

        Map<String, Object> variables = runtimeService.getVariables(procInstId);
        //inputUser是办理请假单任务的人,获取到的信息存进请假单业务类中返回
        for (Map.Entry<String, Object> entry : variables.entrySet()) {
            if(entry.getKey().equals("inputUser")){
                String value = (String) entry.getValue();
                //未审批通过更改申请人状态,2==未通过,默认0==审批中
                Integer i =  leaveRepository.updateStateByName(2,approval.getProposal(),value);
                //未审批通过,把审批人意见设置进申请人信息中进行前台的一个回显
//                Integer i1 = leaveRepository.updateOpinionByName2(approval.getProposal(), value);
            }

        }
    }

查询待办,回显审批

/**
     * 查询当前用户待办任务+回显需要审批的任务信息
     * @param name
     * @return
     */
    @Override
    public BaseResult searchApprovalByName(String name) {

        List<ActRuTask> list = actRuTaskDao.findByAssignee(name);

        if(list.size()>0){
            //查询当前待办任务时,获取请假单信息
            Leave leave = new Leave();
            for (ActRuTask actRuTask : list) {
                String procInstId = actRuTask.getProcInstId();
                leave = searchLeave(procInstId);

            }
            return BaseResult.ok("查询成功",list).append("leave",leave);
        }else {

            List<ActRuIdentitylink> byUserId = actRuIdentitylinkDao.findByUserId(name);

            if (byUserId.size()>0) {
                //查询当前待办任务时,获取请假单信息
                Leave leave = new Leave();
                for (ActRuIdentitylink actRuIdentitylink : byUserId) {
                    if (actRuIdentitylink.getTaskId() != null) {
                        taskService.claim(actRuIdentitylink.getTaskId(), actRuIdentitylink.getUserId());
                        List<ActRuTask> byAssignee = actRuTaskDao.findByAssignee(name);
                        leave = searchLeave(actRuIdentitylink.getProcInstId());
                        return BaseResult.ok("查询成功", byAssignee).append("leave",leave);
                    }
                }
            }
        }
        return BaseResult.ok("暂时没有您的任务");
    }

    /**
     * 获取请假单信息
     * @param procInstId
     * @return
     */
    public Leave searchLeave(String procInstId){
        Map<String, Object> variables = runtimeService.getVariables(procInstId);
        //inputUser是办理请假单任务的人,获取到的信息存进请假单业务类中返回
        for (Map.Entry<String, Object> entry : variables.entrySet()) {
            if(entry.getKey().equals("inputUser")){
                List<Leave> byName = leaveRepository.findByName((String) entry.getValue());
                for (Leave l : byName) {
                    if(l.getState()!=1){
                        return l;
                    }
                }
            }
        }
        return null;
    }

数据库
在这里插入图片描述

2.2 对比案例2,增加的内容(前台VUE)

增加了申请时请假理由,未通过重新申请,增加了审批人审批意见,审批人不同意进行驳回到填写请假单重新填写提交,根据不同的情况更新申请人的状态。
填写请假单:
在这里插入图片描述

查看请假状态:
只有未通过的请假单才有操作"重新申请",其他已通过或者已重新申请的请假单均没有该操作。
在这里插入图片描述

审批人审批:
这里测试请假9天,理由是医院陪护。
需要登录审批人的账号进行审批,这里超过4天只有总经理 “王大”可以审批,先登录。
在这里插入图片描述
在这里插入图片描述
进行审批:
这里测试不同意,意见为:理由不充分。
在这里插入图片描述
然后查看申请人的状态,登录申请人账号进行查看。
可以看出这里已经更新了该申请人的请假状态。
在这里插入图片描述
重新申请
由于没有通过,流程驳回到填写请假单,流程并未结束,这里测试未通过重新申请。
在这里插入图片描述
再次回到审批人待办任务
可以看到重新申请的请假单信息由审批人再次拿到。
在这里插入图片描述
同意,更新申请人状态,流程结束
当前申请人状态,数据库:
在这里插入图片描述
还有待办的任务
在这里插入图片描述
审批人提交,同意,任务完成,待办任务消失,申请人状态更新。
在这里插入图片描述
待办任务消失:
在这里插入图片描述
申请人状态更新:
在这里插入图片描述
申请人查看请假状态:
在这里插入图片描述
本次案例3,增加的功能暂时这么多。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值