springboot集成activiti6


1、導入pom依賴,因為我項目中集成的是mybatisplus,所以要排除activiti自帶的mybatis

<!--activiti基礎包-->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>6.0.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>mybatis</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-transcoder</artifactId>
            <version>1.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-codec</artifactId>
            <version>1.7</version>
        </dependency>

 

2、排除activiti自帶的安全誰

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@EnableScheduling
@Slf4j
public class RenrenApplication {

    public static void main(String[] args) {
        //SpringApplication.
        SpringApplication.run(RenrenApplication.class, args);
    }

}

 

 

3、設置流程定義,bpmn,這個是xml文件,可以直接該后綴名為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="m1588045161726" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <error id="ERR_1"/>
  <process id="leave" isClosed="false" isExecutable="true" name="My process" processType="None">
    <userTask activiti:async="true" activiti:candidateGroups="部門經理" activiti:exclusive="true" id="deptleaderaudit" name="部門領導審批"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="exclusivegateway1" name="Exclusive Gateway"/>
    <userTask activiti:candidateGroups="人事" activiti:exclusive="true" id="hraudit" name="人事審批"/>
    <sequenceFlow id="flow3" name="同意" sourceRef="exclusivegateway1" targetRef="hraudit">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptleaderapprove=='true'}]]></conditionExpression>
    </sequenceFlow>
    <userTask activiti:assignee="${applyuserid}" activiti:exclusive="true" id="modifyapply" name="調整申請"/>
    <sequenceFlow id="flow4" name="拒絕" sourceRef="exclusivegateway1" targetRef="modifyapply">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptleaderapprove=='false'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow6" sourceRef="deptleaderaudit" targetRef="exclusivegateway1"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="exclusivegateway2" name="Exclusive Gateway"/>
    <sequenceFlow id="flow7" sourceRef="modifyapply" targetRef="exclusivegateway2"/>
    <sequenceFlow id="flow8" name="重新申請" sourceRef="exclusivegateway2" targetRef="deptleaderaudit">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply=='true'}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endevent1" name="End"/>
    <sequenceFlow id="flow9" name="結束流程" sourceRef="exclusivegateway2" targetRef="endevent1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply=='false'}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway gatewayDirection="Unspecified" id="exclusivegateway3" name="Exclusive Gateway"/>
    <sequenceFlow id="flow10" sourceRef="hraudit" targetRef="exclusivegateway3"/>
    <sequenceFlow id="flow11" name="拒絕" sourceRef="exclusivegateway3" targetRef="modifyapply">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrapprove=='false'}]]></conditionExpression>
    </sequenceFlow>
    <userTask activiti:assignee="${applyuserid}" activiti:exclusive="true" id="reportback" name="銷假"/>
    <sequenceFlow id="flow12" name="同意" sourceRef="exclusivegateway3" targetRef="reportback">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrapprove=='true'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow13" sourceRef="reportback" targetRef="endevent1"/>
    <startEvent activiti:initiator="${applyuserid}" id="startevent1" name="Start"/>
    <sequenceFlow id="flow14" sourceRef="startevent1" targetRef="deptleaderaudit"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;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="deptleaderaudit" id="Shape-deptleaderaudit">
        <omgdc:Bounds height="55.0" width="105.0" x="250.0" y="220.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="Shape-exclusivegateway1" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="535.0" y="227.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="hraudit" id="Shape-hraudit">
        <omgdc:Bounds height="55.0" width="105.0" x="625.0" y="220.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="modifyapply" id="Shape-modifyapply">
        <omgdc:Bounds height="55.0" width="105.0" x="503.0" y="310.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="Shape-exclusivegateway2" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="535.0" y="410.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="Shape-endevent1">
        <omgdc:Bounds height="32.0" width="32.0" x="890.0" y="413.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway3" id="Shape-exclusivegateway3" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="770.0" y="228.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="reportback" id="Shape-reportback">
        <omgdc:Bounds height="55.0" width="105.0" x="855.0" y="221.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="startevent1" id="Shape-startevent1">
        <omgdc:Bounds height="32.0" width="32.0" x="140.0" y="230.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13" sourceElement="reportback" targetElement="endevent1">
        <omgdi:waypoint x="906.0" y="276.0"/>
        <omgdi:waypoint x="906.0" y="413.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14" sourceElement="startevent1" targetElement="deptleaderaudit">
        <omgdi:waypoint x="172.0" y="246.0"/>
        <omgdi:waypoint x="250.0" y="247.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3" sourceElement="exclusivegateway1" targetElement="hraudit">
        <omgdi:waypoint x="567.0" y="243.0"/>
        <omgdi:waypoint x="625.0" y="247.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="575.0" y="247.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4" sourceElement="exclusivegateway1" targetElement="modifyapply">
        <omgdi:waypoint x="551.0" y="259.0"/>
        <omgdi:waypoint x="551.0" y="310.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="555.0" y="267.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6" sourceElement="deptleaderaudit" targetElement="exclusivegateway1">
        <omgdi:waypoint x="355.0" y="247.5"/>
        <omgdi:waypoint x="535.0" y="243.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7" sourceElement="modifyapply" targetElement="exclusivegateway2">
        <omgdi:waypoint x="551.0" y="365.0"/>
        <omgdi:waypoint x="551.0" y="410.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10" sourceElement="hraudit" targetElement="exclusivegateway3">
        <omgdi:waypoint x="730.0" y="247.5"/>
        <omgdi:waypoint x="770.0" y="244.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8" sourceElement="exclusivegateway2" targetElement="deptleaderaudit">
        <omgdi:waypoint x="538.0" y="429.0"/>
        <omgdi:waypoint x="302.0" y="429.0"/>
        <omgdi:waypoint x="302.0" y="275.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="48.0" x="361.0" y="438.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11" sourceElement="exclusivegateway3" targetElement="modifyapply">
        <omgdi:waypoint x="789.0" y="257.0"/>
        <omgdi:waypoint x="789.0" y="337.0"/>
        <omgdi:waypoint x="608.0" y="337.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="672.0" y="319.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9" sourceElement="exclusivegateway2" targetElement="endevent1">
        <omgdi:waypoint x="567.0" y="426.0"/>
        <omgdi:waypoint x="890.0" y="429.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="48.0" x="659.0" y="437.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12" sourceElement="exclusivegateway3" targetElement="reportback">
        <omgdi:waypoint x="802.0" y="244.0"/>
        <omgdi:waypoint x="855.0" y="248.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="24.0" x="810.0" y="248.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

 

 

