package com.jy.flow.controller; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.jy.flow.adapter.AbstractWarmFlowAdapter; import com.jy.flow.model.dto.FlowHisTaskDto; import com.jy.flow.model.dto.FlowTaskDto; import com.jy.flow.model.dto.WarmFlowHandleDto; import com.jy.flow.model.enums.FlowStatusEnum; import com.jy.flow.model.vo.FlowTaskVo; import com.jy.flow.service.ExecuteService; import com.jy.framework.exception.ServiceException; import com.jy.framework.satoken.LoginContext; import com.jy.system.dao.SysDeptDao; import com.jy.system.dao.SysRoleDao; import com.jy.system.dao.SysUserDao; import com.jy.system.model.entity.SysUser; import jakarta.annotation.Resource; import org.dromara.warm.flow.core.FlowFactory; import org.dromara.warm.flow.core.dto.FlowParams; import org.dromara.warm.flow.core.entity.HisTask; import org.dromara.warm.flow.core.entity.Instance; import org.dromara.warm.flow.core.entity.Node; import org.dromara.warm.flow.core.entity.Skip; import org.dromara.warm.flow.core.entity.Task; import org.dromara.warm.flow.core.entity.User; import org.dromara.warm.flow.core.enums.SkipType; import org.dromara.warm.flow.core.enums.UserType; import org.dromara.warm.flow.core.service.HisTaskService; import org.dromara.warm.flow.core.service.InsService; import org.dromara.warm.flow.core.service.NodeService; import org.dromara.warm.flow.core.service.SkipService; import org.dromara.warm.flow.core.service.TaskService; import org.dromara.warm.flow.core.service.UserService; import org.dromara.warm.flow.core.utils.StreamUtils; import org.dromara.warm.flow.orm.entity.FlowHisTask; import org.dromara.warm.flow.orm.entity.FlowInstance; import org.dromara.warm.flow.orm.entity.FlowSkip; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringJoiner; @RestController @RequestMapping("/flow/execute") public class ExecuteController { @Resource private SysUserDao sysUserDao; @Resource private SysDeptDao sysDeptDao; @Resource private SysRoleDao sysRoleDao; @Resource private HisTaskService hisTaskService; @Resource private TaskService taskService; @Resource private NodeService nodeService; @Resource private InsService insService; @Resource private UserService flowUserservice; @Resource private ExecuteService executeService; @Resource private SkipService skipService; /** * 分页待办任务列表 */ @GetMapping("/todoPage") public Page toDoPage(FlowTaskDto dto) { dto.setPermissionList(AbstractWarmFlowAdapter.permissionList()); Page page = executeService.toDoPage(dto); List list = page.getRecords(); if (list.isEmpty()) { return page; } List taskIds = StreamUtils.toList(list, FlowTaskVo::getId); List userList = flowUserservice.getByAssociateds(taskIds); Map> map = StreamUtils.groupByKey(userList, User::getAssociated); HashMap handlerMap = new HashMap<>(); sysUserDao.list().forEach(item -> handlerMap.put(item.getId().toString(), "用户:" + item.getNickname())); sysRoleDao.list().forEach(item -> handlerMap.put("role:" + item.getId().toString(), "角色:" + item.getName())); sysDeptDao.list().forEach(item -> handlerMap.put("dept:" + item.getId().toString(), "部门:" + item.getName())); for (FlowTaskVo taskVo : list) { if (ObjectUtil.isNull(taskVo)) { continue; } List users = map.get(taskVo.getId()); if (ObjectUtil.isEmpty(users)) { continue; } StringJoiner approverJoiner = new StringJoiner(";"); StringJoiner transferredByJoiner = new StringJoiner(";"); StringJoiner delegateJoiner = new StringJoiner(";"); for (User user : users) { String processed = handlerMap.get(user.getProcessedBy()); switch (UserType.getByKey(user.getType())) { case APPROVAL -> { if (StrUtil.isNotEmpty(processed)) { approverJoiner.add(processed); } } case TRANSFER -> { if (StrUtil.isNotEmpty(processed)) { transferredByJoiner.add(processed); } } case DEPUTE -> { if (StrUtil.isNotEmpty(processed)) { delegateJoiner.add(processed); } } } } taskVo.setApprover(approverJoiner.toString()); taskVo.setTransferredBy(transferredByJoiner.toString()); taskVo.setDelegate(delegateJoiner.toString()); } return page; } /** * 分页已办任务列表 */ @GetMapping("/donePage") public Page donePage(FlowHisTaskDto dto) { dto.setApprover(LoginContext.getUserId().toString()); Page page = executeService.donePage(dto); List list = page.getRecords(); Map userMap = StreamUtils.toMap(sysUserDao.list(), SysUser::getId, SysUser::getNickname); if (CollectionUtils.isEmpty(list)) { return page; } for (FlowHisTask hisTaskVo : list) { if (StrUtil.isNotEmpty(hisTaskVo.getCollaborator())) { hisTaskVo.setCollaborator(userMap.get(Long.valueOf(hisTaskVo.getCollaborator()))); } } return page; } /** * 分页抄送任务列表 */ @GetMapping("/copyPage") public Page copyPage(FlowTaskDto dto) { dto.setPermissionList(AbstractWarmFlowAdapter.permissionList()); return executeService.copyPage(dto); } /** * 查询已办任务历史记录 */ @GetMapping("/doneList/{instanceId}") public List doneList(@PathVariable("instanceId") Long instanceId) { List vo = hisTaskService.list(new FlowHisTask().setInstanceId(instanceId)); if (vo.isEmpty()) { return vo; } Map userMap = StreamUtils.toMap(sysUserDao.list(), SysUser::getId, SysUser::getNickname); for (HisTask hisTask : vo) { if (StrUtil.isNotEmpty(hisTask.getApprover())) { hisTask.setApprover(userMap.get(Long.valueOf(hisTask.getApprover()))); } if (StrUtil.isNotEmpty(hisTask.getCollaborator())) { hisTask.setCollaborator(userMap.get(Long.valueOf(hisTask.getCollaborator()))); } } return vo; } /** * 查询已办任务历史记录 */ @GetMapping("/doneListByBusinessId/{businessId}") public List doneListByBusinessId(@PathVariable("businessId") String businessId) { Instance instance = insService.getOne(new FlowInstance().setBusinessId(businessId)); if (instance == null) { return Collections.emptyList(); } return doneList(instance.getId()); } /** * 查询跳转任意节点列表 */ @GetMapping("/anyNodeList/{instanceId}") public List anyNodeList(@PathVariable("instanceId") Long instanceId) { Instance instance = insService.getById(instanceId); return nodeService.list(FlowFactory.newNode().setDefinitionId(instance.getDefinitionId())); } /** * 办理流程 */ @PostMapping("/handle") public void handle(@RequestBody WarmFlowHandleDto dto) { Task task = taskService.getById(dto.getTaskId()); Long definitionId = task.getDefinitionId(); String nodeCode = null; FlowStatusEnum flowStatus = FlowStatusEnum.APPROVAL; Integer handleType = dto.getHandleType(); String skipType = switch (handleType) { case 1 -> { Node nextNode = nodeService.getNextNode(definitionId, task.getNodeCode(), "", "PASS"); nodeCode = nextNode.getNodeCode(); // 如果是结束节点 if (nextNode.getNodeType() == 2) { flowStatus = FlowStatusEnum.PASS; } yield SkipType.PASS.getKey(); } case 2 -> { nodeCode = task.getNodeCode(); List skipList = skipService.list(new FlowSkip().setDefinitionId(definitionId)); List rejectSkipList = skipList.stream() .filter(item -> "REJECT".equals(item.getSkipType())) .filter(item -> item.getNowNodeCode().equals(task.getNodeCode())) .toList(); int rejectSkipSize = rejectSkipList.size(); if (rejectSkipSize == 0) { while (true) { String tempNodeCode = nodeCode; Skip skip = skipList.stream() .filter(item -> "PASS".equals(item.getSkipType())) .filter(item -> item.getNextNodeCode().equals(tempNodeCode)) .findFirst() .orElse(null); if (skip == null) { throw new ServiceException("流程配置错误:不存在回退节点"); } nodeCode = skip.getNowNodeCode(); if (ObjectUtil.notEqual(skip.getNowNodeType(), 3)) { // 回退到开始节点 if (skip.getNowNodeType() == 0) { flowStatus = FlowStatusEnum.TOBESUBMIT; } break; } } } else if (rejectSkipSize == 1) { Skip skip = rejectSkipList.get(0); if (skip.getNextNodeType().equals(3)) { throw new ServiceException("流程配置错误:节点回退到网关"); } nodeCode = skip.getNextNodeCode(); } else { throw new ServiceException("流程配置错误:存在多个回退节点"); } yield SkipType.REJECT.getKey(); } case 3 -> { flowStatus = FlowStatusEnum.TERMINATE; yield null; } default -> throw new ServiceException("办理类型不存在"); }; FlowParams flowParams = FlowParams.build() .skipType(skipType) .handler(LoginContext.getUserId().toString()) .nodeCode(nodeCode) .message(dto.getMessage()) .permissionFlag(AbstractWarmFlowAdapter.permissionList()) .flowStatus(flowStatus.getKeyStr()); if (handleType == 3) { taskService.termination(dto.getTaskId(), flowParams); } else { taskService.skip(dto.getTaskId(), flowParams); } } }