content: package com.ruoyi.flowable.service.impl;
  
  
  import cn.hutool.core.collection.CollUtil;
  import cn.hutool.core.date.BetweenFormatter;
  import cn.hutool.core.date.DateUtil;
  import cn.hutool.core.util.ObjectUtil;
  import com.ruoyi.common.core.domain.entity.SysDept;
  import com.ruoyi.common.core.domain.entity.SysRole;
  import com.ruoyi.common.core.domain.entity.SysUser;
  import com.ruoyi.common.exception.ServiceException;
  import com.ruoyi.flowable.api.domain.bo.WfTaskBo;
  import com.ruoyi.flowable.constant.TaskConstants;
  import com.ruoyi.flowable.domain.vo.WfFormVo;
  import com.ruoyi.flowable.domain.vo.WfTaskVo;
  import com.ruoyi.flowable.factory.FlowServiceFactory;
  import com.ruoyi.flowable.service.IWfDeployFormService;
  import com.ruoyi.flowable.service.IWfInstanceService;
  import com.ruoyi.flowable.utils.JsonUtils;
  import com.ruoyi.flowable.utils.StringUtils;
  import com.ruoyi.system.api.service.ISysDeptServiceApi;
  import com.ruoyi.system.api.service.ISysRoleServiceApi;
  import com.ruoyi.system.api.service.ISysUserServiceApi;
  import lombok.RequiredArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
  import org.flowable.common.engine.api.FlowableObjectNotFoundException;
  import org.flowable.engine.history.HistoricProcessInstance;
  import org.flowable.engine.task.Comment;
  import org.flowable.identitylink.api.history.HistoricIdentityLink;
  import org.flowable.task.api.history.HistoricTaskInstance;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Service;
  import org.springframework.transaction.annotation.Transactional;
  
  import java.util.*;
  
  /**
   * 工作流流程实例管理
   *
   * @author fengcheng
   * @createTime 2022/3/10 00:12
   */
  @RequiredArgsConstructor
  @Service
  @Slf4j
  public class WfInstanceServiceImpl extends FlowServiceFactory implements IWfInstanceService {
      private final IWfDeployFormService deployFormService;
      @Autowired
      private ISysUserServiceApi userServiceApi;
      @Autowired
      private ISysRoleServiceApi roleServiceApi;
      @Autowired
      private ISysDeptServiceApi deptServiceApi;
  
      /**
       * 结束流程实例
       *
       * @param vo
       */
      @Override
      public void stopProcessInstance(WfTaskBo vo) {
          String taskId = vo.getTaskId();
      }
  
      /**
       * 激活或挂起流程实例
       *
       * @param state      状态
       * @param instanceId 流程实例ID
       */
      @Override
      public void updateState(Integer state, String instanceId) {
          // 激活
          if (state == 1) {
              runtimeService.activateProcessInstanceById(instanceId);
          }
          // 挂起
          if (state == 2) {
              runtimeService.suspendProcessInstanceById(instanceId);
          }
      }
  
      /**
       * 删除流程实例ID
       *
       * @param instanceId   流程实例ID
       * @param deleteReason 删除原因
       */
      @Override
      @Transactional(rollbackFor = Exception.class)
      public void delete(String instanceId, String deleteReason) {
          // 查询历史数据
          HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId);
          if (historicProcessInstance.getEndTime() != null) {
              historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
              return;
          }
          // 删除流程实例
          runtimeService.deleteProcessInstance(instanceId, deleteReason);
          // 删除历史流程实例
          historyService.deleteHistoricProcessInstance(instanceId);
      }
  
      /**
       * 根据实例ID查询历史实例数据
       *
       * @param processInstanceId
       * @return
       */
      @Override
      public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
          HistoricProcessInstance historicProcessInstance =
                  historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
          if (Objects.isNull(historicProcessInstance)) {
              throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId);
          }
          return historicProcessInstance;
      }
  
  
      /**
       * 流程历史流转记录
       *
       * @param procInsId 流程实例Id
       * @return
       */
      @Override
      public Map<String, Object> queryDetailProcess(String procInsId, String deployId) {
          Map<String, Object> map = new HashMap<>(16);
          if (StringUtils.isNotBlank(procInsId)) {
              List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
                      .processInstanceId(procInsId)
                      .orderByHistoricTaskInstanceStartTime().desc()
                      .list();
              List<Comment> commentList = taskService.getProcessInstanceComments(procInsId);
              List<WfTaskVo> taskVoList = new ArrayList<>(taskInstanceList.size());
              taskInstanceList.forEach(taskInstance -> {
                  WfTaskVo taskVo = new WfTaskVo();
                  taskVo.setProcDefId(taskInstance.getProcessDefinitionId());
                  taskVo.setTaskId(taskInstance.getId());
                  taskVo.setTaskDefKey(taskInstance.getTaskDefinitionKey());
                  taskVo.setTaskName(taskInstance.getName());
                  taskVo.setCreateTime(taskInstance.getStartTime());
                  taskVo.setFinishTime(taskInstance.getEndTime());
                  if (StringUtils.isNotBlank(taskInstance.getAssignee())) {
                      Long userId = Long.parseLong(taskInstance.getAssignee());
                      SysUser sysUser = userServiceApi.selectUserById(userId);
                      String nickName = sysUser.getNickName();
                      taskVo.setAssigneeId(userId);
                      taskVo.setAssigneeName(nickName);
                  }
                  // 展示审批人员
                  List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(taskInstance.getId());
                  StringBuilder stringBuilder = new StringBuilder();
                  for (HistoricIdentityLink identityLink : linksForTask) {
                      if ("candidate".equals(identityLink.getType())) {
                          if (StringUtils.isNotBlank(identityLink.getUserId())) {
                              Long userId = Long.parseLong(identityLink.getUserId());
                              SysUser sysUser = userServiceApi.selectUserById(userId);
                              String nickName = sysUser.getNickName();
                              stringBuilder.append(nickName).append(",");
                          }
                          if (StringUtils.isNotBlank(identityLink.getGroupId())) {
                              if (identityLink.getGroupId().startsWith(TaskConstants.ROLE_GROUP_PREFIX)) {
                                  Long roleId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.ROLE_GROUP_PREFIX));
                                  SysRole role = roleServiceApi.selectRoleById(roleId);
                                  stringBuilder.append(role.getRoleName()).append(",");
                              } else if (identityLink.getGroupId().startsWith(TaskConstants.DEPT_GROUP_PREFIX)) {
                                  Long deptId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.DEPT_GROUP_PREFIX));
                                  SysDept dept = deptServiceApi.selectDeptById(deptId);
                                  stringBuilder.append(dept.getDeptName()).append(",");
                              }
                          }
                      }
                  }
                  if (StringUtils.isNotBlank(stringBuilder)) {
                      taskVo.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
                  }
                  if (ObjectUtil.isNotNull(taskInstance.getDurationInMillis())) {
                      taskVo.setDuration(DateUtil.formatBetween(taskInstance.getDurationInMillis(), BetweenFormatter.Level.SECOND));
                  }
                  // 获取意见评论内容
                  if (CollUtil.isNotEmpty(commentList)) {
                      List<Comment> comments = new ArrayList<>();
                      // commentList.stream().filter(comment -> taskInstance.getId().equals(comment.getTaskId())).collect(Collectors.toList());
                      for (Comment comment : commentList) {
                          if (comment.getTaskId().equals(taskInstance.getId())) {
                              comments.add(comment);
                              // taskVo.setComment(WfCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());
                          }
                      }
                      taskVo.setCommentList(comments);
                  }
                  taskVoList.add(taskVo);
              });
              map.put("flowList", taskVoList);
  //            // 查询当前任务是否完成
  //            List<Task> taskList = taskService.createTaskQuery().processInstanceId(procInsId).list();
  //            if (CollectionUtils.isNotEmpty(taskList)) {
  //                map.put("finished", true);
  //            } else {
  //                map.put("finished", false);
  //            }
          }
          // 第一次申请获取初始化表单
          if (StringUtils.isNotBlank(deployId)) {
              WfFormVo formVo = deployFormService.selectDeployFormByDeployId(deployId);
              if (Objects.isNull(formVo)) {
                  throw new ServiceException("请先配置流程表单");
              }
              map.put("formData", JsonUtils.parseObject(formVo.getContent(), Map.class));
          }
          return map;
      }
  }
  