Эх сурвалжийг харах

工作流(部分代码)

wangggziwen 10 сар өмнө
parent
commit
e6624acc11
32 өөрчлөгдсөн 3227 нэмэгдсэн , 5 устгасан
  1. 41 0
      pom.xml
  2. 41 0
      rc-admin/pom.xml
  3. 483 0
      rc-admin/src/main/java/com/ruoyi/web/controller/rc/TApproveDangerController.java
  4. 1 0
      rc-admin/src/main/java/com/ruoyi/web/controller/rc/TAuditController.java
  5. 151 0
      rc-admin/src/main/java/com/ruoyi/web/controller/rc/TQuestionnaireController.java
  6. 1 1
      rc-admin/src/main/resources/application-druid.yml
  7. 14 0
      rc-admin/src/main/resources/application.yml
  8. 42 0
      rc-buisness/pom.xml
  9. 111 0
      rc-buisness/src/main/java/com/ruoyi/rc/domain/DevProcess.java
  10. 216 0
      rc-buisness/src/main/java/com/ruoyi/rc/domain/DevTask.java
  11. 44 0
      rc-buisness/src/main/java/com/ruoyi/rc/domain/TProgress.java
  12. 24 1
      rc-buisness/src/main/resources/mapper/rc/TProgressMapper.xml
  13. 41 0
      rc-common/pom.xml
  14. 89 0
      rc-common/src/main/java/com/ruoyi/common/config/ActivitiConfig.java
  15. 13 0
      rc-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
  16. 6 0
      rc-common/src/main/java/com/ruoyi/common/utils/PageUtils.java
  17. 51 0
      rc-common/src/main/java/com/ruoyi/common/utils/http/HttpContextUtils.java
  18. 63 0
      rc-common/src/main/resources/processes/openitem.bpmn
  19. 63 0
      rc-common/src/main/resources/processes/questionnaire.bpmn
  20. 1 0
      rc-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
  21. 1 1
      ruoyi-ui/package.json
  22. 116 0
      ruoyi-ui/src/api/rc/approvedanger.js
  23. 18 0
      ruoyi-ui/src/api/rc/questionnaire.js
  24. 123 0
      ruoyi-ui/src/views/rc/approve/detail/common-detail.vue
  25. 82 0
      ruoyi-ui/src/views/rc/approve/detail/questionnaire-detail.vue
  26. 3 0
      ruoyi-ui/src/views/rc/approve/index.vue
  27. 205 0
      ruoyi-ui/src/views/rc/approve/myapprove/index.vue
  28. 414 0
      ruoyi-ui/src/views/rc/approve/pending/index.vue
  29. 35 0
      ruoyi-ui/src/views/rc/approve/processImg/index.vue
  30. 257 0
      ruoyi-ui/src/views/rc/approve/taskdone/index.vue
  31. 23 1
      ruoyi-ui/src/views/rc/progress/index.vue
  32. 454 1
      sql/create.sql

+ 41 - 0
pom.xml

@@ -188,6 +188,47 @@
                 <version>${ruoyi.version}</version>
             </dependency>
 
+            <!--审批流-->
+            <dependency>
+                <groupId>org.activiti</groupId>
+                <artifactId>activiti-engine</artifactId>
+                <version>6.0.0</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>org.mybatis</groupId>
+                        <artifactId>mybatis</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>org.activiti</groupId>
+                <artifactId>activiti-spring</artifactId>
+                <version>6.0.0</version>
+            </dependency>
+
+            <!-- 阿里JSON解析器 -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>1.2.74</version>
+            </dependency>
+
+            <!--http-->
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpcore</artifactId>
+                <version>4.4.9</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpclient</artifactId>
+                <version>4.5.13</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpmime</artifactId>
+                <version>4.5.12</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 41 - 0
rc-admin/pom.xml

@@ -68,6 +68,47 @@
             <artifactId>rc-buisness</artifactId>
         </dependency>
 
+        <!--审批流-->
+        <dependency>
+            <groupId>org.activiti</groupId>
+            <artifactId>activiti-engine</artifactId>
+            <version>6.0.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.activiti</groupId>
+            <artifactId>activiti-spring</artifactId>
+            <version>6.0.0</version>
+        </dependency>
+
+        <!-- 阿里JSON解析器 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.74</version>
+        </dependency>
+
+        <!--http-->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.12</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 483 - 0
rc-admin/src/main/java/com/ruoyi/web/controller/rc/TApproveDangerController.java

@@ -0,0 +1,483 @@
+package com.ruoyi.web.controller.rc;
+
+import com.alibaba.fastjson.JSON;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.utils.PageUtils;
+import com.ruoyi.rc.domain.DevProcess;
+import com.ruoyi.rc.domain.DevTask;
+import com.ruoyi.rc.domain.TProgress;
+import com.ruoyi.rc.service.ITProgressService;
+import com.ruoyi.system.service.ISysUserService;
+import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.bpmn.model.FlowNode;
+import org.activiti.bpmn.model.Process;
+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.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Comment;
+import org.activiti.engine.task.Task;
+import org.activiti.image.impl.DefaultProcessDiagramGenerator;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.ruoyi.common.utils.http.HttpContextUtils;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 流程处理
+ *
+ * @author ruoyi
+ * @date 2021-02-20
+ */
+@RestController
+@RequestMapping("/ehs/approvedanger")
+public class TApproveDangerController extends BaseController {
+
+    @Autowired
+    private HistoryService historyService;
+
+    @Autowired
+    private TaskService taskService;
+
+    @Autowired
+    private ISysUserService sysUserService;
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    private ITProgressService tProgressService;
+
+    /**
+     * 我的申请列表
+     */
+    @GetMapping("/myApprovelist")
+    public TableDataInfo myApprovelist(@RequestParam Map<String, Object> params) {
+        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
+        //查询发起流程
+        List<HistoricProcessInstance> historicProcessInstanceList =
+                historyService.createHistoricProcessInstanceQuery()
+                        .startedBy(getUserId().toString()).orderByProcessInstanceStartTime().desc()//参与者,组任务查询
+                        .listPage(PageUtils.getStart(params), Integer.parseInt((String) params.get("pageSize")));
+        Long count = historyService.createHistoricProcessInstanceQuery()
+                .startedBy(getUserId().toString()).count();
+        logger.info(JSON.toJSONString(historicProcessInstanceList));
+        //整合我的申请数据
+        List<DevProcess> list = new ArrayList<>();
+        if (historicProcessInstanceList.size() > 0)
+            for (HistoricProcessInstance h : historicProcessInstanceList
+            ) {
+                HistoricProcessInstance pi = processEngine.getHistoryService()
+                        .createHistoricProcessInstanceQuery().processInstanceId(h.getId()).singleResult();
+                logger.info(JSON.toJSONString(pi));
+                if (pi == null) {
+                    continue;
+                }
+                DevProcess devProcess = new DevProcess();
+                logger.info("审批类型" + pi.getProcessDefinitionName());
+                try {
+                    if (pi.getProcessDefinitionName().equals("问卷审批流程")) {
+                        TProgress progress = tProgressService.selectTProgressById(Long.parseLong(h.getBusinessKey()));
+                        devProcess.setProgress(progress);
+                        devProcess.setApNo(progress.getApNo());
+                    } else if (pi.getProcessDefinitionName().equals("开项审批流程")) {
+
+                    }
+                } catch (Exception e) {
+                    logger.error(e.toString());
+                }
+                devProcess.setBusinessKey(pi.getBusinessKey());
+                devProcess.setProcessCreateTime(pi.getStartTime());
+                devProcess.setProcessId(pi.getId());
+                devProcess.setProcessName(pi.getProcessDefinitionName());
+
+                if (pi.getEndActivityId() != null) {
+                    devProcess.setEnd(true);
+                } else {
+                    devProcess.setEnd(false);
+                }
+                logger.info("devProcess:" + devProcess);
+                list.add(devProcess);
+            }
+        return getDataTable(list , count);
+    }
+
+    /**
+     * 我的待办列表
+     */
+    @GetMapping("/backlogList")
+    public TableDataInfo backlogList(@RequestParam Map<String, Object> params) {
+        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
+        List<Task> taskList = processEngine.getTaskService()//获取任务service
+                .createTaskQuery()//创建查询对象
+                .taskCandidateOrAssigned(getUserId().toString())
+//                .taskAssignee(getUserId().toString())
+                .orderByTaskCreateTime().desc()//参与者,组任务查询
+                .listPage(PageUtils.getStart(params), Integer.parseInt((String) params.get("pageSize")));
+        //分页数据
+        Long count = processEngine.getTaskService().createTaskQuery().taskCandidateUser(getUserId().toString()).count();
+        List<DevTask> list = new ArrayList<>();
+        if (taskList.size() > 0) {
+            for (Task task : taskList) {
+                ProcessInstance pi = processEngine.getRuntimeService()/**表示正在执行的流程实例和执行对象*/
+                        .createProcessInstanceQuery()/**创建流程实例查询*/
+                        .processInstanceId(task.getProcessInstanceId())/**使用流程实例ID查询*/
+                        .singleResult();
+                logger.info("待办任务ID:" + task.getId());
+                logger.info("待办任务name:" + task.getName());
+                logger.info("待办任务创建时间:" + task.getCreateTime());
+                logger.info("待办任务办理人:" + task.getAssignee());
+                logger.info("流程实例ID:" + task.getProcessInstanceId());
+                logger.info("执行对象ID:" + task.getExecutionId());
+                logger.info(task.getTenantId());
+                logger.info(task.getCategory());
+                logger.info(task.getFormKey());
+                logger.info("流程实例Name:" + pi.getProcessDefinitionName());
+                DevTask devTask = new DevTask();
+                devTask.setTaskId(task.getId());
+                devTask.setTaskName(task.getName());
+                devTask.setTaskCreateTime(task.getCreateTime());
+                devTask.setProcessId(task.getProcessInstanceId());
+                devTask.setProcessName(pi.getProcessDefinitionName());
+                devTask.setProcessCreateTime(pi.getStartTime());
+                devTask.setBusinessKey(pi.getBusinessKey());
+                devTask.setBusinessKey(pi.getBusinessKey());
+                if (pi.getProcessDefinitionName().equals("问卷审批流程")) {
+                    TProgress progress = tProgressService.selectTProgressById(Long.parseLong(pi.getBusinessKey()));
+                    devTask.setProgress(progress);
+                    devTask.setApNo(progress.getApNo());
+                } else if (pi.getProcessDefinitionName().equals("开项审批流程")) {
+
+                }
+                list.add(devTask);
+            }
+        }
+        return getDataTable(list,count);
+    }
+
+    /**
+     * 已办任务列表
+     */
+    @GetMapping("/doneTaskList")
+    public TableDataInfo doneTaskList(@RequestParam Map<String, Object> params) {
+        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
+        List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
+                .taskAssignee(getUserId().toString())
+                .finished().orderByHistoricTaskInstanceEndTime().desc()
+                .listPage(PageUtils.getStart(params), Integer.parseInt((String) params.get("pageSize")));
+        //分页数据
+        Long count = historyService.createHistoricTaskInstanceQuery()
+                .taskAssignee(getUserId().toString())
+                .finished().count();
+        logger.info(JSON.toJSONString(taskList));
+        List<DevProcess> list = new ArrayList<>();
+        if (taskList.size() > 0) {
+            for (HistoricTaskInstance h : taskList) {
+                //logger.info("HistoricTaskInstance:" + JSON.toJSONString(h));
+                HistoricProcessInstance pi = processEngine.getHistoryService()
+                        .createHistoricProcessInstanceQuery().processInstanceId(h.getProcessInstanceId()).singleResult();
+                logger.info(JSON.toJSONString(pi));
+                if (pi == null) {
+                    continue;
+                }
+                DevProcess devProcess = new DevProcess();
+                if (pi.getProcessDefinitionName().equals("问卷审批流程")) {
+                    TProgress progress = tProgressService.selectTProgressById(Long.parseLong(pi.getBusinessKey()));
+                    devProcess.setApNo(progress.getApNo());
+                    devProcess.setProgress(progress);
+                } else if (pi.getProcessDefinitionName().equals("开项审批流程")) {
+
+                }
+                devProcess.setBusinessKey(pi.getBusinessKey());
+                devProcess.setProcessCreateTime(pi.getStartTime());
+                devProcess.setProcessId(pi.getId());
+                devProcess.setProcessName(pi.getProcessDefinitionName());
+
+                logger.info("devProcess:" + devProcess);
+                if (pi.getEndActivityId() != null) {
+                    devProcess.setEnd(true);
+                } else {
+                    devProcess.setEnd(false);
+                }
+                list.add(devProcess);
+            }
+        }
+        return getDataTable(list,count);
+    }
+
+    /**
+     * 流转列表
+     */
+    @GetMapping("/hiTaskList")
+    public TableDataInfo hiTaskList(@RequestParam Map<String, Object> params) {
+        String pid = (String) params.get("processId");
+        logger.info("processId:" + JSON.toJSONString(pid));
+        HistoricTaskInstanceQuery htiq = historyService.createHistoricTaskInstanceQuery();
+        List<HistoricTaskInstance> htiLists = htiq.processInstanceId(pid).finished().orderByHistoricTaskInstanceEndTime().asc().list();
+
+
+        logger.info("历史任务:" + JSON.toJSONString(htiLists));
+        List<DevTask> devTaskList = new ArrayList<>();
+        if (htiLists.size() > 0) {
+            for (HistoricTaskInstance hi : htiLists
+            ) {
+                List<Comment> commentList = taskService.getTaskComments(hi.getId());
+                logger.info("评论列表:" + JSON.toJSONString(commentList));
+                DevTask devTask = new DevTask();
+                devTask.setTaskName(hi.getName());
+                devTask.setTaskCreateTime(hi.getCreateTime());
+                devTask.setTaskEndTime(hi.getEndTime());
+                if (commentList.size() > 0) {
+                    devTask.setComment(commentList.get(0).getFullMessage());
+                }
+                SysUser user = sysUserService.selectUserById(Long.parseLong(hi.getAssignee()));
+                devTask.setUserName(user.getNickName());
+                devTaskList.add(devTask);
+            }
+        }
+        //当前任务
+        try {
+            Task task = taskService.createTaskQuery().processInstanceId(pid).active().singleResult();
+            if (task!= null) {
+                task.getName();
+                task.getCreateTime();
+                DevTask devTask = new DevTask();
+                devTask.setTaskName(task.getName());
+                devTask.setTaskCreateTime(task.getCreateTime());
+                if (task.getAssignee()!= null) {
+                    SysUser user = sysUserService.selectUserById(Long.parseLong(task.getAssignee()));
+                    devTask.setUserName(user.getNickName());
+                }
+                devTaskList.add(devTask);
+            }
+        }catch (Exception e) {
+            logger.error(e.toString());
+        }
+        return getDataTable(devTaskList);
+    }
+
+    @GetMapping("/processImg/{processId}")
+    public void currentProcessInstanceImage(@PathVariable("processId") String processId, HttpServletResponse response) throws IOException {
+        InputStream inputStream = currentProcessInstanceImage(processId);
+        OutputStream outputStream = response.getOutputStream();
+        HttpContextUtils.copyImageStream(inputStream, outputStream);
+    }
+
+    /**
+     * 获取当前任务流程图
+     *
+     * @param processId
+     * @return
+     */
+    public InputStream currentProcessInstanceImage(String processId) {
+//        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+//        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processId);
+        HistoricProcessInstance hi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
+        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(hi.getProcessDefinitionId());
+
+        BpmnModel bpmnModel = repositoryService.getBpmnModel(hi.getProcessDefinitionId());
+        // ID 为 流程定义Key
+        Process process = bpmnModel.getProcessById(processDefinition.getKey());
+
+        // 流程节点ID
+        // 获取历史流程实例
+        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
+        // 获取流程中已经执行的节点,按照执行先后顺序排序
+        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId)
+                .orderByHistoricActivityInstanceId().asc().list();
+        // 高亮已经执行流程节点ID集合
+        List<String> highLightedActivitiIds = new ArrayList<>();
+        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
+            highLightedActivitiIds.add(historicActivityInstance.getActivityId());
+        }
+        //获取已完成的节点
+        List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
+                .processInstanceId(processId)
+                .finished().list();
+        //高亮线路id集合
+//        List<String> highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances);
+        List<String> highLightedFlowIds = getHighLine(bpmnModel, historicActivityInstances,finished);
+        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
+
+//     生成流程图
+//        InputStream inputStream = generator.generateJpgDiagram(bpmnModel);
+//        InputStream inputStream = generator.generatePngDiagram(bpmnModel);
+//        InputStream inputStream = generator.generateDiagram(bpmnModel, "jpg", highLightedActivities);
+
+// 生成图片
+        InputStream inputStream = generator.generateDiagram(bpmnModel, "jpg", highLightedActivitiIds, highLightedFlowIds, "宋体", "宋体", "宋体", null, 2.0);
+        return inputStream;
+    }
+
+    /**
+     * 获取流程定义图片
+     *
+     * @param processDefinitionId
+     * @return
+     */
+    public InputStream getDefinitionImage(String processDefinitionId) {
+
+        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
+        InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
+        return inputStream;
+    }
+
+    /**
+     * 获取已经流转的线
+     *
+     * @param bpmnModel
+     * @param historicActivityInstances
+     * @return
+     */
+    private static List<String> getHighLightedFlows(BpmnModel bpmnModel, List<HistoricActivityInstance> historicActivityInstances) {
+        // 高亮流程已发生流转的线id集合
+        List<String> highLightedFlowIds = new ArrayList<>();
+        // 全部活动节点
+        List<FlowNode> historicActivityNodes = new ArrayList<>();
+        // 已完成的历史活动节点
+        List<HistoricActivityInstance> finishedActivityInstances = new ArrayList<>();
+
+        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
+            FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true);
+            historicActivityNodes.add(flowNode);
+            if (historicActivityInstance.getEndTime() != null) {
+                finishedActivityInstances.add(historicActivityInstance);
+            }
+        }
+
+        FlowNode currentFlowNode = null;
+        FlowNode targetFlowNode = null;
+        // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
+        for (HistoricActivityInstance currentActivityInstance : finishedActivityInstances) {
+            // 获得当前活动对应的节点信息及outgoingFlows信息
+            currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
+            List<SequenceFlow> sequenceFlows = currentFlowNode.getOutgoingFlows();
+
+            /**
+             * 遍历outgoingFlows并找到已已流转的 满足如下条件认为已已流转: 1.当前节点是并行网关或兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转
+             */
+            if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
+                // 遍历历史活动节点,找到匹配流程目标节点的
+                for (SequenceFlow sequenceFlow : sequenceFlows) {
+                    targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true);
+                    if (historicActivityNodes.contains(targetFlowNode)) {
+                        highLightedFlowIds.add(targetFlowNode.getId());
+                    }
+                }
+            } else {
+                List<Map<String, Object>> tempMapList = new ArrayList<>();
+                for (SequenceFlow sequenceFlow : sequenceFlows) {
+                    for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
+                        if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
+                            Map<String, Object> map = new HashMap<>();
+                            map.put("highLightedFlowId", sequenceFlow.getId());
+                            map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
+                            tempMapList.add(map);
+                        }
+                    }
+                }
+
+                if (!CollectionUtils.isEmpty(tempMapList)) {
+                    // 遍历匹配的集合,取得开始时间最早的一个
+                    long earliestStamp = 0L;
+                    String highLightedFlowId = null;
+                    for (Map<String, Object> map : tempMapList) {
+                        long highLightedFlowStartTime = Long.valueOf(map.get("highLightedFlowStartTime").toString());
+                        if (earliestStamp == 0 || earliestStamp >= highLightedFlowStartTime) {
+                            highLightedFlowId = map.get("highLightedFlowId").toString();
+                            earliestStamp = highLightedFlowStartTime;
+                        }
+                    }
+
+                    highLightedFlowIds.add(highLightedFlowId);
+                }
+
+            }
+
+        }
+        return highLightedFlowIds;
+    }
+
+    private List<String> getHighLine(BpmnModel bpmnModel, List<HistoricActivityInstance> historicActivityInstances, List<HistoricActivityInstance> finishedActivityInstances) {
+
+        // 高亮流程已发生流转的线id集合
+        List<String> highLightedFlowIds = new ArrayList<>();
+        // 全部活动节点
+        List<FlowNode> historicActivityNodes = new ArrayList<>();
+
+        //1、拿到所有的活动节点定义
+        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
+            FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true);
+            historicActivityNodes.add(flowNode);
+        }
+
+        FlowNode currentFlowNode;
+        FlowNode targetFlowNode;
+        // 2、遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
+        for (HistoricActivityInstance currentActivityInstance : finishedActivityInstances) {
+            // 获得当前活动对应的节点信息及outgoingFlows信息
+            currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
+            List<SequenceFlow> outgoingFlows = currentFlowNode.getOutgoingFlows();
+
+            /*
+             * 遍历outgoingFlows并找到已流转的 满足如下条件认为已已流转:
+             * 1.当前节点是并行网关或包含网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
+             * 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的开始时间最早的流转节点视为有效流转
+             */
+            String activityType = currentActivityInstance.getActivityType();
+
+            if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
+                // 遍历历史活动节点,找到匹配流程目标节点的
+                for (SequenceFlow sequenceFlow : outgoingFlows) {
+                    targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true);
+                    if (historicActivityNodes.contains(targetFlowNode)) {
+                        highLightedFlowIds.add(targetFlowNode.getId());
+                    }
+                }
+                continue;
+            }
+
+            //1、拿到所有的TargetRef
+            List<String> targetRefList = outgoingFlows.stream()
+                    .map(SequenceFlow::getTargetRef)
+                    .collect(Collectors.toList());
+
+            //2、拿到ActivityId == TargetRef的所有 HistoricActivityInstance
+            List<HistoricActivityInstance> historicActivityInstanceList = historicActivityInstances.stream()
+                    .filter((HistoricActivityInstance instance) -> targetRefList.contains(instance.getActivityId()))
+                    .collect(Collectors.toList());
+
+            //3、开始时间>=当前节点结束时间的第一个 HistoricActivityInstance
+            List<HistoricActivityInstance> historicActivityInstanceResultList = historicActivityInstanceList.stream()
+                    .filter(historicActivityInstance -> historicActivityInstance.getStartTime()
+                            .compareTo(currentActivityInstance.getEndTime()) >= 0)
+                    .sorted(Comparator.comparing(HistoricActivityInstance::getStartTime))
+                    .collect(Collectors.toList());
+            if (CollectionUtils.isEmpty(historicActivityInstanceResultList)) {
+                continue;
+            }
+
+            HistoricActivityInstance historicActivityInstanceResult = historicActivityInstanceResultList.get(0);
+
+            //4、HistoricActivityInstance拿到flowid
+            List<SequenceFlow> sequenceFlowList = outgoingFlows.stream()
+                    .filter(sequenceFlow -> sequenceFlow.getTargetRef().equals(historicActivityInstanceResult.getActivityId()))
+                    .collect(Collectors.toList());
+            highLightedFlowIds.addAll(sequenceFlowList.stream().map(e->e.getId()).collect(Collectors.toList()));
+        }
+        return highLightedFlowIds;
+    }
+}

