package org.springblade.mdm.flow.service; import com.baomidou.mybatisplus.core.metadata.IPage; import lombok.AllArgsConstructor; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.task.Comment; import org.flowable.task.api.Task; import org.flowable.task.api.TaskInfoQuery; import org.flowable.task.api.TaskQuery; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.*; import org.springblade.mdm.basesetting.machine.entity.Machine; import org.springblade.mdm.basesetting.machine.service.MachineService; import org.springblade.mdm.commons.service.ParamService; import org.springblade.mdm.flow.constants.FlowVariableConstant; import org.springblade.mdm.flow.entity.FlowProgramFile; import org.springblade.mdm.flow.entity.MdmFlowProcess; import org.springblade.mdm.flow.util.MdmFlowCache; import org.springblade.mdm.flow.vo.FlowVO; import org.springblade.mdm.flow.vo.TodoQueryVO; import org.springblade.system.feign.IUserClient; import org.springblade.system.pojo.entity.User; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.*; /** * 流程业务实现类 * * @author yangys */ @Service @AllArgsConstructor public class FlowBusinessService { private final RuntimeService runtimeService; private final TaskService taskService; private final HistoryService historyService; private final IUserClient userClient; private final FlowProgramFileService flowProgramFileService; private final ParamService paramService; private final MachineService machineService; /** * 查询我的流程(个人待办列表) * @param page 分页信息 * @param createTimeBegin 创建时间开始 * @param createTimeEnd 创建时间截止 * @param keyword 查询关键字 * @return */ public IPage selectTodoPage(IPage page, TodoQueryVO queryVO) {//LocalDateTime createTimeBegin, LocalDateTime createTimeEnd, String keyword //String taskUser = TaskUtil.getTaskUser(); String userId = "" + AuthUtil.getUserId(); List flowList = new LinkedList<>(); TaskQuery todoQuery = taskService.createTaskQuery().taskAssignee(userId).active().includeProcessVariables(); if(queryVO.getMachineSpec() != null){ if(queryVO.getMachineSpec().length==1) {//2个为全选 //查询车床代码集合 String turnVal = paramService.turninngValue(); List machines = machineService.lambdaQuery().eq(Machine::getMachineSpec, turnVal).eq(Machine::getStatus, Machine.STATUS_ENABLE).list(); List turnMachineCodes = machines.stream().map(Machine::getCode).toList(); List specs = Arrays.asList(queryVO.getMachineSpec()); if (specs.contains("1")) { //车床 todoQuery.or(); for (String mCode : turnMachineCodes) { todoQuery.processVariableValueEquals(FlowVariableConstant.MACHINE_CODE, mCode); } todoQuery.endOr(); } else { //加工中心 todoQuery.or(); for (String mCode : turnMachineCodes) { todoQuery.processVariableValueNotEquals(FlowVariableConstant.MACHINE_CODE, mCode); } todoQuery.endOr(); } } } if (Func.isNotEmpty(queryVO.getCreateTimeBegin())) { todoQuery.taskCreatedAfter(DateUtil.toDate(queryVO.getCreateTimeBegin())); } if (Func.isNotEmpty(queryVO.getCreateTimeEnd())) { todoQuery.taskCreatedBefore(DateUtil.toDate(queryVO.getCreateTimeEnd())); } if (Func.isNotEmpty(queryVO.getKeyword())) { addKeywordCondition(todoQuery, queryVO.getKeyword()); } todoQuery.orderByTaskCreateTime().desc(); // 构建列表数据 FlowVO bladeFlow = new FlowVO(); buildFlowTaskList(bladeFlow, flowList, todoQuery,page.getCurrent(),page.getSize()); // 计算总数 long count = todoQuery.count(); // 设置总数 page.setTotal(count); // 设置数据 page.setRecords(flowList); return page; } //TaskInfoQuery //void addKeywordCondition(TaskQuery todoQuery,String keyword) { void addKeywordCondition(TaskInfoQuery todoQuery, String keyword) { if(Func.isNotEmpty(keyword)) { String likeVal = "%" + keyword + "%"; todoQuery.or(); todoQuery.processVariableValueLike(FlowVariableConstant.TITLE,likeVal); todoQuery.processVariableValueLike(FlowVariableConstant.PROCESS_NO, likeVal); todoQuery.processVariableValueLike(FlowVariableConstant.MACHINE_CODE, likeVal); todoQuery.processVariableValueLike(FlowVariableConstant.MACHINE_MODE, likeVal); todoQuery.processVariableValueLike(FlowVariableConstant.PROCESS_NAME, likeVal); todoQuery.processVariableValueLike(FlowVariableConstant.PROCESS_EDITION, likeVal); todoQuery.processVariableValueLike(FlowVariableConstant.CRAFT_EDITION, likeVal); todoQuery.processDefinitionNameLike(likeVal); todoQuery.endOr(); } } /** * 构建流程 * * @param bladeFlow 流程通用类 * @param flowList 流程列表 * @param taskQuery 任务查询类 */ private void buildFlowTaskList(FlowVO bladeFlow, List flowList, TaskQuery taskQuery,Long currentPage,Long pageSize) { if (bladeFlow.getCategory() != null) { taskQuery.processCategoryIn(Func.toStrList(bladeFlow.getCategory())); } if (bladeFlow.getProcessDefinitionName() != null) { taskQuery.processDefinitionName(bladeFlow.getProcessDefinitionName()); } if (bladeFlow.getBeginDate() != null) { taskQuery.taskCreatedAfter(bladeFlow.getBeginDate()); } if (bladeFlow.getEndDate() != null) { taskQuery.taskCreatedBefore(bladeFlow.getEndDate()); } //List tasks = taskQuery.list(); long total = taskQuery.count(); Long firstResult = (currentPage-1)*pageSize; List tasks = taskQuery.listPage(Func.toInt(firstResult), Func.toInt(pageSize)); tasks.forEach(task -> { FlowVO flow = new FlowVO(); flow.setTaskId(task.getId()); flow.setTaskDefinitionKey(task.getTaskDefinitionKey()); flow.setTaskName(task.getName()); flow.setAssignee(task.getAssignee()); flow.setCreateTime(task.getCreateTime()); flow.setClaimTime(task.getClaimTime()); flow.setExecutionId(task.getExecutionId()); flow.setVariables(task.getProcessVariables()); flow.setDueDate(task.getDueDate()); flow.setProcessDefinitionId(task.getProcessDefinitionId()); flow.setFile(getFileString(task.getProcessInstanceId())); flow.setProcessInstanceId(task.getProcessInstanceId()); // 查询流程实例创建时间 HistoricProcessInstance historicProcess = historyService.createHistoricProcessInstanceQuery() .processInstanceId(task.getProcessInstanceId()) .singleResult(); flow.setProcessCreateTime(historicProcess.getStartTime()); R ru = userClient.userInfoById(Long.valueOf(historicProcess.getStartUserId())); if(ru.isSuccess()) { flow.setStartUserName(ru.getData().getName()); } List comments = lastStepComments(task);//taskService.getTaskComments(task.getId()); if(!comments.isEmpty()){ flow.setComment(comments.get(0).getFullMessage()); } MdmFlowProcess processDefinition = MdmFlowCache.getProcessDefinition(task.getProcessDefinitionId()); flow.setCategory(processDefinition.getCategory()); flow.setCategoryName(MdmFlowCache.getCategoryName(processDefinition.getCategory())); flow.setProcessDefinitionId(processDefinition.getId()); flow.setProcessDefinitionName(processDefinition.getName()); flow.setProcessDefinitionKey(processDefinition.getKey()); flow.setProcessDefinitionVersion(processDefinition.getVersion()); flow.setProcessInstanceId(task.getProcessInstanceId()); //flow.setStatus(status); flowList.add(flow); }); } List lastStepComments(Task currentTask){ List previousTasks = historyService.createHistoricActivityInstanceQuery() .processInstanceId(currentTask.getProcessInstanceId()) .activityType("userTask") // 直接查询用户任务类型 .orderByHistoricActivityInstanceEndTime() .desc() .list() .stream() .filter(activity -> !activity.getActivityId().equals(currentTask.getTaskDefinitionKey())) .map(activity -> historyService.createHistoricTaskInstanceQuery() .taskDefinitionKey(activity.getActivityId()) .processInstanceId(activity.getProcessInstanceId()) .orderByHistoricTaskInstanceEndTime() .desc() .list() ) .flatMap(List::stream) .toList(); List comments; if (!previousTasks.isEmpty()) { return taskService.getTaskComments(previousTasks.get(0).getId()); }else{ return Collections.emptyList(); } } public IPage selectAllTaskPage(IPage page, String keyword) { List flowList = new LinkedList<>(); TaskQuery todoQuery = taskService.createTaskQuery().active().includeProcessVariables(); addKeywordCondition(todoQuery, keyword); todoQuery.orderByTaskCreateTime().desc(); // 构建列表数据 FlowVO bladeFlow = new FlowVO(); buildFlowTaskList(bladeFlow, flowList, todoQuery,page.getCurrent(),page.getSize());//FlowEngineConstant.STATUS_TODO // 计算总数 long count = todoQuery.count(); // 设置页数 //page.setSize(count); // 设置总数 page.setTotal(count); // 设置数据 page.setRecords(flowList); return page; } /** * 超时任务查询 * @param page 分页信息 * @param keyword 关键字 * @return 分页数据 */ public IPage selectOvertimePage(IPage page, LocalDate createTimeBegin, LocalDate createTimeEnd, String assigneeName, String keyword) { List flowList = new LinkedList<>(); Date now = new Date(); TaskQuery todoQuery = taskService.createTaskQuery().taskDueBefore(now).active().includeProcessVariables(); if(Func.isNotEmpty(createTimeBegin)) { todoQuery.taskCreatedAfter(DateUtil.toDate(createTimeBegin)); } if(Func.isNotEmpty(createTimeEnd)) { todoQuery.taskCreatedBefore(DateUtil.toDate(createTimeEnd.plusDays(1))); } if(Func.isNotEmpty(keyword)) { todoQuery.taskVariableValueLike("assigneeName", "%"+assigneeName+"%"); } addKeywordCondition(todoQuery, keyword); todoQuery.orderByTaskCreateTime().desc(); // 构建列表数据 FlowVO bladeFlow = new FlowVO(); buildFlowTaskList(bladeFlow, flowList, todoQuery,page.getCurrent(),page.getSize());//FlowEngineConstant.STATUS_TODO // 计算总数 long count = todoQuery.count(); // 设置总数 page.setTotal(count); // 设置数据 page.setRecords(flowList); return page; } /** * 流程查询 功能 的分页 * @param page * @param createTimeBegin * @param createTimeEnd * @param keyword * @return */ public IPage selectSearchPage(IPage page,String myProcessName,String keyword, LocalDate createTimeBegin, LocalDate createTimeEnd) { List flowList = new LinkedList<>(); TaskQuery taskQuery = taskService.createTaskQuery().active().includeProcessVariables(); if(Func.isNotEmpty(createTimeBegin)) { taskQuery.taskCreatedAfter(DateUtil.toDate(createTimeBegin)); } if(Func.isNotEmpty(createTimeEnd)) { taskQuery.taskCreatedBefore(DateUtil.toDate(createTimeEnd.plusDays(1))); } if(Func.isNotEmpty(myProcessName)) { taskQuery.processVariableValueEquals(FlowVariableConstant.MY_PROCESS_NAME, myProcessName); } addKeywordCondition(taskQuery, keyword); taskQuery.orderByTaskCreateTime().desc(); // 构建列表数据 FlowVO bladeFlow = new FlowVO(); buildFlowTaskList(bladeFlow, flowList, taskQuery,page.getCurrent(),page.getSize());//FlowEngineConstant.STATUS_TODO // 计算总数 long count = taskQuery.count(); // 设置总数 page.setTotal(count); // 设置数据 page.setRecords(flowList); return page; } public void deleteProcessInstance(String processInstancesId) { runtimeService.deleteProcessInstance(processInstancesId, "流程查询-删除"); //TODO 删除出关联字段 } /** * 已完结的流程分页列表 * @param page 分页信息 * @param createTimeBegin * @param createTimeEnd * @param keyword 关键字 * @return */ public IPage selectFinishedPage(IPage page, String myProcessName, String keyword,LocalDateTime createTimeBegin, LocalDateTime createTimeEnd) { HistoricProcessInstanceQuery query = this.historyService.createHistoricProcessInstanceQuery().finished().includeProcessVariables(); //.finished() // 只查询已完成的流程.unfinished() // 查询未完成的流程 if(Func.isNotEmpty(myProcessName)) { query.variableValueEquals(FlowVariableConstant.MY_PROCESS_NAME, myProcessName); } if(createTimeBegin!=null) { query.startedAfter(DateUtil.toDate(createTimeBegin)); } if(createTimeEnd!=null) { query.startedBefore(DateUtil.toDate(createTimeEnd)); } if(Func.isNotEmpty(keyword)) { String likeVal = "%" + keyword + "%"; query.or(); query.variableValueLike(FlowVariableConstant.TITLE,likeVal); query.variableValueLike(FlowVariableConstant.PROCESS_NO, likeVal); query.variableValueLike(FlowVariableConstant.MACHINE_CODE, likeVal); query.variableValueLike(FlowVariableConstant.MACHINE_MODE, likeVal); query.variableValueLike(FlowVariableConstant.PROCESS_NAME, likeVal); query.variableValueLike(FlowVariableConstant.PROCESS_EDITION, likeVal); query.variableValueLike(FlowVariableConstant.CRAFT_EDITION, likeVal); query.endOr(); } query.orderByProcessInstanceEndTime().desc(); // 按结束时间降序排列 page.setTotal(query.count()); long firstResult = (page.getCurrent()-1) * page.getSize(); List processes = query .listPage((int)firstResult, (int)page.getSize()); List records = new LinkedList<>(); for(HistoricProcessInstance processInstance : processes) { FlowVO vo = new FlowVO(); vo.setProcessDefinitionKey(processInstance.getProcessDefinitionKey()); vo.setProcessInstanceId(processInstance.getId()); vo.setProcessDefinitionName(processInstance.getProcessDefinitionName()); vo.setVariables(processInstance.getProcessVariables()); vo.setProcessCreateTime(processInstance.getStartTime()); vo.setHistoryTaskEndTime(processInstance.getEndTime()); R ru = userClient.userInfoById(Long.valueOf(processInstance.getStartUserId())); if(ru.isSuccess()) { vo.setStartUserName(ru.getData().getName()); } vo.setFile(getFileString(processInstance.getId())); records.add(vo); } page.setRecords(records); return page; } /** * 异常流程 * @param page * @param myProcessName * @param keyword * @param createTimeBegin * @param createTimeEnd * @return */ public IPage selectExceptionPage(IPage page, String myProcessName, String keyword,LocalDateTime createTimeBegin, LocalDateTime createTimeEnd) { HistoricProcessInstanceQuery query = this.historyService.createHistoricProcessInstanceQuery().finished().includeProcessVariables(); //.finished() // 只查询已完成的流程.unfinished() // 查询未完成的流程 query.variableValueEquals(FlowVariableConstant.EXCEPTION, "1"); if(Func.isNotEmpty(myProcessName)) { query.variableValueEquals(FlowVariableConstant.MY_PROCESS_NAME, myProcessName); } if(createTimeBegin!=null) { query.startedAfter(DateUtil.toDate(createTimeBegin)); } if(createTimeEnd!=null) { query.startedBefore(DateUtil.toDate(createTimeEnd)); } if(Func.isNotEmpty(keyword)) { String likeVal = "%" + keyword + "%"; query.or(); query.variableValueLike(FlowVariableConstant.TITLE,likeVal); query.variableValueLike(FlowVariableConstant.PROCESS_NO, likeVal); query.variableValueLike(FlowVariableConstant.MACHINE_CODE, likeVal); query.variableValueLike(FlowVariableConstant.MACHINE_MODE, likeVal); query.variableValueLike(FlowVariableConstant.PROCESS_NAME, likeVal); query.variableValueLike(FlowVariableConstant.PROCESS_EDITION, likeVal); query.variableValueLike(FlowVariableConstant.CRAFT_EDITION, likeVal); query.endOr(); } query.orderByProcessInstanceEndTime().desc(); // 按结束时间降序排列 page.setTotal(query.count()); long firstResult = (page.getCurrent()-1) * page.getSize(); List processes = query .listPage((int)firstResult, (int)page.getSize()); List records = new LinkedList<>(); for(HistoricProcessInstance processInstance : processes) { FlowVO vo = new FlowVO(); vo.setProcessDefinitionKey(processInstance.getProcessDefinitionKey()); vo.setProcessInstanceId(processInstance.getId()); vo.setProcessDefinitionName(processInstance.getProcessDefinitionName()); vo.setVariables(processInstance.getProcessVariables()); vo.setProcessCreateTime(processInstance.getStartTime()); vo.setHistoryTaskEndTime(processInstance.getEndTime()); R ru = userClient.userInfoById(Long.valueOf(processInstance.getStartUserId())); if(ru.isSuccess()) { vo.setStartUserName(ru.getData().getName()); } vo.setFile(getFileString(processInstance.getId())); records.add(vo); } page.setRecords(records); return page; } /* 获取列表中的文件名 */ String getFileString(String processInstanceId){ String result = ""; List fileList = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, processInstanceId).list(); result = String.join(",",fileList.stream().map(FlowProgramFile::getName).toList()); return result; } /** * 个人已办(已完成任务) * @param page * @param processDefinitionKey * @param createTimeBegin * @param createTimeEnd * @param keyword * @return */ public IPage selectDonePage(IPage page, String processDefinitionKey,LocalDateTime createTimeBegin, LocalDateTime createTimeEnd, String keyword) { String userId = "" + AuthUtil.getUserId(); HistoricTaskInstanceQuery doneTaskQuery = historyService.createHistoricTaskInstanceQuery().taskAssignee(userId).finished().includeProcessVariables(); //.finished() // 只查询已完成的流程.unfinished() // 查询未完成的流程 if(Func.isNotEmpty(processDefinitionKey)) { doneTaskQuery.processDefinitionKey(processDefinitionKey); } if(createTimeBegin!=null) { Date after = DateUtil.toDate(createTimeBegin); doneTaskQuery.taskCreatedAfter(after); //doneTaskQuery.taskCreatedOn(after); //doneTaskQuery.taskInProgressStartTimeAfter(after); } if(createTimeEnd!=null) { Date before = DateUtil.toDate(createTimeEnd); doneTaskQuery.taskCreatedBefore(before); //doneTaskQuery.taskInProgressStartTimeBefore(before); } if (Func.isNotEmpty(keyword)) { addKeywordCondition(doneTaskQuery, keyword); } doneTaskQuery.orderByTaskCreateTime().desc(); // 按结束时间降序排列 page.setTotal(doneTaskQuery.count()); long firstResult = (page.getCurrent()-1) * page.getSize(); List processes = doneTaskQuery .listPage((int)firstResult, (int)page.getSize()); List records = new LinkedList<>(); Map startUserMap = new HashMap<>();//使用userId缓存其姓名 for(HistoricTaskInstance hisTask : processes) { FlowVO vo = new FlowVO(); HistoricProcessInstance processInstance = historyService .createHistoricProcessInstanceQuery() .processInstanceId(hisTask.getProcessInstanceId()) .singleResult(); if(startUserMap.containsKey(processInstance.getStartUserId())) { vo.setStartUserName(startUserMap.get(processInstance.getStartUserId())); }else { R ru = userClient.userInfoById(Long.valueOf(processInstance.getStartUserId())); if (ru.isSuccess()) { vo.setStartUserName(ru.getData().getName()); startUserMap.put(processInstance.getStartUserId(),ru.getData().getName()); } } vo.setProcessCreateTime(processInstance.getStartTime()); vo.setProcessInstanceId(hisTask.getProcessInstanceId()); vo.setProcessDefinitionName(processInstance.getProcessDefinitionName()); vo.setProcessDefinitionKey(processInstance.getProcessDefinitionKey()); vo.setTaskName(hisTask.getName()); vo.setTaskDefinitionKey(hisTask.getTaskDefinitionKey()); vo.setCreateTime(hisTask.getCreateTime()); vo.setEndTime(hisTask.getEndTime()); vo.setVariables(hisTask.getProcessVariables()); vo.setProcessCreateTime(processInstance.getStartTime()); vo.setHistoryTaskEndTime(hisTask.getEndTime()); vo.setFile(getFileString(hisTask.getProcessInstanceId())); records.add(vo); } page.setRecords(records); return page; } }