ExecuteController.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. package com.jy.flow.controller;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  5. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6. import com.jy.flow.adapter.AbstractWarmFlowAdapter;
  7. import com.jy.flow.model.dto.FlowHisTaskDto;
  8. import com.jy.flow.model.dto.FlowTaskDto;
  9. import com.jy.flow.model.dto.WarmFlowHandleDto;
  10. import com.jy.flow.model.enums.FlowStatusEnum;
  11. import com.jy.flow.model.vo.FlowTaskVo;
  12. import com.jy.flow.service.ExecuteService;
  13. import com.jy.framework.exception.ServiceException;
  14. import com.jy.framework.satoken.LoginContext;
  15. import com.jy.system.dao.SysDeptDao;
  16. import com.jy.system.dao.SysRoleDao;
  17. import com.jy.system.dao.SysUserDao;
  18. import com.jy.system.model.entity.SysUser;
  19. import jakarta.annotation.Resource;
  20. import org.dromara.warm.flow.core.FlowFactory;
  21. import org.dromara.warm.flow.core.dto.FlowParams;
  22. import org.dromara.warm.flow.core.entity.HisTask;
  23. import org.dromara.warm.flow.core.entity.Instance;
  24. import org.dromara.warm.flow.core.entity.Node;
  25. import org.dromara.warm.flow.core.entity.Skip;
  26. import org.dromara.warm.flow.core.entity.Task;
  27. import org.dromara.warm.flow.core.entity.User;
  28. import org.dromara.warm.flow.core.enums.SkipType;
  29. import org.dromara.warm.flow.core.enums.UserType;
  30. import org.dromara.warm.flow.core.service.HisTaskService;
  31. import org.dromara.warm.flow.core.service.InsService;
  32. import org.dromara.warm.flow.core.service.NodeService;
  33. import org.dromara.warm.flow.core.service.SkipService;
  34. import org.dromara.warm.flow.core.service.TaskService;
  35. import org.dromara.warm.flow.core.service.UserService;
  36. import org.dromara.warm.flow.core.utils.StreamUtils;
  37. import org.dromara.warm.flow.orm.entity.FlowHisTask;
  38. import org.dromara.warm.flow.orm.entity.FlowInstance;
  39. import org.dromara.warm.flow.orm.entity.FlowSkip;
  40. import org.springframework.web.bind.annotation.GetMapping;
  41. import org.springframework.web.bind.annotation.PathVariable;
  42. import org.springframework.web.bind.annotation.PostMapping;
  43. import org.springframework.web.bind.annotation.RequestBody;
  44. import org.springframework.web.bind.annotation.RequestMapping;
  45. import org.springframework.web.bind.annotation.RestController;
  46. import java.util.Collections;
  47. import java.util.HashMap;
  48. import java.util.List;
  49. import java.util.Map;
  50. import java.util.StringJoiner;
  51. @RestController
  52. @RequestMapping("/flow/execute")
  53. public class ExecuteController {
  54. @Resource
  55. private SysUserDao sysUserDao;
  56. @Resource
  57. private SysDeptDao sysDeptDao;
  58. @Resource
  59. private SysRoleDao sysRoleDao;
  60. @Resource
  61. private HisTaskService hisTaskService;
  62. @Resource
  63. private TaskService taskService;
  64. @Resource
  65. private NodeService nodeService;
  66. @Resource
  67. private InsService insService;
  68. @Resource
  69. private UserService flowUserservice;
  70. @Resource
  71. private ExecuteService executeService;
  72. @Resource
  73. private SkipService skipService;
  74. /**
  75. * 分页待办任务列表
  76. */
  77. @GetMapping("/todoPage")
  78. public Page<FlowTaskVo> toDoPage(FlowTaskDto dto) {
  79. dto.setPermissionList(AbstractWarmFlowAdapter.permissionList());
  80. Page<FlowTaskVo> page = executeService.toDoPage(dto);
  81. List<FlowTaskVo> list = page.getRecords();
  82. if (list.isEmpty()) {
  83. return page;
  84. }
  85. List<Long> taskIds = StreamUtils.toList(list, FlowTaskVo::getId);
  86. List<User> userList = flowUserservice.getByAssociateds(taskIds);
  87. Map<Long, List<User>> map = StreamUtils.groupByKey(userList, User::getAssociated);
  88. HashMap<String, String> handlerMap = new HashMap<>();
  89. sysUserDao.list().forEach(item -> handlerMap.put(item.getId().toString(), "用户:" + item.getNickname()));
  90. sysRoleDao.list().forEach(item -> handlerMap.put("role:" + item.getId().toString(), "角色:" + item.getName()));
  91. sysDeptDao.list().forEach(item -> handlerMap.put("dept:" + item.getId().toString(), "部门:" + item.getName()));
  92. for (FlowTaskVo taskVo : list) {
  93. if (ObjectUtil.isNull(taskVo)) {
  94. continue;
  95. }
  96. List<User> users = map.get(taskVo.getId());
  97. if (ObjectUtil.isEmpty(users)) {
  98. continue;
  99. }
  100. StringJoiner approverJoiner = new StringJoiner(";");
  101. StringJoiner transferredByJoiner = new StringJoiner(";");
  102. StringJoiner delegateJoiner = new StringJoiner(";");
  103. for (User user : users) {
  104. String processed = handlerMap.get(user.getProcessedBy());
  105. switch (UserType.getByKey(user.getType())) {
  106. case APPROVAL -> {
  107. if (StrUtil.isNotEmpty(processed)) {
  108. approverJoiner.add(processed);
  109. }
  110. }
  111. case TRANSFER -> {
  112. if (StrUtil.isNotEmpty(processed)) {
  113. transferredByJoiner.add(processed);
  114. }
  115. }
  116. case DEPUTE -> {
  117. if (StrUtil.isNotEmpty(processed)) {
  118. delegateJoiner.add(processed);
  119. }
  120. }
  121. }
  122. }
  123. taskVo.setApprover(approverJoiner.toString());
  124. taskVo.setTransferredBy(transferredByJoiner.toString());
  125. taskVo.setDelegate(delegateJoiner.toString());
  126. }
  127. return page;
  128. }
  129. /**
  130. * 分页已办任务列表
  131. */
  132. @GetMapping("/donePage")
  133. public Page<FlowHisTask> donePage(FlowHisTaskDto dto) {
  134. dto.setApprover(LoginContext.getUserId().toString());
  135. Page<FlowHisTask> page = executeService.donePage(dto);
  136. List<FlowHisTask> list = page.getRecords();
  137. Map<Long, String> userMap = StreamUtils.toMap(sysUserDao.list(), SysUser::getId, SysUser::getNickname);
  138. if (CollectionUtils.isEmpty(list)) {
  139. return page;
  140. }
  141. for (FlowHisTask hisTaskVo : list) {
  142. if (StrUtil.isNotEmpty(hisTaskVo.getCollaborator())) {
  143. hisTaskVo.setCollaborator(userMap.get(Long.valueOf(hisTaskVo.getCollaborator())));
  144. }
  145. }
  146. return page;
  147. }
  148. /**
  149. * 分页抄送任务列表
  150. */
  151. @GetMapping("/copyPage")
  152. public Page<FlowHisTask> copyPage(FlowTaskDto dto) {
  153. dto.setPermissionList(AbstractWarmFlowAdapter.permissionList());
  154. return executeService.copyPage(dto);
  155. }
  156. /**
  157. * 查询已办任务历史记录
  158. */
  159. @GetMapping("/doneList/{instanceId}")
  160. public List<HisTask> doneList(@PathVariable("instanceId") Long instanceId) {
  161. List<HisTask> vo = hisTaskService.list(new FlowHisTask().setInstanceId(instanceId));
  162. if (vo.isEmpty()) {
  163. return vo;
  164. }
  165. Map<Long, String> userMap = StreamUtils.toMap(sysUserDao.list(), SysUser::getId, SysUser::getNickname);
  166. for (HisTask hisTask : vo) {
  167. if (StrUtil.isNotEmpty(hisTask.getApprover())) {
  168. hisTask.setApprover(userMap.get(Long.valueOf(hisTask.getApprover())));
  169. }
  170. if (StrUtil.isNotEmpty(hisTask.getCollaborator())) {
  171. hisTask.setCollaborator(userMap.get(Long.valueOf(hisTask.getCollaborator())));
  172. }
  173. }
  174. return vo;
  175. }
  176. /**
  177. * 查询已办任务历史记录
  178. */
  179. @GetMapping("/doneListByBusinessId/{businessId}")
  180. public List<HisTask> doneListByBusinessId(@PathVariable("businessId") String businessId) {
  181. Instance instance = insService.getOne(new FlowInstance().setBusinessId(businessId));
  182. if (instance == null) {
  183. return Collections.emptyList();
  184. }
  185. return doneList(instance.getId());
  186. }
  187. /**
  188. * 查询跳转任意节点列表
  189. */
  190. @GetMapping("/anyNodeList/{instanceId}")
  191. public List<Node> anyNodeList(@PathVariable("instanceId") Long instanceId) {
  192. Instance instance = insService.getById(instanceId);
  193. return nodeService.list(FlowFactory.newNode().setDefinitionId(instance.getDefinitionId()));
  194. }
  195. /**
  196. * 办理流程
  197. */
  198. @PostMapping("/handle")
  199. public void handle(@RequestBody WarmFlowHandleDto dto) {
  200. Task task = taskService.getById(dto.getTaskId());
  201. Long definitionId = task.getDefinitionId();
  202. String nodeCode = null;
  203. FlowStatusEnum flowStatus = FlowStatusEnum.APPROVAL;
  204. Integer handleType = dto.getHandleType();
  205. String skipType = switch (handleType) {
  206. case 1 -> {
  207. Node nextNode = nodeService.getNextNode(definitionId, task.getNodeCode(), "", "PASS");
  208. nodeCode = nextNode.getNodeCode();
  209. // 如果是结束节点
  210. if (nextNode.getNodeType() == 2) {
  211. flowStatus = FlowStatusEnum.PASS;
  212. }
  213. yield SkipType.PASS.getKey();
  214. }
  215. case 2 -> {
  216. nodeCode = task.getNodeCode();
  217. List<Skip> skipList = skipService.list(new FlowSkip().setDefinitionId(definitionId));
  218. List<Skip> rejectSkipList = skipList.stream()
  219. .filter(item -> "REJECT".equals(item.getSkipType()))
  220. .filter(item -> item.getNowNodeCode().equals(task.getNodeCode()))
  221. .toList();
  222. int rejectSkipSize = rejectSkipList.size();
  223. if (rejectSkipSize == 0) {
  224. while (true) {
  225. String tempNodeCode = nodeCode;
  226. Skip skip = skipList.stream()
  227. .filter(item -> "PASS".equals(item.getSkipType()))
  228. .filter(item -> item.getNextNodeCode().equals(tempNodeCode))
  229. .findFirst()
  230. .orElse(null);
  231. if (skip == null) {
  232. throw new ServiceException("流程配置错误:不存在回退节点");
  233. }
  234. nodeCode = skip.getNowNodeCode();
  235. if (ObjectUtil.notEqual(skip.getNowNodeType(), 3)) {
  236. // 回退到开始节点
  237. if (skip.getNowNodeType() == 0) {
  238. flowStatus = FlowStatusEnum.TOBESUBMIT;
  239. }
  240. break;
  241. }
  242. }
  243. } else if (rejectSkipSize == 1) {
  244. Skip skip = rejectSkipList.get(0);
  245. if (skip.getNextNodeType().equals(3)) {
  246. throw new ServiceException("流程配置错误:节点回退到网关");
  247. }
  248. nodeCode = skip.getNextNodeCode();
  249. } else {
  250. throw new ServiceException("流程配置错误:存在多个回退节点");
  251. }
  252. yield SkipType.REJECT.getKey();
  253. }
  254. case 3 -> {
  255. flowStatus = FlowStatusEnum.TERMINATE;
  256. yield null;
  257. }
  258. default -> throw new ServiceException("办理类型不存在");
  259. };
  260. FlowParams flowParams = FlowParams.build()
  261. .skipType(skipType)
  262. .handler(LoginContext.getUserId().toString())
  263. .nodeCode(nodeCode)
  264. .message(dto.getMessage())
  265. .permissionFlag(AbstractWarmFlowAdapter.permissionList())
  266. .flowStatus(flowStatus.getKeyStr());
  267. if (handleType == 3) {
  268. taskService.termination(dto.getTaskId(), flowParams);
  269. } else {
  270. taskService.skip(dto.getTaskId(), flowParams);
  271. }
  272. }
  273. }