From 6fbfdf4c73f9673adb7e2777e83565195568f7a8 Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期四, 28 十一月 2024 06:04:16 +0800
Subject: [PATCH] 完善流程(表单回显接口)、项目流程表增加流程实例id字段、流程推进详情接口

---
 business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java |  253 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 245 insertions(+), 8 deletions(-)

diff --git a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
index 31d6031..4856ea1 100644
--- a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
+++ b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
@@ -1,9 +1,21 @@
 package com.ycl.service.impl;
 
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
 import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
+import com.ycl.common.constant.ProcessConstants;
+import com.ycl.common.core.domain.AjaxResult;
+import com.ycl.common.core.domain.entity.SysRole;
+import com.ycl.common.core.domain.entity.SysUser;
+import com.ycl.common.enums.FlowComment;
+import com.ycl.common.utils.SecurityUtils;
+import com.ycl.domain.dto.FlowTaskDto;
+import com.ycl.domain.entity.ProjectInfo;
 import com.ycl.domain.entity.ProjectProcess;
+import com.ycl.domain.vo.ProjectProcessDetailVO;
+import com.ycl.mapper.ProjectInfoMapper;
 import com.ycl.mapper.ProjectProcessMapper;
 import com.ycl.service.ProjectProcessService;
 import com.ycl.common.base.Result;
@@ -11,14 +23,30 @@
 import com.ycl.domain.form.ProjectProcessForm;
 import com.ycl.domain.vo.ProjectProcessVO;
 import com.ycl.domain.query.ProjectProcessQuery;
