diff --git a/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApprover.java b/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApprover.java new file mode 100644 index 0000000000..7378438c5a --- /dev/null +++ b/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApprover.java @@ -0,0 +1,23 @@ +package com.yxt.anrui.flowable.api.flowapprover; + +import com.yxt.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Data +public class FlowApprover extends BaseEntity { + private static final long serialVersionUID = 8140464420543873852L; + @ApiModelProperty("申请sid") + private String businessSid; + @ApiModelProperty("序号") + private Integer sortNo; + @ApiModelProperty("审批人sid") + private String approverSid; + @ApiModelProperty("审批人名称") + private String approvalName; +} diff --git a/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApproverDto.java b/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApproverDto.java new file mode 100644 index 0000000000..2d7597af72 --- /dev/null +++ b/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApproverDto.java @@ -0,0 +1,20 @@ +package com.yxt.anrui.flowable.api.flowapprover; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Data +public class FlowApproverDto { + + @ApiModelProperty("申请sid") + private String businessSid; + @ApiModelProperty("审批人sid") + private List approverSidList; +} diff --git a/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowcc/FlowCc.java b/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowcc/FlowCc.java new file mode 100644 index 0000000000..24f6e3810a --- /dev/null +++ b/anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowcc/FlowCc.java @@ -0,0 +1,21 @@ +package com.yxt.anrui.flowable.api.flowcc; + +import com.yxt.common.core.domain.BaseEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Data +public class FlowCc extends BaseEntity { + private static final long serialVersionUID = -4299550952719113083L; + @ApiModelProperty("申请sid") + private String businessSid; + @ApiModelProperty("抄送人sids") + private String ccSids; + @ApiModelProperty("抄送人名称") + private String ccNames; +} diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java index cb7e2ce5b3..e0628875e7 100644 --- a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java @@ -95,8 +95,6 @@ public class Flow3Service extends MybatisBaseService { private MessageFeign messageFeign; @Autowired private SysFlowccFeign sysFlowccFeign; - @Autowired - private ProcessEngine processEngine; public ResultBean businessStartProcessInstanceById(BusinessVariables bv) { ResultBean rb = ResultBean.fireFail(); @@ -146,6 +144,8 @@ public class Flow3Service extends MybatisBaseService { String id_ = ""; String name_ = ""; String task_def_key_ = ""; + //设置是否是管理员自动审批,默认否 + boolean adminContains = false; //查询当前实例的最新待办任务 List tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); if (StringUtils.isBlank(nextNodeUserSids)) { @@ -168,6 +168,21 @@ public class Flow3Service extends MybatisBaseService { taskService.setVariablesLocal(id_, variables); } } + tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + //遍历待办任务 + for (int i = 0; i < tasks.size(); i++) { + Task task2 = tasks.get(i); + String isMultiInstanceTask = isMultiInstanceTask(task2); + id_ = task2.getId(); + task_def_key_ = task2.getTaskDefinitionKey(); + name_ = task2.getName(); + if ("会签任务".equals(isMultiInstanceTask) || "或签任务".equals(isMultiInstanceTask)) { + if(ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(task2.getAssignee())){ + adminContains = true; + break; + } + } + } } else { Task task2 = tasks.get(0); id_ = task2.getId(); @@ -179,8 +194,10 @@ public class Flow3Service extends MybatisBaseService { taskService.setVariablesLocal(id_, variables); } + + //提交前传入下一环节待办人 - if (ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(nextNodeUserSids)) { + if (ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(nextNodeUserSids) || adminContains) { return handleAutomaticApproval(bv, task, id_, task_def_key_, variables, variablesSeconds, processDefinition); } // 如果申请人与下一环节审批人相同,则自动审批 @@ -301,6 +318,22 @@ public class Flow3Service extends MybatisBaseService { nodeState = task2.getName(); taskDefKey = task2.getTaskDefinitionKey(); } + tasks = taskService.createTaskQuery().processInstanceId(instanceId).list(); + //遍历待办任务 + for (int i = 0; i < tasks.size(); i++) { + Task task2 = tasks.get(i); + isMultiInstanceTask = isMultiInstanceTask(task2); + vo.setTaskId(task2.getId()); + nodeState = task2.getName(); + taskDefKey = task2.getTaskDefinitionKey(); + if ("会签任务".equals(isMultiInstanceTask) || "或签任务".equals(isMultiInstanceTask)) { + if(ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(task2.getAssignee())){ + nextUserSid = ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId(); + adminContains = true; + break; + } + } + } } else { nodeState = FlowComment.SETTLE.getRemark(); taskDefKey = "Event_end"; diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.java new file mode 100644 index 0000000000..a2c0a120ba --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.java @@ -0,0 +1,18 @@ +package com.yxt.anrui.flowable.biz.flow4; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yxt.anrui.flowable.api.flow.Flowable; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Mapper +public interface Flow4Mapper extends BaseMapper { + + List selectByProcInstId(String instanceId); +} diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.xml b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.xml new file mode 100644 index 0000000000..457aa52e23 --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Rest.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Rest.java new file mode 100644 index 0000000000..005a0798f3 --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Rest.java @@ -0,0 +1,111 @@ +package com.yxt.anrui.flowable.biz.flow4; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSONObject; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.yxt.anrui.flowable.api.flow.UpdateFlowFieldVo; +import com.yxt.anrui.flowable.biz.flow2.FlowRest; +import com.yxt.anrui.flowable.feign.form.MessageFlowVo; +import com.yxt.anrui.flowable.feign.form.MessageFlowableQuery; +import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables; +import com.yxt.anrui.portal.api.sysflowcc.SysFlowccVo; +import com.yxt.anrui.portal.api.sysuser.SysUserVo; +import com.yxt.anrui.portal.api.sysuser.UserByRolesAndOrgQuery; +import com.yxt.common.base.utils.StringUtils; +import com.yxt.common.core.result.ResultBean; +import org.apache.tomcat.util.threads.ThreadPoolExecutor; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +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.*; +import java.util.concurrent.*; + +/** + * @description: 通用审批 + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@RestController +@RequestMapping("v4/flow") +public class Flow4Rest { + + Logger log = LoggerFactory.getLogger(FlowRest.class); + + @Autowired + private Flow4Service flowService; + + @PostMapping("/startProcess") + public ResultBean startProcess(@RequestBody BusinessVariables bv) { + ResultBean rb = ResultBean.fireFail(); + //获取表单中的参数 + Map formVariables = bv.getFormVariables(); + formVariables = formVariables == null ? new HashMap<>() : formVariables; + //发起人的组织全路径 + String orgPath = bv.getOrgSidPath(); + formVariables.put("createrOrgPath", orgPath); + formVariables.put("businessSid", bv.getBusinessSid()); + + //启动流程实例 + ResultBean startResultBean = flowService.businessStartProcessInstanceById(bv); + return startResultBean; + } + + @PostMapping("/submit2") + ResultBean submit2() { + ResultBean rb = ResultBean.fireFail(); + List userIds = new ArrayList<>(); + userIds.add("aaa"); + userIds.add("bbb"); + userIds.add("ccc"); + + Map variables = new HashMap<>(); + variables.put("approvers", userIds); + BusinessVariables bv = new BusinessVariables(); + bv.setFormVariables(variables); + bv.setModelId("process_wj9q4vwi:1:17170004"); + bv.setUserSid("7f56f6ec-4a5f-47b0-aaab-158d64cb97b1"); + //启动流程 + ResultBean voResultBean = startProcess(bv); + System.out.println("voResultBean{}" + voResultBean); + return rb.success(); + } + + public ResultBean handleProsess(BusinessVariables bv) { + ResultBean rb = ResultBean.fireFail(); + ResultBean updateFlowFieldVoResultBean = flowService.handleProsess(bv, true); + //添加抄送 + log.info("流程返回:{}", JSONObject.toJSONString(updateFlowFieldVoResultBean)); + //需要判断办结后再执行 TODO + if (updateFlowFieldVoResultBean.getSuccess()) { + log.info("流程返回:{}", JSONObject.toJSONString(updateFlowFieldVoResultBean)); + if ("Event_end".equals(updateFlowFieldVoResultBean.getData().getTaskDefKey())) { + try { + ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() + .setNameFormat("demo-pool-%d").build(); + ExecutorService pool = new ThreadPoolExecutor(2, 100, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); + + Future future1 = pool.submit(() -> { + HashMap map = new HashMap<>(); + map.put("bv", bv); + UpdateFlowFieldVo ufVo = updateFlowFieldVoResultBean.getData(); + ufVo.setTaskId(bv.getTaskId()); + map.put("uff", ufVo); + flowService.cc(map, bv.getTaskDefKey()); + }); + } catch (Exception e) { + e.printStackTrace(); + return rb.setMsg("抄送失败"); + } + } + } + return updateFlowFieldVoResultBean; + } +} diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Service.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Service.java new file mode 100644 index 0000000000..41c6389c4a --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Service.java @@ -0,0 +1,441 @@ +package com.yxt.anrui.flowable.biz.flow4; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.yxt.anrui.flowable.api.flow.Flowable; +import com.yxt.anrui.flowable.api.flow.UpdateFlowFieldVo; +import com.yxt.anrui.flowable.api.flowapprover.FlowApprover; +import com.yxt.anrui.flowable.api.flowapprover.FlowApproverDto; +import com.yxt.anrui.flowable.api.flowcc.FlowCc; +import com.yxt.anrui.flowable.api.flowcomment.FlowComment; +import com.yxt.anrui.flowable.api.flowtask.LatestTaskVo; +import com.yxt.anrui.flowable.api.processcomment.ProcessCommentDto; +import com.yxt.anrui.flowable.api.utils.ProcDefEnum; +import com.yxt.anrui.flowable.biz.flow2.FlowMapper; +import com.yxt.anrui.flowable.biz.flowapprover.FlowApproverService; +import com.yxt.anrui.flowable.biz.flowcc.FlowCcService; +import com.yxt.anrui.flowable.biz.flowtask.FlowTaskService; +import com.yxt.anrui.flowable.biz.process.ProcessService; +import com.yxt.anrui.flowable.biz.processcomment.ProcessCommentService; +import com.yxt.anrui.flowable.common.ProcessConstants; +import com.yxt.anrui.flowable.feign.MessageFeign; +import com.yxt.anrui.flowable.feign.form.MessageFlowVo; +import com.yxt.anrui.flowable.feign.form.MessageFlowableQuery; +import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables; +import com.yxt.anrui.portal.api.sysflowableconfig.SysFlowableConfigFeign; +import com.yxt.anrui.portal.api.sysflowableconfig.SysFlowableConfigQuery; +import com.yxt.anrui.portal.api.sysflowableconfig.SysFlowableConfigVvo; +import com.yxt.anrui.portal.api.sysflowcc.SysFlowccFeign; +import com.yxt.anrui.portal.api.sysflowcc.SysFlowccVo; +import com.yxt.anrui.portal.api.sysuser.SysUserFeign; +import com.yxt.anrui.portal.api.sysuser.SysUserVo; +import com.yxt.anrui.portal.api.sysuser.UserByRolesAndOrgQuery; +import com.yxt.anrui.portal.api.sysuser.UserssQuery; +import com.yxt.common.base.service.MybatisBaseService; +import com.yxt.common.base.utils.StringUtils; +import com.yxt.common.core.result.ResultBean; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.impl.identity.Authentication; +import org.flowable.engine.*; +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.DelegationState; +import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Service +@Slf4j +public class Flow4Service extends MybatisBaseService { + + @Autowired + RepositoryService repositoryService; + @Autowired + RuntimeService runtimeService; + + @Autowired + ManagementService managementService; + @Autowired + ProcessEngineConfigurationImpl processEngineConfiguration; + @Autowired + private SysUserFeign sysUserFeign; + + @Autowired + protected IdentityService identityService; + @Autowired + protected TaskService taskService; + @Autowired + private SysFlowableConfigFeign sysFlowableConfigFeign; + @Autowired + private FlowTaskService flowTaskService; + @Autowired + private ProcessCommentService processCommentService; + + @Autowired + protected HistoryService historyService; + + @Autowired + private ProcessService processService; + + @Autowired + private MessageFeign messageFeign; + @Autowired + private SysFlowccFeign sysFlowccFeign; + + @Autowired + private FlowApproverService flowApproverService; + @Autowired + private FlowCcService flowCcService; + + + /** + * 启动流程 + * + * @param bv + * @return + */ + public ResultBean businessStartProcessInstanceById(BusinessVariables bv) { + ResultBean rb = ResultBean.fireFail(); + UpdateFlowFieldVo updateFlowFieldVo = new UpdateFlowFieldVo(); + String procDefId = bv.getModelId(); + String userSid = bv.getUserSid(); + String nextNodeUserSids = bv.getNextNodeUserSids(); + Map variables = bv.getFormVariables(); + // 获取审批人列表 + List approvers = (List) variables.get("approvers"); + // 获取抄送人列表 + List ccList = (List) variables.get("ccList"); + + + //根据流程定义id查询 + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId) + .latestVersion().singleResult(); + if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) { + return rb.setMsg("流程已被挂起,请先激活流程"); + } + // 设置流程发起人Id到流程中 + ResultBean sysUserVoResultBean = sysUserFeign.fetchBySid(userSid); + SysUserVo sysUser = sysUserVoResultBean.getData(); + identityService.setAuthenticatedUserId(sysUser.getSid()); + variables.put(ProcessConstants.PROCESS_INITIATOR, userSid); + variables.put(ProcessConstants.USER_TYPE_ASSIGNEE, userSid); + ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables); + // 给第一步申请人节点设置任务执行人和意见 + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult(); + if (Objects.nonNull(task)) { + taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.START.getType(), + sysUser.getName() + "发起流程申请"); + taskService.setAssignee(task.getId(), userSid); + taskService.complete(task.getId(), variables); + } + assembleFlowApprover(bv); + //查询当前实例的最新待办任务 + List tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + task = tasks.get(0); + Integer sortNo = sortNo(procDefId, task.getTaskDefinitionKey()); + System.out.println("获取环节序号================" + sortNo); + String approverSid = flowApproverService.selectApproverSid(bv.getBusinessSid(), sortNo); + String id_ = task.getId(); + String task_def_key_ = task.getTaskDefinitionKey(); + String nodeState = task.getName(); + //查询下一环节是否有转办并添加评论 + nextNodeUserSids = change(approverSid, processInstance.getProcessInstanceId()); + taskService.setAssignee(id_, nextNodeUserSids); + taskService.setVariablesLocal(id_, variables); + updateFlowFieldVo.setProcInsId(task.getProcessInstanceId()); + updateFlowFieldVo.setNodeState(nodeState); + updateFlowFieldVo.setTaskId(id_); + updateFlowFieldVo.setTaskDefKey(task_def_key_); + updateFlowFieldVo.setProcDefId(bv.getModelId()); + updateFlowFieldVo.setSid(bv.getBusinessSid()); + updateFlowFieldVo.setName(processDefinition.getName()); + return rb.success().setData(updateFlowFieldVo).setMsg("流程启动成功"); + } + + /** + * 查询下一环节用户是否有转办用户,若有转办用户则添加转办评论 + * + * @param nextNodeUserSids 下一环节用户 + * @param instanceId 实例id + * @return + */ + public String change(String nextNodeUserSids, String instanceId) { + //查询下一环节是否有转办 + String firstSid = ""; + String firstName = ""; + //默认无转办 + boolean isChange = false; + if (StringUtils.isNotBlank(nextNodeUserSids)) { + List nextUserList = Arrays.asList(nextNodeUserSids.split(",")); + if (nextUserList.size() == 1) { + firstSid = nextUserList.get(0); + ResultBean userVoResultBean = sysUserFeign.fetchBySid(firstSid); + if (userVoResultBean.getData() != null) { + firstName = userVoResultBean.getData().getName(); + } + SysFlowableConfigQuery sysFlowableConfigQuery = new SysFlowableConfigQuery(); + sysFlowableConfigQuery.setUserSid(firstSid); + sysFlowableConfigQuery.setNowDate(new Date()); + ResultBean sysFlowableConfigVvoResultBean = sysFlowableConfigFeign.selectByUserSid(sysFlowableConfigQuery); + if (sysFlowableConfigVvoResultBean.getData() != null) { + if (StringUtils.isNotBlank(sysFlowableConfigVvoResultBean.getData().getChangeUserSid())) { + nextNodeUserSids = sysFlowableConfigVvoResultBean.getData().getChangeUserSid(); + isChange = true; + } + } + } + } + if (isChange) {//添加评论 + ResultBean userVoResultBean = sysUserFeign.fetchBySid(nextNodeUserSids); + ProcessCommentDto processCommentDto = new ProcessCommentDto(); + processCommentDto.setReviewerSid(firstSid); + if (userVoResultBean.getData() != null) { + String changeName = userVoResultBean.getData().getName(); + processCommentDto.setReviewer(firstName); + processCommentDto.setContent("交" + changeName + "转办"); + } + processCommentDto.setTime(new Date()); + processCommentDto.setProcessId(instanceId); + processCommentService.saveOrUpdateDto(processCommentDto); + } + return nextNodeUserSids; + } + + public Integer sortNo(String proDefId, String taskDefKey) { + // 获取所有 UserTask,并以 Map 形式存储环节位置 + Map taskKeyToPositionMap = new HashMap<>(); + // 获取流程定义的 BPMN 模型 + BpmnModel bpmnModel = repositoryService.getBpmnModel(proDefId); + // 使用 Stream API 遍历流程元素并缓存顺序 + List userTasks = bpmnModel.getProcesses().stream() + .flatMap(process -> process.getFlowElements().stream()) // 遍历所有流程 + .filter(flowElement -> flowElement instanceof UserTask) // 只筛选 UserTask + .map(flowElement -> (UserTask) flowElement) + .collect(Collectors.toList()); + + // 将 UserTask 的 key 和位置映射到 Map 中 + int position = 1; + for (UserTask userTask : userTasks) { + taskKeyToPositionMap.put(userTask.getId(), position++); + } + Integer taskPosition = taskKeyToPositionMap.get(taskDefKey); + + return taskPosition; + } + + public void assembleFlowApprover(BusinessVariables bv) { + Map variables = bv.getFormVariables(); + // 获取审批人列表 + List approvers = (List) variables.get("approvers"); + // 获取抄送人列表 + List ccList = (List) variables.get("ccList"); + + FlowApproverDto flowApproverDto = new FlowApproverDto(); + flowApproverDto.setBusinessSid(bv.getBusinessSid()); + flowApproverDto.setApproverSidList(approvers); + ResultBean resultBean = flowApproverService.saveFlowApprover(flowApproverDto); + String ccSids = String.join(",", ccList); + ResultBean> listResultBean = sysUserFeign.fetchBySids(ccSids); + List ccNameList = listResultBean.getData().stream().map(v -> v.getName()).collect(Collectors.toList()); + // 将 List 转换为逗号分隔的字符串 + String result = String.join(",", ccNameList); + FlowCc flowCc = new FlowCc(); + flowCc.setBusinessSid(bv.getBusinessSid()); + flowCc.setCcSids(ccSids); + flowCc.setCcNames(result); + flowCcService.insert(flowCc); + } + + /** + * 办理 + * + * @param bv + * @param b + * @return + */ + public ResultBean handleProsess(BusinessVariables bv, boolean b) { + ResultBean rb = ResultBean.fireFail(); + UpdateFlowFieldVo vo = new UpdateFlowFieldVo(); + //获取表单中的参数 + Map formVariables = bv.getFormVariables(); + formVariables = formVariables == null ? new HashMap<>() : formVariables; + formVariables.put("businessSid", bv.getBusinessSid()); + String nextUserSid = bv.getNextNodeUserSids(); + String taskId = bv.getTaskId(); + String userSid = bv.getUserSid(); + String instanceId = bv.getInstanceId(); + String comment = bv.getComment(); + String nodeState = ""; + String taskDefKey = ""; + String orgPath = bv.getOrgSidPath(); + //查询任务id为taskId的任务是否存在 + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + if (Objects.isNull(task)) { + return rb.setMsg("任务不存在"); + } + String assignee = task.getAssignee(); + if (b && (StringUtils.isNotBlank(assignee) && assignee.indexOf(userSid) < 0)) { + return rb.setMsg("当前用户不是环节的待办人,不能进行办理操作!"); + } + if (DelegationState.PENDING.equals(task.getDelegationState())) { + //加签 + Authentication.setAuthenticatedUserId(userSid); + taskService.addComment(taskId, instanceId, + FlowComment.DELEGATE.getType(), comment); + taskService.resolveTask(taskId, formVariables); + nodeState = task.getName(); + taskDefKey = task.getTaskDefinitionKey(); + } else { + //当前环节办理通过,且将下一环节用户放入流程中 + taskService.addComment(taskId, instanceId, FlowComment.NORMAL.getType(), comment); + log.error("taskid:{},userSid:{}", taskId, userSid); + log.error("formVariables:{}", JSON.toJSONString(formVariables)); + taskService.setAssignee(taskId, userSid); + taskService.complete(taskId, formVariables);//当前用户办理通过 + //查询当前实例的最新待办任务 + List tasks = taskService.createTaskQuery().processInstanceId(bv.getInstanceId()).list(); + if (tasks.size() > 0) { + task = tasks.get(0); + Integer sortNo = sortNo(bv.getModelId(), task.getTaskDefinitionKey()); + System.out.println("获取环节序号================" + sortNo); + String approverSid = flowApproverService.selectApproverSid(bv.getBusinessSid(), sortNo); + String id_ = task.getId(); + //查询下一环节用户是否有转办人 + nextUserSid = change(approverSid, bv.getInstanceId()); + taskService.setAssignee(id_, nextUserSid);//将下一环节用户放入流程中 + vo.setTaskId(id_); + //在act_ru_variable表中增加环节上的业务参数的变量 + taskService.setVariablesLocal(id_, formVariables); + nodeState = task.getName(); + taskDefKey = task.getTaskDefinitionKey(); + + } else { + nodeState = FlowComment.SETTLE.getRemark(); + taskDefKey = "Event_end"; + vo.setNodeState(FlowComment.SETTLE.getRemark()); + } + } + vo.setProcInsId(instanceId); + vo.setProcDefId(bv.getModelId()); + vo.setNodeState(nodeState); + vo.setTaskDefKey(taskDefKey); + vo.setSid(bv.getBusinessSid()); + return rb.success().setData(vo); + } + + /** + * 流程抄送的功能 + * + * @param map + * @return + */ + public ResultBean cc(Map map, String taskDefKey) { + ResultBean rb = ResultBean.fireFail(); + log.info("FlowableRest-cc:{}", JSONObject.toJSONString(map)); + Object bv1 = map.get("bv"); + BusinessVariables bv = new BusinessVariables(); + BeanUtil.copyProperties(bv1, bv); + Object uff1 = map.get("uff"); + UpdateFlowFieldVo uff = new UpdateFlowFieldVo(); + BeanUtil.copyProperties(uff1, uff); + uff.setTaskDefKey(taskDefKey); + + FlowCc flowCc = flowCcService.selectByBusinessSid(bv.getBusinessSid()); + StringBuilder userSids = new StringBuilder(flowCc.getCcSids()); + StringBuilder userName = new StringBuilder(flowCc.getCcNames()); + + //抄送的业务逻辑 + MessageFlowableQuery mfq = new MessageFlowableQuery(); + MessageFlowVo messageFlowVo = new MessageFlowVo(); + BeanUtil.copyProperties(uff, messageFlowVo); + mfq.setUfVo(messageFlowVo); + //移动端的参数 + HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() + .includeProcessVariables().taskId(bv.getTaskId()).singleResult(); + if (historicTaskInstance == null) { + log.info("抄送失败:没有获取到业务参数!"); + return rb.setMsg("抄送失败!"); + } + Map processVariables = historicTaskInstance.getProcessVariables(); + String createrOrgPath = (String) processVariables.get("createrOrgPath"); + if (historicTaskInstance == null) { + log.info("抄送失败:没有获取到业务参数!"); + return rb.setMsg("抄送失败!"); + } + // + String assignee = (String) processVariables.get("assignee"); + ResultBean stringResultBean = sysUserFeign.fetchBySid(assignee); + String assigneeName = ""; + if (stringResultBean.getData() != null) { + assigneeName = stringResultBean.getData().getName(); + } + + Map app = new HashMap<>(); + if (processVariables.get("app") != null) { + app = (Map) processVariables.get("app"); + } + log.info("抄送方法-historicTaskInstance:{}", JSONObject.toJSONString(historicTaskInstance)); + mfq.setAppMap(app); + mfq.setBusinessSid(bv.getBusinessSid()); + mfq.setMsgContent(assigneeName + "抄送的流程审批,请查看"); +// act_re_procdef + Map process = processService.getProcessDefByDefId(historicTaskInstance.getProcessDefinitionId()); + log.info("抄送成功-process:{}", process); + if (process == null) { + log.info("抄送失败,流程定义不存在!"); + return rb.setMsg("抄送失败,流程定义不存在!"); + } + mfq.setModuleName(process.get("NAME_")); + if (processVariables.containsKey("orderNames")) { + mfq.setMsgTitle(processVariables.get("orderNames").toString()); + } else { + mfq.setMsgTitle(process.get("NAME_")); + } + if (processVariables.containsKey("sendRecommendSid")) {//增加的其他的抄送人 + userSids.append(processVariables.get("sendRecommendSid").toString()).append(","); + } + //查询是否有设置转办的,抄送给设置转办人员 + List zbUserSids = processCommentService.selectByIdAndComment("转办", bv.getInstanceId()); + zbUserSids.removeAll(Collections.singleton(null)); + if (!zbUserSids.isEmpty()) { + String zbUser = String.join(",", zbUserSids); + userSids.append(zbUser).append(","); + } + userSids.deleteCharAt(userSids.length() - 1); + //若抄送的用户已在审批人员中(审批记录中有该用户),则该用户不抄送 + List taskinstUserSidList = baseMapper.selectByProcInstId(bv.getInstanceId()); + List uss = Arrays.asList(userSids.toString().split(",")); + List uniqueList = new ArrayList(new HashSet(uss)); + uniqueList.removeIf(taskinstUserSidList::contains); + String userSidss = String.join(",", uniqueList); + mfq.setUserSids(userSidss); + mfq.setOrgPath(createrOrgPath); + mfq.setUserSid(assignee); + mfq.setApplicationName(assigneeName); + ResultBean resultBean = messageFeign.pushMessageCC(mfq); + log.info("抄送成功:{}", userName.toString()); + log.info("抄送成功-resultBean:{}", resultBean); + if (!resultBean.getSuccess()) { + log.info("抄送失败,同送消息异常!:{}", JSONObject.toJSONString(resultBean)); + return rb.setMsg("抄送失败,同送消息异常!"); + } + return rb.success().setMsg("抄送" + userName.toString() + "成功!"); + } + +} diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.java new file mode 100644 index 0000000000..6149af4ece --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.java @@ -0,0 +1,17 @@ +package com.yxt.anrui.flowable.biz.flowapprover; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yxt.anrui.flowable.api.flow.Flowable; +import com.yxt.anrui.flowable.api.flowapprover.FlowApprover; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Mapper +public interface FlowApproverMapper extends BaseMapper { + String selectApproverSid(@Param("businessSid") String businessSid, @Param("sortNo") Integer sortNo); +} diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.xml b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.xml new file mode 100644 index 0000000000..223f2ea762 --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverService.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverService.java new file mode 100644 index 0000000000..41364483fe --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverService.java @@ -0,0 +1,53 @@ +package com.yxt.anrui.flowable.biz.flowapprover; + +import com.yxt.anrui.flowable.api.flow.Flowable; +import com.yxt.anrui.flowable.api.flowapprover.FlowApprover; +import com.yxt.anrui.flowable.api.flowapprover.FlowApproverDto; +import com.yxt.anrui.flowable.biz.flow4.Flow4Mapper; +import com.yxt.anrui.portal.api.sysuser.SysUserFeign; +import com.yxt.anrui.portal.api.sysuser.SysUserVo; +import com.yxt.common.base.service.MybatisBaseService; +import com.yxt.common.core.result.ResultBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Service +public class FlowApproverService extends MybatisBaseService { + + @Autowired + private SysUserFeign sysUserFeign; + + public ResultBean saveFlowApprover(FlowApproverDto flowApproverDto) { + ResultBean rb = ResultBean.fireFail(); + String businessSid = flowApproverDto.getBusinessSid(); + List approverSidList = flowApproverDto.getApproverSidList(); + approverSidList.removeAll(Collections.singleton(null)); + if (!approverSidList.isEmpty()) { + for (int i = 0; i < approverSidList.size(); i++) { + FlowApprover flowApprover = new FlowApprover(); + String approverSid = approverSidList.get(i); + Integer sortNo = i + 2; + flowApprover.setBusinessSid(businessSid); + flowApprover.setApproverSid(approverSid); + ResultBean sysUserVoResultBean = sysUserFeign.fetchBySid(approverSid); + SysUserVo sysUser = sysUserVoResultBean.getData(); + flowApprover.setApprovalName(sysUser.getName()); + flowApprover.setSortNo(sortNo); + baseMapper.insert(flowApprover); + } + } + return rb.success(); + } + + public String selectApproverSid(String businessSid, Integer sortNo) { + return baseMapper.selectApproverSid(businessSid,sortNo); + } +} diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.java new file mode 100644 index 0000000000..5aabe3925a --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.java @@ -0,0 +1,16 @@ +package com.yxt.anrui.flowable.biz.flowcc; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yxt.anrui.flowable.api.flowapprover.FlowApprover; +import com.yxt.anrui.flowable.api.flowcc.FlowCc; +import org.apache.ibatis.annotations.Mapper; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Mapper +public interface FlowCcMapper extends BaseMapper { + FlowCc selectByBusinessSid(String businessSid); +} diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.xml b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.xml new file mode 100644 index 0000000000..7d0742116e --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcService.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcService.java new file mode 100644 index 0000000000..8ca47a60a3 --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcService.java @@ -0,0 +1,19 @@ +package com.yxt.anrui.flowable.biz.flowcc; + +import com.yxt.anrui.flowable.api.flowapprover.FlowApprover; +import com.yxt.anrui.flowable.api.flowcc.FlowCc; +import com.yxt.anrui.flowable.biz.flowapprover.FlowApproverMapper; +import com.yxt.common.base.service.MybatisBaseService; +import org.springframework.stereotype.Service; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/2/20 + **/ +@Service +public class FlowCcService extends MybatisBaseService { + public FlowCc selectByBusinessSid(String businessSid) { + return baseMapper.selectByBusinessSid(businessSid); + } +}