From cf4729236ff375d9d73bee81c83d8464a73c27df Mon Sep 17 00:00:00 2001 From: dimengzhe Date: Thu, 6 Feb 2025 16:54:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=9A=E7=AD=BE=E5=92=8C?= =?UTF-8?q?=E6=88=96=E7=AD=BE=E7=9A=84=E5=9B=BA=E5=AE=9A=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../anrui/flowable/biz/flow3/Flow3Rest.java | 46 ++++ .../flowable/biz/flow3/Flow3Service.java | 255 ++++++++++++++++++ 2 files changed, 301 insertions(+) create mode 100644 anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Rest.java create mode 100644 anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java 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 new file mode 100644 index 0000000000..c8bc34eac1 --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Rest.java @@ -0,0 +1,46 @@ +package com.yxt.anrui.flowable.biz.flow3; + +import com.yxt.anrui.flowable.api.flow.UpdateFlowFieldVo; +import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables; +import com.yxt.common.core.result.ResultBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/1/24 + **/ +@RestController +@RequestMapping("v3/flow") +public class Flow3Rest { + + @Autowired + private Flow3Service flowService; + + public ResultBean startProcess2(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.businessStartProcessInstanceById2(bv); + return startResultBean; + } + + @PostMapping("/submit2") + public ResultBean submit222() { + return flowService.submit222(); + } + + +} 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 new file mode 100644 index 0000000000..ed1a3e33a5 --- /dev/null +++ b/anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java @@ -0,0 +1,255 @@ +package com.yxt.anrui.flowable.biz.flow3; + +import com.yxt.anrui.flowable.api.flow.UpdateFlowFieldVo; +import com.yxt.anrui.flowable.api.flowcomment.FlowComment; +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.sqloperationsymbol.BusinessVariables; +import com.yxt.anrui.portal.api.sysflowableconfig.SysFlowableConfigFeign; +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.common.core.result.ResultBean; +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.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.PostMapping; + +import java.util.*; + +import static org.junit.Assert.*; + +/** + * @description: + * @author: dimengzhe + * @date: 2025/1/24 + **/ +@Service +public class Flow3Service { + + @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; + + + /** + * 启动流程 + * + * @param bv + * @return + */ + public ResultBean businessStartProcessInstanceById2(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(); + Map variablesSeconds = bv.getFormVariables(); + //根据流程定义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); + // 给第一步申请人节点设置任务执行人和意见 todo:第一个节点不设置为申请人节点有点问题? + 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); + } + List aggigneeList = (List) variables.get("approvers"); + // 获取多实例任务的所有实例 + List tasks = taskService.createTaskQuery() + .processInstanceId(processInstance.getProcessInstanceId()) // 使用流程实例ID进行过滤 + .taskDefinitionKey("Activity_1f8o20w") // 指定多实例任务的定义Key + .list(); // 查询所有相关的任务实例 + // 确保查询到了多条任务实例 + if (!tasks.isEmpty()) { + // 遍历任务列表并为每个任务设置执行人 + 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); // 为任务设置执行人 + } + } + } + return rb.success().setData(updateFlowFieldVo).setMsg("流程启动成功"); + } + + + public ResultBean submit222() { + String userSid = "7f56f6ec-4a5f-47b0-aaab-158d64cb97b1"; + // 或签任务候选人 + List userIds = new ArrayList<>(); + userIds.add("dc6b9e36-1b31-4b94-908b-d2d7f78a0977"); + userIds.add("657bf5a5-7665-440e-9cbd-ab87eccfbdcc"); + userIds.add("2737e5ee-5ffd-4127-919b-e6694dfc8361"); + + // 会签任务候选人 + List approvers = new ArrayList<>(); + approvers.add("1d85d1fe-e527-4ec5-a5e4-c37a76a36518"); + approvers.add("64e289bc-80cd-487a-9498-5ae61e260f71"); + approvers.add("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); + + // 断言流程实例是否成功启动 + assertNotNull(processInstance); + System.out.println("流程实例ID: " + processInstance.getId()); + + // 查询用户任务 + List tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + // 模拟申请人完成任务 + for (int i = 0; i < tasks.size(); i++) { + Task task = tasks.get(i); + taskService.complete(task.getId(), variables); + } + + tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list(); + assertEquals(approvers.size(), tasks.size()); + + // 验证每个任务是否正确分配给指定的用户 + for (Task task : tasks) { + System.out.println("用户任务ID: " + task.getId()); + System.out.println("任务名称: " + task.getName()); + System.out.println("任务分配给的执行人员: " + task.getAssignee()); + // 添加候选人 + for (String approver : approvers) { + taskService.addCandidateUser(task.getId(), approver); // 将候选人添加到任务 + } + + // 验证任务分配给的执行人员(此时任务没有assignee) + assertNull(task.getAssignee()); // 确保没有直接分配执行人员 + // 验证任务分配给的执行人员 +// assertTrue(approvers.contains(task.getAssignee())); + } + //为候选人分配 任务 + for (int i = 0; i < tasks.size(); i++) { + Task task = tasks.get(i); + taskService.claim(task.getId(), approvers.get(i)); // 由候选人认领任务 + } + + // 模拟两个用户完成任务 + 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(); + //为候选人分配 任务 + 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()); + }*/ + HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery() + .taskId(approvalTask.getId()) + .singleResult(); + if (historicTask != null && historicTask.getEndTime() != 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(); + } + +}