4、代碼測試

LeaveApplyServiceImpl 類
package io.renren.modules.activiti.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.modules.activiti.config.MyProcessDiagramGenerator;
import io.renren.modules.activiti.dao.LeaveApplyDao;
import io.renren.modules.activiti.entity.LeaveApplyEntity;
import io.renren.modules.activiti.service.LeaveApplyService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("leaveApplyService")
public class LeaveApplyServiceImpl extends ServiceImpl<LeaveApplyDao, LeaveApplyEntity> implements LeaveApplyService  {

    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;


    /**
     * 開始請假,啟動實例
     * @param
     */
    @Override
    public void startleave(){
        String leaveApplyId = "8888";
        HashMap<String, Object> hashMap2 = new HashMap<>();
        //${applyuserid}
        hashMap2.put("applyuserid","110");
        //identityservice.setAuthenticatedUserId(userid);
        ProcessInstance leave = runtimeService.startProcessInstanceByKey("leave", leaveApplyId, hashMap2);

        System.out.println("流程實例id:" + leave.getId());
        System.out.println("當前活動Id:" + leave.getActivityId());

    }

    /**
     * 查看部門經理任務
     *
     */
    @Override
    public void departmentApproval() {

        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("部門經理").list();

        System.out.println("部門經理任務有多少:" + tasks.size());
        for (Task task : tasks) {
            //流程實例id
            String instanceid = task.getProcessInstanceId();
            //查出具體的流程
            ProcessInstance ins = runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
            //獲取業務主健
            String businesskey = ins.getBusinessKey();

            System.out.println("業務的id:" + businesskey);
            System.out.println("任務的id:" + task.getId());
            System.out.println("實例的id:" + instanceid);

            //同意
//            HashMap<String, Object> hashMap = new HashMap<>();
//            hashMap.put("deptleaderapprove", true);
//            taskService.claim(task.getId(), "112");
//            taskService.complete(task.getId(), hashMap);
        }
    }


    /**
     * 執行部門經理拾取任務
     * 因為部門經理是在候選人組,所以要先拾取任務claim
     * 如果是設置了主要負責人,那么就可以直接完成任務,用complete
     */
    @Override
    public void claim() {
        //同意,根據上一步獲取的任務id
        taskService.claim("14", "112");
        System.out.println("任務拾取成功");
    }


    /**
     * 部門經理完成任務,同意
     *
     *
     */
    @Override
    public void completeTask(){
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("deptleaderapprove", true);
        taskService.complete("14",hashMap);
        System.out.println("部門經理完成任務,同意");
    }


