| | |
| | | package com.ycl.service.impl; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; |
| | | import com.ycl.common.annotation.DataScope; |
| | | import com.ycl.common.base.Result; |
| | | import com.ycl.common.constant.ProcessOverTimeConstants; |
| | | import com.ycl.common.core.domain.BaseEntity; |
| | |
| | | import com.ycl.domain.entity.ProjectInfo; |
| | | import com.ycl.domain.entity.ProjectProcess; |
| | | import com.ycl.domain.form.ProjectProgressStatisticsForm; |
| | | import com.ycl.domain.query.WaitTodoQuery; |
| | | import com.ycl.domain.vo.*; |
| | | import com.ycl.factory.FlowServiceFactory; |
| | | import com.ycl.mapper.ProcessCodingMapper; |
| | | import com.ycl.mapper.ProcessLogMapper; |
| | | import com.ycl.mapper.ProjectInfoMapper; |
| | | import com.ycl.mapper.ProjectProcessMapper; |
| | | import com.ycl.service.IndexHomeService; |
| | | import com.ycl.service.ProjectProcessService; |
| | | import com.ycl.service.common.TaskCommonService; |
| | | import com.ycl.system.mapper.SysDeptMapper; |
| | | import com.ycl.system.service.ISysDeptService; |
| | | import com.ycl.system.service.ISysRoleService; |
| | |
| | | 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.task.api.Task; |
| | | import org.flowable.task.api.TaskQuery; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.CollectionUtils; |
| | |
| | | private final ISysDeptService sysDeptService; |
| | | |
| | | private final ISysRoleService sysRoleService; |
| | | |
| | | private final TaskCommonService taskCommonService; |
| | | |
| | | |
| | | @Override |
| | | public Result projectCodingStatusCount() { |
| | | //权限控制 |
| | | List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo(); |
| | | |
| | | |
| | | |
| | | |
| | | Map<String,Integer> map = new HashMap<>(); |
| | | map.put(ProcessOverTimeConstants.GREEN,0); |
| | |
| | | return Result.ok().data(map); |
| | | } |
| | | |
| | | @Override |
| | | public List<ProjectInfo> getLoginUserOwnProjectInfo(){ |
| | | //权限控制 |
| | | Long userId = SecurityUtils.getUserId(); |
| | |
| | | |
| | | return Result.ok().data(projectInfoAndFunding); |
| | | } |
| | | @Override |
| | | public int countWaitTask() { |
| | | Long userId = SecurityUtils.getUserId(); |
| | | List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo(); |
| | | if (CollectionUtils.isEmpty(loginUserOwnProjectInfo)) { |
| | | return 0; |
| | | } |
| | | List<Long> ids = loginUserOwnProjectInfo.stream() |
| | | .filter(Objects::nonNull) |
| | | .map(ProjectInfo::getId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(ids)) { |
| | | return 0; |
| | | } |
| | | List<ProjectProcess> projectProcessList = new LambdaQueryChainWrapper<>(projectProcessService.getBaseMapper()) |
| | | .eq(ProjectProcess::getDeleted, Boolean.FALSE) |
| | | .in(ProjectProcess::getProjectId, ids) |
| | | .list(); |
| | | if (CollectionUtils.isEmpty(projectProcessList)) { |
| | | return 0; |
| | | } |
| | | List<String> targetProcessInsIds = projectProcessList.stream() |
| | | .filter(Objects::nonNull) // 过滤null的ProjectProcess对象 |
| | | .map(ProjectProcess::getProcessInsId) |
| | | .filter(defId -> defId != null && !defId.trim().isEmpty()) // 先判null再trim,修复风险3 |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(targetProcessInsIds)) { |
| | | return 0; |
| | | } |
| | | |
| | | List<Task> allRunningTasks = taskService.createTaskQuery().active().list(); |
| | | if (CollectionUtils.isEmpty(allRunningTasks)) { |
| | | return 0; |
| | | } |
| | | List<Task> targetRunningTasks = allRunningTasks.stream() |
| | | .filter(Objects::nonNull) |
| | | .filter(task -> { |
| | | // 先判null,再匹配,修复风险1 |
| | | String processInsId = task.getProcessInstanceId(); |
| | | return processInsId != null && targetProcessInsIds.contains(processInsId); |
| | | }) |
| | | .filter(task -> { |
| | | String assignee = task.getAssignee(); |
| | | return assignee == null || userId.toString().equals(assignee);//排除领取人 |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | |
| | | |
| | | return targetRunningTasks.size(); |
| | | } |
| | | |
| | | @Override |
| | | public Result projectAdvanceCheckPoint() { |
| | |
| | | List<ProjectProcess> projectProcessList = new LambdaQueryChainWrapper<>(projectProcessService.getBaseMapper()) |
| | | .eq(ProjectProcess::getDeleted, Boolean.FALSE) |
| | | .in(ProjectProcess::getProjectId, ids).list(); |
| | | |
| | | Long userId = SecurityUtils.getUserId(); |
| | | //流程实例id集合 |
| | | List<String> targetProcessInsIds = projectProcessList.stream() |
| | | .map(ProjectProcess::getProcessInsId) |
| | |
| | | |
| | | |
| | | List<Task> allRunningTasks = taskService.createTaskQuery().active().list(); |
| | | |
| | | List<Task> targetRunningTasks = allRunningTasks.stream() |
| | | // 关键匹配:任务的流程定义ID 存在于 projectProcessList 的流程定义ID列表中 |
| | | .filter(task -> targetProcessInsIds.contains(task.getProcessInstanceId())) |
| | | .filter(task -> { |
| | | String assignee = task.getAssignee(); |
| | | log.info("assignee:{}",assignee); |
| | | return assignee == null || userId.toString().equals(assignee); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | |
| | | |
| | | List<TaskInfoVo> list = new ArrayList<>(); |
| | | // 按流程实例id分组 |
| | |
| | | .eq(ProcessCoding::getDeleted, Boolean.FALSE) |
| | | .in(ProcessCoding::getTaskId, taskIds) |
| | | .list(); |
| | | log.info("processCodingList.size():{}", processCodingList.size()); // 看日志是否为0 |
| | | Map<String, ProcessCoding> processCodingMap = new HashMap<>(); |
| | | //按taskId转换为map方面下面获取 |
| | | if (!CollectionUtils.isEmpty(processCodingList)){ |
| | | Map<String, ProcessCoding> processCodingMap = processCodingList.stream() |
| | | processCodingMap = processCodingList.stream() |
| | | .filter(Objects::nonNull) // 避免null元素导致NPE(可选保留) |
| | | .filter(vo -> vo.getTaskId() != null) // 过滤taskId为null的无效数据 |
| | | .collect(Collectors.toMap( |
| | |
| | | return newCreateTime.getTime() > oldCreateTime.getTime() ? newVal : oldVal; |
| | | } |
| | | )); |
| | | } |
| | | for (Task task : targetRunningTasks) { |
| | | |
| | | for (Task task : targetRunningTasks) { |
| | | TaskInfoVo taskVo = new TaskInfoVo(); |
| | | |
| | | TaskInfoVo taskVo = new TaskInfoVo(); |
| | | |
| | | taskVo.setId(task.getId()); |
| | | taskVo.setTaskName(task.getName()); |
| | | taskVo.setStartTime(task.getCreateTime()); |
| | | taskVo.setEndTime(task.getDueDate()); |
| | | taskVo.setId(task.getId()); |
| | | taskVo.setTaskName(task.getName()); |
| | | taskVo.setStartTime(task.getCreateTime()); |
| | | taskVo.setEndTime(task.getDueDate()); |
| | | // taskVo.setTaskType(); |
| | | |
| | | List<Long> handlerIds = new ArrayList<>(2); |
| | | List<String> handlerNames = new ArrayList<>(2); |
| | | List<Long> handlerUnitIds = new ArrayList<>(2); |
| | | List<String> handlerUnitNames = new ArrayList<>(2); |
| | | List<String> promoterNames = new ArrayList<>(2); |
| | | List<String> promoterUnitNames = new ArrayList<>(2); |
| | | CustomerTaskVO customerTaskVO = new CustomerTaskVO(); |
| | | customerTaskVO.setHandlerId(handlerIds); |
| | | customerTaskVO.setHandlerName(handlerNames); |
| | | customerTaskVO.setHandlerUnitId(handlerUnitIds); |
| | | customerTaskVO.setHandlerUnitName(handlerUnitNames); |
| | | customerTaskVO.setPromoterName(promoterNames); |
| | | customerTaskVO.setPromoterUnitName(promoterUnitNames); |
| | | List<Long> handlerIds = new ArrayList<>(2); |
| | | List<String> handlerNames = new ArrayList<>(2); |
| | | List<Long> handlerUnitIds = new ArrayList<>(2); |
| | | List<String> handlerUnitNames = new ArrayList<>(2); |
| | | List<String> promoterNames = new ArrayList<>(2); |
| | | List<String> promoterUnitNames = new ArrayList<>(2); |
| | | CustomerTaskVO customerTaskVO = new CustomerTaskVO(); |
| | | customerTaskVO.setHandlerId(handlerIds); |
| | | customerTaskVO.setHandlerName(handlerNames); |
| | | customerTaskVO.setHandlerUnitId(handlerUnitIds); |
| | | customerTaskVO.setHandlerUnitName(handlerUnitNames); |
| | | customerTaskVO.setPromoterName(promoterNames); |
| | | customerTaskVO.setPromoterUnitName(promoterUnitNames); |
| | | |
| | | // 流程处理人信息 |
| | | List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId()); |
| | | for (IdentityLinkInfo identityLink : identityLinksForTask) { |
| | | // 绑定的是用户,查出用户姓名、部门 |
| | | if (StringUtils.isNotBlank(identityLink.getUserId())) { |
| | | // 处理变量表达式,运行中的任务无需再处理表达式了,flowable已经自动根据变量设置了 |
| | | customerTaskVO.setHandlerType(HandlerTypeEnum.USER); |
| | | SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); |
| | | if (Objects.nonNull(sysUser)) { |
| | | customerTaskVO.getHandlerId().add(sysUser.getUserId()); |
| | | customerTaskVO.getHandlerName().add(this.getUserShowName(sysUser)); |
| | | if (Objects.nonNull(sysUser.getDept())) { |
| | | customerTaskVO.getHandlerUnitId().add(sysUser.getDept().getDeptId()); |
| | | customerTaskVO.getHandlerUnitName().add(sysUser.getDept().getDeptName()); |
| | | customerTaskVO.getPromoterName().add(this.getUserShowName(sysUser)); |
| | | String[] str = sysUser.getDept().getAncestors().split(","); |
| | | if (str.length >= 4){ |
| | | customerTaskVO.getPromoterUnitName().add(sysUser.getDept().getParentName() +"-"+sysUser.getDept().getDeptName()); |
| | | }else { |
| | | customerTaskVO.getPromoterUnitName().add(sysUser.getDept().getDeptName()); |
| | | } |
| | | |
| | | // 流程处理人信息 |
| | | List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId()); |
| | | for (IdentityLinkInfo identityLink : identityLinksForTask) { |
| | | // 绑定的是用户,查出用户姓名、部门 |
| | | if (StringUtils.isNotBlank(identityLink.getUserId())) { |
| | | // 处理变量表达式,运行中的任务无需再处理表达式了,flowable已经自动根据变量设置了 |
| | | customerTaskVO.setHandlerType(HandlerTypeEnum.USER); |
| | | SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId())); |
| | | if (Objects.nonNull(sysUser)) { |
| | | customerTaskVO.getHandlerId().add(sysUser.getUserId()); |
| | | customerTaskVO.getHandlerName().add(this.getUserShowName(sysUser)); |
| | | if (Objects.nonNull(sysUser.getDept())) { |
| | | customerTaskVO.getHandlerUnitId().add(sysUser.getDept().getDeptId()); |
| | | customerTaskVO.getHandlerUnitName().add(sysUser.getDept().getDeptName()); |
| | | customerTaskVO.getPromoterName().add(this.getUserShowName(sysUser)); |
| | | String[] str = sysUser.getDept().getAncestors().split(","); |
| | | if (str.length >= 4){ |
| | | customerTaskVO.getPromoterUnitName().add(sysUser.getDept().getParentName() +"-"+sysUser.getDept().getDeptName()); |
| | | }else { |
| | | customerTaskVO.getPromoterUnitName().add(sysUser.getDept().getDeptName()); |
| | | } |
| | | } |
| | | // 绑定的是角色或者部门 |
| | | } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { |
| | | if (identityLink.getGroupId().startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 |
| | | customerTaskVO.setHandlerType(HandlerTypeEnum.DEPT); |
| | | String[] split = identityLink.getGroupId().split(":"); |
| | | if (split.length > 1) { |
| | | // 部门 |
| | | SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); |
| | | if (Objects.nonNull(dept)) { |
| | | customerTaskVO.getHandlerUnitId().add(dept.getDeptId()); |
| | | customerTaskVO.getHandlerUnitName().add(dept.getDeptName()); |
| | | customerTaskVO.getPromoterName().add(this.getDeptLeaderShowName(dept)); |
| | | customerTaskVO.getPromoterUnitName().add(this.setDeptNameWithParentName(dept)); |
| | | } |
| | | } |
| | | } else { |
| | | customerTaskVO.setHandlerType(HandlerTypeEnum.ROLE); |
| | | SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); |
| | | if (Objects.nonNull(role)) { |
| | | customerTaskVO.getHandlerUnitId().add(Long.parseLong(identityLink.getGroupId())); |
| | | customerTaskVO.getHandlerUnitName().add(role.getRoleName()); |
| | | } |
| | | } |
| | | } |
| | | this.distinctVo(customerTaskVO); |
| | | } |
| | | taskVo.setCustomerTaskInfo(customerTaskVO); |
| | | |
| | | //组装任务信息 |
| | | CheckPointVO checkPointVO = processInfoMap.get(task.getProcessInstanceId()); |
| | | if (checkPointVO != null) { |
| | | taskVo.setCheckPointInfo(checkPointVO); |
| | | } |
| | | //超时时间和次数在 processCodingList中 这里需要更具taskId来获得对应信息 |
| | | ProcessCoding processCoding = processCodingMap.get(task.getId()); |
| | | //设置超时信息 |
| | | if (processCoding != null) { |
| | | |
| | | String overTimeTotalStr = processCoding.getOverTimeTotal(); |
| | | long overTimeTotal = 0L; |
| | | if (StringUtils.isNotBlank(overTimeTotalStr)) { |
| | | try { |
| | | overTimeTotal = Long.parseLong(overTimeTotalStr.trim()); |
| | | } catch (NumberFormatException e) { |
| | | |
| | | } |
| | | } |
| | | String overTimeDesc = convertHoursToDayHourStr(overTimeTotal); |
| | | taskVo.setTotalOverTime(overTimeDesc); |
| | | |
| | | // 2. 提取红码阈值 如: 0-22 天-小时 并转换为小时 |
| | | String redTimeStr = processCoding.getRedTime(); |
| | | Long redTimeSec = getTime(redTimeStr); |
| | | Double redTimeHour = null; |
| | | if (redTimeSec != null && redTimeSec > 0) { |
| | | redTimeHour = redTimeSec / 3600.0; |
| | | // 绑定的是角色或者部门 |
| | | } else if (StringUtils.isNotBlank(identityLink.getGroupId())) { |
| | | if (identityLink.getGroupId().startsWith("dept")) { // 部门的id是加了前缀的如:dept:1 |
| | | customerTaskVO.setHandlerType(HandlerTypeEnum.DEPT); |
| | | String[] split = identityLink.getGroupId().split(":"); |
| | | if (split.length > 1) { |
| | | // 部门 |
| | | SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1])); |
| | | if (Objects.nonNull(dept)) { |
| | | customerTaskVO.getHandlerUnitId().add(dept.getDeptId()); |
| | | customerTaskVO.getHandlerUnitName().add(dept.getDeptName()); |
| | | customerTaskVO.getPromoterName().add(this.getDeptLeaderShowName(dept)); |
| | | customerTaskVO.getPromoterUnitName().add(this.setDeptNameWithParentName(dept)); |
| | | } |
| | | } |
| | | } else { |
| | | customerTaskVO.setHandlerType(HandlerTypeEnum.ROLE); |
| | | SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId())); |
| | | if (Objects.nonNull(role)) { |
| | | customerTaskVO.getHandlerUnitId().add(Long.parseLong(identityLink.getGroupId())); |
| | | customerTaskVO.getHandlerUnitName().add(role.getRoleName()); |
| | | } |
| | | } |
| | | long overTimeCount = 0L; |
| | | // 判断超时次数 |
| | | if (overTimeTotal > 0 && redTimeHour != null && redTimeHour > 0) { |
| | | overTimeCount = (long) (overTimeTotal / redTimeHour); |
| | | } |
| | | |
| | | |
| | | taskVo.setOverTimeCount(overTimeCount); |
| | | }else { |
| | | //为null 说明未配置超时时间 默认未超时 |
| | | taskVo.setOverTimeCount(0L); |
| | | taskVo.setTotalOverTime("0小时"); |
| | | } |
| | | list.add(taskVo); |
| | | this.distinctVo(customerTaskVO); |
| | | } |
| | | taskVo.setCustomerTaskInfo(customerTaskVO); |
| | | |
| | | //组装任务信息 |
| | | CheckPointVO checkPointVO = processInfoMap.get(task.getProcessInstanceId()); |
| | | if (checkPointVO != null) { |
| | | taskVo.setCheckPointInfo(checkPointVO); |
| | | } |
| | | //超时时间和次数在 processCodingList中 这里需要更具taskId来获得对应信息 |
| | | ProcessCoding processCoding = processCodingMap.get(task.getId()); |
| | | //设置超时信息 |
| | | if (processCoding != null) { |
| | | |
| | | String overTimeTotalStr = processCoding.getOverTimeTotal(); |
| | | long overTimeTotal = 0L; |
| | | if (StringUtils.isNotBlank(overTimeTotalStr)) { |
| | | try { |
| | | overTimeTotal = Long.parseLong(overTimeTotalStr.trim()); |
| | | } catch (NumberFormatException e) { |
| | | |
| | | } |
| | | } |
| | | String overTimeDesc = convertHoursToDayHourStr(overTimeTotal); |
| | | taskVo.setTotalOverTime(overTimeDesc); |
| | | |
| | | // 2. 提取红码阈值 如: 0-22 天-小时 并转换为小时 |
| | | String redTimeStr = processCoding.getRedTime(); |
| | | Long redTimeSec = getTime(redTimeStr); |
| | | Double redTimeHour = null; |
| | | if (redTimeSec != null && redTimeSec > 0) { |
| | | redTimeHour = redTimeSec / 3600.0; |
| | | } |
| | | long overTimeCount = 0L; |
| | | // 判断超时次数 |
| | | if (overTimeTotal > 0 && redTimeHour != null && redTimeHour > 0) { |
| | | overTimeCount = (long) (overTimeTotal / redTimeHour); |
| | | } |
| | | |
| | | |
| | | taskVo.setOverTimeCount(overTimeCount); |
| | | }else { |
| | | //为null 说明未配置超时时间 默认未超时 |
| | | taskVo.setOverTimeCount(0L); |
| | | taskVo.setTotalOverTime("0小时"); |
| | | } |
| | | list.add(taskVo); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | return Result.ok().data(list); |
| | | } |
| | | |
| | | public HashMap<String,Object> buildEmptyResultMap(){ |
| | | HashMap<String,Object> map = new HashMap<>(); |
| | | map.put("data", new ArrayList<>()); |
| | | map.put("total", 0L); |
| | | return map; |
| | | } |
| | | @Override |
| | | public Result getWaitTaskList(WaitTodoQuery baseQuery) { |
| | | int pageNum = (int) baseQuery.getCurrentPage(); |
| | | int pageSize = (int) baseQuery.getPageSize(); |
| | | Long userId = SecurityUtils.getUserId(); // 当前用户ID |
| | | boolean isAdmin = SecurityUtils.getLoginUser().getUser().isAdmin(); // 是否管理员 |
| | | List<String> userGroups = taskCommonService.getCurrentUserGroups(); // 当前用户所属组 |
| | | List<ProjectInfo> targetProjectList = new ArrayList<>(); |
| | | String queryProjectId = baseQuery.getId(); |
| | | |
| | | |
| | | if ("all".equals(queryProjectId) || StringUtils.isBlank(queryProjectId)){ |
| | | // 查询全部 |
| | | targetProjectList = getLoginUserOwnProjectInfo(); |
| | | }else{ |
| | | try { |
| | | Long projectId = Long.parseLong(queryProjectId); |
| | | // ① 查询该项目基础信息(替换为实际查询方法) |
| | | ProjectInfo projectInfo = projectInfoMapper.selectById(projectId); |
| | | if (projectInfo == null) { |
| | | // 项目不存在,返回空数据 |
| | | return Result.ok().data(buildEmptyResultMap()); |
| | | } |
| | | // |
| | | targetProjectList.add(projectInfo); |
| | | } catch (NumberFormatException e) { |
| | | // 项目ID格式错误,返回空数据 |
| | | return Result.ok().data(buildEmptyResultMap()); |
| | | } |
| | | } |
| | | |
| | | List<Long> projectIds = targetProjectList.stream().map(ProjectInfo::getId).collect(Collectors.toList()); |
| | | |
| | | List<ProjectProcess> projectProcessList = new LambdaQueryChainWrapper<>(projectProcessService.getBaseMapper()) |
| | | .eq(ProjectProcess::getDeleted, Boolean.FALSE) |
| | | .in(ProjectProcess::getProjectId, projectIds).list(); |
| | | // 4. 提取有效的流程实例ID(去重+非空过滤) |
| | | List<String> targetProcessInsIds = projectProcessList.stream() |
| | | .map(ProjectProcess::getProcessInsId) |
| | | .distinct() |
| | | .filter(defId -> defId != null && !defId.trim().isEmpty()) |
| | | .collect(Collectors.toList()); |
| | | |
| | | if (CollectionUtils.isEmpty(targetProcessInsIds)) { |
| | | return Result.ok().data(new HashMap<String, Object>() {{ |
| | | put("data", new ArrayList<>()); |
| | | put("total", 0L); |
| | | }}); |
| | | } |
| | | |
| | | // 5. 构建processInfoMap(核心:项目ID→CheckPointVO,再关联流程信息) |
| | | Map<String, CheckPointVO> map = new HashMap<>(); |
| | | // 先填充项目基础信息 |
| | | for (ProjectInfo projectInfo : targetProjectList) { |
| | | CheckPointVO checkPointVO = new CheckPointVO(); |
| | | checkPointVO.setId(projectInfo.getId()); |
| | | checkPointVO.setProjectName(projectInfo.getProjectName()); |
| | | map.put(String.valueOf(projectInfo.getId()), checkPointVO); |
| | | } |
| | | // 再填充流程信息(部署ID、流程名称等) |
| | | for (ProjectProcess projectProcess : projectProcessList) { |
| | | CheckPointVO checkPointVO = map.get(projectProcess.getProjectId()); |
| | | if (checkPointVO == null) { |
| | | continue; // 无匹配项目,跳过 |
| | | } |
| | | checkPointVO.setProcessDefinitionId(projectProcess.getProcessDefId()); |
| | | checkPointVO.setProcessInstanceId(projectProcess.getProcessInsId()); |
| | | |
| | | // 获得流程部署id和流程名称(兼容运行中/已结束流程) |
| | | ProcessInstance process = runtimeService.createProcessInstanceQuery() |
| | | .processInstanceId(projectProcess.getProcessInsId()).singleResult(); |
| | | if (Objects.nonNull(process)) { |
| | | checkPointVO.setDeployId(process.getDeploymentId()); |
| | | checkPointVO.setProcessName(process.getProcessDefinitionName()); |
| | | } else { |
| | | HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery() |
| | | .processInstanceId(projectProcess.getProcessInsId()).singleResult(); |
| | | if (Objects.nonNull(hisProcess)) { // 避免历史流程为null的NPE |
| | | checkPointVO.setDeployId(hisProcess.getDeploymentId()); |
| | | checkPointVO.setProcessName(hisProcess.getProcessDefinitionName()); |
| | | } |
| | | } |
| | | map.put(projectProcess.getProjectId(), checkPointVO); |
| | | } |
| | | Map<String, CheckPointVO> processInfoMap = map.values().stream() |
| | | .filter(Objects::nonNull) |
| | | .filter(vo -> vo.getProcessInstanceId() != null) |
| | | .collect(Collectors.toMap( |
| | | CheckPointVO::getProcessInstanceId, |
| | | vo -> vo, |
| | | (oldVal, newVal) -> newVal // 重复流程实例ID保留后者 |
| | | )); |
| | | |
| | | TaskQuery query = getTaskService().createTaskQuery() |
| | | .active() // 未完成、未挂起的活跃任务 |
| | | .processInstanceIdIn(targetProcessInsIds); // 仅查项目关联的流程实例任务 |
| | | |
| | | // 权限过滤:非管理员仅查自己有权限的任务(已领取+候选) |
| | | if (!isAdmin) { |
| | | query.or() |
| | | .taskAssignee(userId+"") // 自己已领取的任务 |
| | | .taskCandidateUser(userId+"") // 自己是候选用户的任务 |
| | | .taskCandidateGroupIn(userGroups) // 自己在候选组的任务 |
| | | .endOr(); |
| | | } |
| | | |
| | | query.orderByTaskCreateTime().desc(); |
| | | List<Task> allTaskList = query.list(); |
| | | // 排除领取人问题 |
| | | allTaskList = allTaskList.stream() |
| | | .filter(Objects::nonNull) // 空任务防护 |
| | | .filter(task -> { |
| | | String assignee = task.getAssignee(); |
| | | return assignee == null || userId.toString().equals(assignee); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | Set<String> taskIdSet = new HashSet<>(); |
| | | List<Task> distinctAllTaskList = new ArrayList<>(); |
| | | for (Task task : allTaskList) { |
| | | if (!taskIdSet.contains(task.getId())) { |
| | | taskIdSet.add(task.getId()); |
| | | distinctAllTaskList.add(task); |
| | | // |
| | | } |
| | | } |
| | | |
| | | long distinctTotal = distinctAllTaskList.size(); |
| | | System.out.println("去重后总数:" + distinctTotal); |
| | | |
| | | |
| | | int startIndex = (pageNum - 1) * pageSize; |
| | | List<Task> pageTaskList = new ArrayList<>(); |
| | | if (startIndex < distinctAllTaskList.size()) { |
| | | int endIndex = Math.min(startIndex + pageSize, distinctAllTaskList.size()); |
| | | pageTaskList = distinctAllTaskList.subList(startIndex, endIndex); |
| | | } |
| | | |
| | | |
| | | List<TaskInfoVo> taskInfoVoList = new ArrayList<>(); |
| | | //查询任务状态 |
| | | List<String> taskIds = pageTaskList.stream().map(Task::getId).collect(Collectors.toList()); |
| | | HashMap<String,ProcessLog> taskInfoMap = new HashMap<>(); |
| | | if (!CollectionUtils.isEmpty(taskIds)) { |
| | | taskInfoMap = new LambdaQueryChainWrapper<>(processLogMapper) |
| | | .eq(ProcessLog::getDeleted, Boolean.FALSE) |
| | | .in(ProcessLog::getTaskId, taskIds).list() |
| | | .stream() |
| | | .filter(processLog -> processLog.getTaskId() != null && processLog.getGmtCreate() != null) |
| | | .collect(Collectors.toMap( |
| | | // Key:taskId转字符串 |
| | | ProcessLog::getTaskId, |
| | | // Value:ProcessLog对象本身 |
| | | processLog -> processLog, |
| | | // 冲突策略:保留gmtCreate更新的那条记录 |
| | | (existing, replacement) -> { |
| | | return replacement.getGmtCreate().after(existing.getGmtCreate()) |
| | | ? replacement : existing; |
| | | }, |
| | | HashMap::new |
| | | )); |
| | | } |
| | | |
| | | |
| | | for (Task task : pageTaskList) { |
| | | TaskInfoVo taskVo = new TaskInfoVo(); |
| | | taskVo.setId(task.getId()); |
| | | taskVo.setTaskName(task.getName()); |
| | | taskVo.setStartTime(task.getCreateTime()); |
| | | taskVo.setEndTime(task.getDueDate()); |
| | | // 填充任务状态字段 |
| | | taskVo.setTaskType("待完成"); |
| | | ProcessLog processLog = taskInfoMap.get(task.getId()); |
| | | if (Objects.nonNull(processLog)) { |
| | | taskVo.setTaskType(processLog.getEventType().getDesc()); |
| | | } |
| | | |
| | | CheckPointVO checkPointVO = processInfoMap.get(task.getProcessInstanceId()); |
| | | if (checkPointVO != null) { |
| | | taskVo.setCheckPointInfo(checkPointVO); |
| | | } |
| | | |
| | | taskInfoVoList.add(taskVo); |
| | | } |
| | | //排除 已完成的 |
| | | taskInfoVoList = taskInfoVoList.stream().filter(taskInfoVo -> { |
| | | if (ProcessLogEventTypeEnum.FINISHED.getDesc().equals(taskInfoVo.getTaskType())){ |
| | | return false; |
| | | } |
| | | return true; |
| | | }).collect(Collectors.toList()); |
| | | HashMap<String, Object> resultMap = new HashMap<>(); |
| | | resultMap.put("data", taskInfoVoList); |
| | | resultMap.put("total", distinctTotal); |
| | | return Result.ok().data(resultMap); |
| | | } |
| | | |
| | | |
| | | |
| | | private String convertHoursToDayHourStr(long totalHours) { |
| | | if (totalHours < 0) { |
| | | return "0小时"; // 防御性处理负数场景 |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Result getProjectList(){ |
| | | List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo(); |
| | | return Result.ok().data(loginUserOwnProjectInfo); |
| | | } |
| | | |
| | | @Override |
| | | public Result getProjectSelectList() { |
| | | List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo(); |
| | | if (CollectionUtils.isEmpty(loginUserOwnProjectInfo)) { |
| | | return Result.ok().data(loginUserOwnProjectInfo); |
| | | } |
| | | |
| | | Map<String, String> projectMap = loginUserOwnProjectInfo.stream() |
| | | .collect(Collectors.toMap( |
| | | projectInfo -> String.valueOf(projectInfo.getId()), // key: 项目ID |
| | |
| | | )); |
| | | return Result.ok().data(projectMap); |
| | | } |
| | | |
| | | |
| | | } |