package com.fjhx.feign; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.fjhx.base.BaseEntity; import com.fjhx.constants.FlowConstant; import com.fjhx.constants.FlowExplainConstant; import com.fjhx.constants.StatusConstant; import com.fjhx.entity.example.ExampleDetails; import com.fjhx.entity.example.ExampleInfo; import com.fjhx.entity.process.ProcessInfo; import com.fjhx.entity.process.ProcessNode; import com.fjhx.entity.process.ProcessNodeButton; import com.fjhx.entity.process.ProcessTenant; import com.fjhx.enums.ButtonNameEnum; import com.fjhx.enums.HandleResultEnum; import com.fjhx.enums.ProcessNodeHandleObjectTypeEnum; import com.fjhx.params.ExampleResult; import com.fjhx.params.JumpVo; import com.fjhx.service.example.ExampleDetailsService; import com.fjhx.service.example.ExampleInfoService; import com.fjhx.service.process.ProcessInfoService; import com.fjhx.service.process.ProcessNodeButtonService; import com.fjhx.service.process.ProcessNodeService; import com.fjhx.service.process.ProcessTenantService; import com.fjhx.utils.Assert; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.Func; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @RestController public class FlowClient implements IFlowClient { @Autowired private ExampleInfoService exampleInfoService; @Autowired private ProcessInfoService processInfoService; @Autowired private ProcessTenantService processTenantService; @Autowired private ProcessNodeService processNodeService; @Autowired private ProcessNodeButtonService processNodeButtonService; @Autowired private ExampleDetailsService exampleDetailsService; @Transactional(rollbackFor = Exception.class) @GetMapping(CREATE) @Override public R create(Long flowLinkNo, String code, String nodeCode, String title, String remarks, String cacheData) { ExampleResult exampleResult = new ExampleResult(); Long count = exampleInfoService.count(Wrappers.lambdaQuery() .eq(ExampleInfo::getFlowLinkNo, flowLinkNo) .eq(ExampleInfo::getComplete, StatusConstant.NO)); Assert.eqZero(count, FlowExplainConstant.EXPLAIN_NOT_EXIST); // 查找通用流程 ProcessInfo processInfo = processInfoService.getOne(ProcessInfo::getCode, code); Assert.notEmpty(processInfo, String.format(FlowExplainConstant.PROCESS_NOT_EXIST, code)); // 获取租户流程 ProcessTenant processTenant = processTenantService.getOne(Wrappers.lambdaQuery() .eq(ProcessTenant::getProcessInfoId, processInfo.getId()) .eq(ProcessTenant::getBindingTenantId, AuthUtil.getTenantId()) .eq(ProcessTenant::getCurrentVersion, StatusConstant.YES)); // 创建流程实例 ExampleInfo exampleInfo = new ExampleInfo(); exampleInfo.setProcessInfoId(processInfo.getId()); exampleInfo.setTitle(title); exampleInfo.setFlowLinkNo(flowLinkNo); exampleInfo.setCacheData(cacheData); // 走默认流程,直接完成 if (processTenant == null) { exampleInfo.setComplete(StatusConstant.YES); exampleInfo.setProcessNodeId(FlowConstant.OVER_PROCESS_FLAG); exampleInfo.setProcessNodeCode(FlowConstant.END_CODE); exampleInfo.setFlowType(FlowConstant.FLOW_TYPE_DEFAULT); exampleInfo.setHandleResult(HandleResultEnum.SUCCESS.getType()); exampleInfoService.save(exampleInfo); // 开始流程明细 ExampleDetails startDetails = new ExampleDetails(); startDetails.setExampleInfoId(exampleInfo.getId()); startDetails.setProcessInfoId(processInfo.getId()); startDetails.setNameType(ButtonNameEnum.START.getType()); startDetails.setHandleUserId(AuthUtil.getUserId()); startDetails.setRemarks(remarks); // 结束流程明细 ExampleDetails endDetails = new ExampleDetails(); endDetails.setExampleInfoId(exampleInfo.getId()); endDetails.setProcessInfoId(processInfo.getId()); endDetails.setNameType(ButtonNameEnum.END.getType()); // 封装返回值 exampleResult.setOldExampleInfo(exampleInfo); exampleResult.setExampleInfo(exampleInfo); exampleResult.setExampleDetailsIdList(Arrays.asList(startDetails.getId(), endDetails.getId())); exampleResult.setHandleType(ButtonNameEnum.END.getType()); exampleResult.setCacheDataStr(cacheData); return R.data(exampleResult); } // 查询节点 ProcessNodeButton processNodeButton = processNodeButtonService.getOne(Wrappers.lambdaQuery() .eq(ProcessNodeButton::getProcessTenantId, processTenant.getId()) .eq(ProcessNodeButton::getProcessNodeCode, FlowConstant.START_CODE)); Assert.notEmpty(processNodeButton, FlowExplainConstant.SPECIFY_BRANCH_EMPTY); exampleInfo.setFlowType(FlowConstant.FLOW_TYPE_TENANT); exampleInfo.setProcessTenantId(processTenant.getId()); exampleInfo.setProcessNodeId(processNodeButton.getProcessNodeId()); exampleInfo.setProcessNodeCode(processNodeButton.getProcessNodeCode()); exampleInfo.setComplete(StatusConstant.NO); exampleInfo.setHandleResult(HandleResultEnum.IN_PROGRESS.getType()); exampleInfoService.save(exampleInfo); JumpVo jumpVo = new JumpVo(); setJumpNode(jumpVo, processNodeButton, nodeCode); exampleResult.setJumpVo(jumpVo); return R.data(exampleResult); } @GetMapping(GET_JUMP_VO) @Override public R getJumpVo(Long buttonId, String nodeCode) { JumpVo jumpVo = new JumpVo(); ProcessNodeButton processNodeButton = processNodeButtonService.getById(buttonId); Assert.notEmpty(processNodeButton, "nodeButton is null"); setJumpNode(jumpVo, processNodeButton, nodeCode); return R.data(jumpVo); } @Transactional(rollbackFor = Exception.class) @PostMapping(JUMP) @Override public R jump(JumpVo jumpVo) { // 返回值 ExampleResult exampleResult = new ExampleResult(); // 查询流程实例 ExampleInfo oleExampleInfo = exampleInfoService.getOne(Wrappers.lambdaQuery() .eq(ExampleInfo::getFlowLinkNo, jumpVo.getFlowLinkNo()) .eq(ExampleInfo::getComplete, StatusConstant.NO)); Assert.notEmpty(oleExampleInfo, FlowExplainConstant.EXAMPLE_INFO_NULL); // 复制除一个对象做修改 ExampleInfo exampleInfo = ObjectUtil.clone(oleExampleInfo); String cacheDataStr = jumpVo.getCacheDataStr(); if (ObjectUtil.isNotEmpty(cacheDataStr)) { exampleInfo.setCacheData(cacheDataStr); } // 明细 ExampleDetails exampleDetails = createExampleDetails(exampleInfo, jumpVo.getNameType()); exampleDetails.setProcessNodeButtonId(jumpVo.getButtonId()); exampleDetails.setHandleUserId(AuthUtil.getUserId()); exampleDetails.setRemarks(jumpVo.getRemarks()); // 赋值按钮处理方法 exampleResult.setHandleType(jumpVo.getNameType()); // 驳回 if (ButtonNameEnum.REJECT.getType().equals(jumpVo.getNameType())) { exampleInfo.setHandleResult(HandleResultEnum.FAIL.getType()); } // 通过 else if (FlowConstant.END_CODE.equals(jumpVo.getJumpNodeCode())) { exampleInfo.setHandleResult(HandleResultEnum.SUCCESS.getType()); // 赋值结束处理方法 exampleResult.setHandleType(ButtonNameEnum.END.getType()); } exampleInfo.setProcessNodeId(jumpVo.getJumpNodeId()); exampleInfo.setProcessNodeCode(jumpVo.getJumpNodeCode()); exampleInfo.setHandleObjectType(jumpVo.getHandleObjectType()); exampleInfo.setHandleObjectIdSet(jumpVo.getHandleObjectIdSet()); List exampleDetailsIdList = new ArrayList<>(); // 流程结束 if (FlowConstant.END_CODE.equals(jumpVo.getJumpNodeCode())) { // 赋值流程完成 exampleInfo.setComplete(StatusConstant.YES); // 流程明细 ExampleDetails endExampleDetails = createExampleDetails(exampleInfo, ButtonNameEnum.END.getType()); exampleDetailsService.saveBatch(Arrays.asList(exampleDetails, endExampleDetails)); exampleDetailsIdList.add(exampleDetails.getId()); exampleDetailsIdList.add(endExampleDetails.getId()); } // 正常跳转 else { // 流程明细 exampleDetailsService.save(exampleDetails); exampleDetailsIdList.add(exampleDetails.getId()); // 如果跳转节点到发起(一直回退到发起人),处理人只能是发起人 if (FlowConstant.START_CODE.equals(jumpVo.getJumpNodeCode())) { exampleInfo.setHandleObjectType(ProcessNodeHandleObjectTypeEnum.USER.getType()); exampleInfo.setHandleObjectIdSet(exampleInfo.getCreateUser().toString()); } } exampleInfoService.updateById(exampleInfo); exampleResult.setOldExampleInfo(oleExampleInfo); exampleResult.setExampleInfo(exampleInfo); exampleResult.setCacheDataStr(exampleInfo.getCacheData()); exampleResult.setExampleDetailsIdList(exampleDetailsIdList); return R.data(exampleResult); } @PostMapping(ROLL_BACK) @Override public void rollBack(ExampleResult result) { ExampleInfo oldExampleInfo = result.getOldExampleInfo(); if (result.isDeleteExample()) { exampleInfoService.update(Wrappers.lambdaUpdate() .eq(BaseEntity::getId, oldExampleInfo.getId()) .set(ExampleInfo::getDelFlag, 1) .set(ExampleInfo::getRemarks, "业务异常,本次流程实例已删除") ); } else { exampleInfoService.updateById(oldExampleInfo); } exampleDetailsService.update(Wrappers.lambdaUpdate() .in(BaseEntity::getId, result.getExampleDetailsIdList()) .set(ExampleDetails::getDelFlag, 1) .set(ExampleDetails::getRemarks, "业务异常,本次流程明细已删除") ); } @Override public R withdraw(Long withdrawExampleInfoId, Long withdrawExampleDetailsId) { exampleInfoService.withdraw(withdrawExampleInfoId, withdrawExampleDetailsId); return R.success(); } @Override public R revoke(Long revokeExampleInfoId) { exampleInfoService.revoke(revokeExampleInfoId); return R.success(); } private void setJumpNode(JumpVo jumpVo, ProcessNodeButton processNodeButton, String nodeCode) { // 赋值按钮名称类型 jumpVo.setNameType(processNodeButton.getNameType()); jumpVo.setButtonId(processNodeButton.getId()); ProcessNode processNode; // 非分支跳转 if (ObjectUtil.isNotEmpty(processNodeButton.getJumpNodeId())) { processNode = processNodeService.getById(processNodeButton.getJumpNodeId()); } // 分支跳转 else { // 跳转节点编码不为空 Assert.notEmpty(nodeCode, FlowExplainConstant.SPECIFY_BRANCH_EMPTY); // 查询跳转到哪个分支节点 processNode = processNodeService.getOne(Wrappers.lambdaQuery() .eq(ProcessNode::getParentId, processNodeButton.getProcessNodeId()) .eq(ProcessNode::getCode, nodeCode)); // 分支节点不为空 Assert.notEmpty(processNode, FlowExplainConstant.SPECIFY_BRANCH_EMPTY); } if(ObjectUtil.isNotEmpty(processNode)) { jumpVo.setJumpNodeId(processNode.getId()); jumpVo.setJumpNodeCode(processNode.getCode()); jumpVo.setHandleObjectType(processNode.getHandleObjectType()); jumpVo.setHandleObjectIdSet(processNode.getHandleObjectIdSet()); } } /** * 创建流程实例明细 */ private ExampleDetails createExampleDetails(ExampleInfo exampleInfo, Integer nameType) { ExampleDetails exampleDetails = new ExampleDetails(); exampleDetails.setExampleInfoId(exampleInfo.getId()); exampleDetails.setProcessInfoId(exampleInfo.getProcessInfoId()); exampleDetails.setProcessTenantId(exampleInfo.getProcessTenantId()); exampleDetails.setProcessNodeId(exampleInfo.getProcessNodeId()); exampleDetails.setNameType(nameType); return exampleDetails; } /** * 根据流程实例ID删除流程(伪删除) * * @param exampleInfoId 流程实例ID * @return */ @Transactional(rollbackFor = {Exception.class}) @Override public Boolean deleteByExampleInfoId(Long exampleInfoId) { Boolean flag = true; try { //流程实例 UpdateWrapper exampleInfoWrapper = new UpdateWrapper<>(); exampleInfoWrapper.lambda().set(ExampleInfo::getDelFlag, 1); exampleInfoWrapper.lambda().eq(ExampleInfo::getId, exampleInfoId); exampleInfoService.update(exampleInfoWrapper); //实例明细 UpdateWrapper exampleDetailsWrapper = new UpdateWrapper<>(); exampleDetailsWrapper.lambda().set(ExampleDetails::getDelFlag, 1); exampleDetailsWrapper.lambda().eq(ExampleDetails::getExampleInfoId, exampleInfoId); exampleDetailsService.update(exampleDetailsWrapper); } catch (Exception e) { flag = false; e.printStackTrace(); throw e; } finally { return flag; } } /** * 获取当前节点对应的按钮ID * * @param exampleInfoId 流程实例ID * @return */ @Override public Long getButtonIdByExampleInfoId(Long exampleInfoId) { Long buttonId = null; //查询流程实例信息 ExampleInfo exampleInfo = exampleInfoService.getById(exampleInfoId); if (Func.isNotEmpty(exampleInfo)) { //查询节点按钮信息 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda().eq(ProcessNodeButton::getProcessNodeId, exampleInfo.getProcessNodeId()); ProcessNodeButton button = processNodeButtonService.getOne(wrapper); if (Func.isNotEmpty(button)) { buttonId = button.getId(); } } return buttonId; } }