TaskController.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. package jnpf.flowable.controller;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import com.google.common.collect.ImmutableMap;
  4. import io.swagger.v3.oas.annotations.Operation;
  5. import io.swagger.v3.oas.annotations.tags.Tag;
  6. import jnpf.base.ActionResult;
  7. import jnpf.base.Pagination;
  8. import jnpf.base.UserInfo;
  9. import jnpf.base.controller.SuperController;
  10. import jnpf.base.entity.SystemEntity;
  11. import jnpf.base.vo.PageListVO;
  12. import jnpf.base.vo.PaginationVO;
  13. import jnpf.config.ConfigValueUtil;
  14. import jnpf.constant.MsgCode;
  15. import jnpf.database.util.TenantDataSourceUtil;
  16. import jnpf.exception.WorkFlowException;
  17. import jnpf.flowable.entity.EventLogEntity;
  18. import jnpf.flowable.entity.TaskEntity;
  19. import jnpf.flowable.enums.EventEnum;
  20. import jnpf.flowable.enums.TaskStatusEnum;
  21. import jnpf.flowable.model.candidates.CandidateUserVo;
  22. import jnpf.flowable.model.outside.OutsideModel;
  23. import jnpf.flowable.model.task.*;
  24. import jnpf.flowable.model.template.BeforeInfoVo;
  25. import jnpf.flowable.model.trigger.TriggerInfoModel;
  26. import jnpf.flowable.service.EventLogService;
  27. import jnpf.flowable.service.TaskService;
  28. import jnpf.flowable.service.TriggerTaskService;
  29. import jnpf.flowable.util.*;
  30. import jnpf.permission.entity.UserEntity;
  31. import jnpf.util.*;
  32. import jnpf.util.context.RequestContext;
  33. import lombok.RequiredArgsConstructor;
  34. import org.springframework.beans.factory.annotation.Autowired;
  35. import org.springframework.web.bind.annotation.*;
  36. import java.util.ArrayList;
  37. import java.util.List;
  38. import java.util.Map;
  39. import java.util.Objects;
  40. import java.util.stream.Collectors;
  41. /**
  42. * 流程任务
  43. *
  44. * @author JNPF@YinMai Info. Co., Ltd
  45. * @version 5.0.x
  46. * @since 2024/4/17 15:13
  47. */
  48. @Tag(name = "流程任务", description = "TaskController")
  49. @RestController
  50. @RequestMapping("/api/workflow/task")
  51. @RequiredArgsConstructor
  52. public class TaskController extends SuperController<TaskService, TaskEntity> {
  53. private final TaskService taskService;
  54. @Autowired
  55. private ServiceUtil serviceUtil;
  56. @Autowired
  57. private TaskUtil taskUtil;
  58. @Autowired
  59. private OutsideUtil outsideUtil;
  60. @Autowired
  61. private OperatorUtil operatorUtil;
  62. @Autowired
  63. private ConfigValueUtil configValueUtil;
  64. @Autowired
  65. private EventLogService eventLogService;
  66. @Autowired
  67. private TriggerTaskService triggerTaskService;
  68. /**
  69. * 详情
  70. *
  71. * @param id 任务id
  72. * @param fo 参数类
  73. */
  74. @Operation(summary = "详情")
  75. @GetMapping("/{id}")
  76. public ActionResult getInfo(@PathVariable("id") String id, FlowModel fo) throws WorkFlowException {
  77. String fileNameAll = DesUtil.aesOrDecode(id, false, true);
  78. int i1 = fileNameAll.indexOf(",");
  79. int i2 = fileNameAll.lastIndexOf(",");
  80. id = fileNameAll.substring(i1+1, i2);
  81. if (!Objects.equals(id, UserProvider.getLoginUserId())) {
  82. throw new RuntimeException(MsgCode.FA021.getMsg());
  83. }
  84. String taskId = fileNameAll.substring(0, i1);
  85. if (ObjectUtil.equals(fo.getType(), 2)) {
  86. TriggerInfoModel triggerInfo = triggerTaskService.getInfo(taskId);
  87. return ActionResult.success(triggerInfo);
  88. }
  89. return ActionResult.success(taskService.getInfo(taskId, fo));
  90. }
  91. /**
  92. * 暂存或提交
  93. *
  94. * @param fo 参数类
  95. */
  96. @Operation(summary = "暂存或提交")
  97. @PostMapping
  98. public ActionResult saveOrSubmit(@RequestBody FlowModel fo) throws Exception {
  99. taskService.batchSaveOrSubmit(fo);
  100. operatorUtil.handleOperator();
  101. if (ObjectUtil.equals(TaskStatusEnum.RUNNING.getCode(), fo.getStatus())) {
  102. operatorUtil.event(fo, EventEnum.Init.getStatus());
  103. }
  104. TaskEntity taskEntity = fo.getTaskEntity();
  105. if (taskEntity.getRejectDataId() == null) {
  106. operatorUtil.autoAudit(fo);
  107. operatorUtil.handleOperator();
  108. operatorUtil.handleEvent();
  109. }
  110. operatorUtil.handleTaskStatus();
  111. String msg = TaskStatusEnum.TO_BE_SUBMIT.getCode().equals(fo.getStatus()) ? MsgCode.SU002.get() : MsgCode.SU006.get();
  112. TaskEntity task = taskService.getById(taskEntity.getId());
  113. taskEntity = task == null ? taskEntity : task;
  114. AuditModel model = taskUtil.getAuditModel(taskEntity.getId(), fo, null);
  115. return ActionResult.success(msg, model);
  116. }
  117. /**
  118. * 暂存或提交,已暂存的再次暂存或提交
  119. *
  120. * @param id 任务主键
  121. * @param fo 参数
  122. */
  123. @Operation(summary = "暂存或提交(我发起的)")
  124. @PutMapping("/{id}")
  125. public ActionResult saveOrSubmit(@PathVariable("id") String id, @RequestBody FlowModel fo) throws Exception {
  126. Map<String, Object> data = fo.getFormData();
  127. String flowTaskID = Objects.nonNull(data.get(FlowFormConstant.FLOWTASKID)) ? data.get(FlowFormConstant.FLOWTASKID).toString() : id;
  128. fo.setId(flowTaskID);
  129. TaskEntity taskEntity = taskService.getById(flowTaskID);
  130. if (taskEntity != null) {
  131. taskUtil.isSuspend(taskEntity);
  132. taskUtil.isCancel(taskEntity);
  133. }
  134. taskService.batchSaveOrSubmit(fo);
  135. operatorUtil.handleOperator();
  136. if (ObjectUtil.equals(TaskStatusEnum.RUNNING.getCode(), fo.getStatus())) {
  137. operatorUtil.event(fo, EventEnum.Init.getStatus());
  138. }
  139. taskEntity = fo.getTaskEntity();
  140. if (taskEntity.getRejectDataId() == null) {
  141. operatorUtil.autoAudit(fo);
  142. operatorUtil.handleOperator();
  143. operatorUtil.handleEvent();
  144. }
  145. operatorUtil.handleTaskStatus();
  146. TaskEntity task = taskService.getById(taskEntity.getId());
  147. taskEntity = task == null ? taskEntity : task;
  148. String msg = TaskStatusEnum.TO_BE_SUBMIT.getCode().equals(fo.getStatus()) ? MsgCode.SU002.get() : MsgCode.SU006.get();
  149. AuditModel model = taskUtil.getAuditModel(taskEntity.getId(), fo, null);
  150. return ActionResult.success(msg, model);
  151. }
  152. /**
  153. * 删除
  154. *
  155. * @param id 主键
  156. */
  157. @Operation(summary = "删除")
  158. @DeleteMapping("/{id}")
  159. public ActionResult<String> delete(@PathVariable("id") String id) throws Exception {
  160. List<TaskEntity> list = taskService.delete(id);
  161. taskUtil.deleteFormData(list);
  162. return ActionResult.success(MsgCode.SU003.get());
  163. }
  164. /**
  165. * 我发起的 列表
  166. *
  167. * @param pagination 分页参数
  168. */
  169. @Operation(summary = "我发起的")
  170. @GetMapping
  171. public ActionResult<PageListVO<TaskVo>> list(TaskPagination pagination) {
  172. pagination.setSystemId(serviceUtil.getSystemCodeById(RequestContext.getAppCode()));
  173. List<TaskVo> list = taskService.getList(pagination);
  174. List<TaskVo> voList = new ArrayList<>();
  175. List<UserEntity> userList = serviceUtil.getUserName(list.stream().map(TaskVo::getCreatorUser).collect(Collectors.toList()));
  176. for (TaskVo vo : list) {
  177. UserEntity userEntity = userList.stream().filter(t -> t.getId().equals(vo.getCreatorUser())).findFirst().orElse(null);
  178. vo.setCreatorUser(userEntity != null ? userEntity.getRealName() + "/" + userEntity.getAccount() : "");
  179. voList.add(vo);
  180. }
  181. PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
  182. return ActionResult.page(voList, paginationVO);
  183. }
  184. /**
  185. * 发起撤回
  186. *
  187. * @param id 任务主键
  188. */
  189. @Operation(summary = "发起撤回")
  190. @PutMapping("/Recall/{id}")
  191. public ActionResult<String> recall(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
  192. taskService.recall(id, flowModel);
  193. operatorUtil.event(flowModel, EventEnum.FlowRecall.getStatus());
  194. operatorUtil.handleTaskStatus();
  195. return ActionResult.success(MsgCode.WF008.get());
  196. }
  197. /**
  198. * 催办
  199. *
  200. * @param id 任务主键
  201. */
  202. @Operation(summary = "催办")
  203. @PostMapping("/Press/{id}")
  204. public ActionResult<String> press(@PathVariable("id") String id) throws WorkFlowException {
  205. if (taskService.press(id)) {
  206. return ActionResult.success(MsgCode.WF022.get());
  207. }
  208. return ActionResult.fail(MsgCode.WF023.get());
  209. }
  210. /**
  211. * 撤销
  212. *
  213. * @param id 任务主键
  214. */
  215. @Operation(summary = "撤销")
  216. @PutMapping("/Revoke/{id}")
  217. public ActionResult<String> revoke(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws Exception {
  218. taskService.revoke(id, flowModel);
  219. return ActionResult.success(MsgCode.SU006.get());
  220. }
  221. /**
  222. * 获取流程所关联的用户信息
  223. *
  224. * @param id 任务主键
  225. * @param pagination 分页参数
  226. */
  227. @Operation(summary = "获取流程所关联的用户信息")
  228. @GetMapping("/TaskUserList/{id}")
  229. public ActionResult getTaskUserList(@PathVariable("id") String id, Pagination pagination) {
  230. TaskUserListModel model = taskService.getTaskUserList(id);
  231. String admin = serviceUtil.getAdmin();
  232. List<String> allUserIdList = model.getAllUserIdList();
  233. allUserIdList.remove(admin);
  234. List<CandidateUserVo> userList = taskUtil.getUserModel(allUserIdList, pagination);
  235. PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
  236. return ActionResult.page(userList, paginationVO);
  237. }
  238. /**
  239. * 子流程详情
  240. *
  241. * @param flowModel 参数
  242. */
  243. @Operation(summary = "子流程详情")
  244. @GetMapping("/SubFlowInfo")
  245. public ActionResult subFlowInfo(FlowModel flowModel) throws WorkFlowException {
  246. List<BeforeInfoVo> list = taskService.subFlowInfo(flowModel);
  247. return ActionResult.success(list);
  248. }
  249. /**
  250. * 查看发起表单
  251. *
  252. * @param taskId 任务主键
  253. */
  254. @Operation(summary = "查看发起表单")
  255. @GetMapping("/ViewStartForm/{taskId}")
  256. public ActionResult getStartForm(@PathVariable("taskId") String taskId) throws WorkFlowException {
  257. ViewFormModel model = taskService.getStartForm(taskId);
  258. return ActionResult.success(model);
  259. }
  260. /**
  261. * 外部重试
  262. */
  263. @Operation(summary = "外部重试")
  264. @GetMapping("/Hooks/Retry/{id}")
  265. public ActionResult outsideRetry(@PathVariable("id") String id) throws WorkFlowException {
  266. boolean retryResult = outsideUtil.retry(id);
  267. return ActionResult.success(MsgCode.SU005.get(), retryResult);
  268. }
  269. /**
  270. * 外部审批
  271. */
  272. @Operation(summary = "外部审批")
  273. @PostMapping("/Hooks")
  274. @NoDataSourceBind
  275. public ActionResult outside(@RequestParam(value = "tenantId", required = false) String tenantId, @RequestBody Map<String, Object> body) throws Exception {
  276. if (configValueUtil.isMultiTenancy()) {
  277. // 判断是不是从外面直接请求
  278. if (StringUtil.isNotEmpty(tenantId)) {
  279. //切换成租户库
  280. try {
  281. TenantDataSourceUtil.switchTenant(tenantId);
  282. } catch (Exception e) {
  283. return ActionResult.fail(MsgCode.LOG105.get());
  284. }
  285. }
  286. }
  287. OutsideModel outsideModel = JsonUtil.getJsonToBean(body, OutsideModel.class);
  288. String eventId = outsideModel.getEventId();
  289. EventLogEntity eventLog = StringUtil.isNotEmpty(eventId) ? eventLogService.getById(eventId) : null;
  290. if (eventLog == null) {
  291. throw new WorkFlowException(MsgCode.FA001.get());
  292. }
  293. TaskEntity taskEntity = taskService.getInfo(eventLog.getTaskId());
  294. FlowModel flowModel = new FlowModel();
  295. flowModel.setFormData(outsideModel.getFormData());
  296. flowModel.setId(eventId);
  297. flowModel.setTaskId(eventLog.getTaskId());
  298. try {
  299. String token = AuthUtil.loginTempUser(eventLog.getCreatorUserId(), tenantId);
  300. UserInfo userInfo = UserProvider.getUser(token);
  301. UserProvider.setLoginUser(userInfo);
  302. UserProvider.setLocalLoginUser(userInfo);
  303. flowModel.setUserInfo(userInfo);
  304. outsideUtil.outsideAudit(flowModel, eventLog);
  305. } catch (Exception e) {
  306. operatorUtil.compensate(taskEntity);
  307. throw e;
  308. }
  309. operatorUtil.handleOperator();
  310. operatorUtil.handleEvent();
  311. if (taskEntity.getRejectDataId() == null) {
  312. operatorUtil.autoAudit(flowModel);
  313. operatorUtil.handleOperator();
  314. operatorUtil.handleEvent();
  315. }
  316. return ActionResult.success(MsgCode.WF066.get());
  317. }
  318. @GetMapping("/test")
  319. public Map test() {
  320. return ImmutableMap.of("handleId", "03d159a3-0f88-424c-a24f-02f63855fe4f,9624fa22-ac3a-4184-af0b-b2c720df9d60,3977de33-668c-4585-b09b-239aacfb4ebe");
  321. }
  322. }