    /**
     * 人事處置任務
     *
     */
    @Override
    public void hrCompleteTask(){

        //暫時取一個任務
        //Task task = taskService.createTaskQuery().taskCandidateGroup("人事").singleResult();
        //taskService.setAssignee("666");
        Task task=taskService.createTaskQuery().taskAssignee("666").singleResult();
        System.out.println("人事的任務:"+task);
        //流程實例id
        //String instanceid = task.getProcessInstanceId();
        //查出任務實例
        //ProcessInstance ins = runtimeService.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
        //獲取業務主健
        //String businesskey = ins.getBusinessKey();

        //同意,根據上一步獲取的任務id,拾取任務
        //taskService.claim(task.getId(), "666");

        //完成任務
        //HashMap<String, Object> hashMap = new HashMap<>();
        //hashMap.put("hrapprove", true);
        Map<String, Object> variables = new HashMap<String, Object>();
        //variables.put("hrapprove", true);
        variables.put("content","這是人事666填寫的內容哦");
        //設置local變量,作用域為該任務
        taskService.setVariablesLocal(task.getId(), variables);

        Map<String, Object> variables2 = new HashMap<String, Object>();
        variables2.put("hrapprove", true);
        taskService.complete(task.getId(),variables2);

    }


    /**
     * 時間線
     *
     */
    @Override
    public void taskHistory(){

        // 創建歷史任務查詢對象,根據某實例id
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService
                        .createHistoricTaskInstanceQuery().processInstanceId("5")
                        .orderByTaskCreateTime()
                        .asc();

        // 查詢結果包括 local變量
        HistoricTaskInstanceQuery instanceQuery = historicTaskInstanceQuery.includeTaskLocalVariables();


        List<HistoricTaskInstance> list = instanceQuery.list();

        int index = 1;

        for (HistoricTaskInstance historicTaskInstance : list) {
            System.out.println("==============================");
            System.out.println(" 任務id : " +
                    historicTaskInstance.getId());
            System.out.println(" 任務名稱 : " +
                    historicTaskInstance.getName());
            System.out.println(" 任務負責人 : " +
                    historicTaskInstance.getAssignee());
            System.out.println(" 任務local變量 : "+
                    historicTaskInstance.getTaskLocalVariables());

            //System.out.println("第[" + index + "]個已執行節點=" + historicTaskInstance.getActivityId() + " : " + historicTaskInstance.getActivityName());
            index++;
        }

    }



    public void activityTaskHistory(HttpServletResponse response){

        String processInstanceId = "5";

        try {
            //  獲取歷史流程實例
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(processInstanceId).singleResult();

            if (historicProcessInstance == null) {
                throw new RRException("獲取流程實例ID[" + processInstanceId + "]對應的歷史流程實例失敗!");
            } else {
                // 獲取流程定義
                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                        .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());

                // 獲取流程歷史中已執行節點,並按照節點在流程中執行先后順序排序
                List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
                        .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();

                // 已執行的節點ID集合
                List<String> executedActivityIdList = new ArrayList<String>();
                int index = 1;
                System.out.println("獲取已經執行的節點ID");
                for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
                    executedActivityIdList.add(activityInstance.getActivityId());
                    System.out.println("第[" + index + "]個已執行節點=" + activityInstance.getActivityId() + " : " + activityInstance.getActivityName());
                    index++;
                }

                BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());

                // 已執行的線集合
                List<String> flowIds = new ArrayList<String>();
                // 獲取流程走過的線 (getHighLightedFlows是下面的方法)
                flowIds = getHighLightedFlows(bpmnModel, processDefinition, historicActivityInstanceList);

                // 獲取流程圖圖像字符流
                processEngine.getProcessEngineConfiguration().setProcessDiagramGenerator(new MyProcessDiagramGenerator());
                ProcessDiagramGenerator pec = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
                //配置字體
                InputStream imageStream = pec.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds, "宋體", "微軟雅黑", "黑體", null, 2.0);

                response.setContentType("image/png");
                OutputStream os = response.getOutputStream();
                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                os.close();
                imageStream.close();
            }
            System.out.println("[完成]-獲取流程圖圖像");

        } catch (Exception e) {
            System.out.println(e.getMessage());
            log.error("【異常】-獲取流程圖失敗!" + e.getMessage());
            throw new RRException("獲取流程圖失敗!" + e.getMessage());
        }
    }



    public List<String> getHighLightedFlows(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> historicActivityInstances) {
        //24小時制
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 用以保存高亮的線flowId
        List<String> highFlows = new ArrayList<>();

        for (int i = 0; i < historicActivityInstances.size() - 1; i++) {
            // 對歷史流程節點進行遍歷
            // 得到節點定義的詳細信息
            FlowNode activityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i).getActivityId());

            // 用以保存后續開始時間相同的節點
            List<FlowNode> sameStartTimeNodes = new ArrayList<>();
            FlowNode sameActivityImpl1 = null;

            // 第一個節點
            HistoricActivityInstance activityImpl_ = historicActivityInstances.get(i);
            HistoricActivityInstance activityImp2_;

            for (int k = i + 1; k <= historicActivityInstances.size() - 1; k++) {
                // 后續第1個節點
                activityImp2_ = historicActivityInstances.get(k);

                //都是usertask,且主節點與后續節點的開始時間相同,說明不是真實的后繼節點
                if (activityImpl_.getActivityType().equals("userTask") && activityImp2_.getActivityType().equals("userTask") &&
                        df.format(activityImpl_.getStartTime()).equals(df.format(activityImp2_.getStartTime())))
                {

                } else {//找到緊跟在后面的一個節點
                    sameActivityImpl1 = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(k).getActivityId());
                    break;
                }
            }
            // 將后面第一個節點放在時間相同節點的集合里
            sameStartTimeNodes.add(sameActivityImpl1);
            for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {
                // 后續第一個節點
                HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);
                // 后續第二個節點
                HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);
                // 如果第一個節點和第二個節點開始時間相同保存
                if (df.format(activityImpl1.getStartTime()).equals(df.format(activityImpl2.getStartTime()))) {
                    FlowNode sameActivityImpl2 = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityImpl2.getActivityId());
                    sameStartTimeNodes.add(sameActivityImpl2);
                } else {// 有不相同跳出循環
                    break;
                }
            }
            // 取出節點的所有出去的線
            List<SequenceFlow> pvmTransitions = activityImpl.getOutgoingFlows();
            // 對所有的線進行遍歷
            for (SequenceFlow pvmTransition : pvmTransitions) {
                // 如果取出的線的目標節點存在時間相同的節點里,保存該線的id,進行高亮顯示
                FlowNode pvmActivityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(pvmTransition.getTargetRef());
                if (sameStartTimeNodes.contains(pvmActivityImpl)) {
                    highFlows.add(pvmTransition.getId());
                }
            }

        }
        return highFlows;

    }






}

 

