package com.ycl.service.impl; import com.alibaba.fastjson2.JSONArray; 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.constant.ProcessOverTimeConstants; import com.ycl.common.core.domain.entity.SysDept; import com.ycl.common.core.domain.entity.SysDictData; import com.ycl.common.core.domain.entity.SysRole; import com.ycl.common.core.domain.entity.SysUser; import com.ycl.common.enums.business.*; import com.ycl.common.utils.SecurityUtils; import com.ycl.constant.TaskTypeConstant; import com.ycl.domain.entity.*; import com.ycl.domain.form.*; import com.ycl.domain.json.*; import com.ycl.domain.query.ProcessLogQuery; import com.ycl.domain.vo.*; import com.ycl.event.event.TaskLogEvent; import com.ycl.mapper.ProjectEngineeringMapper; import com.ycl.mapper.ProjectInfoMapper; import com.ycl.mapper.ProjectProcessMapper; import com.ycl.service.*; import com.ycl.common.base.Result; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ycl.domain.query.ProjectProcessQuery; import com.ycl.service.common.TaskCommonService; import com.ycl.system.domain.base.AbsQuery; import com.ycl.system.service.ISysDeptService; import com.ycl.system.service.ISysDictTypeService; import com.ycl.system.service.ISysRoleService; import com.ycl.system.service.ISysUserService; import com.ycl.utils.TreeUtil; import lombok.Synchronized; import org.apache.commons.lang3.StringUtils; import org.flowable.bpmn.model.*; import org.flowable.bpmn.model.Process; import org.flowable.common.engine.impl.util.CollectionUtil; 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.identitylink.api.IdentityLinkInfo; import org.flowable.identitylink.api.IdentityLinkType; import org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntityImpl; 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.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import com.ycl.framework.utils.PageUtil; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.util.*; import java.util.stream.Collectors; /** * 项目流程关系表 服务实现类 * * @author xp * @since 2024-11-26 */ @Service @RequiredArgsConstructor public class ProjectProcessServiceImpl extends ServiceImpl 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 ProjectEngineeringMapper projectEngineeringMapper; private final HistoryService historyService; private final ISysUserService sysUserService; private final ISysRoleService sysRoleService; private final ISysDeptService sysDeptService; private final TaskCommonService taskCommonService; private final IFlowTaskService flowTaskService; private final ISysFormService formService; private final ProcessCodingService processCodingService; private final ApplicationEventPublisher publisher; private final ISysDeptService deptService; private final ProcessLogService processLogService; private final ISysDictTypeService dictTypeService; private final ProcessConfigInfoService processConfigInfoService; /** * 分页查询 * * @param query * @return */ @Override public Result page(ProjectProcessQuery query) { IPage page = PageUtil.getPage(query, ProjectProcessVO.class); baseMapper.getPage(query, page); for (ProjectProcessVO vo : page.getRecords()) { List childList = baseMapper.getEngineeringList(vo.getId()); childList.stream().forEach(child -> { if (StringUtils.isNotBlank(child.getProcessDefId())) { ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(child.getProcessDefId()).singleResult(); if (Objects.nonNull(processDefinition)) { child.setSuspended(processDefinition.isSuspended()); child.setFlowableProcessName(processDefinition.getName() + "(v" + processDefinition.getVersion() + ")"); child.setDeployId(processDefinition.getDeploymentId()); } } }); vo.setChildren(TreeUtil.treeForProjectEng(childList)); vo.setStatus(vo.getProjectStatus()); if (StringUtils.isNotBlank(vo.getProcessDefId())) { ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(vo.getProcessDefId()).singleResult(); if (Objects.nonNull(processDefinition)) { vo.setSuspended(processDefinition.isSuspended()); vo.setFlowableProcessName(processDefinition.getName() + "(v" + processDefinition.getVersion() + ")"); vo.setDeployId(processDefinition.getDeploymentId()); } } } return Result.ok().data(page.getRecords()).total(page.getTotal()); } @Override @Transactional(rollbackFor = Exception.class) public Result projectSetProcess(ProjectProcessForm form) { // 查询该项目是否已经绑定过流程了,检查绑定的流程是否在运行,在运行就删了 ProjectProcess pp = new LambdaQueryChainWrapper<>(baseMapper) .eq(ProjectProcess::getProjectId, form.getProjectId()) .eq(ProjectProcess::getProjectType, form.getProjectType()) .one(); if (Objects.isNull(pp)) { throw new RuntimeException("该项目未绑定流程"); } if (Objects.nonNull(pp.getProcessInsId())) { HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(pp.getProcessInsId()).singleResult(); if (Objects.nonNull(historicProcessInstance)) { // 删除之前流程的数据 if (historicProcessInstance.getEndTime() != null) { historyService.deleteHistoricProcessInstance(historicProcessInstance.getId()); } else { // 删除流程实例 runtimeService.deleteProcessInstance(pp.getProcessInsId(), ""); // 删除历史流程实例 historyService.deleteHistoricProcessInstance(pp.getProcessInsId()); } } } Long unitId = null; if (ProjectProcessTypeEnum.PROJECT.equals(form.getProjectType())) { ProjectInfo project = new LambdaQueryChainWrapper<>(projectInfoMapper) .eq(ProjectInfo::getId, form.getProjectId()) .one(); if (Objects.isNull(project)) { throw new RuntimeException("项目不存在"); } unitId = project.getProjectOwnerUnit(); } else if (ProjectProcessTypeEnum.ENGINEERING.equals(form.getProjectType())) { ProjectEngineering projectEngineering = new LambdaQueryChainWrapper<>(projectEngineeringMapper) .eq(ProjectEngineering::getId, form.getProjectId()) .one(); if (Objects.isNull(projectEngineering)) { throw new RuntimeException("工程不存在"); } unitId = projectEngineering.getUnit(); } SysDept dept = deptService.selectDeptById(unitId); if (Objects.isNull(dept)) { throw new RuntimeException("业主单位不存在"); } String processInsId = this.startPro(form.getProjectId(), form.getProcessDefId(), dept.getDeptId()); new LambdaUpdateChainWrapper<>(baseMapper) .eq(ProjectProcess::getProjectId, form.getProjectId()) .eq(ProjectProcess::getProjectType, form.getProjectType()) .set(ProjectProcess::getProcessDefId, form.getProcessDefId()) .set(ProjectProcess::getProcessInsId, processInsId) .set(ProjectProcess::getDataLaunch, unitId) .update(); return Result.ok("流程变更成功"); } @Override @Transactional(rollbackFor = Exception.class) public Result startProcess(ProjectProcessForm form) { Long unitId = null; if (ProjectProcessTypeEnum.PROJECT.equals(form.getProjectType())) { ProjectInfo project = new LambdaQueryChainWrapper<>(projectInfoMapper) .eq(ProjectInfo::getId, form.getProjectId()) .one(); if (Objects.isNull(project)) { throw new RuntimeException("项目不存在"); } unitId = project.getProjectOwnerUnit(); } else if (ProjectProcessTypeEnum.ENGINEERING.equals(form.getProjectType())) { ProjectEngineering projectEngineering = new LambdaQueryChainWrapper<>(projectEngineeringMapper) .eq(ProjectEngineering::getId, form.getProjectId()) .one(); if (Objects.isNull(projectEngineering)) { throw new RuntimeException("工程不存在"); } unitId = projectEngineering.getUnit(); } SysDept dept = deptService.selectDeptById(unitId); if (Objects.isNull(dept)) { throw new RuntimeException("业主单位不存在"); } String processInsId = this.startPro(form.getProjectId(), form.getProcessDefId(), dept.getDeptId()); ProjectProcess entity = new ProjectProcess(); entity.setProjectId(form.getProjectId()); entity.setProcessDefId(form.getProcessDefId()); entity.setProcessInsId(processInsId); entity.setDataLaunch(unitId); entity.setProjectType(form.getProjectType()); baseMapper.insert(entity); return Result.ok("流程启动成功"); } /** * 启动流程 * * @param projectId * @param processDefId * @return */ private String startPro(String projectId, String processDefId, Long createBy) { ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefId) .latestVersion().singleResult(); if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) { throw new RuntimeException("该流程已被挂起,请先激活流程"); } Map variables = new HashMap<>(2); // 设置流程发起人Id到流程中 SysUser sysUser = SecurityUtils.getLoginUser().getUser(); identityService.setAuthenticatedUserId(sysUser.getUserId().toString()); variables.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUserId()); // 将该项目的申请人(业主方)作为流程中某些环节的处理人 variables.put(ProcessConstants.DATA_LAUNCH, "dept:" + createBy); variables.put("a", 1); ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefId, projectId + "", variables); return processInstance.getId(); } /** * 获取流程详情 * * @param form * @return */ @Override public Result detail(ProjectProcessForm form) { String projectName = ""; String projectCode = ""; if (ProjectProcessTypeEnum.PROJECT.equals(form.getProjectType())) { ProjectInfo projectInfo = projectInfoMapper.selectById(form.getProjectId()); if (Objects.isNull(projectInfo)) { throw new RuntimeException("项目不存在"); } projectName = projectInfo.getProjectName(); projectCode = projectInfo.getProjectCode(); } else if (ProjectProcessTypeEnum.ENGINEERING.equals(form.getProjectType())) { ProjectEngineering projectEngineering = projectEngineeringMapper.selectById(form.getProjectId()); if (Objects.isNull(projectEngineering)) { throw new RuntimeException("工程不存在"); } projectName = projectEngineering.getProjectName(); } ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(baseMapper) .eq(ProjectProcess::getProjectId, form.getProjectId()) .eq(ProjectProcess::getProcessDefId, form.getProcessDefId()) .eq(ProjectProcess::getProjectType, form.getProjectType()) .one(); if (Objects.isNull(projectProcess)) { return Result.error("未设置流程"); } ProjectProcessDetailVO detail = new ProjectProcessDetailVO(); detail.setProjectType(form.getProjectType().getValue()); detail.setProjectId(form.getProjectId()); detail.setProjectName(projectName); detail.setProjectCode(projectCode); ProjectProcessDetailVO.TaskStatistics taskStatistics = new ProjectProcessDetailVO.TaskStatistics(); // 状态统计 taskStatistics.setTotalTaskNum(this.getTotalTaskNum(form.getProcessDefId())); taskStatistics.setTodoTaskNum(this.getTodoTaskNum(projectProcess.getProcessInsId())); taskStatistics.setRemainingTaskNum(this.getRemainingTaskNum(form.getProcessDefId(), projectProcess.getProcessInsId(), taskStatistics.getTotalTaskNum())); taskStatistics.setTimelyFinishedTaskNum(this.getTimelyTaskNum(projectProcess.getProcessInsId())); taskStatistics.setOvertimeTaskNum(this.getOvertimeTaskNum(projectProcess.getProcessInsId())); taskStatistics.setWillOvertimeTaskNum(this.getWillOvertimeTaskNum(projectProcess.getProcessInsId())); taskStatistics.setWaitTaskNum(this.getWaitTaskNum(projectProcess.getProcessInsId())); taskStatistics.setJumpTaskNum(this.getJumpTaskNum(projectProcess.getProcessInsId())); detail.setStatistics(taskStatistics); Result result = Result.ok(); // // 代办任务 // this.getTodoTaskList(projectProcess.getProjectId(), projectProcess.getProcessInsId(), "", 5, 1, result); return result.data(detail); } /** * 容缺任务计数 * @param processInsId * @return */ private Long getWaitTaskNum(String processInsId){ // 查出容缺过的任务 List allWaitTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.WAIT) .orderByDesc(ProcessLog::getGmtCreate) .list(); // 排除容缺后又完成的任务 List finishedTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.FINISHED, ProcessLogEventTypeEnum.REJECT) .list(); List finishedTaskIds = finishedTaskList.stream().map(ProcessLog::getTaskId).distinct().collect(Collectors.toList()); // 得到未完成的容缺任务 List waitTaskIds = allWaitTaskList.stream().filter(log -> !finishedTaskIds.contains(log.getTaskId())).map(ProcessLog::getTaskId).collect(Collectors.toList()); if (CollectionUtils.isEmpty(waitTaskIds)) { return 0L; } // 容缺的任务都属于历史任务,只是需要补表单数据 List hisTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInsId) .taskIds(waitTaskIds) .includeIdentityLinks() .orderByHistoricTaskInstanceStartTime() .desc() .list(); hisTaskList = this.distinctHisTask(hisTaskList); // 排除运行时任务 List runTaskKeys = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); hisTaskList = hisTaskList.stream().filter(his -> !runTaskKeys.contains(his.getTaskDefinitionKey())).collect(Collectors.toList()); return Long.valueOf(hisTaskList.size()); } @Override public Result taskList(com.ycl.domain.query.TaskQuery query) { // 获取项目对应的流程实例id ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(baseMapper) .eq(ProjectProcess::getProjectId, query.getProjectId()) .eq(ProjectProcess::getProcessDefId, query.getProcessDefId()) .one(); if (Objects.isNull(projectProcess)) { throw new RuntimeException("该项目未配置流程"); } Result ok = Result.ok(); switch (query.getTaskType()) { case TaskTypeConstant.ALL: this.getAllUserTask(query.getProjectId(), query.getProcessDefId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getCurrentPage(), (int) query.getPageSize(), ok); break; case TaskTypeConstant.TODO: this.getTodoTaskList(query.getProjectId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getPageSize(), (int) query.getCurrentPage(), ok); ok.data(ok.get("taskList")); break; case TaskTypeConstant.WAIT: this.getWaitTask(query.getProjectId(), query.getProcessDefId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getCurrentPage(), (int) query.getPageSize(), ok); break; case TaskTypeConstant.JUMP: this.getJumpTask(query.getProjectId(), query.getProcessDefId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getCurrentPage(), (int) query.getPageSize(), ok); break; case TaskTypeConstant.REMAINING: this.getRemainingTask(query.getProjectId(), query.getProcessDefId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getCurrentPage(), (int) query.getPageSize(), ok); break; case TaskTypeConstant.TIMELY: this.getTimelyTask(query.getProjectId(), query.getProcessDefId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getCurrentPage(), (int) query.getPageSize(), ok); break; case TaskTypeConstant.OVERTIME: this.getOvertimeTask(query.getProjectId(), query.getProcessDefId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getCurrentPage(), (int) query.getPageSize(), ok); break; case TaskTypeConstant.WILL_OVER_TIME: this.getWillOvertimeTask(query.getProjectId(), query.getProcessDefId(), projectProcess.getProcessInsId(), query.getTaskName(), (int) query.getCurrentPage(), (int) query.getPageSize(), ok); break; default: break; } return ok; } @Override public void getIndexTodoTask(String taskName, int pageSize, int pageNum, Result result) { TaskQuery taskQuery = taskService.createTaskQuery() .active() .includeProcessVariables() .orderByTaskCreateTime().desc(); List insIds = baseMapper.getNormalInsIds(); if (CollectionUtils.isEmpty(insIds)) { result.data(new ArrayList<>()).total(0L); return; } else { taskQuery.processInstanceIdIn(insIds); } if (StringUtils.isNotBlank(taskName)) { taskQuery.taskNameLike(taskName); } if (!SecurityUtils.getLoginUser().getUser().isAdmin()) { taskQuery .or() .taskCandidateGroupIn(taskCommonService.getCurrentUserGroups()) .taskCandidateUser(SecurityUtils.getUserId() + "") .taskAssignee(SecurityUtils.getUserId() + "") .endOr(); } result.total(taskQuery.count()); List allTodoList = taskQuery.list(); List orderList = new ArrayList<>(); allTodoList.stream().forEach(task -> { TaskOrderVO order = new TaskOrderVO(); order.setTaskId(task.getId()); // 计算办理时间,超时的排前面,没超时的由低到高排序,没超时时间的排最后 ProcessCoding processCoding = processCodingService.getByTaskId(task.getId(), task.getProcessInstanceId()); if (Objects.nonNull(processCoding)) { if (StringUtils.isNotBlank(processCoding.getRedTime())) { Long overtime = getTime(processCoding.getRedTime()); long durationTime = 0l; if (Objects.nonNull(processCoding.getStartTaskTime())) { durationTime = ((new Date()).getTime() - processCoding.getStartTaskTime().getTime()) / 1000; } if (overtime > durationTime) { order.setNum((overtime - durationTime) / 3600); } else { order.setNum(-2000000L); } } else { order.setNum(2000000L); } } else { order.setNum(2000000L); } orderList.add(order); }); // 升序排列 Collections.sort(orderList, Comparator.comparingLong(TaskOrderVO::getNum)); int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; if (startNum >= orderList.size()) { result.data(new ArrayList<>()).total(0L); return; } int end = Math.min(endNum, orderList.size()); List targetTaskIds = orderList.subList(startNum, end).stream().map(TaskOrderVO::getTaskId).collect(Collectors.toList()); List taskList = targetTaskIds.stream().map(taskId -> { List list = allTodoList.stream().filter(task -> task.getId().equals(taskId)).collect(Collectors.toList()); if (CollectionUtils.isEmpty(list)) { return null; } return list.get(0); }).filter(Objects::nonNull).collect(Collectors.toList()); List vos = new ArrayList<>(); for (Task task : taskList) { IndexCustomerTaskVO taskVO = new IndexCustomerTaskVO(); // 当前流程信息 taskVO.setTaskId(task.getId()); taskVO.setCreateTime(task.getCreateTime()); taskVO.setProcessDefId(task.getProcessDefinitionId()); taskVO.setExecutionId(task.getExecutionId()); taskVO.setTaskName(task.getName()); taskVO.setTaskStatus(TaskStatusEnum.TODO); // 流程定义信息 ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() .processDefinitionId(task.getProcessDefinitionId()) .singleResult(); taskVO.setDeployId(pd.getDeploymentId()); taskVO.setProcessName(pd.getName() + "(v" + pd.getVersion() + ")"); taskVO.setProcessInsId(task.getProcessInstanceId()); taskVO.setTaskDefinitionKey(task.getTaskDefinitionKey()); // 流程项目信息 ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(baseMapper) .eq(ProjectProcess::getProcessInsId, task.getProcessInstanceId()) .one(); String projectId = ""; String projectName = ""; if (Objects.nonNull(projectProcess)) { if (projectProcess.getProjectType().equals(ProjectProcessTypeEnum.PROJECT)) { ProjectInfo project = projectInfoMapper.selectById(projectProcess.getProjectId()); if (Objects.nonNull(project)) { projectId = projectProcess.getProjectId(); projectName = project.getProjectName(); } } else if (projectProcess.getProjectType().equals(ProjectProcessTypeEnum.ENGINEERING)) { ProjectEngineering engineering = projectEngineeringMapper.selectById(projectProcess.getProjectId()); if (Objects.nonNull(engineering)) { projectId = projectProcess.getProjectId(); projectName = engineering.getProjectName(); } } } taskVO.setProjectId(projectId); taskVO.setProjectName(projectName); // 流程发起人信息 this.setPromoterInfo(taskVO); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); taskVO.setHandlerId(handlerIds); taskVO.setHandlerName(handlerNames); taskVO.setHandlerUnitId(handlerUnitIds); taskVO.setHandlerUnitName(handlerUnitNames); // 流程处理人信息 List identityLinks = taskService.getIdentityLinksForTask(task.getId()); // Boolean aboutMe = taskCommonService.taskAboutMe(identityLinks); // if (! aboutMe) { // continue; // } for (IdentityLinkInfo identityLink : identityLinks) { // 绑定的是用户,查出用户姓名、部门 if (StringUtils.isNotBlank(identityLink.getUserId())) { taskVO.setHandlerType(HandlerTypeEnum.USER); SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); if (Objects.nonNull(sysUser)) { handlerIds.add(sysUser.getUserId()); handlerNames.add(sysUser.getNickName()); if (Objects.nonNull(sysUser.getDept())) { handlerUnitIds.add(sysUser.getDept().getDeptId()); handlerUnitNames.add(sysUser.getDept().getDeptName()); } } // 绑定的是角色或者部门 } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { if (identityLink.getGroupId().startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 taskVO.setHandlerType(HandlerTypeEnum.DEPT); String[] split = identityLink.getGroupId().split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { handlerUnitIds.add(dept.getDeptId()); handlerUnitNames.add(dept.getDeptName()); } } } else { taskVO.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); if (Objects.nonNull(role)) { handlerUnitIds.add(role.getRoleId()); handlerUnitNames.add(role.getRoleName()); } } } } // 检查是否挂起 if (processLogService.taskIsHangup(task.getId(), task.getProcessInstanceId())) { taskVO.setTaskStatus(TaskStatusEnum.HANGUP); } // 计算办理时间 ProcessCoding processCoding = processCodingService.getByTaskId(task.getId(), task.getProcessInstanceId()); if (Objects.nonNull(processCoding)) { if (StringUtils.isNotBlank(processCoding.getRedTime())) { Long overtime = getTime(processCoding.getRedTime()); long durationTime = 0l; if (Objects.nonNull(processCoding.getStartTaskTime())) { durationTime = ((new Date()).getTime() - processCoding.getStartTaskTime().getTime()) / 1000; } if (overtime > durationTime) { taskVO.setRemainingTime((overtime - durationTime) / 3600 + "小时"); } else { taskVO.setRemainingTime("已超时"); } } else { taskVO.setRemainingTime("-"); } } else { taskVO.setRemainingTime("-"); } this.distinctVo(taskVO); vos.add(taskVO); } result.put("taskList", vos); } private Long getTime(String timeStr) { Long time = null; if (StringUtils.isNotBlank(timeStr)) { String[] timeArr = timeStr.split("-"); // 解析天数和小时数 int days = Integer.parseInt(timeArr[0]); int hours = 0; if (timeArr.length > 1) { hours = Integer.parseInt(timeArr[1]); } time = (days * 24L + hours) * 3600L; // //分-秒 // time= (days * 60L) + hours; } return time; } @Override public void getAllTodoTask(String taskName, int pageSize, int pageNum, Result result) { TaskQuery taskQuery = taskService.createTaskQuery() .active() .includeProcessVariables() .includeIdentityLinks() .orderByTaskCreateTime().desc(); if (StringUtils.isNotBlank(taskName)) { taskQuery.processDefinitionNameLike(taskName); } result.total(taskQuery.count()); List taskList = taskQuery.listPage(pageSize * (pageNum - 1), pageSize); List vos = new ArrayList<>(); for (Task task : taskList) { CustomerTaskVO taskVO = new CustomerTaskVO(); // 当前流程信息 taskVO.setTaskId(task.getId()); taskVO.setCreateTime(task.getCreateTime()); taskVO.setProcessDefId(task.getProcessDefinitionId()); taskVO.setExecutionId(task.getExecutionId()); taskVO.setTaskName(task.getName()); taskVO.setTaskStatus(TaskStatusEnum.TODO); // 流程定义信息 ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() .processDefinitionId(task.getProcessDefinitionId()) .singleResult(); taskVO.setDeployId(pd.getDeploymentId()); taskVO.setProcessName(pd.getName()); taskVO.setProcessInsId(task.getProcessInstanceId()); taskVO.setTaskDefinitionKey(task.getTaskDefinitionKey()); // 流程发起人信息 this.setPromoterInfo(taskVO); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); // 流程处理人信息 List identityLinks = task.getIdentityLinks(); for (IdentityLinkInfo identityLink : identityLinks) { // 绑定的是用户,查出用户姓名、部门 if (StringUtils.isNotBlank(identityLink.getUserId())) { taskVO.setHandlerType(HandlerTypeEnum.USER); SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); if (Objects.nonNull(sysUser)) { handlerIds.add(sysUser.getUserId()); handlerNames.add(sysUser.getNickName()); if (Objects.nonNull(sysUser.getDept())) { handlerUnitIds.add(sysUser.getDept().getDeptId()); handlerUnitNames.add(sysUser.getDept().getDeptName()); } } // 绑定的是角色或者部门 } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { if (identityLink.getGroupId().startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 taskVO.setHandlerType(HandlerTypeEnum.DEPT); String[] split = identityLink.getGroupId().split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { handlerUnitIds.add(dept.getDeptId()); handlerUnitNames.add(dept.getDeptName()); } } } else { taskVO.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); if (Objects.nonNull(role)) { handlerUnitIds.add(role.getRoleId()); handlerUnitNames.add(role.getRoleName()); } } } } vos.add(taskVO); } result.put("taskList", vos); } @Override public Result detailByProcessInsId(com.ycl.domain.query.TaskQuery query) { List list = new LambdaQueryChainWrapper<>(baseMapper) .eq(ProjectProcess::getProcessInsId, query.getProcessInsId()) .eq(ProjectProcess::getProcessDefId, query.getProcessDefId()) .list(); return Result.ok().data(list); } @Override public Result taskIsAuditing(String processDefinitionId, String taskId) { Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); Collection processes = bpmnModel.getProcesses(); Boolean needAuditing = Boolean.FALSE; for (Process process : processes) { Collection flowElements = process.getFlowElements(); for (FlowElement flowElement : flowElements) { if (flowElement instanceof UserTask && flowElement.getId().equals(task.getTaskDefinitionKey())) { UserTask userTask = (UserTask) flowElement; needAuditing = taskCommonService.checkHasExeProperty(userTask.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_NEED_AUDITING_TEXT); break; } } } return Result.ok().data(needAuditing); } @Override public Result taskDelegation(TaskDelegationForm form) { Task task = taskService.createTaskQuery().taskId(form.getTaskId()).singleResult(); if (Objects.isNull(task)) { throw new RuntimeException("未在运行任务中找到该任务,无法执行转办操作"); } List identityLinksForTask = taskService.getIdentityLinksForTask(task.getId()); // 转办之前的处理人 List beforeHandlerIds = new ArrayList<>(2); // 转办之前的处理人类型 HandlerTypeEnum beforeHandlerType = null; // 需要先移除之前的处理人 for (IdentityLinkInfo identityLink : identityLinksForTask) { if (StringUtils.isNotBlank(identityLink.getUserId())) { beforeHandlerIds.add(identityLink.getUserId()); beforeHandlerType = HandlerTypeEnum.USER; if (IdentityLinkType.ASSIGNEE.equals(identityLink.getType())) { taskService.deleteUserIdentityLink(task.getId(), identityLink.getUserId(), IdentityLinkType.ASSIGNEE); } else { taskService.deleteCandidateUser(task.getId(), identityLink.getUserId()); } } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { beforeHandlerIds.add(identityLink.getGroupId()); if (identityLink.getGroupId().contains("dept")) { beforeHandlerType = HandlerTypeEnum.DEPT; } else { beforeHandlerType = HandlerTypeEnum.ROLE; } // 从候选组中删除这个组,便不能申领执行任务了 taskService.deleteCandidateGroup(task.getId(), identityLink.getGroupId()); } } DelegateData jsonData = new DelegateData(); jsonData.setBeforeHandlerIds(beforeHandlerIds); jsonData.setBeforeHandlerType(beforeHandlerType); List afterHandlerIds = new ArrayList<>(2); // 再新增处理人 switch (form.getPeopleType()) { case FIX_USER: // 指定用户的话,只能选一个用户 taskService.setAssignee(task.getId(), form.getTargetId()); afterHandlerIds.add(form.getTargetId()); break; case USER: // 用户组的话,可以选多个用户 String[] userList = form.getTargetId().split(","); for (String userId : userList) { taskService.addCandidateUser(task.getId(), userId); } afterHandlerIds.addAll(List.of(userList)); break; case DEPT: String[] deptList = form.getTargetId().split(","); for (String deptId : deptList) { // 添加候选组,便可以申领执行任务了 taskService.addCandidateGroup(task.getId(), deptId); } List deptIds = Arrays.stream(deptList).map(id -> { // 因为部门的id是加了 dept:前缀的,用于区分部门和角色这两个组的概念 String[] split = id.split(":"); return split[1]; }).collect(Collectors.toList()); afterHandlerIds.addAll(deptIds); break; case ROLE: String[] roleList = form.getTargetId().split(","); for (String roleId : roleList) { taskService.addCandidateGroup(task.getId(), roleId); } afterHandlerIds.addAll(List.of(roleList)); break; default: break; } jsonData.setAfterHandlerIds(afterHandlerIds); jsonData.setAfterHandlerType(form.getPeopleType()); // 发布转办事件 publisher.publishEvent(new TaskLogEvent(this, null, SecurityUtils.getUserId(), form.getProjectId(), form.getProcessInsId(), task.getId(), task.getTaskDefinitionKey(), task.getName(), ProcessLogEventTypeEnum.DELEGATE, jsonData)); return Result.ok("转办成功"); } @Override @Transactional(rollbackFor = Exception.class) public Result taskJump(TaskJumpForm form) { Task task = taskService.createTaskQuery().taskId(form.getTaskId()).processInstanceId(form.getProcessInsId()).singleResult(); if (Objects.nonNull(task)) { // 添加跳过日志 publisher.publishEvent(new TaskLogEvent(this, null, SecurityUtils.getUserId(), form.getProjectId(), form.getProcessInsId(), task.getId(), task.getTaskDefinitionKey(), task.getName(), ProcessLogEventTypeEnum.JUMP, new JumpData(form.getDesc()))); // 查出该任务绑定的表单 Map data = new HashMap<>(1); if (StringUtils.isNotBlank(task.getFormKey())) { SysForm sysForm = formService.selectSysFormById(Long.parseLong(task.getFormKey())); if (Objects.nonNull(sysForm)) { data.put(ProcessConstants.TASK_FORM_KEY, JSONObject.parseObject(sysForm.getFormContent())); } } // 完成任务 flowTaskService.completeSubmitForm(form.getTaskId(), data, Boolean.FALSE); } return Result.ok("操作成功"); } @Override public Result taskWait(TaskWaitForm form) { Task task = taskService.createTaskQuery().taskId(form.getTaskId()).processInstanceId(form.getProcessInsId()).singleResult(); if (Objects.nonNull(task)) { // 添加容缺日志 publisher.publishEvent(new TaskLogEvent(this, null, SecurityUtils.getUserId(), form.getProjectId(), form.getProcessInsId(), task.getId(), task.getTaskDefinitionKey(), task.getName(), ProcessLogEventTypeEnum.WAIT, new WaitData(form.getDesc()))); // 查出该任务绑定的表单 Map data = new HashMap<>(1); if (StringUtils.isNotBlank(task.getFormKey())) { SysForm sysForm = formService.selectSysFormById(Long.parseLong(task.getFormKey())); if (Objects.nonNull(sysForm)) { data.put(ProcessConstants.TASK_FORM_KEY, JSONObject.parseObject(sysForm.getFormContent())); } } // 完成任务 flowTaskService.completeSubmitForm(form.getTaskId(), data, Boolean.FALSE); } return Result.ok("操作成功"); } @Override public Result taskSupervise(TaskSuperviseForm form) { Task task = taskService.createTaskQuery().taskId(form.getTaskId()).singleResult(); if (Objects.isNull(task)) { throw new RuntimeException("任务不存在"); } SuperviseData jsonData = new SuperviseData(); jsonData.setCreateTime(new Date()); jsonData.setContent(form.getContent()); jsonData.setSenderId(SecurityUtils.getUserId() + ""); jsonData.setSenderType(HandlerTypeEnum.USER); jsonData.setReceiverIds(form.getReceiverIds()); jsonData.setReceiverType(form.getReceiverType()); jsonData.setSuperviseType(form.getSuperviseType()); ProcessLog processLog = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getTaskId, form.getTaskId()) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.SUPERVISE) .eq(ProcessLog::getProcessInsId, task.getProcessInstanceId()) .one(); List dataList; if (processLog != null) { String eventDataJson = processLog.getEventDataJson(); dataList = JSONArray.parseArray(eventDataJson, SuperviseData.class); } else { processLog = new ProcessLog(); processLog.setUserId(SecurityUtils.getUserId()); dataList = new ArrayList<>(); } dataList.add(jsonData); //添加督办日志 publisher.publishEvent(new TaskLogEvent(this, processLog.getId(), processLog.getUserId(), form.getProjectId(), task.getProcessInstanceId(), form.getTaskId(), task.getTaskDefinitionKey(), task.getName(), ProcessLogEventTypeEnum.SUPERVISE, dataList)); return Result.ok("操作成功"); } @Override @Synchronized public Result taskHangup(TaskHangupForm form) { Task task = taskService.createTaskQuery().taskId(form.getTaskId()).singleResult(); if (Objects.isNull(task)) { throw new RuntimeException("任务不存在"); } List logs = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getTaskId, form.getTaskId()) .eq(ProcessLog::getProcessInsId, form.getProcessInsId()) .eq(ProcessLog::getProjectId, form.getProjectId()) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.HANGUP, ProcessLogEventTypeEnum.CANCEL_HANGUP) .list(); if (logs.size() % 2 != 0) { throw new RuntimeException("该任务正在挂起中,不能再次挂起"); } // 任务挂起只需要存日志,查询待办时如果有这个日志记录,则禁用提交按钮,以此实现任务挂起 publisher.publishEvent(new TaskLogEvent(this, null, SecurityUtils.getUserId(), form.getProjectId(), form.getProcessInsId(), form.getTaskId(), task.getTaskDefinitionKey(), task.getName(), ProcessLogEventTypeEnum.HANGUP, new HangupData(form.getReason()) )); return Result.ok("操作成功"); } @Override @Synchronized public Result cancelTaskHangup(TaskHangupForm form) { Task task = taskService.createTaskQuery().taskId(form.getTaskId()).singleResult(); if (Objects.isNull(task)) { throw new RuntimeException("任务不存在"); } List logs = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getTaskId, form.getTaskId()) .eq(ProcessLog::getProcessInsId, form.getProcessInsId()) .eq(ProcessLog::getProjectId, form.getProjectId()) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.HANGUP, ProcessLogEventTypeEnum.CANCEL_HANGUP) .list(); if (logs.size() % 2 == 0) { throw new RuntimeException("该任务未被挂起,不能取消挂起"); } publisher.publishEvent(new TaskLogEvent(this, null, SecurityUtils.getUserId(), form.getProjectId(), form.getProcessInsId(), form.getTaskId(), task.getTaskDefinitionKey(), task.getName(), ProcessLogEventTypeEnum.CANCEL_HANGUP, new HangupData(form.getReason()) )); return Result.ok("操作成功"); } @Override public Result taskTeamwork(TaskTeamWorkForm form) { Task task = taskService.createTaskQuery().taskId(form.getTaskId()).singleResult(); if (Objects.isNull(task)) { return Result.error("任务不存在"); } ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(projectProcessMapper) .eq(ProjectProcess::getProcessInsId, task.getProcessInstanceId()) .eq(ProjectProcess::getProcessDefId, task.getProcessDefinitionId()) .one(); if (Objects.isNull(projectProcess)) { return Result.error("项目流程未绑定"); } // 1. 保存发起人填写的表单数据,但不直接完成该任务。提交后任务处理人必须等到协同人处理完之后才能完成任务 Map processVariables = new HashMap<>(); //查出字典中需要注入的字段信息 List dictList = dictTypeService.selectDictDataByType("flow_variables").stream().map(SysDictData::getDictValue).collect(Collectors.toList()); Map newV = new HashMap<>(2); if (!org.springframework.util.CollectionUtils.isEmpty(form.getVariables())) { for (String key : form.getVariables().keySet()) { newV.put(task.getTaskDefinitionKey() + "&" + key, form.getVariables().get(key)); //字典里有就放入流程变量中 if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(dictList) && dictList.contains(key)) { processVariables.put(key, form.getVariables().get(key)); } } } if (!processVariables.isEmpty()) { taskService.setVariables(form.getTaskId(), processVariables); } // 2. 保存日志 publisher.publishEvent(new TaskLogEvent(this, null, SecurityUtils.getUserId(), form.getProjectId(), form.getProcessInsId(), form.getTaskId(), task.getTaskDefinitionKey(), task.getName(), ProcessLogEventTypeEnum.TEAM_WORK, new TeamWorkData(form.getHandlerType(), form.getHandlerIds(), TeamWorkStatusEnum.NOT_FINISHED) )); return Result.ok("操作成功"); } @Override public Result getProcessMsg(AbsQuery q) { // 查自己的日志 ProcessLogQuery query = new ProcessLogQuery(); if (! SecurityUtils.isAdmin(SecurityUtils.getUserId())) { query.setUserId(SecurityUtils.getUserId()); } query.setEventTypeList(Arrays.asList(ProcessLogEventTypeEnum.DELEGATE.getValue(), ProcessLogEventTypeEnum.REJECT.getValue(), ProcessLogEventTypeEnum.JUMP.getValue(), ProcessLogEventTypeEnum.FINISHED.getValue(), ProcessLogEventTypeEnum.WAIT.getValue())); query.setCurrentPage(q.getCurrentPage()); query.setPageSize(q.getPageSize()); Result result = processLogService.projectProcessLogPage(query); List logs = (List) result.get("data"); logs.stream().forEach(log -> { if (ProcessLogEventTypeEnum.FINISHED.equals(log.getEventType())) { log.setContent("您完成了任务:" + log.getTaskName()); } else if (ProcessLogEventTypeEnum.REJECT.equals(log.getEventType())) { log.setContent("您驳回了任务:" + log.getTaskName()); } else if (ProcessLogEventTypeEnum.WAIT.equals(log.getEventType())) { log.setContent("您容缺了任务:" + log.getTaskName()); } else if (ProcessLogEventTypeEnum.JUMP.equals(log.getEventType())) { log.setContent("您跳过了任务:" + log.getTaskName()); } }); return Result.ok().data(logs).total((Long) result.get("total")); } /** * 查询待办任务 * * @param projectId * @param processInsId * @param taskName * @param pageSize * @param pageNum * @param result */ public void getTodoTaskList(String projectId, String processInsId, String taskName, int pageSize, int pageNum, Result result) { TaskQuery taskQuery = taskService.createTaskQuery() .active() .processInstanceId(processInsId) .includeProcessVariables() .orderByTaskCreateTime() .desc(); if (StringUtils.isNotBlank(taskName)) { taskQuery.taskNameLike(taskName); } result.total(taskQuery.count()); List taskList = taskQuery.listPage(pageSize * (pageNum - 1), pageSize); List vos = new ArrayList<>(); for (Task task : taskList) { CustomerTaskVO taskVO = new CustomerTaskVO(); this.setRuntimeTaskInfo(task, taskVO, projectId); // 检查是否挂起 if (processLogService.taskIsHangup(task.getId(), task.getProcessInstanceId())) { taskVO.setTaskStatus(TaskStatusEnum.HANGUP); } vos.add(taskVO); } result.put("taskList", vos); } /** * 获取所有任务 * * @param projectId 项目id * @param processDefinitionId 流程运行id * @param processInsId 流程实例id * @param pageNum * @param pageSize * @param result * @return */ private List getAllUserTask(String projectId, String processDefinitionId, String processInsId, String taskName, Integer pageNum, Integer pageSize, Result result) { int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; List allUserTaskElement = this.getAllUserTaskElement(processDefinitionId); if (startNum >= allUserTaskElement.size()) { // 如果起始索引超出了列表的大小,返回一个空列表 return new ArrayList<>(); } if (StringUtils.isNotBlank(taskName)) { // 模拟模糊查询 allUserTaskElement = allUserTaskElement.stream().filter(taskEl -> taskEl.getName().contains(taskName)).collect(Collectors.toList()); } result.total(allUserTaskElement.size()); int end = Math.min(endNum, allUserTaskElement.size()); List userTasks = allUserTaskElement.subList(startNum, end); // 查出流程 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(processInsId).singleResult(); if (Objects.isNull(process)) { // 如果运行时找不到说明是已完成的流程,直接查历史任务 List vos = this.getFinishedProcessTaskInfo(userTasks, projectId, processInsId, processDefinitionId); result.data(vos); return vos; } // 判断任务状态 List vos = userTasks.stream().map(userTask -> { CustomerTaskVO vo = new CustomerTaskVO(); vo.setProcessInsId(process.getId()); vo.setProcessDefId(processDefinitionId); vo.setDeployId(process.getDeploymentId()); vo.setTaskName(userTask.getName()); vo.setProcessName(process.getProcessDefinitionName()); Task task = taskService.createTaskQuery() .processInstanceId(process.getId()) .taskDefinitionKey(userTask.getId()) .singleResult(); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); vo.setHandlerId(handlerIds); vo.setHandlerName(handlerNames); vo.setHandlerUnitId(handlerUnitIds); vo.setHandlerUnitName(handlerUnitNames); vo.setPromoterName(promoterNames); vo.setPromoterUnitName(promoterUnitNames); this.setCandidateInfo(userTask, vo, projectId, processInsId); if (Objects.isNull(task)) { // 如果任务在运行时没找到,那么可能为未开始或者已完成,需要从历史任务中再找一下 List historicTasks = historyService.createHistoricTaskInstanceQuery() .processInstanceId(process.getProcessInstanceId()) .taskDefinitionKey(userTask.getId()) .includeIdentityLinks() .orderByHistoricTaskInstanceStartTime() .desc() .list(); if (CollectionUtils.isEmpty(historicTasks)) { // 未开始的任务,其关联的用户组这些都可以从UserTask中拿到,因为本身未开始的任务是没有task的,所以这里直接查 if (StringUtils.isNotBlank(userTask.getAssignee())) { vo.setHandlerType(HandlerTypeEnum.USER); SysUser sysUser = sysUserService.selectUserById(Long.parseLong(userTask.getAssignee())); if (Objects.nonNull(sysUser)) { vo.getHandlerId().add(sysUser.getUserId()); vo.getHandlerName().add(this.getUserShowName(sysUser)); if (Objects.nonNull(sysUser.getDept())) { vo.getHandlerUnitId().add(sysUser.getDept().getDeptId()); vo.getHandlerUnitName().add(sysUser.getDept().getDeptName()); } } } else if (CollectionUtil.isNotEmpty(userTask.getCandidateGroups())) { List groupIds = userTask.getCandidateGroups(); for (String groupId : groupIds) { // 处理变量表达式,DATA_LAUNCH只可能是部门不会是角色,因为代表的是业主部门 if (groupId.contains(ProcessConstants.DATA_LAUNCH)) { vo.setHandlerType(HandlerTypeEnum.DEPT); this.varYzReview(vo, projectId, processInsId, HandlerTypeEnum.DEPT, 1); } else if (groupId.startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 vo.setHandlerType(HandlerTypeEnum.DEPT); String[] split = groupId.split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { vo.getHandlerUnitId().add(dept.getDeptId()); vo.getHandlerUnitName().add(dept.getDeptName()); vo.getHandlerName().add(this.getDeptLeaderShowName(dept)); } } } else { vo.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(groupId)); if (Objects.nonNull(role)) { vo.getHandlerUnitId().add(role.getRoleId()); vo.getHandlerUnitName().add(role.getRoleName()); } } } } vo.setTaskStatus(TaskStatusEnum.NOT_START); } else { vo.setTaskStatus(TaskStatusEnum.FINISHED); // 如果是已完成的,信息需要单独赋值 vo.setTaskId(historicTasks.get(0).getId()); vo.setExecutionId(historicTasks.get(0).getExecutionId()); vo.setCreateTime(historicTasks.get(0).getStartTime()); // 查询实际处理人 if (StringUtils.isNotBlank(historicTasks.get(0).getAssignee())) { long handlerUserId = Long.parseLong(historicTasks.get(0).getAssignee()); SysUser handlerUser = sysUserService.selectUserById(handlerUserId); if (Objects.nonNull(handlerUser)) { vo.getHandlerId().add(handlerUserId); vo.getHandlerName().add(this.getUserShowName(handlerUser)); if (Objects.nonNull(handlerUser.getDept())) { vo.getHandlerUnitName().add(handlerUser.getDept().getDeptName()); vo.getHandlerUnitId().add(handlerUser.getDept().getDeptId()); } } } vo.setTaskDefinitionKey(historicTasks.get(0).getTaskDefinitionKey()); } } else { vo.setTaskStatus(TaskStatusEnum.TODO); vo.setTaskId(task.getId()); vo.setExecutionId(task.getExecutionId()); vo.setCreateTime(task.getCreateTime()); vo.setTaskDefinitionKey(task.getTaskDefinitionKey()); this.setHandler(vo, null); this.setRuntimeTaskInfo(task, vo, projectId); } this.distinctVo(vo); return vo; }).collect(Collectors.toList()); result.data(vos); return vos; } /** * 查询已完成的流程的任务信息 * * @param userTasks 任务节点列表 * @param processInsId 流程实例id * @param processDefId 流程定义id * @return */ private List getFinishedProcessTaskInfo(List userTasks, String projectId, String processInsId, String processDefId) { HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInsId).singleResult(); if (Objects.isNull(hisProcess)) { return new ArrayList<>(); } List vos = userTasks.stream().map(userTask -> { CustomerTaskVO vo = new CustomerTaskVO(); vo.setProcessInsId(hisProcess.getId()); vo.setProcessDefId(processDefId); vo.setDeployId(hisProcess.getDeploymentId()); vo.setTaskName(userTask.getName()); vo.setProcessName(hisProcess.getProcessDefinitionName()); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); vo.setHandlerId(handlerIds); vo.setHandlerName(handlerNames); vo.setHandlerUnitId(handlerUnitIds); vo.setHandlerUnitName(handlerUnitNames); vo.setPromoterName(promoterNames); vo.setPromoterUnitName(promoterUnitNames); this.setCandidateInfo(userTask, vo, projectId, processInsId); // 查多个是因为驳回后会查出两条及以上,取最新一条 List hisTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(hisProcess.getId()) .taskDefinitionKey(userTask.getId()).includeIdentityLinks() .orderByHistoricTaskInstanceStartTime() .desc() .list(); // 如果未找到历史任务,说明这个任务可能处于某个互斥网关下,实际并未执行 if (CollectionUtils.isEmpty(hisTaskList)) { vo.setTaskStatus(TaskStatusEnum.NOT_START); } else { vo.setTaskStatus(TaskStatusEnum.FINISHED); // 如果是已完成的,信息需要单独赋值 vo.setTaskId(hisTaskList.get(0).getId()); vo.setExecutionId(hisTaskList.get(0).getExecutionId()); vo.setCreateTime(hisTaskList.get(0).getStartTime()); // 查询实际处理人 if (StringUtils.isNotBlank(hisTaskList.get(0).getAssignee())) { long handlerUserId = Long.parseLong(hisTaskList.get(0).getAssignee()); SysUser handlerUser = sysUserService.selectUserById(handlerUserId); if (Objects.nonNull(handlerUser)) { vo.setActualHandlerUserId(hisTaskList.get(0).getAssignee()); vo.setActualHandlerUserName(handlerUser.getNickName()); } } vo.setTaskDefinitionKey(hisTaskList.get(0).getTaskDefinitionKey()); this.setHandler(vo, hisTaskList.get(0).getIdentityLinks()); } return vo; }).filter(Objects::nonNull).collect(Collectors.toList()); return vos; } /** * 设置运行时任务的信息 * * @param task 任务 * @param taskVO 任务vo * @param projectId 项目id */ private void setRuntimeTaskInfo(Task task, CustomerTaskVO taskVO, String projectId) { // 当前流程信息 taskVO.setTaskId(task.getId()); taskVO.setCreateTime(task.getCreateTime()); taskVO.setProcessDefId(task.getProcessDefinitionId()); taskVO.setExecutionId(task.getExecutionId()); taskVO.setTaskName(task.getName()); taskVO.setTaskStatus(TaskStatusEnum.TODO); // 流程定义信息 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); String deployId = ""; String processName = ""; if (Objects.nonNull(process)) { deployId = process.getDeploymentId(); processName = process.getProcessDefinitionName(); } else { HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); deployId = hisProcess.getDeploymentId(); processName = hisProcess.getProcessDefinitionName(); } taskVO.setDeployId(deployId); taskVO.setProcessName(processName); taskVO.setProcessInsId(task.getProcessInstanceId()); taskVO.setTaskDefinitionKey(task.getTaskDefinitionKey()); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); taskVO.setHandlerId(handlerIds); taskVO.setHandlerName(handlerNames); taskVO.setHandlerUnitId(handlerUnitIds); taskVO.setHandlerUnitName(handlerUnitNames); taskVO.setPromoterName(promoterNames); taskVO.setPromoterUnitName(promoterUnitNames); // 流程处理人信息 List identityLinksForTask = taskService.getIdentityLinksForTask(task.getId()); for (IdentityLinkInfo identityLink : identityLinksForTask) { // 绑定的是用户,查出用户姓名、部门 if (StringUtils.isNotBlank(identityLink.getUserId())) { // 处理变量表达式,运行中的任务无需再处理表达式了,flowable已经自动根据变量设置了 // if (identityLink.getUserId().contains(ProcessConstants.DATA_LAUNCH)) { // this.varReview(taskVO, projectId, task.getProcessInstanceId()); // continue; // } taskVO.setHandlerType(HandlerTypeEnum.USER); SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); if (Objects.nonNull(sysUser)) { taskVO.getHandlerId().add(sysUser.getUserId()); taskVO.getHandlerName().add(this.getUserShowName(sysUser)); if (Objects.nonNull(sysUser.getDept())) { taskVO.getHandlerUnitId().add(sysUser.getDept().getDeptId()); taskVO.getHandlerUnitName().add(sysUser.getDept().getDeptName()); taskVO.getPromoterName().add(this.getUserShowName(sysUser)); // if (sysUser.getDept().getAncestors()) String[] str = sysUser.getDept().getAncestors().split(","); if (str.length >= 4){ taskVO.getPromoterUnitName().add(sysUser.getDept().getParentName() +"-"+sysUser.getDept().getDeptName()); }else { taskVO.getPromoterUnitName().add(sysUser.getDept().getDeptName()); } } } // 绑定的是角色或者部门 } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { if (identityLink.getGroupId().startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 taskVO.setHandlerType(HandlerTypeEnum.DEPT); String[] split = identityLink.getGroupId().split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { taskVO.getHandlerUnitId().add(dept.getDeptId()); taskVO.getHandlerUnitName().add(dept.getDeptName()); taskVO.getPromoterName().add(this.getDeptLeaderShowName(dept)); taskVO.getPromoterUnitName().add(this.setDeptNameWithParentName(dept)); } } } else { taskVO.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); if (Objects.nonNull(role)) { taskVO.getHandlerUnitId().add(Long.parseLong(identityLink.getGroupId())); taskVO.getHandlerUnitName().add(role.getRoleName()); } } } this.distinctVo(taskVO); } } /** * 统计按时完成的任务 * * @param processInsId 流程实例id * @return */ private Long getTimelyTaskNum(String processInsId) { // 查出已完成的任务key HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInsId) .finished() .includeIdentityLinks() .orderByTaskCreateTime() .desc(); List hisTaskList = query.list(); if (CollectionUtils.isEmpty(hisTaskList)) { return 0L; } hisTaskList = this.distinctHisTask(hisTaskList); // 排除跳过、容缺的任务,因为这两个操作都会完成任务而产生历史任务 List jumpAndWaitTaskKeys = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.JUMP, ProcessLogEventTypeEnum.WAIT) // TODO 如果运行时任务正好是被驳回的,需要想办法排除调被驳回的任务,不能直接在这加 ProcessLogEventTypeEnum.REJECT .list().stream().map(ProcessLog::getTaskDefKey).collect(Collectors.toList()); List runtimeTaskKey = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); jumpAndWaitTaskKeys.addAll(runtimeTaskKey); hisTaskList = hisTaskList.stream().filter(hisTask -> jumpAndWaitTaskKeys.indexOf(hisTask.getTaskDefinitionKey()) == -1).collect(Collectors.toList()); List hisTaskKeys = hisTaskList.stream().map(HistoricTaskInstance::getTaskDefinitionKey).distinct().collect(Collectors.toList()); Map hisTaskMap = hisTaskList.stream().collect(Collectors.toMap(HistoricTaskInstance::getTaskDefinitionKey, his -> his)); // 查出时间正常的任务key List codeList = new LambdaQueryChainWrapper<>(processCodingService.getBaseMapper()) .eq(ProcessCoding::getProcessInsId, processInsId) .in(ProcessCoding::getTaskDefKey, hisTaskKeys) .list(); List finishedTaskList = new ArrayList<>(); // 判断 for (String key : hisTaskMap.keySet()) { List targetProcessCodings = codeList.stream().filter(code -> key.equals(code.getTaskDefKey())).collect(Collectors.toList()); // 如果已完成的任务没从数据库查找出来,说明该任务没配置赋码等时间,直接设置为按时完成 if (CollectionUtils.isEmpty(targetProcessCodings)) { finishedTaskList.add(hisTaskMap.get(key)); } else { // 按照时间降序排列 targetProcessCodings.sort(Comparator.comparing(ProcessCoding::getGmtCreate).reversed()); ProcessCoding latestProjectProcess = targetProcessCodings.get(0); if (ProcessOverTimeConstants.NORMAL.equals(latestProjectProcess.getOvertimeStatus()) || StringUtils.isBlank(latestProjectProcess.getOvertimeStatus())) { finishedTaskList.add(hisTaskMap.get(key)); } } } return Long.valueOf(finishedTaskList.size()); } /** * 查询按时完成的任务 * * @param processDefinitionId 流程定义id * @param processInsId 流程实例id * @param taskName 任务名称--搜索条件 * @param pageNum * @param pageSize * @param result * @return */ private List getTimelyTask(String projectId, String processDefinitionId, String processInsId, String taskName, Integer pageNum, Integer pageSize, Result result) { int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; // 查出已完成的任务key HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInsId) .finished() .includeIdentityLinks() .orderByTaskCreateTime() .desc(); if (StringUtils.isNotBlank(taskName)) { query.taskNameLike(taskName); } List hisTaskList = query.list(); if (CollectionUtils.isEmpty(hisTaskList)) { result.total(0); return new ArrayList<>(); } hisTaskList = this.distinctHisTask(hisTaskList); // 排除跳过、容缺的任务,因为这两个操作都会完成任务而产生历史任务 List jumpAndWaitTaskKeys = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .eq(ProcessLog::getProjectId, projectId) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.JUMP, ProcessLogEventTypeEnum.WAIT) .list().stream().map(ProcessLog::getTaskDefKey).collect(Collectors.toList()); List runtimeTaskKey = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); jumpAndWaitTaskKeys.addAll(runtimeTaskKey); hisTaskList = hisTaskList.stream().filter(hisTask -> jumpAndWaitTaskKeys.indexOf(hisTask.getTaskDefinitionKey()) == -1).collect(Collectors.toList()); List hisTaskKeys = hisTaskList.stream().map(HistoricTaskInstance::getTaskDefinitionKey).distinct().collect(Collectors.toList()); Map hisTaskMap = hisTaskList.stream().collect(Collectors.toMap(HistoricTaskInstance::getTaskDefinitionKey, his -> his)); // 查出时间正常的任务key List codeList = new LambdaQueryChainWrapper<>(processCodingService.getBaseMapper()) .eq(ProcessCoding::getProcessInsId, processInsId) .in(ProcessCoding::getTaskDefKey, hisTaskKeys) .list(); List finishedTaskList = new ArrayList<>(); // 判断 for (String key : hisTaskMap.keySet()) { List targetProcessCodings = codeList.stream().filter(code -> key.equals(code.getTaskDefKey())).collect(Collectors.toList()); // 如果已完成的任务没从数据库查找出来,说明该任务没配置赋码等时间,直接设置为按时完成 if (CollectionUtils.isEmpty(targetProcessCodings)) { finishedTaskList.add(hisTaskMap.get(key)); } else { // 按照时间降序排列 targetProcessCodings.sort(Comparator.comparing(ProcessCoding::getGmtCreate).reversed()); ProcessCoding latestProjectProcess = targetProcessCodings.get(0); if (ProcessOverTimeConstants.NORMAL.equals(latestProjectProcess.getOvertimeStatus()) || StringUtils.isBlank(latestProjectProcess.getOvertimeStatus())) { finishedTaskList.add(hisTaskMap.get(key)); } } } if (startNum >= finishedTaskList.size()) { // 如果起始索引超出了列表的大小,返回一个空列表 return new ArrayList<>(); } result.total(finishedTaskList.size()); int end = Math.min(endNum, finishedTaskList.size()); List pageFinishedTaskList = finishedTaskList.subList(startNum, end); List taskDefs = pageFinishedTaskList.stream().map(HistoricTaskInstance::getTaskDefinitionKey).collect(Collectors.toList()); Map keyMap = pageFinishedTaskList.stream().collect(Collectors.toMap(HistoricTaskInstance::getTaskDefinitionKey, his -> his)); // 得到目标任务对应的定义 List finishedUserTaskElement = this.getAllUserTaskElement(processDefinitionId).stream().filter(el -> taskDefs.contains(el.getId())).collect(Collectors.toList()); // 查出流程 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(processInsId).singleResult(); String deployId = ""; String processName = ""; if (Objects.nonNull(process)) { deployId = process.getDeploymentId(); processName = process.getProcessDefinitionName(); } else { HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInsId).singleResult(); deployId = hisProcess.getDeploymentId(); processName = hisProcess.getProcessDefinitionName(); } String finalDeployId = deployId; String finalProcessName = processName; List vos = finishedUserTaskElement.stream().map(userTask -> { CustomerTaskVO vo = new CustomerTaskVO(); vo.setProcessInsId(processInsId); vo.setProcessDefId(processDefinitionId); vo.setDeployId(finalDeployId); vo.setTaskName(userTask.getName()); vo.setProcessName(finalProcessName); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); vo.setHandlerId(handlerIds); vo.setHandlerName(handlerNames); vo.setHandlerUnitId(handlerUnitIds); vo.setHandlerUnitName(handlerUnitNames); vo.setPromoterName(promoterNames); vo.setPromoterUnitName(promoterUnitNames); this.setCandidateInfo(userTask, vo, projectId, processInsId); HistoricTaskInstance hisTask = keyMap.get(userTask.getId()); if (Objects.nonNull(hisTask)) { vo.setTaskStatus(TaskStatusEnum.FINISHED); // 如果是已完成的,信息需要单独赋值 vo.setTaskId(hisTask.getId()); vo.setExecutionId(hisTask.getExecutionId()); vo.setCreateTime(hisTask.getStartTime()); // 查询实际处理人 if (StringUtils.isNotBlank(hisTask.getAssignee())) { long handlerUserId = Long.parseLong(hisTask.getAssignee()); SysUser handlerUser = sysUserService.selectUserById(handlerUserId); if (Objects.nonNull(handlerUser)) { vo.getHandlerId().add(handlerUserId); vo.getHandlerName().add(this.getUserShowName(handlerUser)); if (Objects.nonNull(handlerUser.getDept())) { vo.getHandlerUnitId().add(handlerUser.getDept().getDeptId()); vo.getHandlerUnitName().add(handlerUser.getDept().getDeptName()); } } } vo.setTaskDefinitionKey(hisTask.getTaskDefinitionKey()); } this.distinctVo(vo); return vo; }).collect(Collectors.toList()); result.data(vos); return vos; } /** * 用户名称后面跟电话号码 * * @param user * @return */ private String getUserShowName(SysUser user) { return user.getNickName() + (StringUtils.isNotBlank(user.getPhonenumber()) ? "(" + user.getPhonenumber() + ")" : ""); } /** * 部门负责人名称后面跟电话号码 * * @param dept * @return */ private String getDeptLeaderShowName(SysDept dept) { return dept.getLeader() + (StringUtils.isNotBlank(dept.getPhone()) ? "(" + dept.getPhone() + ")" : ""); } /** * 根据任务key去重历史任务,相同情况下取最新的一条 * * @param hisTaskList * @return */ private List distinctHisTask(List hisTaskList) { Map uniqueTasks = new HashMap<>(); for (HistoricTaskInstance task : hisTaskList) { String taskDefinitionKey = task.getTaskDefinitionKey(); HistoricTaskInstance existingTask = uniqueTasks.get(taskDefinitionKey); // 如果任务key重复(可能被驳回过,重新提交导致key重复),取最近的一条 if (existingTask == null || task.getCreateTime().after(existingTask.getCreateTime())) { uniqueTasks.put(taskDefinitionKey, task); } } // 最终去重后的任务列表 return new ArrayList<>(uniqueTasks.values()); } /** * 统计超时的任务数 * * @param processInsId 流程实例id * @return */ private Long getOvertimeTaskNum(String processInsId) { // 查出运行在的任务key List taskList = taskService.createTaskQuery().processInstanceId(processInsId).list(); if (CollectionUtils.isEmpty(taskList)) { return 0L; } List taskKeys = taskList.stream().map(Task::getTaskDefinitionKey).distinct().collect(Collectors.toList()); Map taskMap = taskList.stream().collect(Collectors.toMap(Task::getTaskDefinitionKey, his -> his)); // 查出数据库的任务key List codeList = new LambdaQueryChainWrapper<>(processCodingService.getBaseMapper()) .eq(ProcessCoding::getProcessInsId, processInsId) .in(ProcessCoding::getTaskDefKey, taskKeys) .list(); List tList = new ArrayList<>(); // 判断 for (String key : taskMap.keySet()) { List targetProcessCodings = codeList.stream().filter(code -> key.equals(code.getTaskDefKey())).collect(Collectors.toList()); // 如果已完成的任务没从数据库查找出来,说明该任务没配置赋码等时间,直接设置为按时完成 if (CollectionUtils.isEmpty(targetProcessCodings)) { tList.add(taskMap.get(key)); } else { // 按照时间降序排列 targetProcessCodings.sort(Comparator.comparing(ProcessCoding::getGmtCreate).reversed()); ProcessCoding latestProjectProcess = targetProcessCodings.get(0); if (Objects.nonNull(latestProjectProcess) && ProcessOverTimeConstants.OVERTIME.equals(latestProjectProcess.getOvertimeStatus())) { tList.add(taskMap.get(key)); } } } return Long.valueOf(taskList.size()); } /** * 查询超时的任务 * * @param projectId 项目id * @param processDefinitionId 流程定义id * @param processInsId 流程实例id * @param taskName 任务名称--搜索条件 * @param pageNum * @param pageSize * @param result * @return */ private List getOvertimeTask(String projectId, String processDefinitionId, String processInsId, String taskName, Integer pageNum, Integer pageSize, Result result) { int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; // 查出运行在的任务key List taskList = new ArrayList<>(12); if (StringUtils.isNotBlank(taskName)) { taskList = taskService.createTaskQuery().processInstanceId(processInsId).taskNameLike(taskName).orderByTaskCreateTime().desc().list(); } else { taskList = taskService.createTaskQuery().processInstanceId(processInsId).orderByTaskCreateTime().desc().list(); } if (CollectionUtils.isEmpty(taskList)) { result.total(0); return new ArrayList<>(); } List taskKeys = taskList.stream().map(Task::getTaskDefinitionKey).distinct().collect(Collectors.toList()); Map taskMap = taskList.stream().collect(Collectors.toMap(Task::getTaskDefinitionKey, his -> his)); // 查出数据库的任务key List codeList = new LambdaQueryChainWrapper<>(processCodingService.getBaseMapper()) .eq(ProcessCoding::getProcessInsId, processInsId) .in(ProcessCoding::getTaskDefKey, taskKeys) .list(); List tList = new ArrayList<>(); // 判断 for (String key : taskMap.keySet()) { List targetProcessCodings = codeList.stream().filter(code -> key.equals(code.getTaskDefKey())).collect(Collectors.toList()); // 如果已完成的任务没从数据库查找出来,说明该任务没配置赋码等时间,直接设置为按时完成 if (CollectionUtils.isEmpty(targetProcessCodings)) { tList.add(taskMap.get(key)); } else { // 按照时间降序排列 targetProcessCodings.sort(Comparator.comparing(ProcessCoding::getGmtCreate).reversed()); ProcessCoding latestProjectProcess = targetProcessCodings.get(0); if (Objects.nonNull(latestProjectProcess) && ProcessOverTimeConstants.OVERTIME.equals(latestProjectProcess.getOvertimeStatus())) { tList.add(taskMap.get(key)); } } } if (startNum >= tList.size()) { // 如果起始索引超出了列表的大小,返回一个空列表 return new ArrayList<>(); } result.total(tList.size()); int end = Math.min(endNum, tList.size()); List pageTaskList = tList.subList(startNum, end); List taskDefs = pageTaskList.stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); Map keyMap = pageTaskList.stream().collect(Collectors.toMap(Task::getTaskDefinitionKey, his -> his)); // 得到目标任务对应的定义 List finishedUserTaskElement = this.getAllUserTaskElement(processDefinitionId).stream().filter(el -> taskDefs.contains(el.getId())).collect(Collectors.toList()); // 查询任务相关信息 List vos = finishedUserTaskElement.stream().map(userTask -> { Task task = keyMap.get(userTask.getId()); CustomerTaskVO vo = new CustomerTaskVO(); this.setRuntimeTaskInfo(task, vo, projectId); return vo; }).collect(Collectors.toList()); result.data(vos); return vos; } /** * 统计即将超时的任务数 * * @param processInsId 流程实例id * @return */ private Long getWillOvertimeTaskNum(String processInsId) { // 查出运行在的任务key List taskList = taskService.createTaskQuery().processInstanceId(processInsId).list(); if (CollectionUtils.isEmpty(taskList)) { return 0L; } List taskKeys = taskList.stream().map(Task::getTaskDefinitionKey).distinct().collect(Collectors.toList()); Map taskMap = taskList.stream().collect(Collectors.toMap(Task::getTaskDefinitionKey, his -> his)); // 查出数据库的任务key List codeList = new LambdaQueryChainWrapper<>(processCodingService.getBaseMapper()) .eq(ProcessCoding::getProcessInsId, processInsId) .in(ProcessCoding::getTaskDefKey, taskKeys) .list(); List tList = new ArrayList<>(); // 判断 for (String key : taskMap.keySet()) { List targetProcessCodings = codeList.stream().filter(code -> key.equals(code.getTaskDefKey())).collect(Collectors.toList()); // 如果已完成的任务没从数据库查找出来,说明该任务没配置赋码等时间,直接设置为按时完成 if (CollectionUtils.isEmpty(targetProcessCodings)) { tList.add(taskMap.get(key)); } else { // 按照时间降序排列 targetProcessCodings.sort(Comparator.comparing(ProcessCoding::getGmtCreate).reversed()); ProcessCoding latestProjectProcess = targetProcessCodings.get(0); if (Objects.nonNull(latestProjectProcess) && ProcessOverTimeConstants.WILLOVERTIME.equals(latestProjectProcess.getOvertimeStatus())) { tList.add(taskMap.get(key)); } } } return Long.valueOf(tList.size()); } /** * 查询即将超时的任务 * * @param projectId 项目id * @param processDefinitionId 流程定义id * @param processInsId 流程实例id * @param taskName 任务名称--搜索条件 * @param pageNum * @param pageSize * @param result * @return */ private List getWillOvertimeTask(String projectId, String processDefinitionId, String processInsId, String taskName, Integer pageNum, Integer pageSize, Result result) { int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; // 查出运行在的任务key List taskList = new ArrayList<>(12); if (StringUtils.isNotBlank(taskName)) { taskList = taskService.createTaskQuery().processInstanceId(processInsId).taskNameLike(taskName).orderByTaskCreateTime().desc().list(); } else { taskList = taskService.createTaskQuery().processInstanceId(processInsId).orderByTaskCreateTime().desc().list(); } if (CollectionUtils.isEmpty(taskList)) { result.total(0); return new ArrayList<>(); } List taskKeys = taskList.stream().map(Task::getTaskDefinitionKey).distinct().collect(Collectors.toList()); Map taskMap = taskList.stream().collect(Collectors.toMap(Task::getTaskDefinitionKey, his -> his)); // 查出数据库的任务key List codeList = new LambdaQueryChainWrapper<>(processCodingService.getBaseMapper()) .eq(ProcessCoding::getProcessInsId, processInsId) .in(ProcessCoding::getTaskDefKey, taskKeys) .list(); List tList = new ArrayList<>(); // 判断 for (String key : taskMap.keySet()) { List targetProcessCodings = codeList.stream().filter(code -> key.equals(code.getTaskDefKey())).collect(Collectors.toList()); // 如果已完成的任务没从数据库查找出来,说明该任务没配置赋码等时间,直接设置为按时完成 if (CollectionUtils.isEmpty(targetProcessCodings)) { tList.add(taskMap.get(key)); } else { // 按照时间降序排列 targetProcessCodings.sort(Comparator.comparing(ProcessCoding::getGmtCreate).reversed()); ProcessCoding latestProjectProcess = targetProcessCodings.get(0); if (Objects.nonNull(latestProjectProcess) && ProcessOverTimeConstants.WILLOVERTIME.equals(latestProjectProcess.getOvertimeStatus())) { tList.add(taskMap.get(key)); } } } if (startNum >= tList.size()) { // 如果起始索引超出了列表的大小,返回一个空列表 return new ArrayList<>(); } result.total(tList.size()); int end = Math.min(endNum, tList.size()); List pageTaskList = tList.subList(startNum, end); List taskDefs = pageTaskList.stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); Map keyMap = pageTaskList.stream().collect(Collectors.toMap(Task::getTaskDefinitionKey, his -> his)); // 得到目标任务对应的定义 List finishedUserTaskElement = this.getAllUserTaskElement(processDefinitionId).stream().filter(el -> taskDefs.contains(el.getId())).collect(Collectors.toList()); // 查询任务相关信息 List vos = finishedUserTaskElement.stream().map(userTask -> { Task task = keyMap.get(userTask.getId()); CustomerTaskVO vo = new CustomerTaskVO(); this.setRuntimeTaskInfo(task, vo, projectId); return vo; }).collect(Collectors.toList()); result.data(vos); return vos; } @Override public void getIndexWaitTask(String s, int pageSize, int pageNum, Result result) { // 查出容缺过的任务 List allWaitTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.WAIT) .orderByDesc(ProcessLog::getGmtCreate) .list(); // 排除容缺后又完成的任务 List finishedTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.FINISHED) .list(); List finishedTaskIds = finishedTaskList.stream().map(ProcessLog::getTaskId).distinct().collect(Collectors.toList()); // 得到未完成的容缺任务 List waitTaskIds = allWaitTaskList.stream().filter(log -> !finishedTaskIds.contains(log.getTaskId())).map(ProcessLog::getTaskId).collect(Collectors.toList()); if (CollectionUtils.isEmpty(waitTaskIds)) { result.total(0l); result.data(new ArrayList<>()); return; } List hisTasks = waitTaskIds.stream().map(waitTaskId -> { List logs = allWaitTaskList.stream().filter(item -> item.getTaskId().equals(waitTaskId)).collect(Collectors.toList()); HistoricTaskInstance hisTask = null; if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(logs)) { // 容缺的任务都属于历史任务,只是需要补表单数据 HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery() .processInstanceId(logs.get(0).getProcessInsId()) .taskId(waitTaskId) .includeIdentityLinks() .orderByHistoricTaskInstanceStartTime() .desc(); if (!SecurityUtils.getLoginUser().getUser().isAdmin()) { query .or() .taskCandidateGroupIn(taskCommonService.getCurrentUserGroups()) .taskCandidateUser(SecurityUtils.getUserId() + "") .taskAssignee(SecurityUtils.getUserId() + "") .endOr(); } List hisTaskList = query.list(); hisTaskList = this.distinctHisTask(hisTaskList); if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(hisTaskList)) { hisTask = hisTaskList.get(0); } } return hisTask; }).filter(Objects::nonNull).collect(Collectors.toList()); if (CollectionUtils.isEmpty(hisTasks)) { result.total(0l); result.data(new ArrayList<>()); return; } int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; if (startNum >= hisTasks.size()) { result.total(0l); // 如果起始索引超出了列表的大小,返回一个空列表 result.data(new ArrayList<>()); return; } result.total(hisTasks.size()); int end = Math.min(endNum, hisTasks.size()); List targetTask = hisTasks.subList(startNum, end); // 转换成VO List vos = targetTask.stream().map(userTask -> { IndexCustomerTaskVO vo = new IndexCustomerTaskVO(); vo.setProcessInsId(userTask.getProcessInstanceId()); vo.setProcessDefId(userTask.getProcessDefinitionId()); // 查出流程 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(userTask.getProcessInstanceId()).singleResult(); String deployId = ""; String processName = ""; if (Objects.nonNull(process)) { deployId = process.getDeploymentId(); processName = process.getProcessDefinitionName(); } else { HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery().processInstanceId(userTask.getProcessInstanceId()).singleResult(); deployId = hisProcess.getDeploymentId(); processName = hisProcess.getProcessDefinitionName(); } String finalDeployId = deployId; String finalProcessName = processName; vo.setDeployId(finalDeployId); vo.setTaskName(userTask.getName()); vo.setProcessName(finalProcessName); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); vo.setHandlerId(handlerIds); vo.setHandlerName(handlerNames); vo.setHandlerUnitId(handlerUnitIds); vo.setHandlerUnitName(handlerUnitNames); vo.setPromoterName(promoterNames); vo.setPromoterUnitName(promoterUnitNames); ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(baseMapper) .eq(ProjectProcess::getProcessInsId, userTask.getProcessInstanceId()) .one(); if (Objects.isNull(projectProcess)) { throw new RuntimeException("项目流程未启动"); } String projectId = ""; String projectName = ""; if (Objects.nonNull(projectProcess)) { if (projectProcess.getProjectType().equals(ProjectProcessTypeEnum.PROJECT)) { ProjectInfo project = projectInfoMapper.selectById(projectProcess.getProjectId()); if (Objects.nonNull(project)) { projectId = projectProcess.getProjectId(); projectName = project.getProjectName(); } } else if (projectProcess.getProjectType().equals(ProjectProcessTypeEnum.ENGINEERING)) { ProjectEngineering engineering = projectEngineeringMapper.selectById(projectProcess.getProjectId()); if (Objects.nonNull(engineering)) { projectId = projectProcess.getProjectId(); projectName = engineering.getProjectName(); } } } vo.setProjectId(projectId); vo.setProjectName(projectName); List uTaskList = this.getAllUserTaskElement(userTask.getProcessDefinitionId()).stream().filter(item -> item.getId().equals(userTask.getTaskDefinitionKey())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(uTaskList)) { throw new RuntimeException("未找到流程任务设计"); } this.setCandidateInfo(uTaskList.get(0), vo, projectProcess.getProjectId(), userTask.getProcessInstanceId()); vo.setTaskStatus(TaskStatusEnum.WAIT); // 如果是已完成的,信息需要单独赋值 vo.setTaskId(userTask.getId()); vo.setExecutionId(userTask.getExecutionId()); vo.setCreateTime(userTask.getStartTime()); vo.setTaskDefinitionKey(userTask.getTaskDefinitionKey()); this.distinctVo(vo); return vo; }).collect(Collectors.toList()); result.data(vos); } /** * 获取跳过任务 * * @param processInsId * @return */ private Long getJumpTaskNum(String processInsId) { // 查出跳过的任务 List allJumpTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.JUMP) .orderByDesc(ProcessLog::getGmtCreate) .list(); // 排除驳回的 List rejectTaskIds = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .select(ProcessLog::getTaskId) .eq(ProcessLog::getProcessInsId, processInsId) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.REJECT) .orderByDesc(ProcessLog::getGmtCreate) .list().stream().map(ProcessLog::getTaskId).collect(Collectors.toList()); List jumpTaskIds = allJumpTaskList.stream().map(ProcessLog::getTaskId).collect(Collectors.toList()); jumpTaskIds.removeAll(rejectTaskIds); if(CollectionUtils.isEmpty(jumpTaskIds)) { return 0L; } List hisTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInsId) .finished() .taskIds(jumpTaskIds) .includeIdentityLinks() .orderByHistoricTaskInstanceStartTime() .desc() .list(); hisTaskList = this.distinctHisTask(hisTaskList); // 排除运行时任务 List runTaskKeys = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); hisTaskList = hisTaskList.stream().filter(his -> !runTaskKeys.contains(his.getTaskDefinitionKey())).collect(Collectors.toList()); return Long.valueOf(hisTaskList.size()); } /** * 获取跳过任务 * * @param projectId * @param processDefinitionId * @param processInsId * @param taskName * @param pageNum * @param pageSize * @param result * @return */ private List getJumpTask(String projectId, String processDefinitionId, String processInsId, String taskName, Integer pageNum, Integer pageSize, Result result) { // 查出跳过的任务 List allJumpTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.JUMP) .like(StringUtils.isNotBlank(taskName), ProcessLog::getTaskName, taskName) .orderByDesc(ProcessLog::getGmtCreate) .list(); // 排除驳回的 List rejectTaskIds = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .select(ProcessLog::getTaskId) .eq(ProcessLog::getProcessInsId, processInsId) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.REJECT) .like(StringUtils.isNotBlank(taskName), ProcessLog::getTaskName, taskName) .orderByDesc(ProcessLog::getGmtCreate) .list().stream().map(ProcessLog::getTaskId).collect(Collectors.toList()); List jumpTaskIds = allJumpTaskList.stream().map(ProcessLog::getTaskId).collect(Collectors.toList()); jumpTaskIds.removeAll(rejectTaskIds); if(CollectionUtils.isEmpty(jumpTaskIds)) { result.total(0l); return new ArrayList<>(); } List hisTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInsId) .finished() .taskIds(jumpTaskIds) .includeIdentityLinks() .orderByHistoricTaskInstanceStartTime() .desc() .list(); hisTaskList = this.distinctHisTask(hisTaskList); // 排除运行时任务 List runTaskKeys = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); hisTaskList = hisTaskList.stream().filter(his -> !runTaskKeys.contains(his.getTaskDefinitionKey())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(hisTaskList)) { result.total(0l); return new ArrayList<>(); } int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; if (startNum >= hisTaskList.size()) { result.total(0l); // 如果起始索引超出了列表的大小,返回一个空列表 return new ArrayList<>(); } result.total(hisTaskList.size()); int end = Math.min(endNum, hisTaskList.size()); List targetTaskList = hisTaskList.subList(startNum, end); // 转换成VO // 得到目标任务对应的定义 List taskDefs = targetTaskList.stream().map(HistoricTaskInstance::getTaskDefinitionKey).collect(Collectors.toList()); Map keyMap = targetTaskList.stream().collect(Collectors.toMap(HistoricTaskInstance::getTaskDefinitionKey, his -> his)); List finishedUserTaskElement = this.getAllUserTaskElement(processDefinitionId).stream().filter(el -> taskDefs.contains(el.getId())).collect(Collectors.toList()); // 查出流程 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(processInsId).singleResult(); String deployId = ""; String processName = ""; if (Objects.nonNull(process)) { deployId = process.getDeploymentId(); processName = process.getProcessDefinitionName(); } else { HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInsId).singleResult(); deployId = hisProcess.getDeploymentId(); processName = hisProcess.getProcessDefinitionName(); } String finalDeployId = deployId; String finalProcessName = processName; List vos = finishedUserTaskElement.stream().map(userTask -> { CustomerTaskVO vo = new CustomerTaskVO(); vo.setProcessInsId(processInsId); vo.setProcessDefId(processDefinitionId); vo.setDeployId(finalDeployId); vo.setTaskName(userTask.getName()); vo.setProcessName(finalProcessName); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); vo.setHandlerId(handlerIds); vo.setHandlerName(handlerNames); vo.setHandlerUnitId(handlerUnitIds); vo.setHandlerUnitName(handlerUnitNames); vo.setPromoterName(promoterNames); vo.setPromoterUnitName(promoterUnitNames); this.setCandidateInfo(userTask, vo, projectId, processInsId); HistoricTaskInstance hisTask = keyMap.get(userTask.getId()); if (Objects.nonNull(hisTask)) { vo.setTaskStatus(TaskStatusEnum.JUMP); // 如果是已完成的,信息需要单独赋值 vo.setTaskId(hisTask.getId()); vo.setExecutionId(hisTask.getExecutionId()); vo.setCreateTime(hisTask.getStartTime()); // 查询实际处理人 if (StringUtils.isNotBlank(hisTask.getAssignee())) { long handlerUserId = Long.parseLong(hisTask.getAssignee()); SysUser handlerUser = sysUserService.selectUserById(handlerUserId); if (Objects.nonNull(handlerUser)) { vo.getHandlerId().add(handlerUserId); vo.getHandlerName().add(this.getUserShowName(handlerUser)); if (Objects.nonNull(handlerUser.getDept())) { vo.getHandlerUnitId().add(handlerUser.getDept().getDeptId()); vo.getHandlerUnitName().add(handlerUser.getDept().getDeptName()); } } } this.setHandler(vo, hisTask.getIdentityLinks()); vo.setTaskDefinitionKey(hisTask.getTaskDefinitionKey()); } this.distinctVo(vo); return vo; }).collect(Collectors.toList()); result.data(vos); return vos; } /** * 容缺任务分页 * * @param projectId * @param processDefinitionId * @param processInsId * @param taskName * @param pageNum * @param pageSize * @param result * @return */ private List getWaitTask(String projectId, String processDefinitionId, String processInsId, String taskName, Integer pageNum, Integer pageSize, Result result) { // 查出容缺过的任务 List allWaitTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .eq(ProcessLog::getEventType, ProcessLogEventTypeEnum.WAIT) .like(StringUtils.isNotBlank(taskName), ProcessLog::getTaskName, taskName) .orderByDesc(ProcessLog::getGmtCreate) .list(); // 排除容缺后又完成的任务 List finishedTaskList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .eq(ProcessLog::getProcessInsId, processInsId) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.FINISHED, ProcessLogEventTypeEnum.REJECT) .list(); List finishedTaskIds = finishedTaskList.stream().map(ProcessLog::getTaskId).distinct().collect(Collectors.toList()); // 得到未完成的容缺任务 List waitTaskIds = allWaitTaskList.stream().filter(log -> !finishedTaskIds.contains(log.getTaskId())).map(ProcessLog::getTaskId).collect(Collectors.toList()); if (CollectionUtils.isEmpty(waitTaskIds)) { result.total(0l); return new ArrayList<>(); } // 容缺的任务都属于历史任务,只是需要补表单数据 List hisTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInsId) .taskIds(waitTaskIds) .includeIdentityLinks() .orderByHistoricTaskInstanceStartTime() .desc() .list(); hisTaskList = this.distinctHisTask(hisTaskList); // 排除运行时任务 List runTaskKeys = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); hisTaskList = hisTaskList.stream().filter(his -> !runTaskKeys.contains(his.getTaskDefinitionKey())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(hisTaskList)) { result.total(0l); return new ArrayList<>(); } int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; if (startNum >= hisTaskList.size()) { result.total(0l); // 如果起始索引超出了列表的大小,返回一个空列表 return new ArrayList<>(); } result.total(hisTaskList.size()); int end = Math.min(endNum, hisTaskList.size()); List targetTask = hisTaskList.subList(startNum, end); // 转换成VO // 得到目标任务对应的定义 List taskDefs = targetTask.stream().map(HistoricTaskInstance::getTaskDefinitionKey).collect(Collectors.toList()); Map keyMap = targetTask.stream().collect(Collectors.toMap(HistoricTaskInstance::getTaskDefinitionKey, his -> his)); List finishedUserTaskElement = this.getAllUserTaskElement(processDefinitionId).stream().filter(el -> taskDefs.contains(el.getId())).collect(Collectors.toList()); // 查出流程 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(processInsId).singleResult(); String deployId = ""; String processName = ""; if (Objects.nonNull(process)) { deployId = process.getDeploymentId(); processName = process.getProcessDefinitionName(); } else { HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInsId).singleResult(); deployId = hisProcess.getDeploymentId(); processName = hisProcess.getProcessDefinitionName(); } String finalDeployId = deployId; String finalProcessName = processName; List vos = finishedUserTaskElement.stream().map(userTask -> { CustomerTaskVO vo = new CustomerTaskVO(); vo.setProcessInsId(processInsId); vo.setProcessDefId(processDefinitionId); vo.setDeployId(finalDeployId); vo.setTaskName(userTask.getName()); vo.setProcessName(finalProcessName); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); vo.setHandlerId(handlerIds); vo.setHandlerName(handlerNames); vo.setHandlerUnitId(handlerUnitIds); vo.setHandlerUnitName(handlerUnitNames); vo.setPromoterName(promoterNames); vo.setPromoterUnitName(promoterUnitNames); this.setCandidateInfo(userTask, vo, projectId, processInsId); HistoricTaskInstance hisTask = keyMap.get(userTask.getId()); if (Objects.nonNull(hisTask)) { vo.setTaskStatus(TaskStatusEnum.WAIT); // 如果是已完成的,信息需要单独赋值 vo.setTaskId(hisTask.getId()); vo.setExecutionId(hisTask.getExecutionId()); vo.setCreateTime(hisTask.getStartTime()); // 查询实际处理人 if (StringUtils.isNotBlank(hisTask.getAssignee())) { long handlerUserId = Long.parseLong(hisTask.getAssignee()); SysUser handlerUser = sysUserService.selectUserById(handlerUserId); if (Objects.nonNull(handlerUser)) { vo.getHandlerId().add(handlerUserId); if (Objects.nonNull(handlerUser.getDept())) { vo.getHandlerUnitId().add(handlerUser.getDept().getDeptId()); } } } this.setHandler(vo, hisTask.getIdentityLinks()); vo.setTaskDefinitionKey(hisTask.getTaskDefinitionKey()); } this.distinctVo(vo); return vo; }).collect(Collectors.toList()); result.data(vos); return vos; } /** * 查询剩余事项(未开始的任务) * * @param projectId 项目id * @param processDefinitionId * @param processInsId * @param taskName * @param pageNum * @param pageSize * @param result * @return */ private List getRemainingTask(String projectId, String processDefinitionId, String processInsId, String taskName, Integer pageNum, Integer pageSize, Result result) { // 查出流程 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(processInsId).singleResult(); if (Objects.isNull(process)) { // 如果流程已经完成,那么没有剩余事项了 List vos = new ArrayList<>(1); result.data(vos); return vos; } int startNum = pageSize * (pageNum - 1); int endNum = startNum + pageSize; List allUserTaskElement = this.getAllUserTaskElement(processDefinitionId); // 排除进行中的任务和已完成的任务 List runTaskKeyList = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); List finishedTaskKeyList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .select(ProcessLog::getTaskDefKey) .eq(ProcessLog::getProcessInsId, processInsId) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.FINISHED, ProcessLogEventTypeEnum.JUMP, ProcessLogEventTypeEnum.WAIT) .list().stream().map(ProcessLog::getTaskDefKey).collect(Collectors.toList()); finishedTaskKeyList.addAll(runTaskKeyList); // List finishedTaskKeyList = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInsId).finished().list().stream().map(HistoricTaskInstance::getTaskDefinitionKey).distinct().collect(Collectors.toList()); allUserTaskElement = allUserTaskElement.stream().filter(el -> finishedTaskKeyList.indexOf(el.getId()) == -1).collect(Collectors.toList()); // 模拟模糊查询 if (StringUtils.isNotBlank(taskName)) { allUserTaskElement = allUserTaskElement.stream().filter(taskEl -> taskEl.getName().contains(taskName)).collect(Collectors.toList()); } if (startNum >= allUserTaskElement.size()) { // 如果起始索引超出了列表的大小,返回一个空列表 return new ArrayList<>(); } result.total(allUserTaskElement.size()); int end = Math.min(endNum, allUserTaskElement.size()); List userTasks = allUserTaskElement.subList(startNum, end); // 判断任务状态,构建vo List vos = new ArrayList<>(48); for (UserTask userTask : userTasks) { CustomerTaskVO vo = new CustomerTaskVO(); // 一个任务可能有多个候选人/组,所以需要使用list List handlerIds = new ArrayList<>(2); List handlerNames = new ArrayList<>(2); List handlerUnitIds = new ArrayList<>(2); List handlerUnitNames = new ArrayList<>(2); List promoterNames = new ArrayList<>(2); List promoterUnitNames = new ArrayList<>(2); vo.setHandlerId(handlerIds); vo.setHandlerName(handlerNames); vo.setHandlerUnitId(handlerUnitIds); vo.setHandlerUnitName(handlerUnitNames); vo.setPromoterName(promoterNames); vo.setPromoterUnitName(promoterUnitNames); vo.setProcessInsId(process.getId()); vo.setProcessDefId(processDefinitionId); vo.setDeployId(process.getDeploymentId()); vo.setTaskName(userTask.getName()); vo.setProcessName(process.getProcessDefinitionName()); vo.setTaskStatus(TaskStatusEnum.NOT_START); this.setCandidateInfo(userTask, vo, projectId, processInsId); // 未开始的任务,其关联的用户组这些都可以从UserTask中拿到,因为本身未开始的任务是没有task的,所以这里直接查 if (StringUtils.isNotBlank(userTask.getAssignee())) { vo.setHandlerType(HandlerTypeEnum.USER); SysUser sysUser = sysUserService.selectUserById(Long.parseLong(userTask.getAssignee())); if (Objects.nonNull(sysUser)) { vo.getHandlerId().add(sysUser.getUserId()); vo.getHandlerName().add(sysUser.getNickName()); if (Objects.nonNull(sysUser.getDept())) { vo.getHandlerUnitId().add(sysUser.getDept().getDeptId()); vo.getHandlerUnitName().add(sysUser.getDept().getDeptName()); } } } else if (CollectionUtil.isNotEmpty(userTask.getCandidateGroups())) { List groupIds = userTask.getCandidateGroups(); for (String groupId : groupIds) { // 处理变量表达式,DATA_LAUNCH只可能是部门不会是角色,因为代表的是业主部门 if (groupId.contains(ProcessConstants.DATA_LAUNCH)) { vo.setHandlerType(HandlerTypeEnum.DEPT); this.varYzReview(vo, projectId, processInsId, HandlerTypeEnum.DEPT, 1); } else if (groupId.startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 vo.setHandlerType(HandlerTypeEnum.DEPT); String[] split = groupId.split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { vo.getHandlerUnitId().add(dept.getDeptId()); vo.getHandlerUnitName().add(dept.getDeptName()); } } } else { vo.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(groupId)); if (Objects.nonNull(role)) { vo.getHandlerUnitId().add(role.getRoleId()); vo.getHandlerUnitName().add(role.getRoleName()); } } } } this.distinctVo(vo); vos.add(vo); } result.data(vos); return vos; } /** * 对任务信息中处理人的去重 * * @param vo */ private void distinctVo(CustomerTaskVO vo) { vo.setHandlerId(vo.getHandlerId().stream().distinct().collect(Collectors.toList())); vo.setHandlerName(vo.getHandlerName().stream().distinct().collect(Collectors.toList())); vo.setHandlerUnitId(vo.getHandlerUnitId().stream().distinct().collect(Collectors.toList())); vo.setHandlerUnitName(vo.getHandlerUnitName().stream().distinct().collect(Collectors.toList())); } /** * 处理流程变量-业主单位 * @param setType 0 设置责任单位 1 设置办理单位 * @param vo */ private void varYzReview(CustomerTaskVO vo, String projectId, String processInsId, HandlerTypeEnum type, Integer setType) { ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(projectProcessMapper) .eq(ProjectProcess::getProjectId, projectId) .eq(ProjectProcess::getProcessInsId, processInsId) .one(); if (Objects.isNull(projectProcess)) { throw new RuntimeException("该流程未绑定项目"); } if (HandlerTypeEnum.USER.equals(type) || HandlerTypeEnum.FIX_USER.equals(type)) { SysUser user = sysUserService.selectUserById(projectProcess.getDataLaunch()); if (Objects.nonNull(user) && Objects.nonNull(user.getDept())) { vo.getHandlerName().add(user.getNickName()); vo.getHandlerId().add(user.getUserId()); } } else if (HandlerTypeEnum.DEPT.equals(type)) { SysDept dept = deptService.selectDeptById(projectProcess.getDataLaunch()); if (Objects.nonNull(dept)) { if (setType == 1) { vo.getHandlerUnitId().add(dept.getDeptId()); vo.getHandlerUnitName().add(dept.getDeptName()); vo.getHandlerName().add(this.getDeptLeaderShowName(dept)); } else { vo.getPromoterUnitName().add(dept.getDeptName()); vo.getPromoterName().add(this.getDeptLeaderShowName(dept)); } } } else if (HandlerTypeEnum.ROLE.equals(type)) { SysRole role = sysRoleService.selectRoleById(projectProcess.getDataLaunch()); if (Objects.nonNull(role)) { vo.getHandlerUnitId().add(role.getRoleId()); vo.getHandlerUnitName().add(role.getRoleName()); } } this.distinctVo(vo); } /** * 查询剩余事项(未开始的任务)数量 * * @param processDefinitionId 流程定义id * @param processInsId 流程实例id * @return */ private Long getRemainingTaskNum(String processDefinitionId, String processInsId, long totalNum) { // 查出流程 ProcessInstance process = runtimeService.createProcessInstanceQuery().processInstanceId(processInsId).singleResult(); if (Objects.isNull(process)) { // 运行时未找到流程,说明流程已经结束了 return 0L; } List allUserTaskElement = this.getAllUserTaskElement(processDefinitionId); // 排除进行中的任务和已完成的任务 List runTaskKeyList = taskService.createTaskQuery().processInstanceId(processInsId).list().stream().map(Task::getTaskDefinitionKey).collect(Collectors.toList()); List finishedTaskKeyList = new LambdaQueryChainWrapper<>(processLogService.getBaseMapper()) .select(ProcessLog::getTaskDefKey) .eq(ProcessLog::getProcessInsId, processInsId) .in(ProcessLog::getEventType, ProcessLogEventTypeEnum.FINISHED, ProcessLogEventTypeEnum.JUMP, ProcessLogEventTypeEnum.WAIT) .list().stream().map(ProcessLog::getTaskDefKey).collect(Collectors.toList()); finishedTaskKeyList.addAll(runTaskKeyList); allUserTaskElement = allUserTaskElement.stream().filter(el -> finishedTaskKeyList.indexOf(el.getId()) == -1).collect(Collectors.toList()); return Long.valueOf(allUserTaskElement.size()); } /** * 设置候选人信息/责任单位 * * @param userTask * @param vo * @param projectId * @param processInsId */ private void setCandidateInfo(UserTask userTask, CustomerTaskVO vo, String projectId, String processInsId) { if (StringUtils.isNotBlank(userTask.getAssignee())) { vo.setHandlerType(HandlerTypeEnum.USER); SysUser sysUser = sysUserService.selectUserById(Long.parseLong(userTask.getAssignee())); if (Objects.nonNull(sysUser)) { if (Objects.nonNull(sysUser.getDept())) { // 如果是指定的某个人,那么责任单位是这个人所在的部门 vo.getPromoterUnitName().add(sysUser.getDept().getDeptName()); vo.getPromoterName().add(this.getUserShowName(sysUser)); } } } else if (CollectionUtil.isNotEmpty(userTask.getCandidateGroups())) { List groupIds = userTask.getCandidateGroups(); for (String groupId : groupIds) { // 处理变量表达式,DATA_LAUNCH只可能是部门不会是角色,因为代表的是业主部门 if (groupId.contains(ProcessConstants.DATA_LAUNCH)) { vo.setHandlerType(HandlerTypeEnum.DEPT); this.varYzReview(vo, projectId, processInsId, HandlerTypeEnum.DEPT, 0); } else if (groupId.startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 vo.setHandlerType(HandlerTypeEnum.DEPT); String[] split = groupId.split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { vo.getPromoterUnitName().add(this.setDeptNameWithParentName(dept)); vo.getPromoterName().add(this.getDeptLeaderShowName(dept)); } } } else { vo.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(groupId)); if (Objects.nonNull(role)) { vo.getPromoterUnitName().add(role.getRoleName()); } } } } } /** * 设置部门名称时带上上级部门名称 * @param dept */ private String setDeptNameWithParentName(SysDept dept) { String[] str = dept.getAncestors().split(","); if (str.length >= 4){ return dept.getParentName() + " / " + dept.getDeptName(); }else { return dept.getDeptName(); } } /** * 设置任务的发起人&处理人 只有待办任务和已完成任务才会掉这个方法 * * @param taskVO * @param identityLinkInfos 如果是已完成的任务,用这个去取关联的用户/用户组 */ private void setHandler(CustomerTaskVO taskVO, List identityLinkInfos) { // 流程处理人信息 if (TaskStatusEnum.TODO.equals(taskVO.getTaskStatus())) { List identityLinksForTask = taskService.getIdentityLinksForTask(taskVO.getTaskId()); for (IdentityLink identityLink : identityLinksForTask) { if (StringUtils.isBlank(((IdentityLinkEntityImpl) identityLink).getId())) { continue; } // 绑定的是用户,查出用户姓名、部门 if (StringUtils.isNotBlank(identityLink.getUserId())) { SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); if (Objects.nonNull(sysUser)) { taskVO.setHandlerType(HandlerTypeEnum.USER); taskVO.getHandlerId().add(sysUser.getUserId()); taskVO.getHandlerName().add(this.getUserShowName(sysUser)); if (Objects.nonNull(sysUser.getDept())) { taskVO.getHandlerUnitId().add(sysUser.getDept().getDeptId()); taskVO.getHandlerUnitName().add(sysUser.getDept().getDeptName()); } } // 绑定的是角色或者是部门,需要根据id判断 } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { if (identityLink.getGroupId().startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 taskVO.setHandlerType(HandlerTypeEnum.DEPT); String[] split = identityLink.getGroupId().split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { taskVO.getHandlerUnitId().add(dept.getDeptId()); taskVO.getHandlerUnitName().add(dept.getDeptName()); } } } else { taskVO.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); if (Objects.nonNull(role)) { taskVO.getHandlerUnitId().add(role.getRoleId()); taskVO.getHandlerUnitName().add(role.getRoleName()); } } } } } else if (TaskStatusEnum.FINISHED.equals(taskVO.getTaskStatus()) || TaskStatusEnum.WAIT.equals(taskVO.getTaskStatus())) { for (IdentityLinkInfo identityLink : identityLinkInfos) { // 绑定的是用户,查出用户姓名、部门 if (StringUtils.isNotBlank(identityLink.getUserId())) { taskVO.setHandlerType(HandlerTypeEnum.USER); SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); if (Objects.nonNull(sysUser)) { taskVO.getHandlerId().add(sysUser.getUserId()); taskVO.getHandlerName().add(this.getUserShowName(sysUser)); if (Objects.nonNull(sysUser.getDept())) { taskVO.getHandlerUnitId().add(sysUser.getDept().getDeptId()); taskVO.getHandlerUnitName().add(sysUser.getDept().getDeptName()); } } // 绑定的是角色,查出角色名称 } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { if (identityLink.getGroupId().startsWith("dept")) { taskVO.setHandlerType(HandlerTypeEnum.DEPT); String[] split = identityLink.getGroupId().split(":"); if (split.length > 1) { // 部门 SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); if (Objects.nonNull(dept)) { taskVO.getHandlerUnitId().add(dept.getDeptId()); taskVO.getHandlerUnitName().add(dept.getDeptName()); } } } else { taskVO.setHandlerType(HandlerTypeEnum.ROLE); SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); if (Objects.nonNull(role)) { taskVO.getHandlerUnitId().add(role.getRoleId()); taskVO.getHandlerUnitName().add(role.getRoleName()); } } } } } this.distinctVo(taskVO); } /** * 设置任务发起人 * * @param taskVO */ private void setPromoterInfo(CustomerTaskVO taskVO) { // // 发起人应为上一节点的处理人 // List beforeNodeKey = taskCommonService.getBeforeNodeInfo(taskVO.getProcessDefId(), taskVO.getTaskDefinitionKey()); // List userList = beforeNodeKey.stream().map(key -> { // List historicTaskInstances = historyService.createHistoricTaskInstanceQuery() // .processInstanceId(taskVO.getProcessInsId()) // .taskDefinitionKey(key) // .orderByHistoricTaskInstanceStartTime() // .desc() // .list(); // 之所以用list是因为如果某个任务被驳回过,且如果该任务再次执行时会有多条数据,取最新的一条 // if (!CollectionUtils.isEmpty(historicTaskInstances)) { // // 实际领取这个任务的人,也就是处理人 // String assignee = historicTaskInstances.get(0).getAssignee(); // SysUser startUser = sysUserService.selectUserById(Long.parseLong(assignee)); // return startUser; // } else { // return null; // } // }).filter(user -> Objects.nonNull(user)).collect(Collectors.toList()); // if (CollectionUtils.isEmpty(userList)) { // taskVO.setPromoterName("暂无"); // taskVO.setPromoterUnitName("暂无"); // } else { // taskVO.setPromoterId(userList.stream().map(user -> { // return user.getUserId() + ""; // }).collect(Collectors.joining("、"))); // taskVO.setPromoterName(userList.stream().map(user -> { // return this.getUserShowName(user); // }).collect(Collectors.joining("、"))); // taskVO.setPromoterUnitId(userList.stream().filter(user -> Objects.nonNull(user.getDept())).map(user -> { // return user.getDept().getDeptId() + ""; // }).collect(Collectors.joining("、"))); // taskVO.setPromoterUnitName(userList.stream().filter(user -> Objects.nonNull(user.getDept())).map(user -> { // return user.getDept().getDeptName() + ""; // }).collect(Collectors.joining("、"))); // } } /** * 获取某个流程的所有任务节点 * * @param processDefinitionId * @return */ private List getAllUserTaskElement(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()); } List flowElements = process.getFlowElements().stream().toList(); List userTaskElements = flowElements.stream().filter(flowElement -> flowElement instanceof UserTask).map(flowElement -> { return (UserTask) flowElement; }).collect(Collectors.toList()); return userTaskElements; } /** * 获取流程节点数(总任务数,不包含开始、结束等特殊的,只统计UserTask类型的) * * @param processDefinitionId 流程定义id * @return */ private Long getTotalTaskNum(String processDefinitionId) { return Long.valueOf(this.getAllUserTaskElement(processDefinitionId).size()); } /** * 获取待办任务数 * * @param processInstanceId * @return */ private Long getTodoTaskNum(String processInstanceId) { return taskService.createTaskQuery().active().processInstanceId(processInstanceId).count(); } /** * 获取当前环节的所有任务数 * * @param processInstanceId * @return */ private List getCurrentNodeTaskList(String processInstanceId) { return taskService.createTaskQuery().processDefinitionId(processInstanceId).list(); } }