+ 1 - 0
rc-admin/src/main/java/com/ruoyi/web/controller/rc/TAuditController.java

@@ -148,6 +148,7 @@ public class TAuditController extends BaseController
                 questionnaire.setCode(tQuestionnaireTemplate.getCode());
                 questionnaire.setName(tQuestionnaireTemplate.getName());
                 questionnaire.setDeptId(tAudit.getDeptId());
+                questionnaire.setCompletionStatus("2");
                 tQuestionnaireService.insertTQuestionnaire(questionnaire);
                 // 新增进度
                 TProgress progress = new TProgress();

+ 151 - 0
rc-admin/src/main/java/com/ruoyi/web/controller/rc/TQuestionnaireController.java

@@ -1,10 +1,26 @@
 package com.ruoyi.web.controller.rc;
 
 import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.rc.domain.DevTask;
 import com.ruoyi.rc.domain.TDeptInfo;
+import com.ruoyi.rc.domain.TProgress;
+import com.ruoyi.rc.service.ITProgressService;
 import com.ruoyi.system.service.ISysDeptService;
+
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import javax.servlet.http.HttpServletResponse;
+
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.ProcessEngines;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
+import org.activiti.engine.impl.identity.Authentication;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -41,6 +57,141 @@ public class TQuestionnaireController extends BaseController
     @Autowired
     private ISysDeptService deptService;
 