LeaveApplyService 接口
package io.renren.modules.activiti.service;

import com.baomidou.mybatisplus.extension.service.IService;
import io.renren.common.utils.PageUtils;
import io.renren.modules.activiti.entity.LeaveApplyEntity;
import io.renren.modules.sys.entity.SysRoleEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 請假
 *
 */

public interface LeaveApplyService extends IService<LeaveApplyEntity> {

    void startleave();
    void departmentApproval();
    void claim();
    void completeTask();
    void hrCompleteTask();
    void taskHistory();
    void activityTaskHistory(HttpServletResponse response);

}

 

dao層

package io.renren.modules.activiti.dao;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import io.renren.modules.activiti.entity.LeaveApplyEntity;
import io.renren.modules.sys.entity.SysLogEntity;
import org.apache.ibatis.annotations.Mapper;

/**
 * 請假
 *
 *
 */
@Mapper
public interface LeaveApplyDao extends BaseMapper<LeaveApplyEntity> {
    
}

 

 

controller層

package io.renren.modules.activiti.controller;

import io.renren.modules.activiti.service.LeaveApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/leaveApply")
public class LeaveApplyController {

    @Autowired
    private LeaveApplyService leaveApplyService;


    /**
     * 開始請假,啟動實例
     * @param
     */
    @RequestMapping("/test1")
    public void startleave(){
        leaveApplyService.startleave();
    }

    /**
     * 部門領導審批,同意
     *
     */
    @RequestMapping("/test2")
    public void departmentApproval(){
        leaveApplyService.departmentApproval();
    }

    /**
     * 部門領導拾取任務成功
     *
     */
    @RequestMapping("/test3")
    public void claim(){
        leaveApplyService.claim();
    }


    /**
     * 部門領導完成任務,同意
     *
     */
    @RequestMapping("/test4")
    public void completeTask(){
        leaveApplyService.completeTask();
    }

    /**
     * 人事處置,並設置一些自定義變量
     *
     */
    @RequestMapping("/test5")
    public void hrCompleteTask(){
        leaveApplyService.hrCompleteTask();
    }


    /**
     * 通過實例id,查看改實例處置流程,時間線
     *
     */
    @RequestMapping("/test6")
    public void taskHistory(){
        leaveApplyService.taskHistory();
    }

    /**
     * 已經執行的歷史記錄,通過圖片方式來查看實例執行到哪一步
     *
     */
    @RequestMapping("/test7")
    public void activityTaskHistory(HttpServletResponse response){
        leaveApplyService.activityTaskHistory(response);
    }






}

 

其中最重要的是實現類

其中test6、test7執行的效果圖如下 

/**
     * 通過實例id,查看改實例處置流程,時間線
     *
     */
    @RequestMapping("/test6")
    public void taskHistory(){
        leaveApplyService.taskHistory();
    }

    /**
     * 已經執行的歷史記錄,通過圖片方式來查看實例執行到哪一步
     *
     */
    @RequestMapping("/test7")
    public void activityTaskHistory(HttpServletResponse response){
        leaveApplyService.activityTaskHistory(response);
    }

 

test6:  查看實例執行歷史記錄

 

 

 

test7: 查看實例執行的節點,目前是執行到銷假的步驟

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM