FlowClient.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. package com.fjhx.feign;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  5. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  6. import com.fjhx.base.BaseEntity;
  7. import com.fjhx.constants.FlowConstant;
  8. import com.fjhx.constants.FlowExplainConstant;
  9. import com.fjhx.constants.StatusConstant;
  10. import com.fjhx.entity.example.ExampleDetails;
  11. import com.fjhx.entity.example.ExampleInfo;
  12. import com.fjhx.entity.process.ProcessInfo;
  13. import com.fjhx.entity.process.ProcessNode;
  14. import com.fjhx.entity.process.ProcessNodeButton;
  15. import com.fjhx.entity.process.ProcessTenant;
  16. import com.fjhx.enums.ButtonNameEnum;
  17. import com.fjhx.enums.HandleResultEnum;
  18. import com.fjhx.enums.ProcessNodeHandleObjectTypeEnum;
  19. import com.fjhx.params.ExampleResult;
  20. import com.fjhx.params.JumpVo;
  21. import com.fjhx.service.example.ExampleDetailsService;
  22. import com.fjhx.service.example.ExampleInfoService;
  23. import com.fjhx.service.process.ProcessInfoService;
  24. import com.fjhx.service.process.ProcessNodeButtonService;
  25. import com.fjhx.service.process.ProcessNodeService;
  26. import com.fjhx.service.process.ProcessTenantService;
  27. import com.fjhx.utils.Assert;
  28. import org.springblade.core.secure.utils.AuthUtil;
  29. import org.springblade.core.tool.api.R;
  30. import org.springblade.core.tool.utils.Func;
  31. import org.springframework.beans.factory.annotation.Autowired;
  32. import org.springframework.transaction.annotation.Transactional;
  33. import org.springframework.web.bind.annotation.GetMapping;
  34. import org.springframework.web.bind.annotation.PostMapping;
  35. import org.springframework.web.bind.annotation.RestController;
  36. import java.util.ArrayList;
  37. import java.util.Arrays;
  38. import java.util.List;
  39. @RestController
  40. public class FlowClient implements IFlowClient {
  41. @Autowired
  42. private ExampleInfoService exampleInfoService;
  43. @Autowired
  44. private ProcessInfoService processInfoService;
  45. @Autowired
  46. private ProcessTenantService processTenantService;
  47. @Autowired
  48. private ProcessNodeService processNodeService;
  49. @Autowired
  50. private ProcessNodeButtonService processNodeButtonService;
  51. @Autowired
  52. private ExampleDetailsService exampleDetailsService;
  53. @Transactional(rollbackFor = Exception.class)
  54. @GetMapping(CREATE)
  55. @Override
  56. public R<ExampleResult> create(Long flowLinkNo, String code, String nodeCode, String title, String remarks, String cacheData) {
  57. ExampleResult exampleResult = new ExampleResult();
  58. Long count = exampleInfoService.count(Wrappers.<ExampleInfo>lambdaQuery()
  59. .eq(ExampleInfo::getFlowLinkNo, flowLinkNo)
  60. .eq(ExampleInfo::getComplete, StatusConstant.NO));
  61. Assert.eqZero(count, FlowExplainConstant.EXPLAIN_NOT_EXIST);
  62. // 查找通用流程
  63. ProcessInfo processInfo = processInfoService.getOne(ProcessInfo::getCode, code);
  64. Assert.notEmpty(processInfo, String.format(FlowExplainConstant.PROCESS_NOT_EXIST, code));
  65. // 获取租户流程
  66. ProcessTenant processTenant = processTenantService.getOne(Wrappers.<ProcessTenant>lambdaQuery()
  67. .eq(ProcessTenant::getProcessInfoId, processInfo.getId())
  68. .eq(ProcessTenant::getBindingTenantId, AuthUtil.getTenantId())
  69. .eq(ProcessTenant::getCurrentVersion, StatusConstant.YES));
  70. // 创建流程实例
  71. ExampleInfo exampleInfo = new ExampleInfo();
  72. exampleInfo.setProcessInfoId(processInfo.getId());
  73. exampleInfo.setTitle(title);
  74. exampleInfo.setFlowLinkNo(flowLinkNo);
  75. exampleInfo.setCacheData(cacheData);
  76. // 走默认流程,直接完成
  77. if (processTenant == null) {
  78. exampleInfo.setComplete(StatusConstant.YES);
  79. exampleInfo.setProcessNodeId(FlowConstant.OVER_PROCESS_FLAG);
  80. exampleInfo.setProcessNodeCode(FlowConstant.END_CODE);
  81. exampleInfo.setFlowType(FlowConstant.FLOW_TYPE_DEFAULT);
  82. exampleInfo.setHandleResult(HandleResultEnum.SUCCESS.getType());
  83. exampleInfoService.save(exampleInfo);
  84. // 开始流程明细
  85. ExampleDetails startDetails = new ExampleDetails();
  86. startDetails.setExampleInfoId(exampleInfo.getId());
  87. startDetails.setProcessInfoId(processInfo.getId());
  88. startDetails.setNameType(ButtonNameEnum.START.getType());
  89. startDetails.setHandleUserId(AuthUtil.getUserId());
  90. startDetails.setRemarks(remarks);
  91. // 结束流程明细
  92. ExampleDetails endDetails = new ExampleDetails();
  93. endDetails.setExampleInfoId(exampleInfo.getId());
  94. endDetails.setProcessInfoId(processInfo.getId());
  95. endDetails.setNameType(ButtonNameEnum.END.getType());
  96. // 封装返回值
  97. exampleResult.setOldExampleInfo(exampleInfo);
  98. exampleResult.setExampleInfo(exampleInfo);
  99. exampleResult.setExampleDetailsIdList(Arrays.asList(startDetails.getId(), endDetails.getId()));
  100. exampleResult.setHandleType(ButtonNameEnum.END.getType());
  101. exampleResult.setCacheDataStr(cacheData);
  102. return R.data(exampleResult);
  103. }
  104. // 查询节点
  105. ProcessNodeButton processNodeButton = processNodeButtonService.getOne(Wrappers.<ProcessNodeButton>lambdaQuery()
  106. .eq(ProcessNodeButton::getProcessTenantId, processTenant.getId())
  107. .eq(ProcessNodeButton::getProcessNodeCode, FlowConstant.START_CODE));
  108. Assert.notEmpty(processNodeButton, FlowExplainConstant.SPECIFY_BRANCH_EMPTY);
  109. exampleInfo.setFlowType(FlowConstant.FLOW_TYPE_TENANT);
  110. exampleInfo.setProcessTenantId(processTenant.getId());
  111. exampleInfo.setProcessNodeId(processNodeButton.getProcessNodeId());
  112. exampleInfo.setProcessNodeCode(processNodeButton.getProcessNodeCode());
  113. exampleInfo.setComplete(StatusConstant.NO);
  114. exampleInfo.setHandleResult(HandleResultEnum.IN_PROGRESS.getType());
  115. exampleInfoService.save(exampleInfo);
  116. JumpVo jumpVo = new JumpVo();
  117. setJumpNode(jumpVo, processNodeButton, nodeCode);
  118. exampleResult.setJumpVo(jumpVo);
  119. return R.data(exampleResult);
  120. }
  121. @GetMapping(GET_JUMP_VO)
  122. @Override
  123. public R<JumpVo> getJumpVo(Long buttonId, String nodeCode) {
  124. JumpVo jumpVo = new JumpVo();
  125. ProcessNodeButton processNodeButton = processNodeButtonService.getById(buttonId);
  126. Assert.notEmpty(processNodeButton, "nodeButton is null");
  127. setJumpNode(jumpVo, processNodeButton, nodeCode);
  128. return R.data(jumpVo);
  129. }
  130. @Transactional(rollbackFor = Exception.class)
  131. @PostMapping(JUMP)
  132. @Override
  133. public R<ExampleResult> jump(JumpVo jumpVo) {
  134. // 返回值
  135. ExampleResult exampleResult = new ExampleResult();
  136. // 查询流程实例
  137. ExampleInfo oleExampleInfo = exampleInfoService.getOne(Wrappers.<ExampleInfo>lambdaQuery()
  138. .eq(ExampleInfo::getFlowLinkNo, jumpVo.getFlowLinkNo())
  139. .eq(ExampleInfo::getComplete, StatusConstant.NO));
  140. Assert.notEmpty(oleExampleInfo, FlowExplainConstant.EXAMPLE_INFO_NULL);
  141. // 复制除一个对象做修改
  142. ExampleInfo exampleInfo = ObjectUtil.clone(oleExampleInfo);
  143. String cacheDataStr = jumpVo.getCacheDataStr();
  144. if (ObjectUtil.isNotEmpty(cacheDataStr)) {
  145. exampleInfo.setCacheData(cacheDataStr);
  146. }
  147. // 明细
  148. ExampleDetails exampleDetails = createExampleDetails(exampleInfo, jumpVo.getNameType());
  149. exampleDetails.setProcessNodeButtonId(jumpVo.getButtonId());
  150. exampleDetails.setHandleUserId(AuthUtil.getUserId());
  151. exampleDetails.setRemarks(jumpVo.getRemarks());
  152. // 赋值按钮处理方法
  153. exampleResult.setHandleType(jumpVo.getNameType());
  154. // 驳回
  155. if (ButtonNameEnum.REJECT.getType().equals(jumpVo.getNameType())) {
  156. exampleInfo.setHandleResult(HandleResultEnum.FAIL.getType());
  157. }
  158. // 通过
  159. else if (FlowConstant.END_CODE.equals(jumpVo.getJumpNodeCode())) {
  160. exampleInfo.setHandleResult(HandleResultEnum.SUCCESS.getType());
  161. // 赋值结束处理方法
  162. exampleResult.setHandleType(ButtonNameEnum.END.getType());
  163. }
  164. exampleInfo.setProcessNodeId(jumpVo.getJumpNodeId());
  165. exampleInfo.setProcessNodeCode(jumpVo.getJumpNodeCode());
  166. exampleInfo.setHandleObjectType(jumpVo.getHandleObjectType());
  167. exampleInfo.setHandleObjectIdSet(jumpVo.getHandleObjectIdSet());
  168. List<Long> exampleDetailsIdList = new ArrayList<>();
  169. // 流程结束
  170. if (FlowConstant.END_CODE.equals(jumpVo.getJumpNodeCode())) {
  171. // 赋值流程完成
  172. exampleInfo.setComplete(StatusConstant.YES);
  173. // 流程明细
  174. ExampleDetails endExampleDetails = createExampleDetails(exampleInfo, ButtonNameEnum.END.getType());
  175. exampleDetailsService.saveBatch(Arrays.asList(exampleDetails, endExampleDetails));
  176. exampleDetailsIdList.add(exampleDetails.getId());
  177. exampleDetailsIdList.add(endExampleDetails.getId());
  178. }
  179. // 正常跳转
  180. else {
  181. // 流程明细
  182. exampleDetailsService.save(exampleDetails);
  183. exampleDetailsIdList.add(exampleDetails.getId());
  184. // 如果跳转节点到发起(一直回退到发起人),处理人只能是发起人
  185. if (FlowConstant.START_CODE.equals(jumpVo.getJumpNodeCode())) {
  186. exampleInfo.setHandleObjectType(ProcessNodeHandleObjectTypeEnum.USER.getType());
  187. exampleInfo.setHandleObjectIdSet(exampleInfo.getCreateUser().toString());
  188. }
  189. }
  190. exampleInfoService.updateById(exampleInfo);
  191. exampleResult.setOldExampleInfo(oleExampleInfo);
  192. exampleResult.setExampleInfo(exampleInfo);
  193. exampleResult.setCacheDataStr(exampleInfo.getCacheData());
  194. exampleResult.setExampleDetailsIdList(exampleDetailsIdList);
  195. return R.data(exampleResult);
  196. }
  197. @PostMapping(ROLL_BACK)
  198. @Override
  199. public void rollBack(ExampleResult result) {
  200. ExampleInfo oldExampleInfo = result.getOldExampleInfo();
  201. if (result.isDeleteExample()) {
  202. exampleInfoService.update(Wrappers.<ExampleInfo>lambdaUpdate()
  203. .eq(BaseEntity::getId, oldExampleInfo.getId())
  204. .set(ExampleInfo::getDelFlag, 1)
  205. .set(ExampleInfo::getRemarks, "业务异常,本次流程实例已删除")
  206. );
  207. } else {
  208. exampleInfoService.updateById(oldExampleInfo);
  209. }
  210. exampleDetailsService.update(Wrappers.<ExampleDetails>lambdaUpdate()
  211. .in(BaseEntity::getId, result.getExampleDetailsIdList())
  212. .set(ExampleDetails::getDelFlag, 1)
  213. .set(ExampleDetails::getRemarks, "业务异常,本次流程明细已删除")
  214. );
  215. }
  216. @Override
  217. public R withdraw(Long withdrawExampleInfoId, Long withdrawExampleDetailsId) {
  218. exampleInfoService.withdraw(withdrawExampleInfoId, withdrawExampleDetailsId);
  219. return R.success();
  220. }
  221. @Override
  222. public R revoke(Long revokeExampleInfoId) {
  223. exampleInfoService.revoke(revokeExampleInfoId);
  224. return R.success();
  225. }
  226. private void setJumpNode(JumpVo jumpVo, ProcessNodeButton processNodeButton, String nodeCode) {
  227. // 赋值按钮名称类型
  228. jumpVo.setNameType(processNodeButton.getNameType());
  229. jumpVo.setButtonId(processNodeButton.getId());
  230. ProcessNode processNode;
  231. // 非分支跳转
  232. if (ObjectUtil.isNotEmpty(processNodeButton.getJumpNodeId())) {
  233. processNode = processNodeService.getById(processNodeButton.getJumpNodeId());
  234. }
  235. // 分支跳转
  236. else {
  237. // 跳转节点编码不为空
  238. Assert.notEmpty(nodeCode, FlowExplainConstant.SPECIFY_BRANCH_EMPTY);
  239. // 查询跳转到哪个分支节点
  240. processNode = processNodeService.getOne(Wrappers.<ProcessNode>lambdaQuery()
  241. .eq(ProcessNode::getParentId, processNodeButton.getProcessNodeId())
  242. .eq(ProcessNode::getCode, nodeCode));
  243. // 分支节点不为空
  244. Assert.notEmpty(processNode, FlowExplainConstant.SPECIFY_BRANCH_EMPTY);
  245. }
  246. if(ObjectUtil.isNotEmpty(processNode)) {
  247. jumpVo.setJumpNodeId(processNode.getId());
  248. jumpVo.setJumpNodeCode(processNode.getCode());
  249. jumpVo.setHandleObjectType(processNode.getHandleObjectType());
  250. jumpVo.setHandleObjectIdSet(processNode.getHandleObjectIdSet());
  251. }
  252. }
  253. /**
  254. * 创建流程实例明细
  255. */
  256. private ExampleDetails createExampleDetails(ExampleInfo exampleInfo, Integer nameType) {
  257. ExampleDetails exampleDetails = new ExampleDetails();
  258. exampleDetails.setExampleInfoId(exampleInfo.getId());
  259. exampleDetails.setProcessInfoId(exampleInfo.getProcessInfoId());
  260. exampleDetails.setProcessTenantId(exampleInfo.getProcessTenantId());
  261. exampleDetails.setProcessNodeId(exampleInfo.getProcessNodeId());
  262. exampleDetails.setNameType(nameType);
  263. return exampleDetails;
  264. }
  265. /**
  266. * 根据流程实例ID删除流程(伪删除)
  267. *
  268. * @param exampleInfoId 流程实例ID
  269. * @return
  270. */
  271. @Transactional(rollbackFor = {Exception.class})
  272. @Override
  273. public Boolean deleteByExampleInfoId(Long exampleInfoId) {
  274. Boolean flag = true;
  275. try {
  276. //流程实例
  277. UpdateWrapper<ExampleInfo> exampleInfoWrapper = new UpdateWrapper<>();
  278. exampleInfoWrapper.lambda().set(ExampleInfo::getDelFlag, 1);
  279. exampleInfoWrapper.lambda().eq(ExampleInfo::getId, exampleInfoId);
  280. exampleInfoService.update(exampleInfoWrapper);
  281. //实例明细
  282. UpdateWrapper<ExampleDetails> exampleDetailsWrapper = new UpdateWrapper<>();
  283. exampleDetailsWrapper.lambda().set(ExampleDetails::getDelFlag, 1);
  284. exampleDetailsWrapper.lambda().eq(ExampleDetails::getExampleInfoId, exampleInfoId);
  285. exampleDetailsService.update(exampleDetailsWrapper);
  286. } catch (Exception e) {
  287. flag = false;
  288. e.printStackTrace();
  289. throw e;
  290. } finally {
  291. return flag;
  292. }
  293. }
  294. /**
  295. * 获取当前节点对应的按钮ID
  296. *
  297. * @param exampleInfoId 流程实例ID
  298. * @return
  299. */
  300. @Override
  301. public Long getButtonIdByExampleInfoId(Long exampleInfoId) {
  302. Long buttonId = null;
  303. //查询流程实例信息
  304. ExampleInfo exampleInfo = exampleInfoService.getById(exampleInfoId);
  305. if (Func.isNotEmpty(exampleInfo)) {
  306. //查询节点按钮信息
  307. QueryWrapper<ProcessNodeButton> wrapper = new QueryWrapper<>();
  308. wrapper.lambda().eq(ProcessNodeButton::getProcessNodeId, exampleInfo.getProcessNodeId());
  309. ProcessNodeButton button = processNodeButtonService.getOne(wrapper);
  310. if (Func.isNotEmpty(button)) {
  311. buttonId = button.getId();
  312. }
  313. }
  314. return buttonId;
  315. }
  316. }