+    @Autowired
+    private RuntimeService runtimeService;
+
+    @Autowired
+    private TaskService taskService;
+
+    @Autowired
+    private ITProgressService tProgressService;
+
+    /**
+     * 流程处理
+     */
+    @PutMapping("/handle")
+    public AjaxResult handle(@RequestBody DevTask devTask) {
+        TProgress progress = devTask.getProgress();
+        TQuestionnaire questionnaire = tQuestionnaireService.selectTQuestionnaireById(progress.getQuestionnaireId());
+        String taskId = progress.getTaskId();
+        String taskName = progress.getTaskName();
+        String condition = devTask.getCondition();
+        Map<String, Object> param = new HashMap<>();
+        param.put("condition", condition);
+//
+//        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
+//        TaskService taskService = processEngine.getTaskService();
+//        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+////        String processInstancesId = task.getProcessInstanceId();
+//        processEngine.getTaskService().claim(taskId, getUserId().toString());
+//        taskService.complete(taskId, param);
+//
+//        if (taskName.equals("审核")) {
+//            if ("1".equals(condition)) {
+//                // 进度审批状态修改为4-已通过
+//                progress.setApplyStatus("4");
+//                // 问卷完成情况修改为1-完成
+//                questionnaire.setCompletionStatus("1");
+//            } else {
+//                // 进度审批状态修改为3-未通过
+//                progress.setApplyStatus("3");
+//            }
+//        }
+//
+//        tProgressService.updateTProgress(progress);
+//        String year = questionnaire.getYear();
+//        if (StringUtils.isNotEmpty(year) && !"".equals(year) && year.length() > 4) {
+//            questionnaire.setYear(year.substring(0, year.indexOf("-")));
+//        }
+//        tQuestionnaireService.updateTQuestionnaire(questionnaire);
+//
+//        return AjaxResult.success();
+
+        // 使用任务id,获取任务对象,获取流程实例id
+//        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+
+        if ("1".equals(condition)) {
+            // 进度审批状态修改为4-已通过
+            progress.setApplyStatus("4");
+            // 问卷完成情况修改为1-完成
+            questionnaire.setCompletionStatus("1");
+        } else {
+            // 进度审批状态修改为3-未通过
+            progress.setApplyStatus("3");
+        }
+        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
+        TaskService taskService = processEngine.getTaskService();
+        //认领任务
+        processEngine.getTaskService()
+                .claim(taskId, getUserId().toString());
+//        taskService.addComment(taskId, processInstancesId, devTask.getComment());
+        taskService.complete(taskId, param);
+        // 标记taskId、TaskName
+        List<Task> list = processEngine.getTaskService()//获取任务service
+                .createTaskQuery()//创建查询对象
+                .taskCandidateOrAssigned(questionnaire.getReviewer()+"").list();
+        for (Task t : list) {
+            if (progress.getProcessId().equals(t.getProcessInstanceId())) {
+                progress.setTaskId(t.getId());
+                progress.setTaskName(t.getName());
+            }
+        }
+        // 更新数据
+        tProgressService.updateTProgress(progress);
+        String year = questionnaire.getYear();
+        if (StringUtils.isNotEmpty(year) && !"".equals(year) && year.length() > 4) {
+            questionnaire.setYear(year.substring(0, year.indexOf("-")));
+        }
+        tQuestionnaireService.updateTQuestionnaire(questionnaire);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 提交申请
+     */
+    @PutMapping("/apply")
+    public AjaxResult apply(@RequestBody TProgress tProgress) {
+        // 当前登录用户id
+        String userId = getUserId().toString();
+
+        // 开始流程
+        Authentication.setAuthenticatedUserId(userId);
+        Map<String, Object> variables = new HashMap<>();
+        variables.put("personInCharge", tProgress.getPersonInCharge());
+        variables.put("reviewer", tQuestionnaireService.selectTQuestionnaireById(tProgress.getQuestionnaireId()).getReviewer());
+        long businessKey = tProgress.getId();
+        ProcessInstance pi = runtimeService.startProcessInstanceByKey("questionnaireProcess", String.valueOf(businessKey), variables);
+
+        // 提交申请
+        Map<String, Object> param = new HashMap<>();
+        param.put("condition", "1");
+        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
+        TaskService taskService = processEngine.getTaskService();
+        List<Task> list = taskService.createTaskQuery().taskCandidateOrAssigned(userId).list();
+        String taskId = null;
+        for (Task task : list) {
+            if (task.getProcessInstanceId().equals(pi.getProcessInstanceId())) {
+                taskId = task.getId();
+                System.out.println(taskId);
+            }
+        }
+        processEngine.getTaskService().claim(taskId, getUserId().toString());
+        taskService.complete(taskId, param);
+
+        Task nextTask = taskService.createTaskQuery().singleResult();
+        tProgress.setTaskId(nextTask.getId());
+        tProgress.setTaskName(nextTask.getName());
+        System.out.println(nextTask.getId());
+
+        tProgress.setProcessId(pi.getProcessInstanceId());
+        tProgress.setApNo(DateUtils.dateTimeNow() + userId);
+        tProgress.setApplyStatus("2");//进度审批状态修改为2-待审核
+
+        tProgressService.updateTProgress(tProgress);
+
+        return AjaxResult.success();
+    }
+
     /**
      * 查询问卷列表
      */

+ 1 - 1
rc-admin/src/main/resources/application-druid.yml

@@ -6,7 +6,7 @@ spring:
         druid:
             # 主库数据源
             master:
-                url: jdbc:mysql://localhost:3306/rcaudit
+                url: jdbc:mysql://localhost:3306/rcaudit??zeroDateTimeBehavior=convertToNull
                 username: root
                 password: root
             # 从库数据源

+ 14 - 0
rc-admin/src/main/resources/application.yml

@@ -47,6 +47,20 @@ user:
 
 # Spring配置
 spring:
+  #activiti配置
+  activiti:
+    database-schema-update: false
+    db-identity-used: true
+    history-level: full
+    db-history-used: true
+    #启用异步执行器
+    job-executor-activate: true
+  freemarker:
+    checkTemplateLocation: false
+    classic-compatible: true
+    suffix: .ftlh
+    ettings:
+      recognize_standard_file_extensions: true
   # 资源信息
   messages:
     # 国际化资源文件路径

+ 42 - 0
rc-buisness/pom.xml

@@ -23,6 +23,48 @@
             <artifactId>rc-common</artifactId>
         </dependency>
 
+        <!--审批流-->
+        <dependency>
+            <groupId>org.activiti</groupId>
+            <artifactId>activiti-engine</artifactId>
+            <version>6.0.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.activiti</groupId>
+            <artifactId>activiti-spring</artifactId>
+            <version>6.0.0</version>
+        </dependency>
+
+        <!-- 阿里JSON解析器 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.74</version>
+        </dependency>
+
+        <!--http-->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.12</version>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 111 - 0
rc-buisness/src/main/java/com/ruoyi/rc/domain/DevProcess.java

@@ -0,0 +1,111 @@
+package com.ruoyi.rc.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.util.Date;
+
+/**
+ * 申请管理我的申请显示实体类
+ *
+ * @author ruoyi
+ * @date 2021-02-23
+ */
+public class DevProcess {
+
+    /** 流程ID */
+    private String processId;
+
+    /** 流程名称 */
+    private String processName;
+
+    /** 流程创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
+    private Date processCreateTime;
+
+    /** 业务键 */
+    private String businessKey;
+
+    private String apNo;
+
+    private String apName;
+
+    private TProgress progress;
+
+    public TProgress getProgress() {
+        return progress;
+    }
+
+    public void setProgress(TProgress progress) {
+        this.progress = progress;
+    }
+
+    /** 是否结束 */
+    private boolean isEnd;
+
+    public String getApName() {
+        return apName;
+    }
+
+    public void setApName(String apName) {
+        this.apName = apName;
+    }
+
+    public String getApNo() {
+        return apNo;
+    }
+
+    public void setApNo(String apNo) {
+        this.apNo = apNo;
+    }
+
+    public String getProcessId() {
+        return processId;
+    }
+
+    public void setProcessId(String processId) {
+        this.processId = processId;
+    }
+
+    public String getProcessName() {
+        return processName;
+    }
+
+    public void setProcessName(String processName) {
+        this.processName = processName;
+    }
+
+    public Date getProcessCreateTime() {
+        return processCreateTime;
+    }
+
+    public void setProcessCreateTime(Date processCreateTime) {
+        this.processCreateTime = processCreateTime;
+    }
+
+    public String getBusinessKey() {
+        return businessKey;
+    }
+
+    public void setBusinessKey(String businessKey) {
+        this.businessKey = businessKey;
+    }
+
+    public boolean isEnd() {
+        return isEnd;
+    }
+
+    public void setEnd(boolean end) {
+        isEnd = end;
+    }
+
+    @Override
+    public String toString() {
+        return "DevProcess{" +
+                "processId='" + processId + '\'' +
+                ", processName='" + processName + '\'' +
+                ", processCreateTime=" + processCreateTime +
+                ", businessKey='" + businessKey + '\'' +
+                ", isEnd=" + isEnd +
+                '}';
+    }
+}

+ 216 - 0
rc-buisness/src/main/java/com/ruoyi/rc/domain/DevTask.java

@@ -0,0 +1,216 @@
+package com.ruoyi.rc.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 申请管理我的待办显示实体类
+ *
+ * @author ruoyi
+ * @date 2021-02-23
+ */
+public class DevTask {
+
+    /** 待办任务ID */
+    private String taskId;
+
+    /** 待办任务name */
+    private String taskName;
+
+    /** 待办任务创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date taskCreateTime;
+
+    /** 待办任务结束时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date taskEndTime;
+
+    /** 隐患申请对象 */
+    private Object approveObj;
+
+    /** 流程ID */
+    private String processId;
+
+    /** 流程名称 */
+    private String processName;
+
+    /** 流程创建时间 */
+    private Date processCreateTime;
+
+    /** 业务键 */
+    private String businessKey;
+
+    /** 隐患申请状态 */
+    private String submitType;
+
+    /** 审批评论 */
+    private String comment;
+
+    /** 流转办理人姓名 */
+    private String userName;
+
+    /** 执行人措施前url */
+    private String beforeUrl;
+
+    /** 执行人措施前文件名称 */
+    private String beforeFilename;
+
+    /** 执行人措施后url */
+    private String afterUrl;
+
+    /** 执行人措施后文件名称 */
+    private String afterFilename;
+
+    private String condition;
+
+    private String apNo;
+
+    private TProgress progress;
+
+    public TProgress getProgress() {
+        return progress;
+    }
+
+    public void setProgress(TProgress progress) {
+        this.progress = progress;
+    }
+
+    public String getCondition() {
+        return condition;
+    }
+
+    public void setCondition(String condition) {
+        this.condition = condition;
+    }
+
+    public String getApNo() {
+        return apNo;
+    }
+
+    public void setApNo(String apNo) {
+        this.apNo = apNo;
+    }
+
+    public String getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(String taskId) {
+        this.taskId = taskId;
+    }
+
+    public String getTaskName() {
+        return taskName;
+    }
+
+    public void setTaskName(String taskName) {
+        this.taskName = taskName;
+    }
+
+    public Date getTaskCreateTime() {
+        return taskCreateTime;
+    }
+
+    public void setTaskCreateTime(Date taskCreateTime) {
+        this.taskCreateTime = taskCreateTime;
+    }
+
+    public Date getTaskEndTime() {
+        return taskEndTime;
+    }
+
+    public void setTaskEndTime(Date taskEndTime) {
+        this.taskEndTime = taskEndTime;
+    }
+
+    public String getProcessId() {
+        return processId;
+    }
+
+    public void setProcessId(String processId) {
+        this.processId = processId;
+    }
+
+    public String getProcessName() {
+        return processName;
+    }
+
+    public void setProcessName(String processName) {
+        this.processName = processName;
+    }
+
+    public Date getProcessCreateTime() {
+        return processCreateTime;
+    }
+
+    public void setProcessCreateTime(Date processCreateTime) {
+        this.processCreateTime = processCreateTime;
+    }
+
+    public String getBusinessKey() {
+        return businessKey;
+    }
+
+    public void setBusinessKey(String businessKey) {
+        this.businessKey = businessKey;
+    }
+
+    public String getSubmitType() {
+        return submitType;
+    }
+
+    public void setSubmitType(String submitType) {
+        this.submitType = submitType;
+    }
+
+    public String getComment() { return comment; }
+
+    public void setComment(String comment) { this.comment = comment; }
+
+    public String getUserName() { return userName; }
+
+    public void setUserName(String userName) { this.userName = userName; }
+    public void setBeforeUrl(String beforeUrl) { this.beforeUrl = beforeUrl; }
+
+    public String getBeforeUrl() { return beforeUrl; }
+    public void setBeforeFilename(String beforeFilename) { this.beforeFilename = beforeFilename; }
+
+    public String getBeforeFilename() { return beforeFilename; }
+    public void setAfterUrl(String afterUrl) { this.afterUrl = afterUrl; }
+
+    public String getAfterUrl() { return afterUrl; }
+    public void setAfterFilename(String afterFilename) { this.afterFilename = afterFilename; }
+
+    public String getAfterFilename() { return afterFilename; }
+
+    public Object getApproveObj() {
+        return approveObj;
+    }
+
+    public void setApproveObj(Object approveObj) {
+        this.approveObj = approveObj;
+    }
+
+    @Override
+    public String toString() {
+        return "DevTask{" +
+                "taskId='" + taskId + '\'' +
+                ", taskName='" + taskName + '\'' +
+                ", taskCreateTime=" + taskCreateTime +
+                ", taskEndTime=" + taskEndTime +
+                ", processId='" + processId + '\'' +
+                ", processName='" + processName + '\'' +
+                ", processCreateTime=" + processCreateTime +
+                ", businessKey='" + businessKey + '\'' +
+                ", submitType='" + submitType + '\'' +
+                ", comment='" + comment + '\'' +
+                ", userName='" + userName + '\'' +
+                ", beforeUrl='" + beforeUrl + '\'' +
+                ", beforeFilename='" + beforeFilename + '\'' +
+                ", afterUrl='" + afterUrl + '\'' +
+                ", afterFilename='" + afterFilename + '\'' +
+                '}';
+    }
+}

+ 44 - 0
rc-buisness/src/main/java/com/ruoyi/rc/domain/TProgress.java

@@ -99,6 +99,50 @@ public class TProgress extends BaseEntity
 
     private String name;
 
+    /** 申请编号 */
+    private String apNo;
+
+    /** 流程id */
+    private String processId;
+
+    /** 任务编号 */
+    private String taskId;
+
+    /** 任务名称 */
+    private String taskName;
+
+    public String getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(String taskId) {
+        this.taskId = taskId;
+    }
+
+    public String getTaskName() {
+        return taskName;
+    }
+
+    public void setTaskName(String taskName) {
+        this.taskName = taskName;
+    }
+
+    public String getApNo() {
+        return apNo;
+    }
+
+    public void setApNo(String apNo) {
+        this.apNo = apNo;
+    }
+
+    public String getProcessId() {
+        return processId;
+    }
+
+    public void setProcessId(String processId) {
+        this.processId = processId;
+    }
+
     public String getPersonInChargeName() {
         return personInChargeName;
     }

+ 24 - 1
rc-buisness/src/main/resources/mapper/rc/TProgressMapper.xml

@@ -26,10 +26,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="supporterName"    column="supporter_name"    />
         <result property="code"    column="code"    />
         <result property="name"    column="name"    />
+        <result property="apNo"    column="ap_no"    />
+        <result property="processId"    column="process_id"    />
+        <result property="taskId"    column="task_id"    />
+        <result property="taskName"    column="task_name"    />
     </resultMap>
 
     <sql id="selectTProgressVo">
-        select p.id, questionnaire_id, chap_name, sub_chap_name, sec_sub_chap_name, content, p.person_in_charge, supporter, start_date, target_date, finish_date, preparation, progress, apply_status, p.remarks, p.dept_id, p.audit_id,
+        select p.id, questionnaire_id, chap_name, sub_chap_name, sec_sub_chap_name, content, p.person_in_charge, supporter, start_date, target_date,
+         finish_date, preparation, progress, apply_status, p.remarks, p.dept_id, p.audit_id, p.ap_no, p.process_id, p.task_id, p.task_name,
         u1.nick_name as person_in_charge_name, u2.nick_name as supporter_name,
         q.code as code, q.name as name
         from t_progress p
@@ -57,6 +62,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remarks != null  and remarks != ''"> and remarks = #{remarks}</if>
             <if test="deptId != null  and deptId != ''"> and p.dept_id = #{deptId}</if>
             <if test="auditId != null "> and p.audit_id = #{auditId}</if>
+            <if test="apNo != null "> and p.ap_no = #{apNo}</if>
+            <if test="processId != null "> and p.process_id = #{processId}</if>
+            <if test="taskId != null  and taskId != ''"> and task_id = #{taskId}</if>
+            <if test="taskName != null  and taskName != ''"> and task_name = #{taskName}</if>
         </where>
     </select>
     
@@ -84,6 +93,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remarks != null">remarks,</if>
             <if test="deptId != null">dept_id,</if>
             <if test="auditId != null">audit_id,</if>
+            <if test="apNo != null">ap_no,</if>
+            <if test="processId != null">process_id,</if>
+            <if test="taskId != null">task_id,</if>
+            <if test="taskName != null">task_name,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="questionnaireId != null">#{questionnaireId},</if>
@@ -102,6 +115,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remarks != null">#{remarks},</if>
             <if test="deptId != null">#{deptId},</if>
             <if test="auditId != null">#{auditId},</if>
+            <if test="apNo != null">#{apNo},</if>
+            <if test="processId != null">#{processId},</if>
+            <if test="taskId != null">#{taskId},</if>
+            <if test="taskName != null">#{taskName},</if>
          </trim>
     </insert>
 
@@ -124,6 +141,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remarks != null">remarks = #{remarks},</if>
             <if test="deptId != null">dept_id = #{deptId},</if>
             <if test="auditId != null">audit_id = #{auditId},</if>
+            <if test="apNo != null">ap_no = #{apNo},</if>
+            <if test="processId != null">process_id = #{processId},</if>
+            <if test="taskId != null">task_id = #{taskId},</if>
+            <if test="taskId == null">task_id = null,</if>
+            <if test="taskName != null">task_name = #{taskName},</if>
+            <if test="taskName == null">task_name = null,</if>
         </trim>
         where id = #{id}
     </update>

+ 41 - 0
rc-common/pom.xml

@@ -119,6 +119,47 @@
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
 
+        <!--审批流-->
+        <dependency>
+            <groupId>org.activiti</groupId>
+            <artifactId>activiti-engine</artifactId>
+            <version>6.0.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.activiti</groupId>
+            <artifactId>activiti-spring</artifactId>
+            <version>6.0.0</version>
+        </dependency>
+
+        <!-- 阿里JSON解析器 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.74</version>
+        </dependency>
+
+        <!--http-->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.12</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 89 - 0
rc-common/src/main/java/com/ruoyi/common/config/ActivitiConfig.java

@@ -0,0 +1,89 @@
+package com.ruoyi.common.config;
+
+
+import org.activiti.engine.*;
+import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;
+import org.activiti.engine.repository.DeploymentBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+import java.io.IOException;
+
+/**
+ * 使用Java类完成配置文件
+ */
+@Configuration
+public class ActivitiConfig {
+
+    @Autowired
+    private DataSource dataSource;
+
+    @Autowired
+    private ResourcePatternResolver resourceLoader;
+
+    /**
+     * 初始化配置,将创建28张表
+     *
+     * @return
+     */
+    @Bean
+    public StandaloneProcessEngineConfiguration processEngineConfiguration() {
+        StandaloneProcessEngineConfiguration configuration = new StandaloneProcessEngineConfiguration();
+        configuration.setDataSource(dataSource);
+        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
+        configuration.setDbIdentityUsed(false);
+        configuration.setAsyncExecutorActivate(true);
+        configuration.setActivityFontName("宋体");
+        configuration.setAnnotationFontName("宋体");
+        configuration.setLabelFontName("宋体");
+        return configuration;
+    }
+
+    @Bean
+    public ProcessEngine processEngine() {
+        return processEngineConfiguration().buildProcessEngine();
+    }
+
+    @Bean
+    public RepositoryService repositoryService() {
+        return processEngine().getRepositoryService();
+    }
+
+    @Bean
+    public RuntimeService runtimeService() {
+        return processEngine().getRuntimeService();
+    }
+
+    @Bean
+    public TaskService taskService() {
+        return processEngine().getTaskService();
+    }
+
+    @Bean
+    public HistoryService historyService() {
+        return processEngine().getHistoryService();
+    }
+
+    /**
+     * 部署流程
+     *
+     * @throws IOException
+     */
+    @PostConstruct
+    public void initProcess() throws IOException {
+        DeploymentBuilder deploymentBuilder = repositoryService().createDeployment();
+        Resource common = resourceLoader.getResource("classpath:/processes/questionnaire.bpmn"); //加载流程图资源文件
+        deploymentBuilder.enableDuplicateFiltering().addInputStream(common.getFilename(), common.getInputStream()).name("问卷审批流程").deploy(); //按流程id部署
+
+//        DeploymentBuilder deploymentBuilder1 = repositoryService().createDeployment();
+//        Resource major= resourceLoader.getResource("classpath:/processes/openitem.bpmn");
+//        deploymentBuilder1.enableDuplicateFiltering().addInputStream(major.getFilename(), major.getInputStream()).name("开项审批流程").deploy();
+    }
+}
+
+

+ 13 - 0
rc-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java

@@ -207,4 +207,17 @@ public class BaseController
     {
         return getLoginUser().getUser().getNickName();
     }
+
+    /**
+     * 响应请求分页数据
+     */
+    protected TableDataInfo getDataTable(List<?> list , long count)
+    {
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(HttpStatus.SUCCESS);
+        rspData.setMsg("查询成功");
+        rspData.setRows(list);
+        rspData.setTotal(count);
+        return rspData;
+    }
 }

