¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.dromara.workflow.service.impl; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.dromara.common.core.domain.dto.StartProcessReturnDTO; |
| | | import org.dromara.common.core.domain.dto.UserDTO; |
| | | import org.dromara.common.core.enums.BusinessStatusEnum; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.service.UserService; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.core.utils.ValidatorUtils; |
| | | import org.dromara.common.core.validate.AddGroup; |
| | | import org.dromara.common.core.validate.EditGroup; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import org.dromara.warm.flow.core.dto.FlowParams; |
| | | import org.dromara.warm.flow.core.entity.*; |
| | | import org.dromara.warm.flow.core.enums.NodeType; |
| | | import org.dromara.warm.flow.core.enums.SkipType; |
| | | import org.dromara.warm.flow.core.service.*; |
| | | import org.dromara.warm.flow.orm.entity.*; |
| | | import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper; |
| | | import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper; |
| | | import org.dromara.warm.flow.orm.mapper.FlowTaskMapper; |
| | | import org.dromara.workflow.common.ConditionalOnEnable; |
| | | import org.dromara.workflow.common.enums.TaskAssigneeType; |
| | | import org.dromara.workflow.common.enums.TaskStatusEnum; |
| | | import org.dromara.workflow.domain.bo.*; |
| | | import org.dromara.workflow.domain.vo.FlowHisTaskVo; |
| | | import org.dromara.workflow.domain.vo.FlowTaskVo; |
| | | import org.dromara.workflow.handler.FlowProcessEventHandler; |
| | | import org.dromara.workflow.handler.WorkflowPermissionHandler; |
| | | import org.dromara.workflow.mapper.FlwCategoryMapper; |
| | | import org.dromara.workflow.mapper.FlwTaskMapper; |
| | | import org.dromara.workflow.service.IFlwTaskService; |
| | | import org.dromara.workflow.utils.WorkflowUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static org.dromara.workflow.common.constant.FlowConstant.*; |
| | | |
| | | /** |
| | | * ä»»å¡ æå¡å±å®ç° |
| | | * |
| | | * @author may |
| | | */ |
| | | @ConditionalOnEnable |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class FlwTaskServiceImpl implements IFlwTaskService { |
| | | |
| | | private final TaskService taskService; |
| | | private final InsService insService; |
| | | private final DefService defService; |
| | | private final HisTaskService hisTaskService; |
| | | private final NodeService nodeService; |
| | | private final FlowInstanceMapper flowInstanceMapper; |
| | | private final FlowTaskMapper flowTaskMapper; |
| | | private final FlowHisTaskMapper flowHisTaskMapper; |
| | | private final IdentifierGenerator identifierGenerator; |
| | | private final FlowProcessEventHandler flowProcessEventHandler; |
| | | private final UserService userService; |
| | | private final FlwTaskMapper flwTaskMapper; |
| | | private final FlwCategoryMapper flwCategoryMapper; |
| | | |
| | | /** |
| | | * å¯å¨ä»»å¡ |
| | | * |
| | | * @param startProcessBo å¯å¨æµç¨åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public StartProcessReturnDTO startWorkFlow(StartProcessBo startProcessBo) { |
| | | String businessId = startProcessBo.getBusinessId(); |
| | | if (StringUtils.isBlank(businessId)) { |
| | | throw new ServiceException("å¯å¨å·¥ä½æµæ¶å¿
é¡»å
å«ä¸å¡ID"); |
| | | } |
| | | // å¯å¨æµç¨å®ä¾ï¼æäº¤ç³è¯·ï¼ |
| | | Map<String, Object> variables = startProcessBo.getVariables(); |
| | | // æµç¨å起人 |
| | | variables.put(INITIATOR, LoginHelper.getUserIdStr()); |
| | | // ä¸å¡id |
| | | variables.put(BUSINESS_ID, businessId); |
| | | FlowInstance flowInstance = flowInstanceMapper.selectOne(new LambdaQueryWrapper<>(FlowInstance.class) |
| | | .eq(FlowInstance::getBusinessId, businessId)); |
| | | if (ObjectUtil.isNotNull(flowInstance)) { |
| | | BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus()); |
| | | List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId())); |
| | | StartProcessReturnDTO dto = new StartProcessReturnDTO(); |
| | | dto.setProcessInstanceId(taskList.get(0).getInstanceId()); |
| | | dto.setTaskId(taskList.get(0).getId()); |
| | | return dto; |
| | | } |
| | | FlowParams flowParams = new FlowParams(); |
| | | flowParams.flowCode(startProcessBo.getFlowCode()); |
| | | flowParams.variable(startProcessBo.getVariables()); |
| | | flowParams.flowStatus(BusinessStatusEnum.DRAFT.getStatus()); |
| | | Instance instance; |
| | | try { |
| | | instance = insService.start(businessId, flowParams); |
| | | } catch (Exception e) { |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | // ç³è¯·äººæ§è¡æµç¨ |
| | | List<Task> taskList = taskService.list(new FlowTask().setInstanceId(instance.getId())); |
| | | if (taskList.size() > 1) { |
| | | throw new ServiceException("è¯·æ£æ¥æµç¨ç¬¬ä¸ä¸ªç¯èæ¯å¦ä¸ºç³è¯·äººï¼"); |
| | | } |
| | | StartProcessReturnDTO dto = new StartProcessReturnDTO(); |
| | | dto.setProcessInstanceId(instance.getId()); |
| | | dto.setTaskId(taskList.get(0).getId()); |
| | | return dto; |
| | | } |
| | | |
| | | /** |
| | | * åçä»»å¡ |
| | | * |
| | | * @param completeTaskBo åçä»»å¡åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean completeTask(CompleteTaskBo completeTaskBo) { |
| | | try { |
| | | // è·åä»»å¡IDå¹¶æ¥è¯¢å¯¹åºçæµç¨ä»»å¡åå®ä¾ä¿¡æ¯ |
| | | Long taskId = completeTaskBo.getTaskId(); |
| | | List<String> messageType = completeTaskBo.getMessageType(); |
| | | String notice = completeTaskBo.getNotice(); |
| | | // è·åæé人 |
| | | List<FlowCopyBo> flowCopyList = completeTaskBo.getFlowCopyList(); |
| | | FlowTask flowTask = flowTaskMapper.selectById(taskId); |
| | | if (ObjectUtil.isNull(flowTask)) { |
| | | throw new ServiceException("æµç¨ä»»å¡ä¸å卿任å¡å·²å®¡æ¹ï¼"); |
| | | } |
| | | Instance ins = insService.getById(flowTask.getInstanceId()); |
| | | // è·åæµç¨å®ä¹ä¿¡æ¯ |
| | | Definition definition = defService.getById(flowTask.getDefinitionId()); |
| | | // æ£æ¥æµç¨ç¶ææ¯å¦ä¸ºè稿ãå·²æ¤éæå·²éåç¶æï¼è¥æ¯åæ§è¡æµç¨æäº¤çå¬ |
| | | if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) { |
| | | flowProcessEventHandler.processHandler(definition.getFlowCode(), ins.getBusinessId(), ins.getFlowStatus(), null, true); |
| | | } |
| | | // æå»ºæµç¨åæ°ï¼å
æ¬åéã跳转类åãæ¶æ¯ãå¤ç人ãæéçä¿¡æ¯ |
| | | FlowParams flowParams = new FlowParams(); |
| | | flowParams.variable(completeTaskBo.getVariables()); |
| | | flowParams.skipType(SkipType.PASS.getKey()); |
| | | flowParams.message(completeTaskBo.getMessage()); |
| | | flowParams.flowStatus(BusinessStatusEnum.WAITING.getStatus()).hisStatus(TaskStatusEnum.PASS.getStatus()); |
| | | |
| | | flowParams.hisTaskExt(completeTaskBo.getFileId()); |
| | | // æ§è¡ä»»å¡è·³è½¬ï¼å¹¶æ ¹æ®è¿åçå¤ç人设置ä¸ä¸æ¥å¤ç人 |
| | | Instance instance = taskService.skip(taskId, flowParams); |
| | | this.setHandler(instance, flowTask, flowCopyList); |
| | | // æ¶æ¯éç¥ |
| | | WorkflowUtils.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice); |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置åç人 |
| | | * |
| | | * @param instance å®ä¾ |
| | | * @param task (å½åä»»å¡)æªåççä»»å¡ |
| | | * @param flowCopyList æé人 |
| | | */ |
| | | private void setHandler(Instance instance, FlowTask task, List<FlowCopyBo> flowCopyList) { |
| | | if (ObjectUtil.isNull(instance)) { |
| | | return; |
| | | } |
| | | // æ·»å æé人 |
| | | this.setCopy(task, flowCopyList); |
| | | // æ ¹æ®æµç¨å®ä¾IDæ¥è¯¢ææå
³èçä»»å¡ |
| | | List<FlowTask> flowTasks = this.selectByInstId(instance.getId()); |
| | | if (CollUtil.isEmpty(flowTasks)) { |
| | | return; |
| | | } |
| | | List<Long> taskIdList = StreamUtils.toList(flowTasks, FlowTask::getId); |
| | | // è·åä¸å½åä»»å¡å
³èçç¨æ·å表 |
| | | List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(taskIdList); |
| | | if (CollUtil.isEmpty(associatedUsers)) { |
| | | return; |
| | | } |
| | | List<User> userList = new ArrayList<>(); |
| | | // éåä»»å¡å表ï¼å¤çæ¯ä¸ªä»»å¡çåç人 |
| | | for (FlowTask flowTask : flowTasks) { |
| | | List<User> users = StreamUtils.filter(associatedUsers, user -> Objects.equals(user.getAssociated(), flowTask.getId())); |
| | | if (CollUtil.isNotEmpty(users)) { |
| | | userList.addAll(WorkflowUtils.buildUser(users, flowTask.getId())); |
| | | } |
| | | } |
| | | // æ¹éå é¤ç°æä»»å¡çåçäººè®°å½ |
| | | WorkflowUtils.getFlowUserService().deleteByTaskIds(taskIdList); |
| | | // ç¡®ä¿è¦ä¿åç userList ä¸ä¸ºç©º |
| | | if (CollUtil.isEmpty(userList)) { |
| | | return; |
| | | } |
| | | WorkflowUtils.getFlowUserService().saveBatch(userList); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å æé人 |
| | | * |
| | | * @param task ä»»å¡ä¿¡æ¯ |
| | | * @param flowCopyList æé人 |
| | | */ |
| | | public void setCopy(FlowTask task, List<FlowCopyBo> flowCopyList) { |
| | | if (CollUtil.isEmpty(flowCopyList)) { |
| | | return; |
| | | } |
| | | // æ·»å æéäººè®°å½ |
| | | FlowHisTask flowHisTask = flowHisTaskMapper.selectList(new LambdaQueryWrapper<>(FlowHisTask.class).eq(FlowHisTask::getTaskId, task.getId())).get(0); |
| | | FlowNode flowNode = new FlowNode(); |
| | | flowNode.setNodeCode(flowHisTask.getTargetNodeCode()); |
| | | flowNode.setNodeName(flowHisTask.getTargetNodeName()); |
| | | //çææ°çä»»å¡id |
| | | long taskId = identifierGenerator.nextId(null).longValue(); |
| | | task.setId(taskId); |
| | | task.setNodeName("ãæéã" + task.getNodeName()); |
| | | Date updateTime = new Date(flowHisTask.getUpdateTime().getTime() - 1000); |
| | | FlowParams flowParams = FlowParams.build(); |
| | | flowParams.skipType(SkipType.NONE.getKey()); |
| | | flowParams.hisStatus(TaskStatusEnum.COPY.getStatus()); |
| | | flowParams.message("ãæéç»ã" + StreamUtils.join(flowCopyList, FlowCopyBo::getUserName)); |
| | | HisTask hisTask = hisTaskService.setSkipHisTask(task, flowNode, flowParams); |
| | | hisTask.setCreateTime(updateTime); |
| | | hisTask.setUpdateTime(updateTime); |
| | | hisTaskService.save(hisTask); |
| | | List<User> userList = flowCopyList.stream() |
| | | .map(flowCopy -> { |
| | | FlowUser flowUser = new FlowUser(); |
| | | flowUser.setType(TaskAssigneeType.COPY.getCode()); |
| | | flowUser.setProcessedBy(String.valueOf(flowCopy.getUserId())); |
| | | flowUser.setAssociated(taskId); |
| | | return flowUser; |
| | | }).collect(Collectors.toList()); |
| | | // æ¹éä¿åæé人å |
| | | WorkflowUtils.getFlowUserService().saveBatch(userList); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå¾
åä»»å¡ |
| | | * |
| | | * @param flowTaskBo åæ° |
| | | * @param pageQuery å页 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<FlowTaskVo> pageByTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) { |
| | | QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo); |
| | | queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey()); |
| | | queryWrapper.in("t.processed_by", SpringUtils.getBean(WorkflowPermissionHandler.class).permissions()); |
| | | queryWrapper.in("t.flow_status", BusinessStatusEnum.WAITING.getStatus()); |
| | | Page<FlowTaskVo> page = this.getFlowTaskVoPage(pageQuery, queryWrapper); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çå·²åä»»å¡ |
| | | * |
| | | * @param flowTaskBo åæ° |
| | | * @param pageQuery å页 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<FlowHisTaskVo> pageByTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) { |
| | | QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo); |
| | | queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey()); |
| | | queryWrapper.in("t.approver", LoginHelper.getUserIdStr()); |
| | | queryWrapper.orderByDesc("t.create_time").orderByDesc("t.update_time"); |
| | | Page<FlowHisTaskVo> page = flwTaskMapper.getListFinishTask(pageQuery.build(), queryWrapper); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å¾
åä»»å¡ |
| | | * |
| | | * @param flowTaskBo åæ° |
| | | * @param pageQuery å页 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<FlowTaskVo> pageByAllTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) { |
| | | QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo); |
| | | queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey()); |
| | | Page<FlowTaskVo> page = getFlowTaskVoPage(pageQuery, queryWrapper); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | private Page<FlowTaskVo> getFlowTaskVoPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper) { |
| | | Page<FlowTaskVo> page = flwTaskMapper.getListRunTask(pageQuery.build(), queryWrapper); |
| | | List<FlowTaskVo> records = page.getRecords(); |
| | | if (CollUtil.isNotEmpty(records)) { |
| | | List<Long> taskIds = StreamUtils.toList(records, FlowTaskVo::getId); |
| | | Map<Long, List<UserDTO>> listMap = currentTaskAllUser(taskIds); |
| | | records.forEach(t -> { |
| | | List<UserDTO> userList = listMap.getOrDefault(t.getId(), Collections.emptyList()); |
| | | if (CollUtil.isNotEmpty(userList)) { |
| | | t.setAssigneeIds(StreamUtils.join(userList, e -> String.valueOf(e.getUserId()))); |
| | | t.setAssigneeNames(StreamUtils.join(userList, UserDTO::getNickName)); |
| | | } |
| | | }); |
| | | } |
| | | return page; |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å·²åä»»å¡ |
| | | * |
| | | * @param flowTaskBo åæ° |
| | | * @param pageQuery å页 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<FlowHisTaskVo> pageByAllTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) { |
| | | QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo); |
| | | Page<FlowHisTaskVo> page = flwTaskMapper.getListFinishTask(pageQuery.build(), queryWrapper); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åç¨æ·çæé |
| | | * |
| | | * @param flowTaskBo åæ° |
| | | * @param pageQuery å页 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<FlowTaskVo> pageByTaskCopy(FlowTaskBo flowTaskBo, PageQuery pageQuery) { |
| | | QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo); |
| | | queryWrapper.in("t.processed_by", LoginHelper.getUserIdStr()); |
| | | Page<FlowTaskVo> page = flwTaskMapper.getTaskCopyByPage(pageQuery.build(), queryWrapper); |
| | | return TableDataInfo.build(page); |
| | | } |
| | | |
| | | private QueryWrapper<FlowTaskBo> buildQueryWrapper(FlowTaskBo flowTaskBo) { |
| | | QueryWrapper<FlowTaskBo> wrapper = Wrappers.query(); |
| | | wrapper.like(StringUtils.isNotBlank(flowTaskBo.getNodeName()), "t.node_name", flowTaskBo.getNodeName()); |
| | | wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowName()), "t.flow_name", flowTaskBo.getFlowName()); |
| | | wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowCode()), "t.flow_code", flowTaskBo.getFlowCode()); |
| | | wrapper.in(CollUtil.isNotEmpty(flowTaskBo.getCreateByIds()), "t.create_by", flowTaskBo.getCreateByIds()); |
| | | if (StringUtils.isNotBlank(flowTaskBo.getCategory())) { |
| | | List<Long> categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowTaskBo.getCategory())); |
| | | wrapper.in("t.category", StreamUtils.toList(categoryIds, Convert::toStr)); |
| | | } |
| | | wrapper.orderByDesc("t.create_time"); |
| | | return wrapper; |
| | | } |
| | | |
| | | /** |
| | | * 驳åä»»å¡ |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean backProcess(BackProcessBo bo) { |
| | | try { |
| | | Long taskId = bo.getTaskId(); |
| | | String notice = bo.getNotice(); |
| | | List<String> messageType = bo.getMessageType(); |
| | | String message = bo.getMessage(); |
| | | FlowTask task = flowTaskMapper.selectById(taskId); |
| | | if (ObjectUtil.isNull(task)) { |
| | | throw new ServiceException("ä»»å¡ä¸åå¨ï¼"); |
| | | } |
| | | Instance inst = insService.getById(task.getInstanceId()); |
| | | BusinessStatusEnum.checkBackStatus(inst.getFlowStatus()); |
| | | Long definitionId = task.getDefinitionId(); |
| | | Definition definition = defService.getById(definitionId); |
| | | String applyNodeCode = WorkflowUtils.applyNodeCode(definitionId); |
| | | FlowParams flowParams = FlowParams.build(); |
| | | flowParams.nodeCode(bo.getNodeCode()); |
| | | flowParams.message(message); |
| | | flowParams.skipType(SkipType.REJECT.getKey()); |
| | | flowParams.flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus()) |
| | | .hisStatus(TaskStatusEnum.BACK.getStatus()); |
| | | flowParams.hisTaskExt(bo.getFileId()); |
| | | taskService.skip(task.getId(), flowParams); |
| | | |
| | | Instance instance = insService.getById(inst.getId()); |
| | | this.setHandler(instance, task, null); |
| | | // æ¶æ¯éç¥ |
| | | WorkflowUtils.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice); |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åå¯é©³åçåç½®èç¹ |
| | | * |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @param nowNodeCode å½åèç¹ |
| | | */ |
| | | @Override |
| | | public List<Node> getBackTaskNode(Long definitionId, String nowNodeCode) { |
| | | List<Node> nodeCodes = nodeService.getByNodeCodes(Collections.singletonList(nowNodeCode), definitionId); |
| | | if (!CollUtil.isNotEmpty(nodeCodes)) { |
| | | return nodeCodes; |
| | | } |
| | | //夿æ¯å¦é
ç½®äºåºå®é©³åèç¹ |
| | | Node node = nodeCodes.get(0); |
| | | if (StringUtils.isNotBlank(node.getAnyNodeSkip())) { |
| | | return nodeService.getByNodeCodes(Collections.singletonList(node.getAnyNodeSkip()), definitionId); |
| | | } |
| | | //è·åå¯é©³åçåç½®èç¹ |
| | | List<Node> nodes = nodeService.previousNodeList(definitionId, nowNodeCode); |
| | | if (CollUtil.isNotEmpty(nodes)) { |
| | | return StreamUtils.filter(nodes, e -> NodeType.BETWEEN.getKey().equals(e.getNodeType())); |
| | | } |
| | | return nodes; |
| | | } |
| | | |
| | | /** |
| | | * ç»æ¢ä»»å¡ |
| | | * |
| | | * @param bo åæ° |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean terminationTask(FlowTerminationBo bo) { |
| | | try { |
| | | Long taskId = bo.getTaskId(); |
| | | Task task = taskService.getById(taskId); |
| | | if (task == null) { |
| | | throw new ServiceException("ä»»å¡ä¸åå¨ï¼"); |
| | | } |
| | | Instance instance = insService.getById(task.getInstanceId()); |
| | | if (ObjectUtil.isNotNull(instance)) { |
| | | BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus()); |
| | | } |
| | | FlowParams flowParams = new FlowParams(); |
| | | flowParams.message(bo.getComment()); |
| | | flowParams.flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) |
| | | .hisStatus(TaskStatusEnum.TERMINATION.getStatus()); |
| | | taskService.termination(taskId, flowParams); |
| | | return true; |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æç
§ä»»å¡idæ¥è¯¢ä»»å¡ |
| | | * |
| | | * @param taskIdList ä»»å¡id |
| | | */ |
| | | @Override |
| | | public List<FlowTask> selectByIdList(List<Long> taskIdList) { |
| | | return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) |
| | | .in(FlowTask::getId, taskIdList)); |
| | | } |
| | | |
| | | /** |
| | | * æç
§ä»»å¡idæ¥è¯¢ä»»å¡ |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @Override |
| | | public FlowTaskVo selectById(Long taskId) { |
| | | Task task = taskService.getById(taskId); |
| | | if (ObjectUtil.isNull(task)) { |
| | | return null; |
| | | } |
| | | FlowTaskVo flowTaskVo = BeanUtil.toBean(task, FlowTaskVo.class); |
| | | Instance instance = insService.getById(task.getInstanceId()); |
| | | Definition definition = defService.getById(task.getDefinitionId()); |
| | | flowTaskVo.setFlowStatus(instance.getFlowStatus()); |
| | | flowTaskVo.setVersion(definition.getVersion()); |
| | | flowTaskVo.setFlowCode(definition.getFlowCode()); |
| | | flowTaskVo.setFlowName(definition.getFlowName()); |
| | | flowTaskVo.setBusinessId(instance.getBusinessId()); |
| | | List<Node> nodeList = nodeService.getByNodeCodes(Collections.singletonList(flowTaskVo.getNodeCode()), instance.getDefinitionId()); |
| | | if (CollUtil.isNotEmpty(nodeList)) { |
| | | Node node = nodeList.get(0); |
| | | flowTaskVo.setNodeRatio(node.getNodeRatio()); |
| | | } |
| | | return flowTaskVo; |
| | | } |
| | | |
| | | /** |
| | | * æç
§ä»»å¡idæ¥è¯¢ä»»å¡ |
| | | * |
| | | * @param taskIdList ä»»å¡id |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public List<FlowHisTask> selectHisTaskByIdList(List<Long> taskIdList) { |
| | | return flowHisTaskMapper.selectList(new LambdaQueryWrapper<>(FlowHisTask.class) |
| | | .in(FlowHisTask::getId, taskIdList)); |
| | | } |
| | | |
| | | /** |
| | | * æç
§ä»»å¡idæ¥è¯¢ä»»å¡ |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | * @return ç»æ |
| | | */ |
| | | @Override |
| | | public FlowHisTask selectHisTaskById(Long taskId) { |
| | | return flowHisTaskMapper.selectOne(new LambdaQueryWrapper<>(FlowHisTask.class) |
| | | .eq(FlowHisTask::getId, taskId)); |
| | | } |
| | | |
| | | /** |
| | | * æç
§å®ä¾idæ¥è¯¢ä»»å¡ |
| | | * |
| | | * @param instanceIdList æµç¨å®ä¾id |
| | | */ |
| | | @Override |
| | | public List<FlowTask> selectByInstIdList(List<Long> instanceIdList) { |
| | | return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) |
| | | .in(FlowTask::getInstanceId, instanceIdList)); |
| | | } |
| | | |
| | | /** |
| | | * æç
§å®ä¾idæ¥è¯¢ä»»å¡ |
| | | * |
| | | * @param instanceId æµç¨å®ä¾id |
| | | */ |
| | | @Override |
| | | public List<FlowTask> selectByInstId(Long instanceId) { |
| | | return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) |
| | | .eq(FlowTask::getInstanceId, instanceId)); |
| | | } |
| | | |
| | | /** |
| | | * ä»»å¡æä½ |
| | | * |
| | | * @param bo åæ° |
| | | * @param taskOperation æä½ç±»åï¼å§æ´¾ delegateTaskã转å transferTaskãå ç¾ addSignatureãåç¾ reductionSignature |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean taskOperation(TaskOperationBo bo, String taskOperation) { |
| | | FlowParams flowParams = new FlowParams(); |
| | | flowParams.message(bo.getMessage()); |
| | | if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) { |
| | | flowParams.ignore(true); |
| | | } |
| | | |
| | | // æ ¹æ®æä½ç±»åæå»º FlowParams |
| | | switch (taskOperation) { |
| | | case DELEGATE_TASK, TRANSFER_TASK -> { |
| | | ValidatorUtils.validate(bo, AddGroup.class); |
| | | flowParams.addHandlers(Collections.singletonList(bo.getUserId())); |
| | | } |
| | | case ADD_SIGNATURE -> { |
| | | ValidatorUtils.validate(bo, EditGroup.class); |
| | | flowParams.addHandlers(bo.getUserIds()); |
| | | } |
| | | case REDUCTION_SIGNATURE -> { |
| | | ValidatorUtils.validate(bo, EditGroup.class); |
| | | flowParams.reductionHandlers(bo.getUserIds()); |
| | | } |
| | | default -> { |
| | | log.error("Invalid operation type:{} ", taskOperation); |
| | | throw new ServiceException("Invalid operation type " + taskOperation); |
| | | } |
| | | } |
| | | |
| | | Long taskId = bo.getTaskId(); |
| | | FlowTaskVo flowTaskVo = selectById(taskId); |
| | | if ("addSignature".equals(taskOperation) || "reductionSignature".equals(taskOperation)) { |
| | | if (flowTaskVo.getNodeRatio().compareTo(BigDecimal.ZERO) == 0) { |
| | | throw new ServiceException(flowTaskVo.getNodeName() + "䏿¯ä¼ç¾èç¹ï¼"); |
| | | } |
| | | } |
| | | // 设置任å¡ç¶æå¹¶æ§è¡å¯¹åºçä»»å¡æä½ |
| | | switch (taskOperation) { |
| | | //å§æ´¾ä»»å¡ |
| | | case DELEGATE_TASK -> { |
| | | flowParams.hisStatus(TaskStatusEnum.DEPUTE.getStatus()); |
| | | return taskService.depute(taskId, flowParams); |
| | | } |
| | | //转åä»»å¡ |
| | | case TRANSFER_TASK -> { |
| | | flowParams.hisStatus(TaskStatusEnum.TRANSFER.getStatus()); |
| | | return taskService.transfer(taskId, flowParams); |
| | | } |
| | | //å ç¾ï¼å¢å åç人 |
| | | case ADD_SIGNATURE -> { |
| | | flowParams.hisStatus(TaskStatusEnum.SIGN.getStatus()); |
| | | return taskService.addSignature(taskId, flowParams); |
| | | } |
| | | //åç¾ï¼åå°åç人 |
| | | case REDUCTION_SIGNATURE -> { |
| | | flowParams.hisStatus(TaskStatusEnum.SIGN_OFF.getStatus()); |
| | | return taskService.reductionSignature(taskId, flowParams); |
| | | } |
| | | default -> { |
| | | log.error("Invalid operation type:{} ", taskOperation); |
| | | throw new ServiceException("Invalid operation type " + taskOperation); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ä»»å¡åçäººï¼æ¤æ¹æ³å°ä¼æ¹éä¿®æ¹ææä»»å¡çåçäººï¼ |
| | | * |
| | | * @param taskIdList ä»»å¡id |
| | | * @param userId ç¨æ·id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean updateAssignee(List<Long> taskIdList, String userId) { |
| | | if (CollUtil.isEmpty(taskIdList)) { |
| | | return false; |
| | | } |
| | | try { |
| | | List<FlowTask> flowTasks = this.selectByIdList(taskIdList); |
| | | // æ¹éå é¤ç°æä»»å¡çåçäººè®°å½ |
| | | if (CollUtil.isNotEmpty(flowTasks)) { |
| | | WorkflowUtils.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); |
| | | List<User> userList = flowTasks.stream() |
| | | .map(flowTask -> { |
| | | FlowUser flowUser = new FlowUser(); |
| | | flowUser.setType(TaskAssigneeType.APPROVER.getCode()); |
| | | flowUser.setProcessedBy(userId); |
| | | flowUser.setAssociated(flowTask.getId()); |
| | | return flowUser; |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | if (CollUtil.isNotEmpty(userList)) { |
| | | WorkflowUtils.getFlowUserService().saveBatch(userList); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * è·å任塿æåç人 |
| | | * |
| | | * @param taskIdList ä»»å¡id |
| | | */ |
| | | @Override |
| | | public Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList) { |
| | | Map<Long, List<UserDTO>> map = new HashMap<>(); |
| | | // è·åä¸å½åä»»å¡å
³èçç¨æ·å表 |
| | | List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(taskIdList); |
| | | Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated); |
| | | for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) { |
| | | List<User> value = entry.getValue(); |
| | | if (CollUtil.isNotEmpty(value)) { |
| | | List<UserDTO> userDTOS = userService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy()))); |
| | | map.put(entry.getKey(), userDTOS); |
| | | } |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | | * è·åå½åä»»å¡çææåç人 |
| | | * |
| | | * @param taskId ä»»å¡id |
| | | */ |
| | | @Override |
| | | public List<UserDTO> currentTaskAllUser(Long taskId) { |
| | | // è·åä¸å½åä»»å¡å
³èçç¨æ·å表 |
| | | List<User> userList = WorkflowUtils.getFlowUserService().getByAssociateds(Collections.singletonList(taskId)); |
| | | if (CollUtil.isEmpty(userList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return userService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy()))); |
| | | } |
| | | } |