+import com.ycl.system.service.ISysRoleService;
+import com.ycl.system.service.ISysUserService;
+import org.apache.commons.lang3.StringUtils;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.Process;
+import org.flowable.bpmn.model.StartEvent;
+import org.flowable.engine.*;
+import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.identitylink.api.IdentityLink;
+import org.flowable.task.api.Task;
+import org.flowable.task.api.TaskQuery;
+import org.flowable.task.api.history.HistoricTaskInstance;
+import org.flowable.task.api.history.HistoricTaskInstanceQuery;
 import org.springframework.stereotype.Service;
 import lombok.RequiredArgsConstructor;
 import com.ycl.framework.utils.PageUtil;
 import org.springframework.beans.BeanUtils;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
 
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -32,6 +60,14 @@
 public class ProjectProcessServiceImpl extends ServiceImpl<ProjectProcessMapper, ProjectProcess> implements ProjectProcessService {
 
     private final ProjectProcessMapper projectProcessMapper;
+    private final RuntimeService runtimeService;
+    private final TaskService taskService;
+    private final IdentityService identityService;
+    private final RepositoryService repositoryService;
+    private final ProjectInfoMapper projectInfoMapper;
+    private final HistoryService historyService;
+    private final ISysUserService sysUserService;
+    private final ISysRoleService sysRoleService;
 
     /**
      * 鍒嗛〉鏌ヨ
@@ -46,15 +82,48 @@
     }
 
     /**
-     * 鏍规嵁id鏌ユ壘
-     * @param id
+     * 鑾峰彇娴佺▼璇︽儏
+     * @param projectId
      * @return
      */
     @Override
-    public Result detail(Integer id) {
-        ProjectProcessVO vo = baseMapper.getById(id);
-        Assert.notNull(vo, "璁板綍涓嶅瓨鍦�");
-        return Result.ok().data(vo);
+    public Result detail(Long projectId, String processId) {
+        // 椤圭洰淇℃伅
+        ProjectInfo projectInfo = new LambdaQueryChainWrapper<>(projectInfoMapper)
+                .select(ProjectInfo::getId, ProjectInfo::getProjectName, ProjectInfo::getProjectCode)
+                .eq(ProjectInfo::getId, projectId)
+                .one();
+
+        if (Objects.isNull(projectInfo)) {
+            return Result.error("璇ラ」鐩笉瀛樺湪");
+        }
+
+        ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(baseMapper)
+                .eq(ProjectProcess::getProjectId, projectId)
+                .eq(ProjectProcess::getFlowableProcessId, processId)
+                .one();
+        if (Objects.isNull(projectProcess)) {
+            return Result.error("璇ラ」鐩湭璁剧疆娴佺▼");
+        }
+
+        ProjectProcessDetailVO detail = new ProjectProcessDetailVO();
+        detail.setProjectId(projectId);
+        detail.setProjectName(projectInfo.getProjectName());
+        detail.setProjectCode(projectInfo.getProjectCode());
+
+        ProjectProcessDetailVO.TaskStatistics taskStatistics = new ProjectProcessDetailVO.TaskStatistics();
+        // 鐘舵�佺粺璁�
+        taskStatistics.setTotalTaskNum(this.getTotalTaskNum(processId));
+        taskStatistics.setTodoTaskNum(this.getTodoTaskNum(projectProcess.getProcessInstanceId()));
+//        taskStatistics.setCurrentTask(this.getCurrentNodeTaskList(projectProcess.getProcessInstanceId()));
+        taskStatistics.setRemainingTaskNum(this.getNotFinishedTaskNum(projectProcess.getProcessInstanceId()));
+        detail.setStatistics(taskStatistics);
+
+        Result result = Result.ok();
+
+        // 浠e姙浠诲姟
+        this.getTodoTaskList(projectProcess.getProcessInstanceId(),"", 1, 5, result);
+        return result.data(detail);
     }
 
 
@@ -76,4 +145,172 @@
         }
         return Result.ok("娴佺▼鍙樻洿鎴愬姛");
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result startProcess(String projectId, String processId) {
+        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processId)
+                .latestVersion().singleResult();
+        if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
+            return Result.error("璇ユ祦绋嬪凡琚寕璧�,璇峰厛婵�娲绘祦绋�");
+        }
+        Map<String, Object> variables = new HashMap<>(2);
+        // 璁剧疆娴佺▼鍙戣捣浜篒d鍒版祦绋嬩腑
+        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
+        identityService.setAuthenticatedUserId(sysUser.getUserId().toString());
+        variables.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUserId());
+        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processId, projectId, variables);
+//        // 娴佺▼鍙戣捣鏃� 璺宠繃鍙戣捣浜鸿妭鐐�
+//        // 缁欑涓�姝ョ敵璇蜂汉鑺傜偣璁剧疆浠诲姟鎵ц浜哄拰鎰忚
+//        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
+//        if (Objects.nonNull(task)) {
+//            taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.NORMAL.getType(), sysUser.getNickName() + "鍙戣捣娴佺▼鐢宠");
+//            taskService.complete(task.getId(), variables);
+//        }
+        // 椤圭洰娴佺▼鍏宠仈娴佺▼瀹炰緥id
+        new LambdaUpdateChainWrapper<>(baseMapper)
+                .eq(ProjectProcess::getProjectId, projectId)
+                .eq(ProjectProcess::getFlowableProcessId, processId)
+                .set(ProjectProcess::getProcessInstanceId, processInstance.getProcessInstanceId())
+                .update();
+        return Result.ok("娴佺▼鍚姩鎴愬姛");
+    }
+
+
+    private void getTodoTaskList(String processInstanceId, String name, Integer pageNum, Integer pageSize, Result result) {
+        TaskQuery taskQuery = taskService.createTaskQuery()
+                .active()
+                .processInstanceId(processInstanceId)
+                .includeProcessVariables()
+                .orderByTaskCreateTime().desc();
+
+//        TODO 浼犲叆鍚嶇О鏌ヨ涓嶅埌鏁版嵁?
+        if (StringUtils.isNotBlank(name)) {
+            taskQuery.processDefinitionNameLike(name);
+        }
+        result.total(taskQuery.count());
+        List<Task> taskList = taskQuery.listPage(pageSize * (pageNum - 1), pageSize);
+        List<FlowTaskDto> flowList = new ArrayList<>();
+        for (Task task : taskList) {
+            FlowTaskDto flowTask = new FlowTaskDto();
+            // 褰撳墠娴佺▼淇℃伅
+            flowTask.setTaskId(task.getId());
+            flowTask.setTaskDefKey(task.getTaskDefinitionKey());
+            flowTask.setCreateTime(task.getCreateTime());
+            flowTask.setProcDefId(task.getProcessDefinitionId());
+            flowTask.setExecutionId(task.getExecutionId());
+            flowTask.setTaskName(task.getName());
+            // 娴佺▼瀹氫箟淇℃伅
+            ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
+                    .processDefinitionId(task.getProcessDefinitionId())
+                    .singleResult();
+            flowTask.setDeployId(pd.getDeploymentId());
+            flowTask.setProcDefName(pd.getName());
+            flowTask.setProcDefVersion(pd.getVersion());
+            flowTask.setProcInsId(task.getProcessInstanceId());
+
+            // 娴佺▼鍙戣捣浜轰俊鎭�
+            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
+                    .processInstanceId(task.getProcessInstanceId())
+                    .singleResult();
+            SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
+            flowTask.setStartUserId(startUser.getUserId().toString());
+            flowTask.setStartUserName(startUser.getNickName());
+            flowTask.setStartDeptName(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptName() : "");
+            // 娴佺▼澶勭悊浜轰俊鎭�
+            List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
+            for (IdentityLink identityLink : identityLinksForTask) {
+                // 缁戝畾鐨勬槸鐢ㄦ埛锛屾煡鍑虹敤鎴峰鍚嶃�侀儴闂�
+                if (StringUtils.isNotBlank(identityLink.getUserId())) {
+                    SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId()));
+                    if (Objects.nonNull(sysUser)) {
+                        flowTask.setAssigneeId(sysUser.getUserId());
+                        if (Objects.nonNull(sysUser.getDept())) {
+                            flowTask.setAssigneeDeptName(sysUser.getDept().getDeptName());
+                        }
+                        flowTask.setAssigneeName(sysUser.getNickName());
+                    }
+                // 缁戝畾鐨勬槸瑙掕壊锛屾煡鍑鸿鑹插悕绉�
+                } else if (StringUtils.isNotBlank(identityLink.getGroupId())) {
+                    SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
+                    if (Objects.nonNull(role)) {
+                        flowTask.setAssigneeId(Long.parseLong(identityLink.getGroupId()));
+                        flowTask.setAssigneeDeptName("鐢辨嫢鏈夎鑹诧細銆�" + role.getRoleName() + "銆戠殑浜哄鐞�");
+                        flowTask.setAssigneeName("鏆傛湭澶勭悊");
+                    }
+                }
+            }
+            flowList.add(flowTask);
+        }
+        result.put("taskList", flowList);
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鑺傜偣鏁帮紙鎬讳换鍔℃暟锛屼笉鍖呭惈寮�濮嬨�佺粨鏉熺瓑鐗规畩鐨勶紝鍙粺璁serTask绫诲瀷鐨勶級
+     *
+     * @param processDefinitionId  娴佺▼瀹氫箟id
+     * @return
+     */
+    private Long getTotalTaskNum(String processDefinitionId) {
+        // 鑾峰彇娴佺▼瀹氫箟
+        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
+                .processDefinitionId(processDefinitionId)
+                .singleResult();
+
+        if (processDefinition == null) {
+            throw new IllegalArgumentException("娴佺▼瀹氫箟ID鏃犳晥: " + processDefinitionId);
+        }
+
+        // 鑾峰彇BPMN妯″瀷
+        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
+        if (bpmnModel == null) {
+            throw new IllegalStateException("鏃犳硶鑾峰彇BPMN妯″瀷: " + processDefinitionId);
+        }
+
+        // 鑾峰彇娴佺▼瀵硅薄
+        Process process = bpmnModel.getProcessById(processDefinition.getKey());
+        if (process == null) {
+            throw new IllegalStateException("鏃犳硶鑾峰彇娴佺▼瀵硅薄: " + processDefinition.getKey());
+        }
+
+        // 璁$畻浠诲姟鑺傜偣鏁伴噺
+        Long taskNodeCount = 0L;
+        List<FlowElement> flowElements = process.getFlowElements().stream().toList();
+        for (FlowElement flowElement : flowElements) {
+            if (flowElement instanceof org.flowable.bpmn.model.UserTask) {
+                taskNodeCount++;
+            }
+        }
+        return taskNodeCount;
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鍓╀綑鏈畬鎴愮殑浠诲姟鏁�
+     *
+     * @param processInstanceId
+     * @return
+     */
+    private Long getNotFinishedTaskNum(String processInstanceId) {
+        return historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).processUnfinished().count();
+    }
+
+    /**
+     * 鑾峰彇寰呭姙浠诲姟鏁�
+     *
+     * @param processInstanceId
+     * @return
+     */
+    private Long getTodoTaskNum(String processInstanceId) {
+        return taskService.createTaskQuery().active().processInstanceId(processInstanceId).count();
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鐜妭鐨勬墍鏈変换鍔℃暟
+     *
+     * @param processInstanceId
+     * @return
+     */
+    private List<Task> getCurrentNodeTaskList(String processInstanceId) {
+       return taskService.createTaskQuery().processDefinitionId(processInstanceId).list();
+    }
 }

--
Gitblit v1.8.0