+ 6 - 0
rc-common/src/main/java/com/ruoyi/common/utils/PageUtils.java

@@ -5,6 +5,8 @@ import com.ruoyi.common.core.page.PageDomain;
 import com.ruoyi.common.core.page.TableSupport;
 import com.ruoyi.common.utils.sql.SqlUtil;
 
+import java.util.Map;
+
 /**
  * 分页工具类
  * 
@@ -12,6 +14,10 @@ import com.ruoyi.common.utils.sql.SqlUtil;
  */
 public class PageUtils extends PageHelper
 {
+    public static int getStart(Map<String, Object> params) {
+        return (Integer.parseInt((String) params.get("pageNum")) - 1) * Integer.parseInt((String) params.get("pageSize"));
+    }
+
     /**
      * 设置请求分页数据
      */

+ 51 - 0
rc-common/src/main/java/com/ruoyi/common/utils/http/HttpContextUtils.java

@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ * <p>
+ * https://www.renren.io
+ * <p>
+ * 版权所有,侵权必究!
+ */
+
+package com.ruoyi.common.utils.http;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class HttpContextUtils {
+
+    public static void copyImageStream(InputStream inputStream, OutputStream outputStream) {
+        try {
+            IOUtils.copy(inputStream, outputStream);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                inputStream.close();
+                outputStream.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static HttpServletRequest getHttpServletRequest() {
+        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+    }
+
+    public static String getDomain() {
+        HttpServletRequest request = getHttpServletRequest();
+        StringBuffer url = request.getRequestURL();
+        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
+    }
+
+    public static String getOrigin() {
+        HttpServletRequest request = getHttpServletRequest();
+        return request.getHeader("Origin");
+    }
+}

+ 63 - 0
rc-common/src/main/resources/processes/openitem.bpmn

@@ -0,0 +1,63 @@
+<?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="openitemProcess" name="开项审批流程" isExecutable="true">
+    <startEvent id="startevent" name="start"></startEvent>
+    <endEvent id="endevent" name="end"></endEvent>
+    <userTask id="apply" name="提交申请" activiti:assignee="#{personInCharge}"></userTask>
+    <sequenceFlow id="flow1" sourceRef="startevent" targetRef="apply"></sequenceFlow>
+    <userTask id="verify" name="审核" activiti:assignee="#{reviewer}"></userTask>
+    <sequenceFlow id="flow2" name="提交" sourceRef="apply" targetRef="verify">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${condition == 1}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="flow3" name="驳回" sourceRef="verify" targetRef="apply">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${condition == 0}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="flow4" name="通过" sourceRef="verify" targetRef="endevent">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${condition == 1}]]></conditionExpression>
+    </sequenceFlow>
+  </process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_openitemProcess">
+    <bpmndi:BPMNPlane bpmnElement="openitemProcess" id="BPMNPlane_openitemProcess">
+      <bpmndi:BPMNShape bpmnElement="startevent" id="BPMNShape_startevent">
+        <omgdc:Bounds height="35.0" width="35.0" x="60.0" y="140.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="endevent" id="BPMNShape_endevent">
+        <omgdc:Bounds height="35.0" width="35.0" x="550.0" y="140.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="apply" id="BPMNShape_apply">
+        <omgdc:Bounds height="55.0" width="105.0" x="180.0" y="130.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="verify" id="BPMNShape_verify">
+        <omgdc:Bounds height="55.0" width="105.0" x="355.0" y="130.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
+        <omgdi:waypoint x="95.0" y="157.0"></omgdi:waypoint>
+        <omgdi:waypoint x="180.0" y="157.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
+        <omgdi:waypoint x="285.0" y="157.0"></omgdi:waypoint>
+        <omgdi:waypoint x="355.0" y="157.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="32.0" x="300.0" y="140.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
+        <omgdi:waypoint x="407.0" y="185.0"></omgdi:waypoint>
+        <omgdi:waypoint x="406.0" y="248.0"></omgdi:waypoint>
+        <omgdi:waypoint x="309.0" y="248.0"></omgdi:waypoint>
+        <omgdi:waypoint x="232.0" y="248.0"></omgdi:waypoint>
+        <omgdi:waypoint x="232.0" y="185.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="32.0" x="301.0" y="230.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
+        <omgdi:waypoint x="460.0" y="157.0"></omgdi:waypoint>
+        <omgdi:waypoint x="550.0" y="157.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="32.0" x="479.0" y="140.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</definitions>

+ 63 - 0
rc-common/src/main/resources/processes/questionnaire.bpmn

@@ -0,0 +1,63 @@
+<?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="questionnaireProcess" name="问卷审批流程" isExecutable="true">
+    <startEvent id="startevent" name="start"></startEvent>
+    <endEvent id="endevent" name="end"></endEvent>
+    <userTask id="apply" name="提交申请" activiti:assignee="#{personInCharge}"></userTask>
+    <sequenceFlow id="flow1" sourceRef="startevent" targetRef="apply"></sequenceFlow>
+    <userTask id="verify" name="审核" activiti:assignee="#{reviewer}"></userTask>
+    <sequenceFlow id="flow2" name="提交" sourceRef="apply" targetRef="verify">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${condition == 1}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="flow3" name="驳回" sourceRef="verify" targetRef="apply">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${condition == 0}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="flow4" name="通过" sourceRef="verify" targetRef="endevent">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${condition == 1}]]></conditionExpression>
+    </sequenceFlow>
+  </process>
+  <bpmndi:BPMNDiagram id="BPMNDiagram_questionnaireProcess">
+    <bpmndi:BPMNPlane bpmnElement="questionnaireProcess" id="BPMNPlane_questionnaireProcess">
+      <bpmndi:BPMNShape bpmnElement="startevent" id="BPMNShape_startevent">
+        <omgdc:Bounds height="35.0" width="35.0" x="60.0" y="140.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="endevent" id="BPMNShape_endevent">
+        <omgdc:Bounds height="35.0" width="35.0" x="550.0" y="140.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="apply" id="BPMNShape_apply">
+        <omgdc:Bounds height="55.0" width="105.0" x="180.0" y="130.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="verify" id="BPMNShape_verify">
+        <omgdc:Bounds height="55.0" width="105.0" x="355.0" y="130.0"></omgdc:Bounds>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
+        <omgdi:waypoint x="95.0" y="157.0"></omgdi:waypoint>
+        <omgdi:waypoint x="180.0" y="157.0"></omgdi:waypoint>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
+        <omgdi:waypoint x="285.0" y="157.0"></omgdi:waypoint>
+        <omgdi:waypoint x="355.0" y="157.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="32.0" x="300.0" y="140.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
+        <omgdi:waypoint x="407.0" y="185.0"></omgdi:waypoint>
+        <omgdi:waypoint x="406.0" y="248.0"></omgdi:waypoint>
+        <omgdi:waypoint x="309.0" y="248.0"></omgdi:waypoint>
+        <omgdi:waypoint x="232.0" y="248.0"></omgdi:waypoint>
+        <omgdi:waypoint x="232.0" y="185.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="32.0" x="301.0" y="230.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
+        <omgdi:waypoint x="460.0" y="157.0"></omgdi:waypoint>
+        <omgdi:waypoint x="550.0" y="157.0"></omgdi:waypoint>
+        <bpmndi:BPMNLabel>
+          <omgdc:Bounds height="16.0" width="100.0" x="479.0" y="140.0"></omgdc:Bounds>
+        </bpmndi:BPMNLabel>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+</definitions>

+ 1 - 0
rc-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

@@ -115,6 +115,7 @@ public class SecurityConfig
                     // 静态资源,可匿名访问
                     .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                     .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
+                        .antMatchers("/ehs/approvedanger/processImg/**").permitAll()
                     // 除上面外的所有请求全部需要鉴权认证
                     .anyRequest().authenticated();
             })

+ 1 - 1
ruoyi-ui/package.json

@@ -41,7 +41,7 @@
     "clipboard": "2.0.8",
     "core-js": "3.37.1",
     "echarts": "5.4.0",
-    "element-ui": "2.15.14",
+    "element-ui": "2.15.8",
     "file-saver": "2.0.5",
     "fuse.js": "6.4.3",
     "highlight.js": "9.18.5",

+ 116 - 0
ruoyi-ui/src/api/rc/approvedanger.js

