lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/constant/BusinessCodeConst.java
@@ -45,5 +45,7 @@ String PCR0004 = "PCR0004"; //设备能源部 String PCR0005 = "PCR0005"; //机动办管理员 String PCR0006 = "PCR0006"; } lxzn-module-eam/src/main/java/org/jeecg/modules/eam/controller/EamThirdMaintenanceOrderController.java
@@ -1,6 +1,7 @@ package org.jeecg.modules.eam.controller; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.annotations.Api; @@ -211,4 +212,27 @@ }); return Result.OK("批量领取成功 " + i.get() + " 条工单!"); } /** * 我的待办,审批动作 * * @param request * @return */ @ApiOperation(value = "三保工单-执行操作", notes = "三保工单-执行操作") @PutMapping(value = "/approval") public Result<?> approval(@RequestBody EamThirdMaintenanceRequest request) { if (request == null) { return Result.error("审批的对象不能为空!"); } // 检查请求参数 if (StrUtil.isBlank(request.getTaskId()) || StrUtil.isBlank(request.getDataId()) || StrUtil.isBlank(request.getInstanceId())) { return Result.error("审批任务错误或不存在!"); } EamThirdMaintenanceOrder entity = eamThirdMaintenanceOrderService.approval(request); if (entity == null) { return Result.error("操作失败!"); } return Result.ok("操作成功!"); } } lxzn-module-eam/src/main/java/org/jeecg/modules/eam/request/EamThirdMaintenanceRequest.java
@@ -75,4 +75,7 @@ private String confirmComment; @ApiModelProperty(value = "确认类型") private String confirmDealType; /**领导确认意见*/ @ApiModelProperty(value = "领导确认意见") private String leaderConfirmComment; } lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/IEamThirdMaintenanceOrderService.java
@@ -43,4 +43,11 @@ * @return */ boolean collect(String id); /** * 审批流程 * @param request * @return */ EamThirdMaintenanceOrder approval(EamThirdMaintenanceRequest request); } lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamThirdMaintenanceOrderServiceImpl.java
@@ -7,19 +7,23 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; import org.flowable.engine.TaskService; import org.flowable.task.api.Task; import org.jeecg.common.api.vo.FileUploadResult; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.DataBaseConstant; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.eam.aspect.annotation.EquipmentHistoryLog; import org.jeecg.modules.eam.constant.BusinessCodeConst; import org.jeecg.modules.eam.constant.EquipmentMaintenanceStatus; import org.jeecg.modules.eam.constant.SecondMaintenanceStatusEnum; import org.jeecg.modules.eam.constant.EquipmentOperationTagEnum; import org.jeecg.modules.eam.constant.ThirdMaintenanceStatusEnum; import org.jeecg.modules.eam.entity.EamEquipment; import org.jeecg.modules.eam.entity.EamThirdMaintenanceOrder; @@ -35,6 +39,7 @@ import org.jeecg.modules.flowable.service.IFlowDefinitionService; import org.jeecg.modules.flowable.service.IFlowTaskService; import org.jeecg.modules.system.service.ISysUserService; import org.jeecg.modules.system.vo.UserSelector; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -279,12 +284,15 @@ if (entity == null) { throw new JeecgBootException("要领取的工单不存在,请刷新重试!"); } if (!SecondMaintenanceStatusEnum.WAIT_MAINTENANCE.name().equals(entity.getMaintenanceStatus())) { if (!ThirdMaintenanceStatusEnum.WAIT_MAINTENANCE.name().equals(entity.getMaintenanceStatus())) { throw new JeecgBootException("该工单已进行过领取!"); } EamEquipment equipment = eamEquipmentService.getById(entity.getEquipmentId()); if (equipment == null) { throw new JeecgBootException("设备不存在,添加失败!"); } if (StringUtils.isBlank(equipment.getEquipmentManager())) { throw new JeecgBootException("设备未分配设备管理员,无法进入下级审批!"); } LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); if(sysUser == null || !BusinessCodeConst.PCR0001.equals(sysUser.getPost())) { @@ -310,9 +318,9 @@ variables.put("comment", entity.getRemark()); } variables.put("proofreading", true); List<String> usernames = new ArrayList<>(); usernames.add(entity.getOperator()); variables.put("NextAssignee", usernames); //并行任务会签 variables.put("maintenance_execution", Collections.singletonList(sysUser.getUsername())); variables.put("precision_check", Collections.singletonList(equipment.getEquipmentManager())); Result result = flowDefinitionService.startProcessInstanceByKey("third_maintenance_process", variables); if (result != null) { //更新设备保养状态 @@ -322,6 +330,149 @@ return true; } @Override @Transactional(rollbackFor = Exception.class) @EquipmentHistoryLog(operationTag = EquipmentOperationTagEnum.THIRD_MAINTENANCE, businessTable = "eam_third_maintenance_order") public EamThirdMaintenanceOrder approval(EamThirdMaintenanceRequest request) { EamThirdMaintenanceOrder entity = eamThirdMaintenanceOrderMapper.selectById(request.getId()); if (entity == null) { throw new JeecgBootException("审批的数据已删除,请刷新重试!"); } // 获取当前登录用户 LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); if (user == null || StrUtil.isBlank(user.getId())) { throw new JeecgBootException("未获取到登录用户,请重新登录后再试!"); } request.setAssignee(user.getUsername()); // 获取流程业务记录 FlowMyBusiness flowMyBusiness = flowMyBusinessService.getFlowMyBusiness(request.getInstanceId(), request.getTaskId()); if (flowMyBusiness == null) { throw new JeecgBootException("流程实例不存在,请刷新后重试!"); } boolean userAuthorized = isUserAuthorized(flowMyBusiness, user); if (!userAuthorized) { throw new JeecgBootException("用户无权操作此任务,请刷新后重试!"); } // 认领任务 if (!claimTask(flowMyBusiness.getTaskId(), user)) { throw new JeecgBootException("任务不存在、已完成或已被他人认领!"); } EamEquipment equipment = eamEquipmentService.getById(entity.getEquipmentId()); if (equipment == null) { throw new JeecgBootException("设备不存在,请检查!"); } ThirdMaintenanceStatusEnum status = ThirdMaintenanceStatusEnum.getInstance(entity.getMaintenanceStatus()); if (status == null) { return null; } //流程变量 Map<String, Object> values = new HashMap<>(); List<String> userApprovalList; List<UserSelector> userSelectors; switch (status) { case UNDER_MAINTENANCE: boolean parallelCompletion = flowTaskService.checkParallelCompletion(flowMyBusiness.getTaskId()); //执行完成 userSelectors = sysUserService.selectOperatorList(equipment.getEquipmentCode(), equipment.getOrgId(), BusinessCodeConst.PCR0006); if (CollectionUtil.isEmpty(userSelectors)) { throw new JeecgBootException("设备未分配给车间班组长,无法进入下级审批!"); } userApprovalList = userSelectors.stream().map(UserSelector::getUsername).collect(Collectors.toList()); values.put("dataId", entity.getId()); values.put("organization", "三保执行结束"); values.put("comment", "三保执行结束"); if (parallelCompletion) { values.put("NextAssignee", userApprovalList); } request.setComment("三保执行结束"); //设置entity if (parallelCompletion) { entity.setMaintenanceStatus(ThirdMaintenanceStatusEnum.WAIT_CONFIRM.name()); entity.setActualEndTime(new Date()); } if ("maintenance_execution".equals(flowMyBusiness.getTaskNameId())) { //执行保养 //处理附件 if (CollectionUtil.isNotEmpty(request.getImageFilesResult())) { List<FileUploadResult> fileUploadResultList = request.getImageFilesResult(); ObjectMapper mapper = new ObjectMapper(); try { String referenceFile = mapper.writeValueAsString(fileUploadResultList); entity.setImageFiles(referenceFile); } catch (JsonProcessingException e) { log.error("JSON转换失败:" + e.getMessage(), e); } } //处理详情 if (CollectionUtil.isNotEmpty(request.getTableDetailList())) { thirdMaintenanceOrderDetailService.updateBatchById(request.getTableDetailList()); } } else if ("precision_check".equals(flowMyBusiness.getTaskNameId())) { entity.setPrecisionChecker(user.getUsername()); entity.setPrecisionCheckTime(new Date()); //处理精度检验 if (CollectionUtil.isNotEmpty(request.getPrecisionDetailList())) { precisionCheckDetailService.updateBatchById(request.getPrecisionDetailList()); } } if (parallelCompletion) { //更新设备保养状态 eamEquipmentExtendService.updateEquipmentMaintenanceStatus(entity.getEquipmentId(), EquipmentMaintenanceStatus.THIRD_MAINTENANCE_WAIT_CONFIRM.name()); } break; case WAIT_CONFIRM: userSelectors = sysUserService.selectOperatorList(equipment.getEquipmentCode(), equipment.getOrgId(), BusinessCodeConst.PCR0003); if (CollectionUtil.isEmpty(userSelectors)) { throw new JeecgBootException("设备未分配给车间班组长,无法进入下级审批!"); } //班组长确认 userApprovalList = userSelectors.stream().map(UserSelector::getUsername).collect(Collectors.toList()); values.put("dataId", entity.getId()); values.put("organization", request.getConfirmComment()); values.put("comment", request.getConfirmComment()); values.put("NextAssignee", userApprovalList); values.put("confirmation", request.getConfirmDealType()); request.setComment(request.getConfirmComment()); //设置entity entity.setMaintenanceStatus(ThirdMaintenanceStatusEnum.WAIT_LEADER_CONFIRM.name()); entity.setConfirmUser(user.getUsername()); entity.setConfirmComment(request.getConfirmComment()); entity.setConfirmTime(new Date()); //处理报修 List<EamThirdMaintenanceOrderDetail> collect = request.getTableDetailList().stream().filter((detail) -> CommonConstant.DEFAULT_1.equals(detail.getReportFlag())).collect(Collectors.toList()); if (CollectionUtil.isNotEmpty(collect)) { eamReportRepairService.reportRepairFromThirdMaintenance(equipment.getId(), entity.getOperator(), collect); } break; case WAIT_LEADER_CONFIRM: values.put("dataId", entity.getId()); values.put("organization", request.getLeaderConfirmComment()); values.put("comment", request.getLeaderConfirmComment()); request.setComment(request.getLeaderConfirmComment()); //设置entity entity.setMaintenanceStatus(ThirdMaintenanceStatusEnum.COMPLETE.name()); entity.setConfirmLeader(user.getUsername()); entity.setLeaderConfirmComment(request.getLeaderConfirmComment()); entity.setLeaderConfirmTime(new Date()); //更新设备保养状态 eamEquipmentExtendService.updateEquipmentMaintenanceStatus(entity.getEquipmentId(), EquipmentMaintenanceStatus.NORMAL.name()); break; } request.setValues(values); // 完成流程任务 Result result = flowTaskService.complete(request); if (!result.isSuccess()) { throw new JeecgBootException("审批失败,请刷新查看!"); } //保存工单 eamThirdMaintenanceOrderMapper.updateById(entity); return entity; } private boolean isUserAuthorized(FlowMyBusiness flowMyBusiness, LoginUser user) { List<String> todoUsers = JSON.parseArray(flowMyBusiness.getTodoUsers(), String.class); return todoUsers != null && todoUsers.contains(user.getUsername()); lxzn-module-flowable/src/main/java/org/jeecg/modules/flowable/apithird/business/service/IFlowMyBusinessService.java
@@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.flowable.apithird.business.entity.FlowMyBusiness; import java.util.List; /** * @Description: 流程业务扩展表 * @Author: jeecg-boot @@ -17,9 +19,23 @@ FlowMyBusiness getFlowMyBusiness(String instanceId); /** * 根据流程实例id 获取 流程实例 * @param instanceId 流程实例id * @return */ FlowMyBusiness getFlowMyBusiness(String instanceId, String taskId); /** * 获取流程实例 * @param dataId 业务Id * @return */ FlowMyBusiness selectByDataId(String dataId); /** * 获取流程实例 多实例并行,存在多条记录 * @param dataId * @return */ List<FlowMyBusiness> selectListByDataId(String dataId); } lxzn-module-flowable/src/main/java/org/jeecg/modules/flowable/apithird/business/service/impl/FlowMyBusinessServiceImpl.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.collections4.CollectionUtils; import org.flowable.engine.HistoryService; import org.flowable.engine.history.HistoricActivityInstance; import org.jeecg.modules.flowable.apithird.business.dto.FlowMyBusinessDto; @@ -18,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Collections; import java.util.Date; import java.util.List; @@ -37,14 +39,14 @@ public HistoricActivityInstance getPreviousNode(String taskId) { // 获取当前任务的执行实例 ID String executionId = historyService.createHistoricTaskInstanceQuery() String processInstanceId = historyService.createHistoricTaskInstanceQuery() .taskId(taskId) .singleResult() .getExecutionId(); .getProcessInstanceId(); // 查询历史活动实例 List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery() .executionId(executionId) .processInstanceId(processInstanceId) .activityType("userTask") .finished() .orderByHistoricActivityInstanceEndTime() @@ -135,9 +137,28 @@ } @Override public FlowMyBusiness getFlowMyBusiness(String instanceId, String taskId) { List<FlowMyBusiness> businessList = super.list( new QueryWrapper<FlowMyBusiness>().eq("process_instance_id", instanceId).eq("task_id", taskId)); return businessList.isEmpty() ? null : businessList.get(0); } @Override public FlowMyBusiness selectByDataId(String dataId) { List<FlowMyBusiness> businessList = super.list( new QueryWrapper<FlowMyBusiness>().eq("data_id", dataId)); return businessList.isEmpty() ? null : businessList.get(0); } @Override public List<FlowMyBusiness> selectListByDataId(String dataId) { //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题 LambdaQueryWrapper<FlowMyBusiness> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(FlowMyBusiness::getDataId, dataId); List<FlowMyBusiness> list = flowMyBusinessMapper.selectList(queryWrapper); if(CollectionUtils.isEmpty(list)){ return Collections.emptyList(); } return list; } } lxzn-module-flowable/src/main/java/org/jeecg/modules/flowable/controller/FlowTaskController.java
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.flowable.domain.dto.FlowNextDto; import org.jeecg.modules.flowable.domain.dto.FlowTaskDto; import org.jeecg.modules.flowable.domain.vo.FlowTaskVo; import org.jeecg.modules.flowable.service.IFlowTaskService; @@ -17,6 +18,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; /** * <p>工作流任务管理<p> @@ -154,7 +156,7 @@ @ApiOperation(value = "获取下一节点") @PostMapping(value = "/nextFlowNode") public Result getNextFlowNode(@RequestBody FlowTaskVo flowTaskVo) { public Result<List<FlowNextDto>> getNextFlowNode(@RequestBody FlowTaskVo flowTaskVo) { return flowTaskService.getNextFlowNode(flowTaskVo); } lxzn-module-flowable/src/main/java/org/jeecg/modules/flowable/service/IFlowTaskService.java
@@ -3,6 +3,7 @@ import org.flowable.task.api.Task; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.flowable.apithird.business.dto.FlowMyBusinessDto; import org.jeecg.modules.flowable.domain.dto.FlowNextDto; import org.jeecg.modules.flowable.domain.dto.FlowViewerDto; import org.jeecg.modules.flowable.domain.vo.FlowTaskVo; @@ -180,9 +181,13 @@ * @param flowTaskVo 任务 * @return */ Result getNextFlowNode(FlowTaskVo flowTaskVo); Result<List<FlowNextDto>> getNextFlowNode(FlowTaskVo flowTaskVo); /** * 检查 并行任务节点是否都已完成 * @param currentTaskId * @return */ boolean checkParallelCompletion(String currentTaskId); } lxzn-module-flowable/src/main/java/org/jeecg/modules/flowable/service/impl/FlowDefinitionServiceImpl.java
@@ -1,6 +1,8 @@ package org.jeecg.modules.flowable.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; @@ -44,7 +46,6 @@ /** * 流程定义 * */ @Service public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFlowDefinitionService { @@ -201,6 +202,7 @@ InputStream in = processDiagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engConf.getActivityFontName(), engConf.getLabelFontName(), engConf.getAnnotationFontName(), engConf.getClassLoader(), 1.0, true); return in; } /** * 读取xml * @@ -244,6 +246,7 @@ Result result = startProcessInstanceById(processDefinition.getId(),variables); return result; } /** * 根据流程定义ID启动流程实例 * @@ -283,13 +286,11 @@ //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题 FlowMyBusiness business = flowMyBusinessService.getByDataId(dataId); //设置数据 FlowNextDto nextFlowNode = flowTaskService.getNextFlowNode(task.getId(), variables); List<FlowNextDto> nextFlowNodeList = flowTaskService.getNextFlowNode(task.getId(), variables); taskService.complete(task.getId(), variables); //下一个实例节点 多实例会是一个list,随意取一个即可 数组中定义Key是一致的 //Task task2 = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).active().singleResult(); List<Task> task2List = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).active().list(); Task task2 = null; if(task2List.size()>0) task2 = task2List.get(0); String doneUsers = business.getDoneUsers(); // 处理过流程的人 JSONArray doneUserList = new JSONArray(); @@ -300,9 +301,25 @@ doneUserList.add(sysUser.getUsername()); } if (nextFlowNode!=null){ //**有下一个节点 if (CollectionUtil.isEmpty(nextFlowNodeList)) { // **没有下一个节点,流程已经结束了 business.setProcessDefinitionId(procDefId) .setProcessInstanceId(processInstance.getProcessInstanceId()) // .setActStatus(ActStatus.pass) .setProposer(sysUser.getUsername()) .setDoneUsers(doneUserList.toJSONString()) ; flowMyBusinessService.updateById(business); } else if (nextFlowNodeList.size() == 1) { //下个节点只有一个 FlowNextDto nextFlowNode = nextFlowNodeList.get(0); UserTask nextTask = nextFlowNode.getUserTask(); Task task2 = null; Optional<Task> first = task2List.stream().filter(t -> t.getTaskDefinitionKey().equals(nextTask.getId())).findFirst(); if (first.isPresent()) { task2 = first.get(); } if (task2 != null) { //能够处理下个节点的候选人 List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList(); @@ -310,7 +327,7 @@ //spring容器类名 String serviceImplName = business.getServiceImplName(); FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName); List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(), variables); List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionId(), variables); business.setProcessDefinitionId(procDefId) .setProcessInstanceId(processInstance.getProcessInstanceId()) //// .setActStatus(ActStatus.start) @@ -322,8 +339,53 @@ .setDoneUsers(doneUserList.toJSONString()); if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){ // 删除后重写 for (Task task2One : task2List) { for (String oldUser : collect_username) { taskService.deleteCandidateUser(task2.getId(), oldUser); } // 业务层有指定候选人,覆盖 for (String newUser : beforeParamsCandidateUsernames) { taskService.addCandidateUser(task2.getId(), newUser); } business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); } else { // 业务层没有指定候选人,直接覆盖 business.setTodoUsers(JSON.toJSONString(collect_username)); } flowMyBusinessService.updateById(business); } } else { for (FlowNextDto nextFlowNode : nextFlowNodeList) { //**有下一个节点 UserTask nextTask = nextFlowNode.getUserTask(); Task task2 = null; Optional<Task> first = task2List.stream().filter(t -> t.getTaskDefinitionKey().equals(nextTask.getId())).findFirst(); if (first.isPresent()) { task2 = first.get(); } if (task2 != null) { //新的业务流程节点 FlowMyBusiness newBusiness = BeanUtil.copyProperties(business, FlowMyBusiness.class, "id"); //能够处理下个节点的候选人 List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList(); List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList()); //spring容器类名 String serviceImplName = newBusiness.getServiceImplName(); FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName); List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionId(), variables); newBusiness.setProcessDefinitionId(procDefId) .setProcessInstanceId(processInstance.getProcessInstanceId()) //// .setActStatus(ActStatus.start) .setProposer(sysUser.getUsername()) .setTaskId(task2.getId()) .setTaskName(nextTask.getName()) .setTaskNameId(nextTask.getId()) .setPriority(nextTask.getPriority()) .setDoneUsers(doneUserList.toJSONString()); if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) { // 删除后重写 for (Task task2One : task2List) { for (String oldUser : beforeParamsCandidateUsernames) { taskService.deleteCandidateUser(task2One.getId(),oldUser); } } @@ -333,27 +395,37 @@ taskService.addCandidateUser(task2One.getId(),newUser); } } business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); newBusiness.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); }else { // 业务层没有指定候选人,直接覆盖 business.setTodoUsers(JSON.toJSONString(collect_username)); newBusiness.setTodoUsers(JSON.toJSONString(collect_username)); // 删除后重写 for (Task task2One : task2List) { for (String oldUser : collect_username) { taskService.deleteCandidateUser(task2One.getId(), oldUser); } } else { // **没有下一个节点,流程已经结束了 business.setProcessDefinitionId(procDefId) .setProcessInstanceId(processInstance.getProcessInstanceId()) // .setActStatus(ActStatus.pass) .setProposer(sysUser.getUsername()) .setDoneUsers(doneUserList.toJSONString()) ; } flowMyBusinessService.updateById(business); // 业务层有指定候选人,覆盖 for (Task task2One : task2List) { for (String newUser : collect_username) { taskService.addCandidateUser(task2One.getId(), newUser); } } } flowMyBusinessService.save(newBusiness); } } //删除原有的业务数据 flowMyBusinessService.removeById(business.getId()); } //spring容器类名 String serviceImplName = business.getServiceImplName(); FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName); // 流程处理完后,进行回调业务层 business.setValues(variables); if (flowCallBackService!=null)flowCallBackService.afterFlowHandle(business); if (flowCallBackService != null) { flowCallBackService.afterFlowHandle(business); } return Result.OK("流程启动成功"); } lxzn-module-flowable/src/main/java/org/jeecg/modules/flowable/service/impl/FlowTaskServiceImpl.java
@@ -1,5 +1,6 @@ package org.jeecg.modules.flowable.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; @@ -68,6 +69,7 @@ import java.util.stream.Collectors; /** * **/ @Service @Slf4j @@ -78,6 +80,7 @@ private IFlowThirdService iFlowThirdService; @Autowired FlowMyBusinessServiceImpl flowMyBusinessService; /** * 完成任务 * @@ -111,7 +114,7 @@ //业务数据id String dataId = taskVo.getDataId(); //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题 FlowMyBusiness business = flowMyBusinessService.getByDataId(dataId); FlowMyBusiness business = flowMyBusinessService.getFlowMyBusiness(taskVo.getInstanceId(), taskVo.getTaskId()); //spring容器类名 String serviceImplName = business.getServiceImplName(); FlowCallBackServiceI flowCallBackService = (FlowCallBackServiceI) SpringContextUtils.getBean(serviceImplName); @@ -124,7 +127,9 @@ // 业务层有设置变量,使用业务层的变量 values = flowBeforeParamsValues; } FlowNextDto nextFlowNode = this.getNextFlowNode(task.getId(), values); //并行网关 多任务 List<FlowNextDto> nextFlowNodeList = this.getNextFlowNode(task.getId(), values); //下一个实例节点 if (DelegationState.PENDING.equals(task.getDelegationState())) { taskService.resolveTask(taskVo.getTaskId(), values); @@ -132,21 +137,6 @@ taskService.complete(taskVo.getTaskId(), values); } List<Task> task2List = taskService.createTaskQuery().processInstanceId(business.getProcessInstanceId()).active().list(); Task task2 = null; if (CollUtil.isNotEmpty(task2List)){ task2 = task2List.get(0); } // 下个节点候选人 List<String> beforeParamsCandidateUsernames = Lists.newArrayList(); if(task2!=null){ beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(),taskVo.getValues()); } List<String> candidateUsers = taskVo.getCandidateUsers(); if (CollUtil.isNotEmpty(candidateUsers)){ // 前端传入候选人 覆盖 beforeParamsCandidateUsernames = candidateUsers; } String doneUsers = business.getDoneUsers(); // 处理过流程的人 JSONArray doneUserList = new JSONArray(); @@ -157,7 +147,33 @@ doneUserList.add(loginUser.getUsername()); } if (task2!=null && task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())){ if (CollectionUtils.isEmpty(nextFlowNodeList)) { // **没有下一个节点,流程已经结束了 business .setDoneUsers(doneUserList.toJSONString()) .setTodoUsers("") .setTaskId("") .setTaskNameId("") .setTaskName("") ; flowMyBusinessService.updateById(business); } else if (nextFlowNodeList.size() == 1) { FlowNextDto nextFlowNode = nextFlowNodeList.get(0); UserTask nextTask = nextFlowNode.getUserTask(); Task task2 = null; Optional<Task> first = task2List.stream().filter(t -> t.getTaskDefinitionKey().equals(nextTask.getId())).findFirst(); task2 = first.orElseGet(() -> task2List.get(0)); if (task2 != null) { // 下个节点候选人 List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(), taskVo.getValues()); List<String> candidateUsers = taskVo.getCandidateUsers(); if (CollUtil.isNotEmpty(candidateUsers)) { // 前端传入候选人 覆盖 beforeParamsCandidateUsernames = candidateUsers; } if (task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())) { //多实例 会签 TODO // * 当前节点是会签节点,没有走完 business.setTaskId(task2.getId()) // .setActStatus(ActStatus.doing) @@ -166,37 +182,26 @@ String todoUsersStr = business.getTodoUsers(); JSONArray todosArr = JSON.parseArray(todoUsersStr); // 删除后重写 for (Task task2One : task2List) { for (Object oldUser : todosArr) { taskService.deleteCandidateUser(task2One.getId(),oldUser.toString()); } taskService.deleteCandidateUser(task2.getId(), oldUser.toString()); } // 重写 if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){ beforeParamsCandidateUsernames.remove(loginUser.getUsername()); // 业务层有指定候选人,覆盖 for (Task task2One : task2List) { for (String newUser : beforeParamsCandidateUsernames) { taskService.addCandidateUser(task2One.getId(),newUser); } taskService.addCandidateUser(task2.getId(), newUser); } business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); } else { todosArr.remove(loginUser.getUsername()); for (Task task2One : task2List) { for (Object oldUser : todosArr) { taskService.addCandidateUser(task2One.getId(),oldUser.toString()); } taskService.addCandidateUser(task2.getId(), oldUser.toString()); } business.setTodoUsers(todosArr.toJSONString()); } } else { // * 下一节点是会签节点 或 普通用户节点,逻辑一致 if (nextFlowNode!=null){ //**有下一个节点 UserTask nextTask = nextFlowNode.getUserTask(); //能够处理下个节点的候选人 List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList(); List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList()); @@ -214,43 +219,120 @@ .setTodoUsers(JSON.toJSONString(collect_username)) ; // 删除后重写 for (Task task2One : task2List) { for (String oldUser : collect_username) { taskService.deleteCandidateUser(task2One.getId(),oldUser); taskService.deleteCandidateUser(task2.getId(), oldUser); } } if (CollUtil.isEmpty(candidateUsers)&&CollUtil.isNotEmpty(beforeParamsCandidateUsernames)){ if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) { // 前端没有传入候选人 && 业务层有指定候选人,覆盖 for (Task task2One : task2List) { for (String newUser : beforeParamsCandidateUsernames) { taskService.addCandidateUser(task2One.getId(),newUser); } taskService.addCandidateUser(task2.getId(), newUser); } business.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); } else { for (Task task2One : task2List) { for (String oldUser : collect_username) { taskService.addCandidateUser(task2One.getId(),oldUser); taskService.addCandidateUser(task2.getId(), oldUser); } business.setTodoUsers(JSON.toJSONString(collect_username)); } } } flowMyBusinessService.updateById(business); } else { for(FlowNextDto nextFlowNode : nextFlowNodeList) { //**有下一个节点 UserTask nextTask = nextFlowNode.getUserTask(); Task task2 = null; Optional<Task> first = task2List.stream().filter(t -> t.getTaskDefinitionKey().equals(nextTask.getId())).findFirst(); if (first.isPresent()) { task2 = first.get(); } if (task2 != null) { //新的业务流程节点 FlowMyBusiness newBusiness = BeanUtil.copyProperties(business, FlowMyBusiness.class, "id"); // 下个节点候选人 List<String> beforeParamsCandidateUsernames = flowCallBackService.flowCandidateUsernamesOfTask(task2.getTaskDefinitionKey(), taskVo.getValues()); List<String> candidateUsers = taskVo.getCandidateUsers(); if (CollUtil.isNotEmpty(candidateUsers)) { // 前端传入候选人 覆盖 beforeParamsCandidateUsernames = candidateUsers; } if (task.getTaskDefinitionKey().equals(task2.getTaskDefinitionKey())) { //多实例 会签 TODO // * 当前节点是会签节点,没有走完 newBusiness.setTaskId(task2.getId()) // .setActStatus(ActStatus.doing) .setDoneUsers(doneUserList.toJSONString()) ; String todoUsersStr = business.getTodoUsers(); JSONArray todosArr = JSON.parseArray(todoUsersStr); // 删除后重写 for (Object oldUser : todosArr) { taskService.deleteCandidateUser(task2.getId(), oldUser.toString()); } // 重写 if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) { beforeParamsCandidateUsernames.remove(loginUser.getUsername()); // 业务层有指定候选人,覆盖 for (String newUser : beforeParamsCandidateUsernames) { taskService.addCandidateUser(task2.getId(), newUser); } newBusiness.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); } else { todosArr.remove(loginUser.getUsername()); for (Object oldUser : todosArr) { taskService.addCandidateUser(task2.getId(), oldUser.toString()); } newBusiness.setTodoUsers(todosArr.toJSONString()); } } else { // **没有下一个节点,流程已经结束了 business .setDoneUsers(doneUserList.toJSONString()) .setTodoUsers("") .setTaskId("") .setTaskNameId("") .setTaskName("") ; //能够处理下个节点的候选人 List<SysUser> nextFlowNodeUserList = nextFlowNode.getUserList(); List<String> collect_username = nextFlowNodeUserList.stream().map(SysUser::getUsername).collect(Collectors.toList()); if (CollUtil.isNotEmpty(candidateUsers)) { // 前端传入候选人 collect_username = candidateUsers; } newBusiness .setTaskId(task2.getId()) // .setActStatus(ActStatus.doing) .setTaskNameId(nextTask.getId()) .setTaskName(nextTask.getName()) .setPriority(nextTask.getPriority()) .setDoneUsers(doneUserList.toJSONString()) .setTodoUsers(JSON.toJSONString(collect_username)) ; // 删除后重写 for (String oldUser : collect_username) { taskService.deleteCandidateUser(task2.getId(), oldUser); } if (CollUtil.isNotEmpty(beforeParamsCandidateUsernames)) { // 前端没有传入候选人 && 业务层有指定候选人,覆盖 for (String newUser : beforeParamsCandidateUsernames) { taskService.addCandidateUser(task2.getId(), newUser); } newBusiness.setTodoUsers(JSON.toJSONString(beforeParamsCandidateUsernames)); } else { for (String oldUser : collect_username) { taskService.addCandidateUser(task2.getId(), oldUser); } newBusiness.setTodoUsers(JSON.toJSONString(collect_username)); } } flowMyBusinessService.save(newBusiness); } flowMyBusinessService.updateById(business); } //删除原有的业务数据 flowMyBusinessService.removeById(business.getId()); } flowMyBusinessService.updateById(business); // 流程处理完后,进行回调业务层 business.setValues(values); if (flowCallBackService!=null)flowCallBackService.afterFlowHandle(business); if (flowCallBackService != null) { flowCallBackService.afterFlowHandle(business); } return Result.OK(); } @@ -266,6 +348,7 @@ flowTaskVo.setTaskId(business.getTaskId()); this.taskReject(flowTaskVo); } /** * 驳回任务 * @@ -487,6 +570,7 @@ } } @Override public void taskReturnByDataId(FlowTaskVo flowTaskVo){ //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题 @@ -494,6 +578,7 @@ flowTaskVo.setTaskId(business.getTaskId()); taskReturn(flowTaskVo); } /** * 退回任务 * @@ -671,6 +756,7 @@ /** * 结束流程 * * @param processInstanceId 流程实例 ID * @param deleteReason 定义删除原因 */ @@ -942,6 +1028,7 @@ /** * 判断多个任务是否处于同一流程节点 * * @param taskIds 逗号分隔的任务ID字符串 * @return 统一结果封装 */ @@ -1327,6 +1414,7 @@ /** * 顺序抽取节点 * * @param orderKeys 容器 * @param sourceKey 源 * @param flowElements 所有的节点对象 @@ -1373,45 +1461,75 @@ * @return */ @Override public Result getNextFlowNode(FlowTaskVo flowTaskVo) { public Result<List<FlowNextDto>> getNextFlowNode(FlowTaskVo flowTaskVo) { // todo 似乎逻辑未写完,待检查 FlowNextDto flowNextDto = this.getNextFlowNode(flowTaskVo.getTaskId(), flowTaskVo.getValues()); if (flowNextDto==null) { List<FlowNextDto> nextDtoList = this.getNextFlowNode(flowTaskVo.getTaskId(), flowTaskVo.getValues()); if (CollectionUtils.isEmpty(nextDtoList)) { return Result.OK("流程已完结", null); } return Result.OK(flowNextDto); return Result.OK(nextDtoList); } @Override public boolean checkParallelCompletion(String currentTaskId) { //获取当前任务 Task currentTask = taskService.createTaskQuery().taskId(currentTaskId).singleResult(); if (currentTask == null) { return false; } //获取当前执行 Execution execution = runtimeService.createExecutionQuery().executionId(currentTask.getExecutionId()).singleResult(); if (execution == null) { return false; } String parentId = execution.getParentId(); if (StringUtils.isBlank(parentId)) { //没有父节点 代表没有并行任务 return true; } // 获取所有兄弟执行 List<Execution> siblingExecutions = runtimeService.createExecutionQuery() .parentId(parentId) .list(); for (Execution siblingExecution : siblingExecutions) { if (!siblingExecution.getId().equals(execution.getId())) { //非自身的兄弟节点 long count = runtimeService.createActivityInstanceQuery().executionId(siblingExecution.getId()).unfinished().count(); if (count > 0) { return false; } } } return true; } /** * 获取下一个节点信息,流程定义上的节点信息 * * @param taskId 当前节点id * @param values 流程变量 * @return 如果返回null,表示没有下一个节点,流程结束 */ public FlowNextDto getNextFlowNode(String taskId, Map<String, Object> values) { public List<FlowNextDto> getNextFlowNode(String taskId, Map<String, Object> values) { //当前节点 Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (Objects.nonNull(task)) { // 下个任务节点 List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, values); if (CollectionUtils.isNotEmpty(nextUserTask)) { FlowNextDto flowNextDto = new FlowNextDto(); List<FlowNextDto> nextDtoList = Lists.newArrayList(); FlowNextDto flowNextDto; for (UserTask userTask : nextUserTask) { flowNextDto = new FlowNextDto(); flowNextDto.setUserTask(userTask); //待办人员 List<SysUser> sysUserFromTask = this.getSysUserFromTask(userTask); flowNextDto.setUserList(sysUserFromTask); MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics(); if (Objects.nonNull(multiInstance)) { // 会签 多实例 String collectionString = multiInstance.getInputDataItem(); Object colObj = values.get(collectionString); List<String> userNameList = null; if(colObj!=null){ userNameList = (List) colObj; } if (CollUtil.isNotEmpty(userNameList)){ //多任务并行 Object colObj = values.get(userTask.getId()); if (Objects.nonNull(colObj)) { List<String> userNameList = (List) colObj; // 待办人员从变量中获取 否则就是节点中配置的用户 sysUserFromTask List<SysUser> userList = Lists.newArrayList(); for (String username : userNameList) { @@ -1426,20 +1544,17 @@ } else { // 变量中没有传入,写入节点中配置的用户 List<String> collect_username = sysUserFromTask.stream().map(SysUser::getUsername).collect(Collectors.toList()); values.put(collectionString,collect_username); values.put(userTask.getId(), collect_username); } } else { // todo 读取自定义节点属性做些啥? //String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE); String userType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE); nextDtoList.add(flowNextDto); } } return flowNextDto; return nextDtoList; } } return null; } public List<SysUser> getSysUserFromTask(UserTask userTask) { String assignee = userTask.getAssignee(); if (StrUtil.isNotBlank(assignee)){ @@ -1465,6 +1580,7 @@ } return Lists.newArrayList(); } /** * 流程完成时间处理 *