diff --git a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Rest.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Rest.java index c8bc34eac1..af5ed8881b 100644 --- a/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Rest.java +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Rest.java @@ -1,15 +1,23 @@ package com.yxt.anrui.flowable.biz.flow3; +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.sqloperationsymbol.BusinessVariables; +import com.yxt.common.base.utils.StringUtils; import com.yxt.common.core.result.ResultBean; +import org.apache.tomcat.util.threads.ThreadPoolExecutor; +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.HashMap; import java.util.Map; +import java.util.concurrent.*; /** * @description: @@ -19,11 +27,13 @@ import java.util.Map; @RestController @RequestMapping("v3/flow") public class Flow3Rest { + Logger log = LoggerFactory.getLogger(Flow3Rest.class); @Autowired private Flow3Service flowService; - public ResultBean startProcess2(BusinessVariables bv) { + @PostMapping("/startProcess") + public ResultBean startProcess(@RequestBody BusinessVariables bv) { ResultBean rb = ResultBean.fireFail(); //获取表单中的参数 Map formVariables = bv.getFormVariables(); @@ -32,14 +42,49 @@ public class Flow3Rest { String orgPath = bv.getOrgSidPath(); formVariables.put("createrOrgPath", orgPath); formVariables.put("businessSid", bv.getBusinessSid()); + //启动流程实例 - ResultBean startResultBean = flowService.businessStartProcessInstanceById2(bv); + ResultBean startResultBean = flowService.businessStartProcessInstanceById(bv); return startResultBean; } @PostMapping("/submit2") public ResultBean submit222() { - return flowService.submit222(); + return flowService.submit333(); + } + + @PostMapping("/handleProsess") + public ResultBean handleProsess(@RequestBody 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/flow3/Flow3Service.java b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java index ad90ddb006..a98d5400ab 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 @@ -1,24 +1,48 @@ package com.yxt.anrui.flowable.biz.flow3; +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +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.flow2.FlowDelegateQuery; +import com.yxt.anrui.flowable.api.flow2.FlowableMessageVo; import com.yxt.anrui.flowable.api.flowcomment.FlowComment; +import com.yxt.anrui.flowable.api.flowtask.DelegateQuery; +import com.yxt.anrui.flowable.api.flowtask.FlowTaskDto; +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.flowtask.FlowTaskService; +import com.yxt.anrui.flowable.biz.process.ExpressionCmd; 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.sysuser.SysUserFeign; -import com.yxt.anrui.portal.api.sysuser.SysUserVo; +import com.yxt.anrui.portal.api.sysflowcc.SysFlowccVo; +import com.yxt.anrui.portal.api.sysuser.*; +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.*; +import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.engine.*; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.identitylink.service.IdentityLinkService; +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; @@ -35,7 +59,8 @@ import static org.junit.Assert.*; * @date: 2025/1/24 **/ @Service -public class Flow3Service { +@Slf4j +public class Flow3Service extends MybatisBaseService { @Autowired RepositoryService repositoryService; @@ -70,6 +95,8 @@ public class Flow3Service { private MessageFeign messageFeign; @Autowired private SysFlowccFeign sysFlowccFeign; + @Autowired + private ProcessEngine processEngine; /** @@ -78,13 +105,26 @@ public class Flow3Service { * @param bv * @return */ - public ResultBean businessStartProcessInstanceById2(BusinessVariables bv) { + public ResultBean businessStartProcessInstanceById(BusinessVariables bv) { ResultBean rb = ResultBean.fireFail(); + // 或签任务候选人 + List userIds = Arrays.asList( + "dc6b9e36-1b31-4b94-908b-d2d7f78a0977", + "657bf5a5-7665-440e-9cbd-ab87eccfbdcc", + "2737e5ee-5ffd-4127-919b-e6694dfc8361"); + + // 会签任务候选人 + List approvers = Arrays.asList( + "1d85d1fe-e527-4ec5-a5e4-c37a76a36518", + "64e289bc-80cd-487a-9498-5ae61e260f71", + "7ffcd76a-4fa0-4c9c-87ca-a0c2116bb2ed"); UpdateFlowFieldVo updateFlowFieldVo = new UpdateFlowFieldVo(); String procDefId = bv.getModelId(); String userSid = bv.getUserSid(); - String nextNodeUserSids = bv.getNextNodeUserSids(); + Map variables = bv.getFormVariables(); + variables.put("userSids", userIds); + variables.put("approvers", approvers); Map variablesSeconds = bv.getFormVariables(); //根据流程定义id查询 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId) @@ -107,27 +147,977 @@ public class Flow3Service { taskService.setAssignee(task.getId(), userSid); taskService.complete(task.getId(), variables); } - List aggigneeList = (List) variables.get("approvers"); - // 获取多实例任务的所有实例 - List tasks = taskService.createTaskQuery() - .processInstanceId(processInstance.getProcessInstanceId()) // 使用流程实例ID进行过滤 - .taskDefinitionKey("Activity_1f8o20w") // 指定多实例任务的定义Key - .list(); // 查询所有相关的任务实例 - // 确保查询到了多条任务实例 - if (!tasks.isEmpty()) { - // 遍历任务列表并为每个任务设置执行人 + + boolean isMultiInstanceTaskNext = false; + + //根据流程实例的id查询最新的待办环节 + ResultBean> latestTasksNew = flowTaskService.getLatestTasksNew(processInstance.getId()); + List data = latestTasksNew.getData(); + LatestTaskVo latestTaskVo = data.get(0); + String id_ = latestTaskVo.getId_(); + String task_def_key_ = latestTaskVo.getTask_def_key_(); + //获取下一环节待办人 + if (StringUtils.isBlank(bv.getNextNodeUserSids())) { + List tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); for (int i = 0; i < tasks.size(); i++) { - Task taskss = tasks.get(i); - // 确保任务和用户数量匹配,避免索引越界 - if (i < aggigneeList.size()) { - String assignee = aggigneeList.get(i); // 获取用户 - taskService.setAssignee(taskss.getId(), assignee); // 为任务设置执行人 + Task task2 = tasks.get(i); + String isMultiInstanceTask = isMultiInstanceTask(task2); + if ("会签任务".equals(isMultiInstanceTask)) { + taskService.claim(task2.getId(), approvers.get(i)); // 由候选人认领任务 + isMultiInstanceTaskNext = true; + } else { + ResultBean userResultBean = getNextNodeUser(bv); + bv.setNextNodeUserSids(userResultBean.getData()); + break; } } } + if (!isMultiInstanceTaskNext) { + String nextNodeUserSids = bv.getNextNodeUserSids(); + //查询下一环节是否有转办并添加评论 + nextNodeUserSids = change(nextNodeUserSids, processInstance.getProcessInstanceId()); + taskService.setAssignee(id_, nextNodeUserSids); + taskService.setVariablesLocal(id_, variables); + if (ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(nextNodeUserSids)) { + bv.setModelId(procDefId); + bv.setInstanceId(task.getProcessInstanceId()); + bv.setTaskId(id_); + bv.setUserSid(nextNodeUserSids); + bv.setBusinessSid(bv.getBusinessSid()); + bv.setTaskDefKey(task_def_key_); + bv.setFormVariables(variables); + bv.setOrgSidPath(bv.getOrgSidPath()); + bv.setComment("系统自动跳过!"); + bv.setFormVariables(variablesSeconds); + bv.setNextNodeUserSids(""); + ResultBean updateFlowFieldVoResultBean = handleProsess(bv, false); + if (updateFlowFieldVoResultBean.getSuccess() && updateFlowFieldVoResultBean.getData() != null) { + UpdateFlowFieldVo vo = updateFlowFieldVoResultBean.getData(); + updateFlowFieldVo.setProcInsId(vo.getProcInsId()); + updateFlowFieldVo.setNodeState(vo.getNodeState()); + updateFlowFieldVo.setTaskId(vo.getTaskId()); + updateFlowFieldVo.setTaskDefKey(vo.getTaskDefKey()); + updateFlowFieldVo.setProcDefId(bv.getModelId()); + updateFlowFieldVo.setSid(bv.getBusinessSid()); + updateFlowFieldVo.setName(processDefinition.getName()); + return rb.success().setData(updateFlowFieldVo).setMsg("流程启动成功"); + } + } + if (bv.getUserSid().equals(nextNodeUserSids)) { + //如果申请人与下一环节审批人相同,则自动审批 + bv.setModelId(procDefId); + bv.setInstanceId(task.getProcessInstanceId()); + bv.setTaskId(id_); + bv.setUserSid(nextNodeUserSids); + bv.setBusinessSid(bv.getBusinessSid()); + bv.setTaskDefKey(task_def_key_); + bv.setFormVariables(variables); + bv.setOrgSidPath(bv.getOrgSidPath()); + bv.setFormVariables(variablesSeconds); + bv.setComment("因与申请人相同,系统自动处理,需以下一级审批人审批意见为准!"); + bv.setNextNodeUserSids(""); + ResultBean updateFlowFieldVoResultBean = handleProsess(bv, false); + if (updateFlowFieldVoResultBean.getSuccess() && updateFlowFieldVoResultBean.getData() != null) { + UpdateFlowFieldVo vo = updateFlowFieldVoResultBean.getData(); + updateFlowFieldVo.setProcInsId(vo.getProcInsId()); + updateFlowFieldVo.setNodeState(vo.getNodeState()); + updateFlowFieldVo.setTaskId(vo.getTaskId()); + updateFlowFieldVo.setTaskDefKey(vo.getTaskDefKey()); + updateFlowFieldVo.setProcDefId(bv.getModelId()); + updateFlowFieldVo.setSid(bv.getBusinessSid()); + updateFlowFieldVo.setName(processDefinition.getName()); + return rb.success().setData(updateFlowFieldVo).setMsg("流程启动成功"); + } + } + } + updateFlowFieldVo.setProcInsId(task.getProcessInstanceId()); + updateFlowFieldVo.setNodeState(latestTaskVo.getName_()); + 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; + } + + /** + * 办理 + * + * @param bv + * @param b + * @return + */ + public ResultBean handleProsess(BusinessVariables bv, boolean b) { + ResultBean rb = ResultBean.fireFail(); + UpdateFlowFieldVo vo = new UpdateFlowFieldVo(); + // 或签任务候选人 + List userIds = Arrays.asList( + "dc6b9e36-1b31-4b94-908b-d2d7f78a0977", + "657bf5a5-7665-440e-9cbd-ab87eccfbdcc", + "2737e5ee-5ffd-4127-919b-e6694dfc8361"); + + // 会签任务候选人 + List approvers = Arrays.asList( + "1d85d1fe-e527-4ec5-a5e4-c37a76a36518", + "64e289bc-80cd-487a-9498-5ae61e260f71", + "7ffcd76a-4fa0-4c9c-87ca-a0c2116bb2ed"); + //获取表单中的参数 + Map formVariables = bv.getFormVariables(); + formVariables = formVariables == null ? new HashMap<>() : formVariables; + formVariables.put("businessSid", bv.getBusinessSid()); + formVariables.put("userSids", userIds); + formVariables.put("approvers", approvers); + 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(); + //设置下一环节审批人是否自动审批通过,默认否 + boolean contains = false; + //设置是否是管理员自动审批,默认否 + boolean adminContains = false; + //查询任务id为taskId的任务是否存在 + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + if (Objects.isNull(task)) { + return rb.setMsg("任务不存在"); + } + boolean isMultiInstanceTaskNext = false; + String service = (String) formVariables.get("service"); + String ydfOrgPath = (String) formVariables.get("ydfOrgPath"); + if ("公司间调车".equals(service) && "Activity_0695qh4".equals(bv.getTaskDefKey())) { + if (StringUtils.isBlank(nextUserSid)) { + bv.setOrgSidPath(ydfOrgPath); + ResultBean stringResultBean = getNextNodeUserSidsOfSubmit(bv); + if (!stringResultBean.getSuccess()) { + //下一环节用户为空的情况 + nextUserSid = ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId(); + adminContains = true; + } else { + nextUserSid = stringResultBean.getData(); + } + } + } else if (StringUtils.isBlank(nextUserSid)) { + //是否是多实例任务 + String isMultiInstanceTask = isMultiInstanceTask(task); + if (!"会签任务".equals(isMultiInstanceTask) && !"或签任务".equals(isMultiInstanceTask)) { + //获取下一环节用户 + ResultBean stringResultBean = getNextNodeUserSidsOfSubmit(bv); + if (!stringResultBean.getSuccess()) { + //下一环节用户为空的情况 + nextUserSid = ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId(); + adminContains = true; + } else { + nextUserSid = stringResultBean.getData(); + } + } + } else { + //若下一环节用户与系统管理员一致,则自动审批 + if (ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(nextUserSid)) { + adminContains = true; + } + } + String assignee = task.getAssignee(); + if (b && (StringUtils.isNotBlank(assignee) && assignee.indexOf(userSid) < 0)) { + return rb.setMsg("当前用户不是环节的待办人,不能进行办理操作!"); + } + + if (DelegationState.PENDING.equals(task.getDelegationState())) { + adminContains = false; + //加签 + Authentication.setAuthenticatedUserId(userSid); + taskService.addComment(taskId, instanceId, + FlowComment.DELEGATE.getType(), comment); + taskService.resolveTask(taskId, formVariables); + nodeState = task.getName(); + taskDefKey = task.getTaskDefinitionKey(); + } else { + boolean checkTask = false;//是否要查询当前任务是否是会签环节 + List tasks = taskService.createTaskQuery().processInstanceId(instanceId).list(); + if (tasks.size() == 1) { + checkTask = true; + } + 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); + if (checkTask) { + tasks = taskService.createTaskQuery().processInstanceId(instanceId).list(); + for (int i = 0; i < tasks.size(); i++) { + Task task2 = tasks.get(i); + String isMultiInstanceTask = isMultiInstanceTask(task2); + if ("会签任务".equals(isMultiInstanceTask)) { + taskService.claim(task2.getId(), approvers.get(i)); // 由候选人认领任务 + isMultiInstanceTaskNext = true; + } else if ("或签任务".equals(isMultiInstanceTask)) { + taskService.claim(task2.getId(), userIds.get(i)); // 由候选人认领任务 + isMultiInstanceTaskNext = true; + } else { + ResultBean userResultBean = getNextNodeUser(bv); + bv.setNextNodeUserSids(userResultBean.getData()); + break; + } + } + } + //根据流程实例的id取最新的待办环节,给环节设置上用户sid + ResultBean> ll = flowTaskService.getLatestTasksNew(instanceId); + if (ll.getData().size() > 0) { + LatestTaskVo latestTaskVo = ll.getData().get(0); + String id_ = latestTaskVo.getId_(); + if (!isMultiInstanceTaskNext && checkTask) { + //查询下一环节用户是否有转办人 + nextUserSid = change(nextUserSid, bv.getInstanceId()); + taskService.setAssignee(id_, nextUserSid);//将下一环节用户放入流程中 + } + vo.setTaskId(id_); + //在act_ru_variable表中增加环节上的业务参数的变量 + taskService.setVariablesLocal(id_, formVariables); + nodeState = latestTaskVo.getName_(); + taskDefKey = latestTaskVo.getTask_def_key_(); + } else { + nodeState = FlowComment.SETTLE.getRemark(); + taskDefKey = "Event_end"; + vo.setNodeState(FlowComment.SETTLE.getRemark()); + } + + + } + //设置管理员是否自动审批的字段是否是是。//若下一环节用户与系统管理员一致,则自动审批 + if (adminContains) { + bv.setUserSid(nextUserSid); + bv.setTaskId(vo.getTaskId()); + bv.setTaskDefKey(taskDefKey); + bv.setComment("系统自动跳过"); + bv.setNextNodeUserSids(""); + return handleProsess(bv, false); + } + if (!isMultiInstanceTaskNext) { + if (!DelegationState.PENDING.equals(task.getDelegationState())) { + //获取该流程所有要走的环节节点 + List flowElements = calApprovePath(bv.getModelId(), + bv.getFormVariables()); + for (int i = 0; i < flowElements.size(); i++) { + FlowElement flowElement = flowElements.get(i); + String id = flowElement.getId(); + if (taskDefKey.equals(id) && i + 1 < flowElements.size()) { + //获取下下一环节 + FlowElement flowElement1 = flowElements.get(i + 1); + List sysUserVoLists2 = new ArrayList<>(); + if (i + 2 < flowElements.size()) { + //获取下下下一环节用户 + FlowElement flowElement2 = flowElements.get(i + 2); + if (flowElement2 instanceof UserTask) { + UserTask userTask = (UserTask) flowElement2; + List candidateGroups = userTask.getCandidateGroups(); + UserssQuery userssQuery = new UserssQuery(); + userssQuery.setCandidateGroups(candidateGroups); + userssQuery.setOrgSidPath(orgPath); + sysUserVoLists2 = sysUserFeign.getUsersByRoles(userssQuery).getData(); + if (sysUserVoLists2 == null) { + sysUserVoLists2 = new ArrayList<>(); + } + } + } + if (flowElement1 instanceof UserTask) { + UserTask userTask = (UserTask) flowElement1; + List candidateGroups = userTask.getCandidateGroups(); + List sysUserVoLists = new ArrayList<>(); + UserssQuery userssQuery = new UserssQuery(); + userssQuery.setCandidateGroups(candidateGroups); + userssQuery.setOrgSidPath(orgPath); + sysUserVoLists = sysUserFeign.getUsersByRoles(userssQuery).getData(); + if (sysUserVoLists == null) { + sysUserVoLists = new ArrayList<>(); + } + //当前环节运营部总经理 刘丽艳 点击同意 下一环节 事业部副总经理 (nextUserSid) 和事业部总经理(sysUserVoLists.get(0).getSid()) + //判断查询回来的用户的集合size是1 并且用户的sid和下一环节的用户的sid相同。 + if (sysUserVoLists.size() == 1 && sysUserVoLists.get(0).getSid().equals(nextUserSid)) { + contains = true; + break; + } + //如果下下一环节无用户,下下下一环节用户与下一环节用户相同且只有一个,则下一环节用户自动审批。 + if (sysUserVoLists.size() == 0 && sysUserVoLists2.size() == 1 && sysUserVoLists2.get(0).getSid().equals(nextUserSid)) { + contains = true; + break; + } + } + } + if (contains) { + break; + } + } + } + } + + + if (contains) { + bv.setUserSid(nextUserSid); + bv.setTaskId(vo.getTaskId()); + bv.setTaskDefKey(taskDefKey); + bv.setComment("因与下一级审批人相同,系统自动处理,需以下一级审批人审批意见为准!"); + return handleProsess(bv, false); + } + vo.setProcInsId(instanceId); + vo.setProcDefId(bv.getModelId()); + vo.setNodeState(nodeState); + vo.setTaskDefKey(taskDefKey); + vo.setSid(bv.getBusinessSid()); + return rb.success().setData(vo); + } + + /** + * 获取下一环节用户 + * + * @param bv + * @return + */ + public ResultBean getNextNodeUserSidsOfSubmit(BusinessVariables bv) { + ResultBean rb = ResultBean.fireFail(); + String orgPath = bv.getOrgSidPath(); + String taskDefKey = bv.getTaskDefKey(); + //根据业务参数取流程流转的环节 信息 + List> list = (List>) getProcessCirculationNodesByMap(bv).getData(); + Map task_map = new HashMap<>(); + boolean endTask = true; + for (int i = 0; i < list.size(); i++) { + String id = list.get(i).get("id").toString(); + if (id.equals(taskDefKey) && i + 1 < list.size()) { + task_map = list.get(i + 1); + endTask = false; + } + } + if (endTask) { + task_map.put("name", "结束"); + return rb.success(); + } else { + Object o = task_map.get("candidateGroups"); + JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(o)); + String roleSid = jsonArray.get(0).toString(); + //根据组织架构、角色两个参数取相关符合条件的用户信息 + UserQuery userQuery = new UserQuery(); + userQuery.setRoleSid(roleSid); + userQuery.setOrgSidPath(orgPath); + String nextNodeUserSids_ = ""; + List sysUserVos = sysUserFeign.getUserByRole(userQuery).getData(); + if (sysUserVos == null || sysUserVos.size() < 1) { + return rb; + } else { + StringBuilder nextNodeUserSids = new StringBuilder(); + for (SysUserVo su : sysUserVos) { + nextNodeUserSids.append(su.getSid()).append(","); + } + //符合条件的用户的sid,拼接的字符串 + nextNodeUserSids_ = nextNodeUserSids.toString(); + nextNodeUserSids_ = nextNodeUserSids_.substring(0, nextNodeUserSids_.length() - 1); + } + return rb.success().setData(nextNodeUserSids_); + } + } + + /** + * 流程抄送的功能 + * + * @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); + + //流程定义的id + String modelId = bv.getModelId(); + //将modelId根据冒号:分成三部分,取第一部分作为key + List stringList = Arrays.asList(modelId.split(":")); + modelId = stringList.get(0); + //抄送的角色的sid + ResultBean roleSidByModelId = sysFlowccFeign.getRoleSidByModelId(modelId); + //组织机构sid + String orgSidPath = bv.getOrgSidPath(); + if (roleSidByModelId.getData() == null) { + log.info("抄送失败,没有配置对应的角色!"); + return rb.setMsg("抄送失败,没有配置对应的角色!"); + } + SysFlowccVo data = roleSidByModelId.getData(); + if (StringUtils.isBlank(data.getRoleSid())) { + log.info("抄送失败,没有配置对应的角色!"); + return rb.setMsg("抄送失败,没有配置对应的角色!"); + } + List list = Arrays.asList(data.getRoleSid().split(",")); + UserByRolesAndOrgQuery userQuery = new UserByRolesAndOrgQuery(); + userQuery.setRoleSids(list); + userQuery.setOrgSidPath(orgSidPath); + List sysUserVos = sysUserFeign.getUserByRoles(userQuery).getData(); + if (sysUserVos == null || sysUserVos.size() < 1) { + log.info("抄送失败,没有用户!"); + return rb.setMsg("抄送失败,没有用户!"); + } + StringBuilder userName = new StringBuilder(); + StringBuilder userSids = new StringBuilder(); + sysUserVos.forEach(f -> { + userName.append(f.getName()).append(","); + userSids.append(f.getSid()).append(","); + }); + + //抄送的业务逻辑 + 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.setUserSids(userSids.toString()); + 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() + "成功!"); + } + + public ResultBean> getMessageList(int minutes) { + ResultBean> rb = ResultBean.fireFail(); + List list = baseMapper.getMessageList(minutes); + + return rb.success().setData(list); + } + + public ResultBean getMessageReminder(String proDefId, String procInstId) { + ResultBean rb = ResultBean.fireFail(); + FlowableMessageVo flowableMessageVo = baseMapper.getMessageReminder(proDefId, procInstId); + return rb.success().setData(flowableMessageVo); + } + + public ResultBean delegate(FlowDelegateQuery flowDelegateQuery) { + ResultBean rb = ResultBean.fireFail(); + DelegateQuery delegateQuery = new DelegateQuery(); + BeanUtil.copyProperties(flowDelegateQuery, delegateQuery); + ResultBean delegate = flowTaskService.delegate(delegateQuery); + String userSid = flowDelegateQuery.getUserSid(); + String assigneeSid = flowDelegateQuery.getAssignee(); + String instanceId = flowDelegateQuery.getInstanceId(); + String views = ""; + if (StringUtils.isNotBlank(flowDelegateQuery.getViews())) { + views = flowDelegateQuery.getViews(); + } + ResultBean userVoResultBean1 = sysUserFeign.fetchBySid(userSid); + String userName = ""; + if (userVoResultBean1.getData() != null) { + userName = userVoResultBean1.getData().getName(); + } + ResultBean userVoResultBean2 = sysUserFeign.fetchBySid(assigneeSid); + ProcessCommentDto processCommentDto = new ProcessCommentDto(); + processCommentDto.setReviewerSid(userSid); + if (userVoResultBean2.getData() != null) { + String changeName = userVoResultBean2.getData().getName(); + processCommentDto.setReviewer(userName); + processCommentDto.setContent(userName + "加签给" + changeName + ":" + views); + } + processCommentDto.setTime(new Date()); + processCommentDto.setProcessId(instanceId); + processCommentService.saveOrUpdateDto(processCommentDto); + //加签内容推送至待阅 + HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() + .includeProcessVariables().taskId(delegateQuery.getTaskId()).singleResult(); + if (historicTaskInstance == null) { + return rb.setMsg("分享失败!"); + } + MessageFlowVo messageFlowVo = new MessageFlowVo(); + String procDefId = historicTaskInstance.getProcessDefinitionId(); + String procInsId = historicTaskInstance.getProcessInstanceId(); + String nodeState = historicTaskInstance.getName(); + String taskDefKey = historicTaskInstance.getTaskDefinitionKey(); + messageFlowVo.setProcDefId(procDefId); + messageFlowVo.setTaskId(delegateQuery.getTaskId()); + messageFlowVo.setNodeState(nodeState); + messageFlowVo.setProcInsId(procInsId); + messageFlowVo.setTaskDefKey(taskDefKey); + Map processVariables = historicTaskInstance.getProcessVariables(); + MessageFlowableQuery mfq = new MessageFlowableQuery(); + mfq.setUfVo(messageFlowVo); + String createrOrgPath = (String) processVariables.get("createrOrgPath"); + if (historicTaskInstance == null) { + 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"); + } + mfq.setAppMap(app); + String businessSid = (String) processVariables.get("businessSid"); + mfq.setBusinessSid(businessSid); + mfq.setMsgContent(userName + "分享的流程审批,请查看"); +// act_re_procdef + Map process = processService.getProcessDefByDefId(historicTaskInstance.getProcessDefinitionId()); + + mfq.setModuleName(process.get("NAME_")); + if (processVariables.containsKey("orderNames")) { + mfq.setMsgTitle(processVariables.get("orderNames").toString()); + } else { + mfq.setMsgTitle(process.get("NAME_")); + } + mfq.setUserSids(assigneeSid); + mfq.setOrgPath(createrOrgPath); + mfq.setUserSid(assignee); + mfq.setApplicationName(assigneeName); + ResultBean resultBean = messageFeign.pushMessageShare(mfq); + return rb.success(); + + } + + public ResultBean assignTask(FlowDelegateQuery flowDelegateQuery) { + ResultBean rb = ResultBean.fireFail(); + DelegateQuery delegateQuery = new DelegateQuery(); + BeanUtil.copyProperties(flowDelegateQuery, delegateQuery); + ResultBean assignTask = flowTaskService.assignTask(delegateQuery); + String userSid = flowDelegateQuery.getUserSid(); + String assigneeSid = flowDelegateQuery.getAssignee(); + String instanceId = flowDelegateQuery.getInstanceId(); + String views = ""; + if (StringUtils.isNotBlank(flowDelegateQuery.getViews())) { + views = flowDelegateQuery.getViews(); + } + ResultBean userVoResultBean1 = sysUserFeign.fetchBySid(userSid); + String userName = ""; + if (userVoResultBean1.getData() != null) { + userName = userVoResultBean1.getData().getName(); + } + ResultBean userVoResultBean2 = sysUserFeign.fetchBySid(assigneeSid); + ProcessCommentDto processCommentDto = new ProcessCommentDto(); + processCommentDto.setReviewerSid(userSid); + if (userVoResultBean2.getData() != null) { + String changeName = userVoResultBean2.getData().getName(); + processCommentDto.setReviewer(userName); + processCommentDto.setContent(userName + "转办给" + changeName + ":" + views); + } + processCommentDto.setTime(new Date()); + processCommentDto.setProcessId(instanceId); + processCommentService.saveOrUpdateDto(processCommentDto); + //转办内容推送至待阅 + HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() + .includeProcessVariables().taskId(delegateQuery.getTaskId()).singleResult(); + if (historicTaskInstance == null) { + return rb.setMsg("分享失败!"); + } + MessageFlowVo messageFlowVo = new MessageFlowVo(); + String procDefId = historicTaskInstance.getProcessDefinitionId(); + String procInsId = historicTaskInstance.getProcessInstanceId(); + String nodeState = historicTaskInstance.getName(); + String taskDefKey = historicTaskInstance.getTaskDefinitionKey(); + messageFlowVo.setProcDefId(procDefId); + messageFlowVo.setTaskId(delegateQuery.getTaskId()); + messageFlowVo.setNodeState(nodeState); + messageFlowVo.setProcInsId(procInsId); + messageFlowVo.setTaskDefKey(taskDefKey); + Map processVariables = historicTaskInstance.getProcessVariables(); + MessageFlowableQuery mfq = new MessageFlowableQuery(); + mfq.setUfVo(messageFlowVo); + String createrOrgPath = (String) processVariables.get("createrOrgPath"); + if (historicTaskInstance == null) { + 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"); + } + mfq.setAppMap(app); + String businessSid = (String) processVariables.get("businessSid"); + mfq.setBusinessSid(businessSid); + mfq.setMsgContent(userName + "分享的流程审批,请查看"); +// act_re_procdef + Map process = processService.getProcessDefByDefId(historicTaskInstance.getProcessDefinitionId()); + + mfq.setModuleName(process.get("NAME_")); + if (processVariables.containsKey("orderNames")) { + mfq.setMsgTitle(processVariables.get("orderNames").toString()); + } else { + mfq.setMsgTitle(process.get("NAME_")); + } + mfq.setUserSids(userSid); + mfq.setOrgPath(createrOrgPath); + mfq.setUserSid(assignee); + mfq.setApplicationName(assigneeName); + ResultBean resultBean = messageFeign.pushMessageShare(mfq); + return rb.success(); + } + + + public ResultBean getApplicantInfoForUrgeCount(String taskId, String procInstId) { + ResultBean rb = ResultBean.fireFail(); + FlowableMessageVo flowableMessageVo = baseMapper.getApplicantInfoForUrgeCount(taskId, procInstId); + String procDefId = ""; + if (null != flowableMessageVo) { + procDefId = flowableMessageVo.getProDefId(); + } + List messageVos = baseMapper.getApplicantInfos(procDefId, procInstId); + messageVos.removeAll(Collections.singleton(null)); + FlowableMessageVo messageVo = new FlowableMessageVo(); + if (!messageVos.isEmpty()) { + messageVo = messageVos.get(2); + } + return rb.success().setData(messageVo); + } + + public ResultBean getTask(String taskId, String procInstId) { + ResultBean rb = ResultBean.fireFail(); + FlowableMessageVo flowableMessageVo = baseMapper.getTask(taskId, procInstId); + return rb.success().setData(flowableMessageVo); + } + + public ResultBean getTaskNameForUrgeCount(String taskId, String procInstId) { + ResultBean rb = ResultBean.fireFail(); + FlowTaskDto flowTask = new FlowTaskDto(); + flowTask.setTaskId(taskId); + HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().taskId(flowTask.getTaskId()).singleResult(); + flowTask.setProcessVariables(historicTaskInstance.getProcessVariables()); + if (flowTask.getProcessVariables().containsKey("orderNames")) { + flowTask.setProcDefName(flowTask.getProcessVariables().get("orderNames").toString()); + } else { + FlowableMessageVo task = baseMapper.getTask(taskId, procInstId); + if (null != task) { + String proDefId = task.getProDefId(); + FlowableMessageVo flowableMessageVo = baseMapper.selTaskNameForUrgeCount(proDefId); + if (null != flowableMessageVo) { + if (StringUtils.isNotBlank(flowableMessageVo.getNodeName())) { + flowTask.setProcDefName(flowableMessageVo.getNodeName()); + } + } + } + } + return rb.success().setData(flowTask); + } + + public ResultBean getApprovalResult(String proDefId, String procInstId) { + ResultBean rb = ResultBean.fireFail(); + FlowableMessageVo vo = baseMapper.getApprovalResult(proDefId, procInstId); + if (vo != null) { + String taskId = vo.getTaskId(); + if (StringUtils.isNotBlank(vo.getEndTime())) { + String type = baseMapper.getComment(taskId, procInstId); + if (type.equals("6")) { + vo.setResult("终止"); + } else if (type.equals("1")) { + vo.setResult("通过"); + } + } else { + vo.setResult("审批中"); + } + } + return rb.success().setData(vo); + } + + public ResultBean getNextNodeUser(BusinessVariables bv) { + ResultBean rb = ResultBean.fireFail(); + //根据业务参数取流程流转的环节 信息 + List> list = (List>) getProcessCirculationNodesByMap(bv).getData(); + if (list == null || list.size() < 2) { + return rb.setMsg("流程设计问题"); + } + //取第二个环节的配置角色 + Object o = list.get(1).get("candidateGroups"); + if (o == null) { + return rb.setMsg("流程设计问题"); + } + JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(o)); + String roleSid = jsonArray.get(0).toString(); + //根据组织架构、角色两个参数取相关符合条件的用户信息 + UserQuery userQuery = new UserQuery(); + userQuery.setRoleSid(roleSid); + userQuery.setOrgSidPath(bv.getOrgSidPath()); + String nextNodeUserSids_ = ""; + List sysUserVos = sysUserFeign.getUserByRole(userQuery).getData(); + if (sysUserVos == null || sysUserVos.size() < 1) { + nextNodeUserSids_ = ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId(); + } else { + StringBuilder nextNodeUserSids = new StringBuilder(); + for (SysUserVo su : sysUserVos) { + nextNodeUserSids.append(su.getSid()).append(","); + } + //符合条件的用户的sid,拼接的字符串 + nextNodeUserSids_ = nextNodeUserSids.toString(); + nextNodeUserSids_ = nextNodeUserSids_.substring(0, nextNodeUserSids_.length() - 1); + } + return rb.success().setData(nextNodeUserSids_); + + } + + /** + * 根据业务参数取流程流转的环节 信息 + * + * @param bv + * @return + */ + public ResultBean getProcessCirculationNodesByMap(BusinessVariables bv) { + ResultBean>> rb = new ResultBean>>(); + String modelId = bv.getModelId(); + List flowElements = calApprovePath(modelId, bv.getFormVariables()); + List> list = new ArrayList<>(); + for (FlowElement f : flowElements) { + Map map = new HashMap<>(); + map.put("name", f.getName()); + map.put("id", f.getId()); + String s = JSON.toJSONString(f); + JSONObject jsonObject = JSONObject.parseObject(s); + log.info("item:{}", jsonObject); + Object candidateGroups = jsonObject.get("candidateGroups"); + map.put("candidateGroups", candidateGroups); + list.add(map); + } + return rb.setData(list); + } + + /** + * 1. 首先拿到BpmnModel,所有流程定义信息都可以通过BpmnModel获取;若流程尚未发起,则用modelId查询最新部署的流程定义数据; + * 若流程已经发起,可以通过流程实例的processDefinitionId查询流程定义的历史数据。 + * + * @param variableMap 流程变量,用于计算条件分支 + */ + public List calApprovePath(String modelId, Map variableMap) { + BpmnModel bpmnModel = repositoryService.getBpmnModel(modelId); + Collection flowElements = new ArrayList<>(); + Collection flowElements2 = bpmnModel.getMainProcess().getFlowElements(); + flowElements.addAll(flowElements2); + List passElements = new ArrayList<>(); + dueStartElement(passElements, flowElements, variableMap); + return passElements; + } + + /** + * 2. 找到开始节点,通过它的目标节点,然后再不断往下找。 + */ + private void dueStartElement(List passElements, Collection flowElements, Map variableMap) { + Optional startElementOpt = flowElements.stream().filter(flowElement -> flowElement instanceof StartEvent).findFirst(); + startElementOpt.ifPresent(startElement -> { + flowElements.remove(startElement); + List outgoingFlows = ((StartEvent) startElement).getOutgoingFlows(); + String targetRef = outgoingFlows.get(0).getTargetRef(); + // 根据ID找到FlowElement + FlowElement targetElementOfStartElement = getFlowElement(flowElements, targetRef); + if (targetElementOfStartElement instanceof UserTask) { + this.getPassElementList(passElements, flowElements, targetElementOfStartElement, variableMap); + } + }); + } + + /** + * 3. 我只用到了UserTask、ExclusiveGateway、ParallelGateway,所以代码里只列举了这三种,如果用到了其他的,可以再自己补充 + */ + private void getPassElementList(List passElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) { + // 任务节点 + if (curFlowElement instanceof UserTask) { + this.dueUserTaskElement(passElements, flowElements, curFlowElement, variableMap); + return; + } + // 排他网关 + if (curFlowElement instanceof ExclusiveGateway) { + this.dueExclusiveGateway(passElements, flowElements, curFlowElement, variableMap); + return; + } + // 并行网关 + if (curFlowElement instanceof ParallelGateway) { + this.dueParallelGateway(passElements, flowElements, curFlowElement, variableMap); + } + } + + private void dueUserTaskElement(List passElements, Collection flowElements, + FlowElement curFlowElement, Map variableMap) { + passElements.add(curFlowElement); + List outgoingFlows = ((UserTask) curFlowElement).getOutgoingFlows(); + String targetRef = outgoingFlows.get(0).getTargetRef(); + if (outgoingFlows.size() > 1) { + // 找到表达式成立的sequenceFlow + SequenceFlow sequenceFlow = getSequenceFlow(variableMap, outgoingFlows); + targetRef = sequenceFlow.getTargetRef(); + } + // 根据ID找到FlowElement + FlowElement targetElement = getFlowElement(flowElements, targetRef); + this.getPassElementList(passElements, flowElements, targetElement, variableMap); + } + + private void dueExclusiveGateway(List passElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) { + // 获取符合条件的sequenceFlow的目标FlowElement + List exclusiveGatewayOutgoingFlows = ((ExclusiveGateway) curFlowElement).getOutgoingFlows(); + flowElements.remove(curFlowElement); + // 找到表达式成立的sequenceFlow + SequenceFlow sequenceFlow = getSequenceFlow(variableMap, exclusiveGatewayOutgoingFlows); + // 根据ID找到FlowElement + FlowElement targetElement = getFlowElement(flowElements, sequenceFlow.getTargetRef()); + this.getPassElementList(passElements, flowElements, targetElement, variableMap); + } + + private void dueParallelGateway(List passElements, Collection flowElements, FlowElement curFlowElement, Map variableMap) { + FlowElement targetElement; + List parallelGatewayOutgoingFlows = ((ParallelGateway) curFlowElement).getOutgoingFlows(); + for (SequenceFlow sequenceFlow : parallelGatewayOutgoingFlows) { + targetElement = getFlowElement(flowElements, sequenceFlow.getTargetRef()); + this.getPassElementList(passElements, flowElements, targetElement, variableMap); + } + } + + private FlowElement getFlowElement(Collection flowElements, String targetRef) { + return flowElements.stream().filter(flowElement -> targetRef.equals(flowElement.getId())).findFirst().orElse(null); + } + + /** + * 4. 根据传入的变量,计算出表达式成立的那一条SequenceFlow + * + * @param variableMap + * @param outgoingFlows + * @return + */ + private SequenceFlow getSequenceFlow(Map variableMap, List outgoingFlows) { + Optional sequenceFlowOpt = outgoingFlows.stream().filter(item -> { + try { + return this.getElValue(item.getConditionExpression(), variableMap); + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + }).findFirst(); + return sequenceFlowOpt.orElse(outgoingFlows.get(0)); + } + + private boolean getElValue(String exp, Map variableMap) { + return managementService.executeCommand(new ExpressionCmd(runtimeService, processEngineConfiguration, null, exp, variableMap)); + } + public ResultBean submit222() { String userSid = "7f56f6ec-4a5f-47b0-aaab-158d64cb97b1"; @@ -207,16 +1197,155 @@ public class Flow3Service { Task lastTask = tasks.get(tasks.size() - 1); taskService.complete(lastTask.getId()); + //====================================================================================== + //===或签任务 + List approvalTasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + //为候选人分配 任务 + for (int i = 0; i < approvalTasks.size(); i++) { + Task task = approvalTasks.get(i); + taskService.claim(task.getId(), userIds.get(0)); // 由候选人认领任务 + } + // 模拟只有一个人完成任务 + approvalTasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + Task approvalTask = approvalTasks.get(0); + + taskService.complete(approvalTask.getId()); + + //==待定 + // 手动更新历史记录中的 `ASSIGNEE_` 和 `END_TIME_` + HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery() + .taskId(approvalTask.getId()).singleResult(); + if (historicTask != null) { + // 只有在实际完成的用户任务记录中才更新这些字段 + System.out.println("Task completed by: " + historicTask.getAssignee()); + System.out.println("Task end time: " + historicTask.getEndTime()); + } + + //====================================================================================== + //===总经理审批 + List approvalTasks2 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + Task approvalTask2 = approvalTasks2.get(0); + taskService.claim(approvalTask2.getId(), "503efb39-7889-4185-807f-624271a951aa"); + taskService.complete(approvalTask2.getId()); + // 检查流程实例是否已经结束 + boolean isEnded2 = runtimeService.createProcessInstanceQuery() + .processInstanceId(processInstance.getId()) + .singleResult() == null; + assertTrue(isEnded2); + + return ResultBean.fireSuccess(); + } + + + /* private boolean isMultiInstanceTask(Task task, boolean isSequential) { + // 获取任务节点的ID + String taskDefinitionKey = task.getTaskDefinitionKey(); + + // 获取流程定义对象 + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .processDefinitionId(task.getProcessDefinitionId()) + .singleResult(); + + // 获取BPMN模型,解析任务定义 + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); + FlowElement flowElement = bpmnModel.getFlowElement(taskDefinitionKey); + + // 判断flowElement是否是UserTask,并且获取其multiInstanceLoopCharacteristics + if (flowElement instanceof UserTask) { + UserTask userTask = (UserTask) flowElement; + // 获取multiInstanceLoopCharacteristics + MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics(); + if (multiInstance != null) { + boolean sequential = multiInstance.isSequential(); + return sequential == isSequential; + } + } + return false; + }*/ + + + public ResultBean submit333() { + String userSid = "7f56f6ec-4a5f-47b0-aaab-158d64cb97b1"; + // 或签任务候选人 + List userIds = Arrays.asList( + "dc6b9e36-1b31-4b94-908b-d2d7f78a0977", + "657bf5a5-7665-440e-9cbd-ab87eccfbdcc", + "2737e5ee-5ffd-4127-919b-e6694dfc8361"); + + // 会签任务候选人 + List approvers = Arrays.asList( + "1d85d1fe-e527-4ec5-a5e4-c37a76a36518", + "64e289bc-80cd-487a-9498-5ae61e260f71", + "7ffcd76a-4fa0-4c9c-87ca-a0c2116bb2ed"); + + //准备流程变量 + Map variables = new HashMap<>(); + variables.put("userSids", userIds); + variables.put("approvers", approvers); + variables.put(ProcessConstants.PROCESS_INITIATOR, userSid); + variables.put(ProcessConstants.USER_TYPE_ASSIGNEE, userSid); + // 设置流程发起人Id到流程中 + ResultBean sysUserVoResultBean = sysUserFeign.fetchBySid(userSid); + SysUserVo sysUser = sysUserVoResultBean.getData(); + identityService.setAuthenticatedUserId(sysUser.getSid()); + // 启动流程实例 + ProcessInstance processInstance = runtimeService.startProcessInstanceById("process_rrqxpsu8:5:16907561", variables); + + // 查询用户任务 + List tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + // 模拟申请人完成任务 + for (int i = 0; i < tasks.size(); i++) { + Task task = tasks.get(i); + String isMultiInstanceTask = isMultiInstanceTask(task); + if ("单一审批任务".equals(isMultiInstanceTask)) { + taskService.complete(task.getId()); + } else { + taskService.claim(task.getId(), approvers.get(i)); // 由候选人认领任务 + } + } + + tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + assertEquals(approvers.size(), tasks.size()); + boolean isMultiInstanceTaskNext = false; + for (int i = 0; i < tasks.size(); i++) { + Task task = tasks.get(i); + String isMultiInstanceTask = isMultiInstanceTask(task); + if ("单一审批任务".equals(isMultiInstanceTask)) { + taskService.complete(task.getId()); + } else { + taskService.claim(task.getId(), approvers.get(i)); // 由候选人认领任务 + isMultiInstanceTaskNext = true; + } + } + if (isMultiInstanceTaskNext) { + // 模拟两个用户完成任务 + for (int i = 0; i < 2; i++) { + Task task = tasks.get(i); + taskService.complete(task.getId()); + } + } + + // 检查流程实例是否仍然处于活动状态 + boolean isEnded = runtimeService.createProcessInstanceQuery() + .processInstanceId(processInstance.getId()) + .singleResult() == null; + assertFalse(isEnded); + + // 处理最后一个人 + Task lastTask = tasks.get(tasks.size() - 1); + taskService.complete(lastTask.getId()); //====================================================================================== //===或签任务 - List approvalTasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + List approvalTasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); //为候选人分配 任务 for (int i = 0; i < approvalTasks.size(); i++) { Task task = approvalTasks.get(i); + String isMultiInstanceTask = isMultiInstanceTask(task); + System.out.println("或签任务" + isMultiInstanceTask); taskService.claim(task.getId(), userIds.get(0)); // 由候选人认领任务 } - // 模拟只有一个人完成任务 + // 模拟只有一个人完成任务 approvalTasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); Task approvalTask = approvalTasks.get(0); @@ -236,6 +1365,7 @@ public class Flow3Service { //===总经理审批 List approvalTasks2 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); Task approvalTask2 = approvalTasks2.get(0); + String isMultiInstanceTask = isMultiInstanceTask(approvalTask2); taskService.claim(approvalTask2.getId(), "503efb39-7889-4185-807f-624271a951aa"); taskService.complete(approvalTask2.getId()); // 检查流程实例是否已经结束 @@ -244,7 +1374,35 @@ public class Flow3Service { .singleResult() == null; assertTrue(isEnded2); + return ResultBean.fireSuccess(); } + // 判断是否为会签任务 + private String isMultiInstanceTask(Task task) { + ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() + .processDefinitionId(task.getProcessDefinitionId()).singleResult(); + + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId()); + FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey()); + + if (flowElement instanceof UserTask) { + UserTask userTask = (UserTask) flowElement; + MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics(); + if (multiInstance != null) { + String completionCondition = multiInstance.getCompletionCondition(); + // 去除 ${} 和多余的空格 + String normalizedCondition = completionCondition.replaceAll("[${}\\s]", ""); + if (normalizedCondition != null && normalizedCondition.matches("nrOfCompletedInstances>=?1")) { + return "或签任务"; // **或签任务** + } else { + return "会签任务"; // **会签任务** + } + } else { + return "单一审批任务"; // **普通单人任务** + } + } + return null; + } + }