@@ -0,0 +1,116 @@
+import request from '@/utils/request'
+
+// 查询隐患申请列表
+export function listApprovedanger(query) {
+  return request({
+    url: '/ehs/approvedanger/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询我的申请详细
+export function getMyApprovelist(query) {
+  return request({
+    url: '/ehs/approvedanger/myApprovelist',
+    method: 'get',
+  params: query
+  })
+}
+
+// 查询我的待办详细
+export function getPendinglist(query) {
+  return request({
+    url: '/ehs/approvedanger/backlogList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询已办任务详细
+export function getTaskdonelist(query) {
+  return request({
+    url: '/ehs/approvedanger/doneTaskList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询流转列表详细
+export function getHistorylist(query) {
+  return request({
+    url: '/ehs/approvedanger/hiTaskList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询隐患申请详细
+export function getApprovedanger(id) {
+  return request({
+    url: '/ehs/approvedanger/' + id,
+    method: 'get'
+  })
+}
+
+//开启审批流程
+export function saveApprovedanger(data) {
+  return request({
+    url: '/ehs/approvedanger/save',
+    method: 'post',
+    data: data
+  })
+}
+
+//新增一般隐患开项
+export function saveGeneral(data) {
+  return request({
+    url: '/ehs/approvedanger/savegeneral',
+    method: 'post',
+    data: data
+  })
+}
+
+// 新增隐患申请
+export function addApprovedanger(data) {
+  return request({
+    url: '/ehs/approvedanger',
+    method: 'post',
+    data: data
+  })
+}
+
+// 处理隐患申请
+export function handleApprovedanger(data) {
+  return request({
+    url: '/ehs/approvedanger/handle',
+    method: 'put',
+    data: data
+  })
+}
+
+// 修改隐患申请
+export function updateApprovedanger(data) {
+  return request({
+    url: '/ehs/approvedanger',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除隐患申请
+export function delApprovedanger(id) {
+  return request({
+    url: '/ehs/approvedanger/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出隐患申请
+export function exportApprovedanger(query) {
+  return request({
+    url: '/ehs/approvedanger/export',
+    method: 'get',
+    params: query
+  })
+}

+ 18 - 0
ruoyi-ui/src/api/rc/questionnaire.js

@@ -1,5 +1,23 @@
 import request from '@/utils/request'
 
+// 提交申请
+export function handleQuestionnaire(data) {
+  return request({
+    url: '/rc/questionnaire/handle',
+    method: 'put',
+    data: data
+  })
+}
+
+// 提交申请
+export function applyQuestionnaire(data) {
+  return request({
+    url: '/rc/questionnaire/apply',
+    method: 'put',
+    data: data
+  })
+}
+
 // 查询问卷列表
 export function listQuestionnaire(query) {
   return request({

+ 123 - 0
ruoyi-ui/src/views/rc/approve/detail/common-detail.vue

@@ -0,0 +1,123 @@
+<!--<template>-->
+  <!--<el-dialog :close-on-click-modal="false" :title="title" :visible.sync="visible" :append-to-body="true" width="600px">-->
+
+
+    <!--<el-table :data="historyList" border v-loading="historyLoading" style="width: 100%;">-->
+      <!--<el-table-column width="100" prop="taskName" header-align="center" align="center" label="流程进度"></el-table-column>-->
+      <!--<el-table-column width="80" prop="userName" header-align="center" align="center" label="处理人"></el-table-column>-->
+      <!--<el-table-column prop="comment" header-align="center" align="center" label="备注 / 审批意见"></el-table-column>-->
+      <!--<el-table-column width="100" prop="taskCreateTime" header-align="center" align="center" label="开始时间"></el-table-column>-->
+      <!--<el-table-column width="100" prop="taskEndTime" header-align="center" align="center" label="结束时间"></el-table-column>-->
+    <!--</el-table>-->
+
+    <!--<div slot="footer" class="dialog-footer">-->
+      <!--<el-button type="success" @click="dataFormSubmit(1)">通 过</el-button>-->
+      <!--<el-button type="info" @click="dataFormSubmit(0)">驳 回</el-button>-->
+      <!--<el-button @click="visible = false">返回</el-button>-->
+    <!--</div>-->
+  <!--</el-dialog>-->
+<!--</template>-->
+
+<!--<script>-->
+  <!--import { getToken } from "@/utils/auth";-->
+  <!--import { treeselect, listDept } from "@/api/system/dept";-->
+  <!--import Treeselect from "@riophae/vue-treeselect";-->
+  <!--import "@riophae/vue-treeselect/dist/vue-treeselect.css";-->
+  <!--import {getHistorylist} from "@/api/branch/approvedanger";-->
+
+<!--export default {-->
+  <!--name: "questionnaire-detail",-->
+  <!--components: { Treeselect },-->
+  <!--data() {-->
+    <!--return {-->
+      <!--rules: {-->
+      <!--},-->
+      <!--taskForm: {},-->
+      <!--title: null,-->
+      <!--visible: false,-->
+      <!--deptOptions: [],-->
+      <!--//流转列表-->
+      <!--historyList: [],-->
+      <!--// rejectList: [],-->
+      <!--historyLoading: true,-->
+      <!--dialogType: 0,-->
+    <!--}-->
+  <!--},-->
+  <!--methods: {-->
+    <!--init(id, taskId, processId, taskName, dialogType) {-->
+      <!--// 流转列表-->
+      <!--getHistorylist({ "processId": processId }).then(response => {-->
+        <!--this.historyList = response.rows;-->
+        <!--this.historyLoading = false-->
+      <!--});-->
+      <!--this.reset();-->
+      <!--this.visible = true;-->
+      <!--// if (taskName == "支部申请") {-->
+      <!--//   this.newDeptIdDisabled = false;-->
+      <!--// } else {-->
+      <!--//   this.newDeptIdDisabled = true;-->
+      <!--// }-->
+      <!--// this.dialogType = dialogType;-->
+      <!--// if (dialogType == 1) {-->
+      <!--//   this.title =  taskName + "处理";-->
+      <!--// } else {-->
+      <!--//   this.title = "查看详情";-->
+      <!--// }-->
+      <!--// this.taskForm.objId = id;-->
+      <!--// this.taskForm.taskId = taskId;-->
+      <!--// this.taskForm.taskName = taskName;-->
+      <!--// getMember(id).then(response => {-->
+      <!--//   this.taskForm.obj = response.data;-->
+      <!--//   this.taskForm.oldDeptId = Number(response.data.oldDeptId);-->
+      <!--//   this.taskForm.newDeptId = Number(response.data.newDeptId);-->
+      <!--//   this.taskForm.userId = Number(response.data.userId);-->
+      <!--//   console.log(typeof(this.taskForm.newDeptId))-->
+      <!--//   console.log(typeof(this.taskForm.userId))-->
+      <!--// });-->
+      <!--// this.getTreeselect();-->
+      <!--// this.getUserList();-->
+    <!--},-->
+
+    <!--reset() {-->
+      <!--this.taskForm =  {-->
+        <!--oldDeptId: null,-->
+        <!--newDeptId: null,-->
+        <!--comment: '',-->
+      <!--};-->
+    <!--},-->
+
+    <!--dataFormSubmit(condition) {-->
+      <!--this.$refs["form"].validate(valid => {-->
+        <!--if (valid) {-->
+          <!--if (this.taskForm.taskName == "支部申请") {-->
+            <!--this.taskForm.obj.oldDeptId = this.taskForm.oldDeptId;-->
+            <!--this.taskForm.obj.newDeptId = this.taskForm.newDeptId;-->
+            <!--this.$forceUpdate();-->
+          <!--}-->
+          <!--this.taskForm.condition = condition;-->
+          <!--handle(this.taskForm).then(response => {-->
+            <!--this.visible = false;-->
+            <!--this.$modal.msgSuccess("提交成功");-->
+            <!--// refreshDataList事件:调用父组件getList方法刷新页面-->
+            <!--this.$emit('refreshDataList');-->
+          <!--});-->
+        <!--}-->
+      <!--});-->
+    <!--},-->
+
+    <!--/** 查询部门下拉树结构 */-->
+    <!--getTreeselect() {-->
+      <!--treeselect().then(response => {-->
+        <!--this.deptOptions = response.data;-->
+      <!--});-->
+    <!--},-->
+  <!--}-->
+<!--}-->
+<!--</script>-->
+
+<!--<style scoped lang="scss">-->
+  <!--::v-deep .el-input.is-disabled .el-input__inner {-->
+    <!--color: #606266;-->
+    <!--background-color: transparent;-->
+  <!--}-->
+<!--</style>-->

+ 82 - 0
ruoyi-ui/src/views/rc/approve/detail/questionnaire-detail.vue

@@ -0,0 +1,82 @@
+<template>
+  <el-dialog :close-on-click-modal="false" :title="title" :visible.sync="visible" :append-to-body="true" width="600px">
+
+    <span>{{progress}}</span>
+
+    <el-table :data="historyList" border v-loading="historyLoading" style="width: 100%;">
+      <el-table-column width="100" prop="taskName" header-align="center" align="center" label="流程进度"></el-table-column>
+      <el-table-column width="80" prop="userName" header-align="center" align="center" label="处理人"></el-table-column>
+      <el-table-column prop="comment" header-align="center" align="center" label="备注 / 审批意见"></el-table-column>
+      <el-table-column width="100" prop="taskCreateTime" header-align="center" align="center" label="开始时间"></el-table-column>
+      <el-table-column width="100" prop="taskEndTime" header-align="center" align="center" label="结束时间"></el-table-column>
+    </el-table>
+
+    <div slot="footer" class="dialog-footer">
+      <el-button type="success" @click="dataFormSubmit(1)">通 过</el-button>
+      <el-button type="info" @click="dataFormSubmit(0)">驳 回</el-button>
+      <el-button @click="visible = false">返回</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  import { getToken } from "@/utils/auth";
+  import { treeselect, listDept } from "@/api/system/dept";
+  import Treeselect from "@riophae/vue-treeselect";
+  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+  import {getHistorylist} from "@/api/rc/approvedanger";
+  import { handleQuestionnaire } from "@/api/rc/questionnaire";
+
+export default {
+  name: "questionnaire-detail",
+  components: { Treeselect },
+  data() {
+    return {
+      rules: {
+      },
+      taskForm: {},
+      title: null,
+      visible: false,
+      deptOptions: [],
+      //流转列表
+      historyList: [],
+      // rejectList: [],
+      historyLoading: true,
+      dialogType: 0,
+      progress: 0,
+    }
+  },
+  methods: {
+    init(progress, taskId, processId, taskName, dialogType) {
+      this.progress = progress;
+      this.taskForm.progress = progress;
+      // 流转列表
+      getHistorylist({ "processId": processId }).then(response => {
+        this.historyList = response.rows;
+        this.historyLoading = false
+      });
+      this.visible = true;
+      this.getTreeselect();
+    },
+    reset() {
+      this.taskForm =  {
+      };
+    },
+    dataFormSubmit(condition) {
+      this.taskForm.condition = condition;
+      handleQuestionnaire(this.taskForm).then(response => {
+        this.visible = false;
+        this.$modal.msgSuccess("提交成功");
+        // refreshDataList事件:调用父组件getList方法刷新页面
+        this.$emit('refreshDataList');
+      });
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      treeselect().then(response => {
+        this.deptOptions = response.data;
+      });
+    },
+  }
+}
+</script>

+ 3 - 0
ruoyi-ui/src/views/rc/approve/index.vue

@@ -0,0 +1,3 @@
+<template >
+  <router-view />
+</template>

+ 205 - 0
ruoyi-ui/src/views/rc/approve/myapprove/index.vue

@@ -0,0 +1,205 @@
+<template >
+  <div class="app-container">
+    <el-table v-loading="loading" :data="approvedangerList" @selection-change="handleSelectionChange" :height="clientHeight" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="流程ID" align="center" prop="processId" :show-overflow-tooltip="true"/>
+      <el-table-column label="流程名称" align="center" prop="processName" :show-overflow-tooltip="true"/>
+      <el-table-column label="流程创建时间" align="center" prop="processCreateTime" :show-overflow-tooltip="true"/>
+      <el-table-column label="申请编号" align="center" prop="apNo" :show-overflow-tooltip="true"/>
+      <el-table-column
+        prop="isEnd"
+        header-align="center"
+        align="center"
+        label="是否结束">
+        <template slot-scope="scope">
+          <el-tag
+            :type="scope.row.end? 'success' : 'danger'"
+            disable-transitions>{{scope.row.end? '是' : '否'}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="120" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="detailHandle(scope.row)"
+          >查看</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="processImg(scope.row.processId)"
+          >流程图</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+    <process-img v-if="processImgVisible" ref="processImg" @refreshDataList="getList"></process-img>
+    <questionnaire-detail v-if="questionnaireVisible" ref="questionnaireDetail" @refreshDataList="getList"/>
+  </div>
+</template>
+
+<script>
+  import {getMyApprovelist} from "@/api/rc/approvedanger";
+  import {treeselect} from "@/api/system/dept";
+  import Treeselect from "@riophae/vue-treeselect";
+  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+  import ProcessImg from '../processImg'
+  import QuestionnaireDetail from "@/views/rc/approve/detail/questionnaire-detail";
+
+  export default {
+    name: "Myapprove",
+    components: {
+      Treeselect,
+      ProcessImg,
+      QuestionnaireDetail
+    },
+    data() {
+      return {
+        // 遮罩层
+        loading: true,
+        processImgVisible: false,
+        questionnaireVisible: false,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: false,
+        // 总条数
+        total: 0,
+        // 我的申请表格数据
+        approvedangerList: [],
+        // 弹出层标题
+        title: "",
+        // 部门树选项
+        deptOptions: undefined,
+        clientHeight:300,
+        // 是否显示弹出层
+        open: false,
+        // 装置名称字典
+        plantCodeOptions: [],
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 20,
+          plantCode: null,
+          recorderId: null,
+          hiddendangerLevel: null,
+          hiddendangerContent: null,
+          measures: null,
+          completeTime: null,
+          status: null,
+          creattime: null,
+          endtime: null,
+          processId: null,
+          approveNo: null,
+          deptId: null,
+        },
+        // 表单参数
+        form: {},
+      };
+    },
+    watch: {
+      // 根据名称筛选部门树
+      deptName(val) {
+        this.$refs.tree.filter(val);
+      }
+    },
+    created() {
+      //设置表格高度对应屏幕高度
+      this.$nextTick(() => {
+        this.clientHeight = document.body.clientHeight -200
+      })
+      this.getList();
+      this.getTreeselect();
+    },
+    methods: {
+      /** 查询隐患申请列表 */
+      getList() {
+        this.loading = true;
+        getMyApprovelist(this.queryParams).then(response => {
+          this.approvedangerList = response.rows;
+          this.total = response.total;
+          this.loading = false;
+        });
+      },
+      //操作审批流程
+      detailHandle (row) {
+        if (row.processName == "问卷审批流程") {
+          this.title = '处理问卷审批流程';
+          this.questionnaireVisible = true
+          this.$nextTick(() => {
+            this.$refs.questionnaireDetail.init(row.progress, row.taskId, row.processId, row.taskName)
+          })
+        }
+      },
+      /** 查询部门下拉树结构 */
+      getTreeselect() {
+        treeselect().then(response => {
+          this.deptOptions = response.data;
+        });
+      },
+      // 装置名称字典翻译
+      plantCodeFormat(row, column) {
+        return this.selectDictLabel(this.plantCodeOptions, row.plantCode);
+      },
+      // 取消按钮
+      cancel() {
+        this.open = false;
+        this.reset();
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          id: null,
+          plantCode: null,
+          recorderId: null,
+          hiddendangerLevel: null,
+          hiddendangerContent: null,
+          measures: null,
+          completeTime: null,
+          status: 0,
+          creattime: null,
+          endtime: null,
+          processId: null,
+          approveNo: null,
+          deptId: null,
+          delFlag: null
+        };
+        this.resetForm("form");
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.resetForm("queryForm");
+        this.handleQuery();
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map(item => item.id)
+        this.single = selection.length!==1
+        this.multiple = !selection.length
+      },
+      processImg (processId) {
+        console.log(processId)
+        this.processImgVisible = true
+        this.$nextTick(() => {
+          this.$refs.processImg.init(processId)
+        })
+      },
+    }
+  };
+</script>

+ 414 - 0
ruoyi-ui/src/views/rc/approve/pending/index.vue

@@ -0,0 +1,414 @@
+<template >
+  <div class="app-container">
+    <!-- 顶部工具栏 -->
+    <!--<el-row :gutter="10">-->
+      <!--<div class="top-right-btn">-->
+        <!--<el-row>-->
+          <!--<el-tooltip  effect="dark" :content="tagsView.refresh" placement="top">-->
+            <!--<el-button size="mini" circle icon="el-icon-refresh" @click="getList()" />-->
+          <!--</el-tooltip>-->
+        <!--</el-row>-->
+      <!--</div>-->
+    <!--</el-row>-->
+    <el-table v-loading="loading" :data="approvedangerList" @selection-change="handleSelectionChange" :height="clientHeight" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="流程ID" align="center" prop="processId" :show-overflow-tooltip="true"/>
+      <el-table-column label="流程名称" align="center" prop="processName" :show-overflow-tooltip="true"/>
+      <el-table-column label="流程创建时间" align="center" prop="processCreateTime" :show-overflow-tooltip="true"/>
+      <el-table-column label="待办任务名称" align="center" prop="taskName" :show-overflow-tooltip="true"/>
+      <el-table-column label="待办任务创建时间" align="center" prop="taskCreateTime" :show-overflow-tooltip="true"/>
+      <el-table-column label="申请编号" align="center" prop="apNo" :show-overflow-tooltip="true"/>
+      <el-table-column label="操作" align="center" width="120" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="addOrUpdateHandle(scope.row)"
+          >处理</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="processImg(scope.row.processId)"
+          >流程图</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!--&lt;!&ndash; 弹窗, 新增 / 修改 &ndash;&gt;-->
+    <!--<div v-if="addOrUpdateVisible">-->
+      <!--<el-dialog  :close-on-click-modal="false" v-dialogDrag :visible.sync="addOrUpdateVisible" :destroy-on-close="true">-->
+        <!--<add-or-update v-if="this.infoprocessName === ($t('重大隐患')+' '+ $t('审批流程') )|| this.infoprocessName === ($t('普通隐患')+' ' + $t('审批流程') )" :info="approveInfo"></add-or-update>-->
+        <!--<accident v-if="this.infoprocessName === ($t('事件')+ $t('审批流程'))" :info="approveInfo" @recordInfo="approveChange($event)"></accident>-->
+        <!--<el-form>-->
+          <!--<el-form-item :label="$t('上传措施前照片')" prop="before" v-if="this.infoTaskName === '执行人'">-->
+            <!--<el-upload-->
+              <!--ref="uploadbefore"-->
+              <!--:limit="1"-->
+              <!--:headers="uploadbefore.headers"-->
+              <!--:action="uploadbefore.url"-->
+              <!--:disabled="uploadbefore.isUploading"-->
+              <!--:on-progress="handleFileUploadProgressBefore"-->
+              <!--:on-success="handleFileSuccessBefore"-->
+              <!--:auto-upload="true"-->
+              <!--drag-->
+            <!--&gt;-->
+              <!--<i class="el-icon-upload"></i>-->
+              <!--<div class="el-upload__text">-->
+                <!--{{ $t('将文件拖到此处,或') }}-->
+                <!--<em>{{ $t('点击上传') }}</em>-->
+              <!--</div>-->
+            <!--</el-upload>-->
+          <!--</el-form-item>-->
+          <!--<el-form-item :label="$t('上传措施后照片')" prop="after" v-if="this.infoTaskName === $t('执行人')">-->
+            <!--<el-upload-->
+              <!--ref="uploadafter"-->
+              <!--:limit="1"-->
+              <!--:headers="uploadafter.headers"-->
+              <!--:action="uploadafter.url"-->
+              <!--:disabled="uploadafter.isUploading"-->
+              <!--:on-progress="handleFileUploadProgressAfter"-->
+              <!--:on-success="handleFileSuccessAfter"-->
+              <!--drag-->
+            <!--&gt;-->
+              <!--<i class="el-icon-upload"></i>-->
+              <!--<div class="el-upload__text">-->
+                <!--{{ $t('将文件拖到此处,或') }}-->
+                <!--<em>{{ $t('点击上传') }}</em>-->
+              <!--</div>-->
+            <!--</el-upload>-->
+          <!--</el-form-item>-->
+          <!--<el-form-item :label="$t('审批意见')" prop="comment">-->
+            <!--<el-input v-model="comment" :placeholder="$t('请输入') + $t('审批意见')" maxlength="100" show-word-limit></el-input>-->
+          <!--</el-form-item>-->
+        <!--</el-form>-->
+        <!--<span v-if="this.infoprocessName ===  ($t('重大隐患')+' ' + $t('审批流程') ) || this.infoprocessName === ($t('普通隐患')+' '  + $t('审批流程') )" slot="footer">-->
+          <!--<span v-if="this.infoTaskName === $t('执行人')" class="dialog-footer">-->
+            <!--<el-button type="primary" @click="dataFormSubmit(1)">{{ $t('已完成') }}</el-button>-->
+            <!--<el-button type="danger" @click="dataFormSubmit(0)">{{ $t('无法执行') }}</el-button>-->
+          <!--</span>-->
+          <!--<span v-if="this.infoTaskName === $t('验证人')" class="dialog-footer">-->
+            <!--<el-button type="primary" @click="dataFormSubmit(1)">{{ $t('通过') }}</el-button>-->
+            <!--<el-button type="danger" @click="dataFormSubmit(0)">{{ $t('无效') }}</el-button>-->
+            <!--<el-button type="warning" @click="dataFormSubmit(2)">{{ $t('未达标') }}</el-button>-->
+          <!--</span>-->
+          <!--<span v-if="this.infoTaskName === $t('记录人')" class="dialog-footer">-->
+            <!--<el-button type="primary" @click="dataFormSubmit(1)">{{ $t('重新提交') }}</el-button>-->
+          <!--</span>-->
+          <!--<span v-if="this.infoTaskName === $t('确认')" class="dialog-footer">-->
+            <!--<el-button type="primary" @click="dataFormSubmit(1)">{{ $t('确认') }}</el-button>-->
+            <!--<el-button type="danger" @click="dataFormSubmit(0)">{{ $t('确认')+' ' + $t('不通过') }}</el-button>-->
+          <!--</span>-->
+        <!--</span>-->
+        <!--<span v-if="this.infoprocessName === ($t('事件') + $t('审批流程'))" slot="footer">-->
+          <!--<span v-if="this.infoTaskName === $t('记录人')" class="dialog-footer">-->
+            <!--<el-button type="primary" @click="dataFormSubmit(1)">{{ $t('提交') }}</el-button>-->
+          <!--</span>-->
+        <!--</span>-->
+      <!--</el-dialog>-->
+    <!--</div>-->
+
+    <!--<add-or-update v-if="specDealVisible" ref="specDeal" @refreshDataList="getList"></add-or-update>-->
+    <!--<spec-modify v-if="specModifyDealVisible" ref="specModifyDeal" @refreshDataList="getList"></spec-modify>-->
+    <!--<spec-training-plan v-if="specTrainingPlanDealVisible" ref="specTrainingPlanDeal" @refreshDataList="getList"></spec-training-plan>-->
+    <process-img v-if="processImgVisible" ref="processImg" @refreshDataList="getList"></process-img>
+    <!--<intact-resolve v-if="intactResolveVisible" ref="intactResolveDeal" @refreshDataList="getList"></intact-resolve>-->
+    <!--<kekao-resolve v-if="kekaoResolveVisible" ref="kekaoResolveDeal" @refreshDataList="getList"></kekao-resolve>-->
+    <!--<spec-maintenance v-if="specMaintenanceVisible" ref="specMaintenance" @refreshDataList="getList"></spec-maintenance>-->
+    <!--<invoice-detail v-if="invoiceDetailVisible" ref="invoiceDetail" @refreshDataList="getList"></invoice-detail>-->
+    <!--<offlinevalve-detail v-if="offlinevalveDetailVisible" ref="offlinevalveDetail" @refreshDataList="getList"></offlinevalve-detail>-->
+    <!--<safetychange-detail v-if="safetychangeDetailVisible" ref="safetychangeDetail" @refreshDataList="getList"></safetychange-detail>-->
+    <common-detail v-if="commonVisible" ref="commonDetail" @refreshDataList="getList"/>
+  </div>
+</template>
+
+<script>
+  import {getPendinglist, handleApprovedanger} from "@/api/rc/approvedanger";
+  import ProcessImg from '../processImg/index';
+  import {treeselect} from "@/api/system/dept";
+  import {getToken} from "@/utils/auth";
+  import Treeselect from "@riophae/vue-treeselect";
+  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+  import CommonDetail from "@/views/rc/approve/detail/common-detail";
+  // import SpecMaintenance from "@/views/approve/pending/specMaintenance-deal";
+  // import KekaoResolve from '../approveDetail/kekao-resolve';
+  // import InvoiceDetail from "@/views/approve/approveDetail/invoice-detail";
+  // import OfflinevalveDetail from "@/views/approve/approveDetail/offlinevalve-detail";
+  // import SafetychangeDetail from "@/views/approve/approveDetail/safetychange-detail";
+  // import SaiApplyDetail from "@/views/approve/approveDetail/sai-apply-detail";
+  // import AddOrUpdate from './spec-detail';
+  // import SpecModify from './specModify-deal';
+  // import SpecTrainingPlan from './specTrainingPlan-deal';
+  // import IntactResolve from '../approveDetail/intact-resolve';
+  // import Accident from '../approveaccidentDetail/index';
+
+  export default {
+    name: "Pending",
+    components: {
+      CommonDetail,
+      Treeselect,
+      ProcessImg,
+    },
+    data() {
+      return {
+        // 遮罩层
+        loading: true,
+        //弹窗界面是否开启
+        addOrUpdateVisible: false,
+        processImgVisible: false,
+        specDealVisible: false,
+        specModifyDealVisible: false,
+        specTrainingPlanDealVisible: false,
+        intactResolveVisible:false,
+        kekaoResolveVisible:false,
+        specMaintenanceVisible: false,
+        invoiceDetailVisible:false,
+        offlinevalveDetailVisible:false,
+        safetychangeDetailVisible:false,
+        saiApplyVisible:false,
+        commonVisible: false,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: false,
+        // 总条数
+        total: 0,
+        // 我的申请表格数据
+        approvedangerList: [],
+        // 弹出层标题
+        title: "",
+        // 部门树选项
+        deptOptions: undefined,
+        clientHeight:300,
+        // 是否显示弹出层
+        open: false,
+        // 装置名称字典
+        plantCodeOptions: [],
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 20,
+          plantCode: null,
+          recorderId: null,
+          hiddendangerLevel: null,
+          hiddendangerContent: null,
+          measures: null,
+          completeTime: null,
+          status: null,
+          creattime: null,
+          endtime: null,
+          processId: null,
+          approveNo: null,
+          deptId: null,
+        },
+        // 措施前上传照片参数
+        uploadbefore: {
+          file: "",
+          // 是否禁用上传
+          isUploading: false,
+          // 是否更新已经存在的用户数据
+          updateSupport: 0,
+          // 设置上传的请求头部
+          headers: { Authorization: "Bearer " + getToken() },
+          // 上传的地址
+          url: process.env.VUE_APP_BASE_API + "/common/upload",
+          // 报告附件上传位置编号
+          ids: 0,
+          commonfileList: null,
+        },
+        // 措施后上传照片参数
+        uploadafter: {
+          file: "",
+          // 是否禁用上传
+          isUploading: false,
+          // 是否更新已经存在的用户数据
+          updateSupport: 0,
+          // 设置上传的请求头部
+          headers: { Authorization: "Bearer " + getToken() },
+          // 上传的地址
+          url: process.env.VUE_APP_BASE_API + "/common/upload",
+          // 报告附件上传位置编号
+          ids: 0,
+          commonfileList: null,
+        },
+        // 表单参数
+        form: {},
+        //事件记录人更新内容
+        recordInfo: {},
+        //处理数据传输
+        approveInfo: null,
+        //审批显示按键判断依据
+        infoprocessName: null,
+        infoTaskName: null,
+        //上传措施前后照片url,文件名称
+        beforeUrl: null,
+        beforeFilename: null,
+        afterUrl: null,
+        afterFilename: null,
+        //审批备注
+        comment: null
+      };
+    },
+    watch: {
+      // 根据名称筛选部门树
+      deptName(val) {
+        this.$refs.tree.filter(val);
+      }
+    },
+    created() {
+      //设置表格高度对应屏幕高度
+      this.$nextTick(() => {
+        this.clientHeight = document.body.clientHeight -200
+      })
+      this.getList();
+      this.getTreeselect();
+      this.getDicts("PLANT_DIVIDE").then(response => {
+        this.plantCodeOptions = response.data;
+      });
+    },
+    methods: {
+      /** 查询隐患申请列表 */
+      getList() {
+        this.loading = true;
+        getPendinglist(this.queryParams).then(response => {
+          this.approvedangerList = response.rows;
+          this.total = response.total;
+          this.loading = false;
+        });
+      },
+      /** 查询部门下拉树结构 */
+      getTreeselect() {
+        treeselect().then(response => {
+          this.deptOptions = response.data;
+        });
+      },
+      // 装置名称字典翻译
+      plantCodeFormat(row, column) {
+        return this.selectDictLabel(this.plantCodeOptions, row.plantCode);
+      },
+      // 取消按钮
+      cancel() {
+        this.addOrUpdateVisible = false;
+        this.reset();
+      },
+      /** 事件子组件传值 */
+      approveChange(value) {
+        this.recordInfo = value
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          id: null,
+          plantCode: null,
+          recorderId: null,
+          hiddendangerLevel: null,
+          hiddendangerContent: null,
+          measures: null,
+          completeTime: null,
+          status: 0,
+          creattime: null,
+          endtime: null,
+          processId: null,
+          approveNo: null,
+          deptId: null,
+          delFlag: null,
+          submitType: null,
+          commont: null,
+          accidentLevel: null,
+          executorId: null
+
+        };
+        this.resetForm("form");
+      },
+      //操作审批流程
+      addOrUpdateHandle (row) {
+        if (row.processName == "通用审批流程") {
+          this.commonVisible = true
+          this.$nextTick(() => {
+            this.$refs.commonDetail.init(row.obj.memberId, row.taskId, row.processId, row.taskName, 1)
+          })
+        }
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map(item => item.id)
+        this.single = selection.length!==1
+        this.multiple = !selection.length
+      },
+      // 表单提交
+      dataFormSubmit (val) {
+        //相关信息
+        this.form = this.approveInfo
+        this.form.submitType = val
+        this.form.comment = this.comment
+        // 审批确认后,申请人填写相关信息
+        if (this.form.processName === (this.$t('事件') + this.$t('审批流程'))) {
+          this.form.accidentLevel = this.recordInfo.accidentLevel;
+          this.form.measures = this.recordInfo.measures;
+          this.form.executorId = this.recordInfo.executorId;
+          this.form.completeTime = this.recordInfo.completeTime;
+          console.info("accidentLevel:" + this.form.accidentLevel)
+          console.info("measures:" + this.form.measures)
+          console.info("executorId:" + this.form.executorId)
+          console.info("completeTime:" + this.form.completeTime)
+        }
+        //提交审批
+        this.form.beforeUrl = this.beforeUrl
+        this.form.beforeFilename = this.beforeFilename
+        this.form.afterUrl = this.afterUrl
+        this.form.afterFilename = this.afterFilename
+        handleApprovedanger(this.form).then(response => {
+          this.msgSuccess(this.$t('处理成功'));
+          this.addOrUpdateVisible = false;
+          this.getList();
+        });
+        this.$nextTick(function () {
+          this.comment = ''
+        })
+      },
+      // 文件上传中处理
+      handleFileUploadProgressBefore(event, file, fileList) {
+        this.uploadbefore.isUploading = true;
+      },
+      handleFileUploadProgressAfter(event, file, fileList) {
+        this.uploadafter.isUploading = true;
+      },
+      // 文件上传成功处理
+      handleFileSuccessBefore(response, file, fileList) {
+        this.uploadbefore.isUploading = false;
+        //this.$refs.uploadbefore.clearFiles();
+        this.beforeUrl = response.url;
+        this.beforeFilename = response.fileName;
+      },
+      handleFileSuccessAfter(response, file, fileList) {
+        this.uploadafter.isUploading = false;
+        //this.$refs.uploadafter.clearFiles();
+        this.afterUrl = response.url;
+        this.afterFilename = response.fileName;
+      },
+      // 提交上传文件
+      submitFileForm() {
+        this.$refs.uploadbefore.submit()
+        this.$refs.uploadafter.submit()
+      },
+      processImg (processId) {
+        this.processImgVisible = true
+        this.$nextTick(() => {
+          this.$refs.processImg.init(processId)
+        })
+      },
+    }
+  };
+</script>

+ 35 - 0
ruoyi-ui/src/views/rc/approve/processImg/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <el-dialog  :close-on-click-modal="false"
+    title="流程图"
+    :visible.sync="visible">
+  <div style="padding-top: 0px;">
+    <img :src=getUrl() style="width: 100%"/>
+  </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="visible = false">返回</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+
+  export default {
+    data () {
+      return {
+        visible: false,
+        dataListLoading: false,
+        dataList: [],
+        processId: ''
+      }
+    },
+    methods: {
+      init (processId) {
+        this.processId = processId
+        this.visible = true
+      },
+      getUrl () {
+        return process.env.VUE_APP_BASE_API + '/ehs/approvedanger/processImg/' + this.processId
+      }
+    }
+  }
+</script>

+ 257 - 0
ruoyi-ui/src/views/rc/approve/taskdone/index.vue

@@ -0,0 +1,257 @@
+<template >
+  <div class="app-container">
+    <el-table v-loading="loading" :data="approvedangerList" @selection-change="handleSelectionChange" :height="clientHeight" border>
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="流程ID" align="center" prop="processId" :show-overflow-tooltip="true"/>
+      <el-table-column label="流程名称" align="center" prop="processName" :show-overflow-tooltip="true"/>
+      <el-table-column label="流程创建时间" align="center" prop="processCreateTime" :show-overflow-tooltip="true"/>
+      <el-table-column label="申请人姓名" align="center" prop="apName" :show-overflow-tooltip="true"/>
+<!--      <el-table-column :label="$t('隐患级别')" align="center" prop="tApprove.hiddendangerLevel" :show-overflow-tooltip="true"/>-->
+      <el-table-column label="申请编号" align="center" prop="apNo" :show-overflow-tooltip="true"/>
+      <el-table-column
+        prop="isEnd"
+        header-align="center"
+        align="center"
+        label="是否结束">
+        <template slot-scope="scope">
+          <el-tag
+            :type="scope.row.end? 'success' : 'danger'"
+            disable-transitions>{{scope.row.end? '是' : '否'}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" width="120" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleView(scope.row)"
+          >查看</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="processImg(scope.row.processId)"
+          >流程图</el-button>
+        </template>
+      </el-table-column>
+      </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 弹窗, 查看 -->
+<!--    <div v-if="addOrUpdateVisible">-->
+<!--      <el-dialog  :close-on-click-modal="false" v-dialogDrag :visible.sync="addOrUpdateVisible" :destroy-on-close="true">-->
+<!--        <add-or-update :info="approveInfo"></add-or-update>-->
+<!--      </el-dialog>-->
+<!--    </div>-->
+    <process-img v-if="processImgVisible" ref="processImg" @refreshDataList="getList"></process-img>
+    <!--<add-or-update v-if="specDealVisible" ref="specDeal" @refreshDataList="getList"></add-or-update>-->
+    <!--<spec-modify v-if="specModifyDealVisible" ref="specModifyDeal" @refreshDataList="getList"></spec-modify>-->
+    <!--<spec-training-plan v-if="specTrainingPlanVisible" ref="specTrainingPlan" @refreshDataList="getList"></spec-training-plan>-->
+    <!--<spec-maintenance v-if="specMaintenanceVisible" ref="specMaintenance" @refreshDataList="getList"></spec-maintenance>-->
+    <!--<intact-detail v-if="intactDetailVisible" ref="intactDetail" @refreshDataList="getList"></intact-detail>-->
+    <!--<kekao-detail v-if="kekaoDetailVisible" ref="kekaoDetail" @refreshDataList="getList"></kekao-detail>-->
+    <!--<invoice-detail v-if="invoiceDetailVisible" ref="invoiceDetail" @refreshDataList="getList"></invoice-detail>-->
+    <!--<offlinevalve-detail v-if="offlinevalveDetailVisible" ref="offlinevalveDetail" @refreshDataList="getList"></offlinevalve-detail>-->
+    <!--<safetychange-detail v-if="safetychangeDetailVisible" ref="safetychangeDetail" @refreshDataList="getList"></safetychange-detail>-->
+    <!--<sai-apply-detail v-if="saiApplyVisible" ref="saiApplyDetail" @refreshDataList="getList"></sai-apply-detail>-->
+    <common-detail v-if="commonVisible" ref="commonDetail" @refreshDataList="getList"/>
+  </div>
+</template>
+
+<script>
+  import { getTaskdonelist } from "@/api/rc/approvedanger";
+  // import AddOrUpdate from '../approveDetail/spec-detail';
+  import { treeselect } from "@/api/system/dept";
+  // import { getToken } from "@/utils/auth";
+  import Treeselect from "@riophae/vue-treeselect";
+  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+  import ProcessImg from "../processImg/index";
+
+  import CommonDetail from "@/views/rc/approve/detail/common-detail";
+  // import SpecModify from '../approveDetail/specModify-detail';
+  // import SpecTrainingPlan from '../approveDetail/specTrainingPlan-detaill';
+  // import SpecMaintenance from "@/views/approve/approveDetail/specMaintenance-detail";
+  // import IntactDetail from "@/views/approve/approveDetail/intact-detail";
+  // import KekaoDetail from "@/views/approve/approveDetail/kekao-detail";
+  // import InvoiceDetail from "@/views/approve/approveDetail/invoice-detail";
+  // import OfflinevalveDetail from "@/views/approve/approveDetail/offlinevalve-detail";
+  // import SafetychangeDetail from "@/views/approve/approveDetail/safetychange-detail";
+  // import SaiApplyDetail from "@/views/approve/approveDetail/sai-apply-detail";
+
+  export default {
+    name: "Taskdone",
+    components: {
+    //   SaiApplyDetail,
+    //   SafetychangeDetail,
+    //   OfflinevalveDetail,
+      Treeselect,
+      CommonDetail,
+    // AddOrUpdate,
+      ProcessImg,
+      // SpecModify,SpecTrainingPlan,SpecMaintenance,IntactDetail,KekaoDetail,InvoiceDetail
+    },
+    data() {
+      return {
+        // 遮罩层
+        loading: true,
+        processImgVisible: false,
+        specDealVisible: false,
+        specModifyDealVisible: false,
+        specTrainingPlanVisible: false,
+        specMaintenanceVisible: false,
+        intactDetailVisible:false,
+        kekaoDetailVisible:false,
+        invoiceDetailVisible:false,
+        offlinevalveDetailVisible:false,
+        safetychangeDetailVisible:false,
+        saiApplyVisible:false,
+        commonVisible: false,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: false,
+        // 总条数
+        total: 0,
+        // 我的申请表格数据
+        approvedangerList: [],
+        // 弹出层标题
+        title: "",
+        // 部门树选项
+        deptOptions: undefined,
+        clientHeight:300,
+        // 是否显示弹出层
+        open: false,
+        // 装置名称字典
+        plantCodeOptions: [],
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 20,
+          plantCode: null,
+          recorderId: null,
+          hiddendangerLevel: null,
+          hiddendangerContent: null,
+          measures: null,
+          completeTime: null,
+          status: null,
+          creattime: null,
+          endtime: null,
+          processId: null,
+          approveNo: null,
+          deptId: null,
+        },
+        // 表单参数
+        form: {},
+        //处理数据传输
+        approveInfo: null,
+        //弹窗界面是否开启
+        addOrUpdateVisible: false,
+      };
+    },
+    watch: {
+      // 根据名称筛选部门树
+      deptName(val) {
+        this.$refs.tree.filter(val);
+      }
+    },
+    created() {
+      //设置表格高度对应屏幕高度
+      this.$nextTick(() => {
+        this.clientHeight = document.body.clientHeight -200
+      })
+      this.getList();
+      this.getTreeselect();
+      this.getDicts("PLANT_DIVIDE").then(response => {
+        this.plantCodeOptions = response.data;
+      });
+    },
+    methods: {
+      /** 查询隐患申请列表 */
+      getList() {
+        this.loading = true;
+        getTaskdonelist(this.queryParams).then(response => {
+          this.approvedangerList = response.rows;
+          this.total = response.total;
+          this.loading = false;
+        });
+      },
+      /** 查询部门下拉树结构 */
+      getTreeselect() {
+        treeselect().then(response => {
+          this.deptOptions = response.data;
+        });
+      },
+      /** 查看操作 */
+      handleView (row) {
+        if (row.processName == "通用审批流程") {
+          this.commonVisible = true
+          this.$nextTick(() => {
+            this.$refs.commonDetail.init(row.obj.memberId, row.taskId, row.processId, row.taskName, 2)
+          })
+        }
+      },
+      // 装置名称字典翻译
+      plantCodeFormat(row, column) {
+        return this.selectDictLabel(this.plantCodeOptions, row.plantCode);
+      },
+      // 取消按钮
+      cancel() {
+        this.open = false;
+        this.reset();
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          id: null,
+          plantCode: null,
+          recorderId: null,
+          hiddendangerLevel: null,
+          hiddendangerContent: null,
+          measures: null,
+          completeTime: null,
+          status: 0,
+          creattime: null,
+          endtime: null,
+          processId: null,
+          approveNo: null,
+          deptId: null,
+          delFlag: null
+        };
+        this.resetForm("form");
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.resetForm("queryForm");
+        this.handleQuery();
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map(item => item.id)
+        this.single = selection.length!==1
+        this.multiple = !selection.length
+      },
+      processImg (processId) {
+        this.processImgVisible = true
+        this.$nextTick(() => {
+          this.$refs.processImg.init(processId)
+        })
+      },
+    }
+  };
+</script>

+ 23 - 1
ruoyi-ui/src/views/rc/progress/index.vue

@@ -176,6 +176,12 @@
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
           >删除</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleApply(scope.row)"
+            v-if="(scope.row.applyStatus == 1 || scope.row.applyStatus == 3) && scope.row.preparation == 6"
+          >提交申请</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -281,6 +287,7 @@
 
 <script>
 import { listProgress, getProgress, delProgress, addProgress, updateProgress } from "@/api/rc/progress";
+import { applyQuestionnaire } from "@/api/rc/questionnaire";
 import { listAllUser } from "@/api/system/user";
 
 export default {
@@ -340,6 +347,22 @@ export default {
     this.getUserList();
   },
   methods: {
+    /** 提交申请按钮操作 */
+    handleApply(row) {
+      this.$confirm('是否确认提交?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: "warning"
+      }).then(function() {
+        return applyQuestionnaire(row);
+      }).then(() => {
+        this.getList()
+        this.$message({
+          message: '提交成功',
+          type: 'success'
+        });
+      })
+    },
     handleDoc(row , type) {
       this.$router.push({path: '/rc/file', query: {linkId: row.questionnaireId, linkName: 'questionnaire'}})
     },
@@ -361,7 +384,6 @@ export default {
       this.loading = true;
       this.queryParams.auditId = this.$route.query.auditId;
       listProgress(this.queryParams).then(response => {
-        console.log(response)
         this.progressList = response.rows;
         this.total = response.total;
         this.loading = false;

+ 454 - 1
sql/create.sql

@@ -162,4 +162,457 @@ create table t_commonfile
   p_value varchar(1000) comment '业务字段',
   p_date datetime comment '业务时间',
 	primary key (id)
-) engine=innodb auto_increment=100 comment = '通用附件表';
+) engine=innodb auto_increment=100 comment = '通用附件表';
+
+-- ----------------------------
+-- Activiti表
+-- ----------------------------
+create table ACT_GE_BYTEARRAY
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  NAME_ VARCHAR(255),
+  DEPLOYMENT_ID_ VARCHAR(64),
+  BYTES_ BLOB,
+  GENERATED_ int(1),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_GE_PROPERTY
+(
+  NAME_ VARCHAR(64) not null,
+  VALUE_ VARCHAR(300),
+  REV_ int,
+  primary key (NAME_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_ACTINST
+(
+  ID_ VARCHAR(64) not null,
+  PROC_DEF_ID_ VARCHAR(64) not null,
+  PROC_INST_ID_ VARCHAR(64) not null,
+  EXECUTION_ID_ VARCHAR(64) not null,
+  ACT_ID_ VARCHAR(255) not null,
+  TASK_ID_ VARCHAR(64),
+  CALL_PROC_INST_ID_ VARCHAR(64),
+  ACT_NAME_ VARCHAR(255),
+  ACT_TYPE_ VARCHAR(255) not null,
+  ASSIGNEE_ VARCHAR(255),
+  START_TIME_ TIMESTAMP(6) not null,
+  END_TIME_ TIMESTAMP(6),
+  DURATION_ int(19),
+  DELETE_REASON_ VARCHAR(2000),
+  TENANT_ID_ VARCHAR(255) default '',
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_ATTACHMENT
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  USER_ID_ VARCHAR(255),
+  NAME_ VARCHAR(255),
+  DESCRIPTION_ VARCHAR(2000),
+  TYPE_ VARCHAR(255),
+  TASK_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  URL_ VARCHAR(2000),
+  CONTENT_ID_ VARCHAR(64),
+  TIME_ TIMESTAMP(6),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_COMMENT
+(
+  ID_ VARCHAR(64) not null,
+  TYPE_ VARCHAR(255),
+  TIME_ TIMESTAMP(6) not null,
+  USER_ID_ VARCHAR(255),
+  TASK_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  ACTION_ VARCHAR(255),
+  MESSAGE_ VARCHAR(2000),
+  FULL_MSG_ BLOB,
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_DETAIL
+(
+  ID_ VARCHAR(64) not null,
+  TYPE_ VARCHAR(255) not null,
+  PROC_INST_ID_ VARCHAR(64),
+  EXECUTION_ID_ VARCHAR(64),
+  TASK_ID_ VARCHAR(64),
+  ACT_INST_ID_ VARCHAR(64),
+  NAME_ VARCHAR(255) not null,
+  VAR_TYPE_ VARCHAR(64),
+  REV_ int,
+  TIME_ TIMESTAMP(6) not null,
+  BYTEARRAY_ID_ VARCHAR(64),
+  DOUBLE_ int,
+  LONG_ int(19),
+  TEXT_ VARCHAR(2000),
+  TEXT2_ VARCHAR(2000),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_IDENTITYLINK
+(
+  ID_ VARCHAR(64) not null,
+  GROUP_ID_ VARCHAR(255),
+  TYPE_ VARCHAR(255),
+  USER_ID_ VARCHAR(255),
+  TASK_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_PROCINST
+(
+  ID_ VARCHAR(64) not null,
+  PROC_INST_ID_ VARCHAR(64) not null,
+  BUSINESS_KEY_ VARCHAR(255),
+  PROC_DEF_ID_ VARCHAR(64) not null,
+  START_TIME_ TIMESTAMP(6) not null,
+  END_TIME_ TIMESTAMP(6),
+  DURATION_ int(19),
+  START_USER_ID_ VARCHAR(255),
+  START_ACT_ID_ VARCHAR(255),
+  END_ACT_ID_ VARCHAR(255),
+  SUPER_PROCESS_INSTANCE_ID_ VARCHAR(64),
+  DELETE_REASON_ VARCHAR(2000),
+  TENANT_ID_ VARCHAR(255) default '',
+  NAME_ VARCHAR(255),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_TASKINST
+(
+  ID_ VARCHAR(64) not null,
+  PROC_DEF_ID_ VARCHAR(64),
+  TASK_DEF_KEY_ VARCHAR(255),
+  PROC_INST_ID_ VARCHAR(64),
+  EXECUTION_ID_ VARCHAR(64),
+  PARENT_TASK_ID_ VARCHAR(64),
+  NAME_ VARCHAR(255),
+  DESCRIPTION_ VARCHAR(2000),
+  OWNER_ VARCHAR(255),
+  ASSIGNEE_ VARCHAR(255),
+  START_TIME_ TIMESTAMP(6) not null,
+  CLAIM_TIME_ TIMESTAMP(6),
+  END_TIME_ TIMESTAMP(6),
+  DURATION_ int(19),
+  DELETE_REASON_ VARCHAR(2000),
+  PRIORITY_ int,
+  DUE_DATE_ TIMESTAMP(6),
+  FORM_KEY_ VARCHAR(255),
+  CATEGORY_ VARCHAR(255),
+  TENANT_ID_ VARCHAR(255) default '',
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_HI_VARINST
+(
+  ID_ VARCHAR(64) not null,
+  PROC_INST_ID_ VARCHAR(64),
+  EXECUTION_ID_ VARCHAR(64),
+  TASK_ID_ VARCHAR(64),
+  NAME_ VARCHAR(255) not null,
+  VAR_TYPE_ VARCHAR(100),
+  REV_ int,
+  BYTEARRAY_ID_ VARCHAR(64),
+  DOUBLE_ int,
+  LONG_ int(19),
+  TEXT_ VARCHAR(2000),
+  TEXT2_ VARCHAR(2000),
+  CREATE_TIME_ TIMESTAMP(6),
+  LAST_UPDATED_TIME_ TIMESTAMP(6),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_ID_INFO
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  USER_ID_ VARCHAR(64),
+  TYPE_ VARCHAR(64),
+  KEY_ VARCHAR(255),
+  VALUE_ VARCHAR(255),
+  PASSWORD_ BLOB,
+  PARENT_ID_ VARCHAR(255),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_PROCDEF_INFO
+(
+  ID_ VARCHAR(64) not null,
+  PROC_DEF_ID_ VARCHAR(64) not null,
+  REV_ int,
+  INFO_JSON_ID_ VARCHAR(64),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RE_DEPLOYMENT
+(
+  ID_ VARCHAR(64) not null,
+  NAME_ VARCHAR(255),
+  CATEGORY_ VARCHAR(255),
+  KEY_ VARCHAR(255),
+  TENANT_ID_ VARCHAR(255) default '',
+  DEPLOY_TIME_ TIMESTAMP(6),
+  ENGINE_VERSION_ VARCHAR(255),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RE_MODEL
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  NAME_ VARCHAR(255),
+  KEY_ VARCHAR(255),
+  CATEGORY_ VARCHAR(255),
+  CREATE_TIME_ TIMESTAMP(6),
+  LAST_UPDATE_TIME_ TIMESTAMP(6),
+  VERSION_ int,
+  META_INFO_ VARCHAR(2000),
+  DEPLOYMENT_ID_ VARCHAR(64),
+  EDITOR_SOURCE_VALUE_ID_ VARCHAR(64),
+  EDITOR_SOURCE_EXTRA_VALUE_ID_ VARCHAR(64),
+  TENANT_ID_ VARCHAR(255) default '',
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RE_PROCDEF
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  CATEGORY_ VARCHAR(255),
+  NAME_ VARCHAR(255),
+  KEY_ VARCHAR(255) not null,
+  VERSION_ int not null,
+  DEPLOYMENT_ID_ VARCHAR(64),
+  RESOURCE_NAME_ VARCHAR(2000),
+  DGRM_RESOURCE_NAME_ VARCHAR(4000),
+  DESCRIPTION_ VARCHAR(2000),
+  HAS_START_FORM_KEY_ int(1),
+  HAS_GRAPHICAL_NOTATION_ int(1),
+  SUSPENSION_STATE_ int,
+  TENANT_ID_ VARCHAR(255) default '',
+  ENGINE_VERSION_ VARCHAR(255),
+  constraint ACT_UNIQ_PROCDEF
+  unique (KEY_, VERSION_, TENANT_ID_),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_EVENT_SUBSCR
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  EVENT_TYPE_ VARCHAR(255) not null,
+  EVENT_NAME_ VARCHAR(255),
+  EXECUTION_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  ACTIVITY_ID_ VARCHAR(64),
+  CONFIGURATION_ VARCHAR(255),
+  CREATED_ TIMESTAMP(6) not null,
+  PROC_DEF_ID_ VARCHAR(64),
+  TENANT_ID_ VARCHAR(255) default '',
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_EXECUTION
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  PROC_INST_ID_ VARCHAR(64),
+  BUSINESS_KEY_ VARCHAR(255),
+  PARENT_ID_ VARCHAR(64),
+  PROC_DEF_ID_ VARCHAR(64),
+  SUPER_EXEC_ VARCHAR(64),
+  ROOT_PROC_INST_ID_ VARCHAR(64),
+  ACT_ID_ VARCHAR(255),
+  IS_ACTIVE_ int(1),
+  IS_CONCURRENT_ int(1),
+  IS_SCOPE_ int(1),
+  IS_EVENT_SCOPE_ int(1),
+  IS_MI_ROOT_ int(1),
+  SUSPENSION_STATE_ int,
+  CACHED_ENT_STATE_ int,
+  TENANT_ID_ VARCHAR(255) default '',
+  NAME_ VARCHAR(255),
+  START_TIME_ TIMESTAMP(6),
+  START_USER_ID_ VARCHAR(255),
+  LOCK_TIME_ TIMESTAMP(6),
+  IS_COUNT_ENABLED_ int(1),
+  EVT_SUBSCR_COUNT_ int,
+  TASK_COUNT_ int,
+  JOB_COUNT_ int,
+  TIMER_JOB_COUNT_ int,
+  SUSP_JOB_COUNT_ int,
+  DEADLETTER_JOB_COUNT_ int,
+  VAR_COUNT_ int,
+  ID_LINK_COUNT_ int,
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_DEADLETTER_JOB
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  TYPE_ VARCHAR(255) not null,
+  EXCLUSIVE_ int(1),
+  EXECUTION_ID_ VARCHAR(64),
+  PROCESS_INSTANCE_ID_ VARCHAR(64),
+  PROC_DEF_ID_ VARCHAR(64),
+  EXCEPTION_STACK_ID_ VARCHAR(64),
+  EXCEPTION_MSG_ VARCHAR(2000),
+  DUEDATE_ TIMESTAMP(6),
+  REPEAT_ VARCHAR(255),
+  HANDLER_TYPE_ VARCHAR(255),
+  HANDLER_CFG_ VARCHAR(2000),
+  TENANT_ID_ VARCHAR(255) default '',
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_IDENTITYLINK
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  GROUP_ID_ VARCHAR(255),
+  TYPE_ VARCHAR(255),
+  USER_ID_ VARCHAR(255),
+  TASK_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  PROC_DEF_ID_ VARCHAR(64),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_JOB
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  TYPE_ VARCHAR(255) not null,
+  LOCK_EXP_TIME_ TIMESTAMP(6),
+  LOCK_OWNER_ VARCHAR(255),
+  EXCLUSIVE_ int(1),
+  EXECUTION_ID_ VARCHAR(64),
+  PROCESS_INSTANCE_ID_ VARCHAR(64),
+  PROC_DEF_ID_ VARCHAR(64),
+  RETRIES_ int,
+  EXCEPTION_STACK_ID_ VARCHAR(64),
+  EXCEPTION_MSG_ VARCHAR(2000),
+  DUEDATE_ TIMESTAMP(6),
+  REPEAT_ VARCHAR(255),
+  HANDLER_TYPE_ VARCHAR(255),
+  HANDLER_CFG_ VARCHAR(2000),
+  TENANT_ID_ VARCHAR(255) default '',
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_SUSPENDED_JOB
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  TYPE_ VARCHAR(255) not null,
+  EXCLUSIVE_ int(1),
+  PROCESS_INSTANCE_ID_ VARCHAR(64),
+  RETRIES_ int,
+  EXCEPTION_STACK_ID_ VARCHAR(64),
+  EXCEPTION_MSG_ VARCHAR(2000),
+  DUEDATE_ TIMESTAMP(6),
+  REPEAT_ VARCHAR(255),
+  HANDLER_TYPE_ VARCHAR(255),
+  HANDLER_CFG_ VARCHAR(2000),
+  TENANT_ID_ VARCHAR(255) default '',
+  EXECUTION_ID_ VARCHAR(64),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_TASK
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  EXECUTION_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  PROC_DEF_ID_ VARCHAR(64),
+  NAME_ VARCHAR(255),
+  PARENT_TASK_ID_ VARCHAR(64),
+  DESCRIPTION_ VARCHAR(2000),
+  TASK_DEF_KEY_ VARCHAR(255),
+  OWNER_ VARCHAR(255),
+  ASSIGNEE_ VARCHAR(255),
+  DELEGATION_ VARCHAR(64),
+  PRIORITY_ int,
+  CREATE_TIME_ TIMESTAMP(6),
+  DUE_DATE_ TIMESTAMP(6),
+  CATEGORY_ VARCHAR(255),
+  SUSPENSION_STATE_ int,
+  TENANT_ID_ VARCHAR(255) default '',
+  FORM_KEY_ VARCHAR(255),
+  CLAIM_TIME_ TIMESTAMP(6),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_TIMER_JOB
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  TYPE_ VARCHAR(255) not null,
+  LOCK_EXP_TIME_ TIMESTAMP(6),
+  LOCK_OWNER_ VARCHAR(255),
+  EXCLUSIVE_ int(1),
+  EXECUTION_ID_ VARCHAR(64),
+  PROCESS_INSTANCE_ID_ VARCHAR(64),
+  PROC_DEF_ID_ VARCHAR(64),
+  RETRIES_ int,
+  EXCEPTION_STACK_ID_ VARCHAR(64),
+  EXCEPTION_MSG_ VARCHAR(2000),
+  DUEDATE_ TIMESTAMP(6),
+  REPEAT_ VARCHAR(255),
+  HANDLER_TYPE_ VARCHAR(255),
+  HANDLER_CFG_ VARCHAR(2000),
+  TENANT_ID_ VARCHAR(255) default '',
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_RU_VARIABLE
+(
+  ID_ VARCHAR(64) not null,
+  REV_ int,
+  TYPE_ VARCHAR(255) not null,
+  NAME_ VARCHAR(255) not null,
+  EXECUTION_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  TASK_ID_ VARCHAR(64),
+  BYTEARRAY_ID_ VARCHAR(64),
+  DOUBLE_ int,
+  LONG_ int(19),
+  TEXT_ VARCHAR(2000),
+  TEXT2_ VARCHAR(2000),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_EVT_LOG
+(
+  LOG_NR_ int(19) not null,
+  TYPE_ VARCHAR(64),
+  PROC_DEF_ID_ VARCHAR(64),
+  PROC_INST_ID_ VARCHAR(64),
+  EXECUTION_ID_ VARCHAR(64),
+  TASK_ID_ VARCHAR(64),
+  TIME_STAMP_ TIMESTAMP(6) not null,
+  USER_ID_ VARCHAR(255),
+  DATA_ BLOB,
+  LOCK_OWNER_ VARCHAR(255),
+  LOCK_TIME_ TIMESTAMP(6),
+  IS_PROCESSED_ int(3) default 0,
+  primary key (LOG_NR_)
+)engine=innodb auto_increment=100;
+create table ACT_ID_GROUP
+(
+  ID_ varchar(64) not null
+    primary key,
+  REV_ int,
+  NAME_ varchar(255),
+  TYPE_ varchar(255),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_ID_USER
+(
+  ID_ varchar(64) not null,
+  REV_ int,
+  FIRST_ varchar(255),
+  LAST_ varchar(255),
+  EMAIL_ varchar(255),
+  PWD_ varchar(255),
+  PICTURE_ID_ varchar(64),
+  primary key (ID_)
+)engine=innodb auto_increment=100;
+create table ACT_ID_MEMBERSHIP
+(
+  USER_ID_ varchar(64) not null,
+  GROUP_ID_ varchar(64) not null,
+  primary key (USER_ID_)
+)engine=innodb auto_increment=100;
+
+ALTER TABLE t_progress ADD process_id varchar(255) NULL COMMENT '流程id';
+ALTER TABLE t_progress ADD ap_no varchar(255) NULL COMMENT '申请编号';
+ALTER TABLE t_progress ADD task_id varchar(255) NULL COMMENT '任务编号';
+ALTER TABLE t_progress ADD task_name varchar(255) NULL COMMENT '任务名称';
+