diff --git a/skyeye-activiti/src/main/java/com/skyeye/activiti/listener/MultiInstanceloopListener.java b/skyeye-activiti/src/main/java/com/skyeye/activiti/listener/MultiInstanceloopListener.java new file mode 100644 index 0000000000000000000000000000000000000000..16c75bc2bb7ac9d80293049840f8e7de8c76326b --- /dev/null +++ b/skyeye-activiti/src/main/java/com/skyeye/activiti/listener/MultiInstanceloopListener.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 卫志强 QQ:598748873@qq.com Inc. All rights reserved. 开源地址:https://gitee.com/doc_wei01/skyeye + ******************************************************************************/ + +package com.skyeye.activiti.listener; + +import com.gexin.fastjson.JSON; +import org.activiti.engine.delegate.DelegateExecution; +import org.activiti.engine.delegate.ExecutionListener; + +/** + * @ClassName: MultiInstanceloopListener + * @Description: + * @author: skyeye云系列--卫志强 + * @date: 2021/12/14 22:37 + * @Copyright: 2021 https://gitee.com/doc_wei01/skyeye Inc. All rights reserved. + * 注意:本内容仅限购买后使用.禁止私自外泄以及用于其他的商业目的 + */ +public class MultiInstanceloopListener implements ExecutionListener { + + @Override + public void notify(DelegateExecution execution) throws Exception { + System.out.println(JSON.toJSONString(execution)); + } + +} diff --git a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/ActivitiTaskService.java b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/ActivitiTaskService.java index 2fc2236bf6cbe6a35abe23997f54dfe62ea36249..29f82ae631c03eb794ca0fabd2ea1568206b21be 100644 --- a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/ActivitiTaskService.java +++ b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/ActivitiTaskService.java @@ -6,6 +6,8 @@ package com.skyeye.activiti.service; import com.skyeye.common.object.InputObject; import com.skyeye.common.object.OutputObject; +import org.activiti.bpmn.model.UserTask; +import org.activiti.engine.impl.pvm.process.ActivityImpl; import java.util.Map; @@ -47,4 +49,20 @@ public interface ActivitiTaskService { void setNextUserTaskApproval(String processInstanceId, String approverId); + /** + * 根据taskId获取UserTask对象 + * + * @param taskId 任务id + * @return UserTask对象 + */ + UserTask getCurrentUserTaskByTaskId(String taskId); + + /** + * 根据流程id获取当前节点信息 + * + * @param processInstanceId 流程id + * @return 当前节点信息 + */ + ActivityImpl getCurrentActivityNode(String processInstanceId); + } diff --git a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/CounterSignService.java b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/CounterSignService.java index 494daa90db374aa7a70ea31a38a5c821fb684e9a..8f990177e38d40819c1df7a6ff8aa94f3fd95929 100644 --- a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/CounterSignService.java +++ b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/CounterSignService.java @@ -7,9 +7,11 @@ package com.skyeye.activiti.service; import com.skyeye.common.object.InputObject; import com.skyeye.common.object.OutputObject; import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics; +import org.activiti.bpmn.model.UserTask; import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior; +import org.activiti.engine.impl.pvm.process.ActivityImpl; -import java.util.Map; +import java.util.List; /** * @ClassName: CounterSignService @@ -51,39 +53,43 @@ public interface CounterSignService { /** * 创建 多实例 行为解释器 * - * @param processInstanceId - * @param sequential + * @param currentTask 当前任务节点 + * @param activityImpl 流程节点信息 + * @param sequential 是否串行 * @return */ - MultiInstanceActivityBehavior createMultiInstanceBehavior(String processInstanceId, boolean sequential); + MultiInstanceActivityBehavior createMultiInstanceBehavior(UserTask currentTask, ActivityImpl activityImpl, boolean sequential); /** * 创建多实例行为解释器 * - * @param processInstanceId 流程id + * @param currentTask 当前任务节点 + * @param activityImpl 流程节点信息 * @param sequential 是否串行 * @param assigneeListExp 用户组表达 * @param assigneeExp 用户标识 * @return */ - MultiInstanceActivityBehavior createMultiInstanceBehavior(String processInstanceId, boolean sequential, String assigneeListExp, String assigneeExp); + MultiInstanceActivityBehavior createMultiInstanceBehavior(UserTask currentTask, ActivityImpl activityImpl, boolean sequential, + String assigneeListExp, String assigneeExp); /** * 将 普通节点转换成为会签 任务 * - * @param taskId - * @param sequential - * @param data + * @param taskId 任务id + * @param sequential 是否串行 + * @param userIds 用户id */ - void covertToMultiInstance(String taskId, boolean sequential, Map data); + void covertToMultiInstance(String taskId, boolean sequential, List userIds); /** - * 将 普通节点转换成为会签 任务 - * @param taskId - * @param sequential + * 将 普通节点转换成为会签 任务 + * + * @param taskId 任务id + * @param sequential 是否串行 * @param assigneeExp 任务执行人表达式 - * @param data + * @param userIds 用户id */ - void covertToMultiInstance(String taskId, boolean sequential, String assigneeExp, Map data); + void covertToMultiInstance(String taskId, boolean sequential, String assigneeExp, List userIds); } diff --git a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/ActivitiTaskServiceImpl.java b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/ActivitiTaskServiceImpl.java index da957781c87dcc66ee2e62c916c2b2d422b687e8..babdc8eaec95f41072c2deeb32561b85aad83b20 100644 --- a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/ActivitiTaskServiceImpl.java +++ b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/ActivitiTaskServiceImpl.java @@ -22,13 +22,19 @@ import com.skyeye.eve.dao.ActModleTypeDao; import com.skyeye.eve.dao.ActUserProcessInstanceIdDao; import com.skyeye.eve.dao.SysEveUserDao; import com.skyeye.exception.CustomException; -import com.skyeye.jedis.JedisClientService; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.bpmn.model.UserTask; import org.activiti.engine.HistoryService; +import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.history.HistoricTaskInstance; import org.activiti.engine.history.HistoricVariableInstance; +import org.activiti.engine.impl.RepositoryServiceImpl; +import org.activiti.engine.impl.persistence.entity.ExecutionEntity; +import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; +import org.activiti.engine.impl.pvm.process.ActivityImpl; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.activiti.engine.task.TaskQuery; @@ -59,9 +65,6 @@ public class ActivitiTaskServiceImpl implements ActivitiTaskService { @Autowired private TaskService taskService; - @Autowired - public JedisClientService jedisClient; - @Autowired private RuntimeService runtimeService; @@ -86,6 +89,9 @@ public class ActivitiTaskServiceImpl implements ActivitiTaskService { @Autowired private RedisCache redisCache; + @Autowired + protected RepositoryService repositoryService; + /** * @Title: queryUserAgencyTasksListByUserId * @Description: 获取用户待办任务 @@ -719,4 +725,33 @@ public class ActivitiTaskServiceImpl implements ActivitiTaskService { } } + public UserTask getCurrentUserTaskByTaskId(String taskId){ + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); + org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0); + // 当前节点 + UserTask currentUserTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey()); + return currentUserTask; + } + + public ActivityImpl getCurrentActivityNode(String processInstanceId){ + // 获取流程发布Id信息 + String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); + ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(definitionId); + ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + + // 当前流程节点Id信息 + String activitiId = execution.getActivityId(); + // 获取流程所有节点信息 + List activitiList = processDefinitionEntity.getActivities(); + // 遍历所有节点信息 + for (ActivityImpl activityImpl : activitiList) { + String id = activityImpl.getId(); + if (activitiId.equals(id)) { + return activityImpl; + } + } + return null; + } + } diff --git a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/CounterSignServiceImpl.java b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/CounterSignServiceImpl.java index 566d61703f41da57bcdaa201a093f7e5d9db709f..1b16cd742920572247ab62767edbc4f912d82976 100644 --- a/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/CounterSignServiceImpl.java +++ b/skyeye-activiti/src/main/java/com/skyeye/activiti/service/impl/CounterSignServiceImpl.java @@ -4,33 +4,34 @@ package com.skyeye.activiti.service.impl; -import com.skyeye.activiti.service.CounterSignService; -import com.skyeye.common.constans.ActivitiConstants; -import com.skyeye.common.object.InputObject; -import com.skyeye.common.object.OutputObject; -import org.activiti.bpmn.model.BpmnModel; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics; import org.activiti.bpmn.model.UserTask; import org.activiti.engine.ProcessEngine; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; -import org.activiti.engine.impl.RepositoryServiceImpl; import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior; import org.activiti.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; import org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.activiti.engine.impl.el.ExpressionManager; -import org.activiti.engine.impl.persistence.entity.ExecutionEntity; -import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.pvm.process.ActivityImpl; -import org.activiti.engine.task.Task; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.List; -import java.util.Map; +import com.skyeye.activiti.listener.MultiInstanceloopListener; +import com.skyeye.activiti.service.ActivitiTaskService; +import com.skyeye.activiti.service.CounterSignService; +import com.skyeye.common.constans.ActivitiConstants; +import com.skyeye.common.object.InputObject; +import com.skyeye.common.object.OutputObject; + +import net.sf.json.JSONArray; /** * @ClassName: CounterSignServiceImpl @@ -44,17 +45,20 @@ import java.util.Map; public class CounterSignServiceImpl implements CounterSignService { @Autowired - protected ProcessEngine processEngine; + private ProcessEngine processEngine; @Autowired - protected TaskService taskService; + private TaskService taskService; @Autowired - protected RepositoryService repositoryService; + private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; + @Autowired + private ActivitiTaskService activitiTaskService; + /** * 将 普通节点转换成为会签 任务 * @@ -65,6 +69,9 @@ public class CounterSignServiceImpl implements CounterSignService { @Override public void covertToMultiInstance(InputObject inputObject, OutputObject outputObject) throws Exception { Map params = inputObject.getParams(); + String taskId = params.get("taskId").toString(); + boolean sequential = Boolean.parseBoolean(params.get("sequential").toString()); + List userIds = JSONArray.fromObject(params.get("userIds").toString()); } @@ -79,9 +86,14 @@ public class CounterSignServiceImpl implements CounterSignService { @Override public MultiInstanceLoopCharacteristics createMultiInstanceLoopCharacteristics(boolean isSequential, String assigneeListExp, String assignee) { MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = new MultiInstanceLoopCharacteristics(); + // 是否串行 multiInstanceLoopCharacteristics.setSequential(isSequential); + // 审批人集合参数 multiInstanceLoopCharacteristics.setInputDataItem(assigneeListExp); + // 迭代集合 multiInstanceLoopCharacteristics.setElementVariable(assignee); + // 完成条件 已完成数等于实例数${nrOfActiveInstances == nrOfInstances} + multiInstanceLoopCharacteristics.setCompletionCondition(""); return multiInstanceLoopCharacteristics; } @@ -99,43 +111,42 @@ public class CounterSignServiceImpl implements CounterSignService { /** * 创建 多实例 行为解释器 * - * @param processInstanceId 流程id - * @param sequential + * @param currentTask 当前任务节点 + * @param activityImpl 流程节点信息 + * @param sequential 是否串行 * @return */ @Override - public MultiInstanceActivityBehavior createMultiInstanceBehavior(String processInstanceId, boolean sequential) { - return createMultiInstanceBehavior(processInstanceId, sequential, ActivitiConstants.DEFAULT_ASSIGNEE_LIST_EXP, ActivitiConstants.ASSIGNEE_USER); + public MultiInstanceActivityBehavior createMultiInstanceBehavior(UserTask currentTask, ActivityImpl activityImpl, boolean sequential) { + return createMultiInstanceBehavior(currentTask, activityImpl, sequential, ActivitiConstants.DEFAULT_ASSIGNEE_LIST_EXP, + ActivitiConstants.ASSIGNEE_USER); } /** * 创建多实例行为解释器 * - * @param processInstanceId 流程id - * @param sequential 是否串行 - * @param assigneeListExp 用户组表达 - * @param assigneeExp 用户标识 + * @param currentTask 当前任务节点 + * @param activityImpl 流程节点信息 + * @param sequential 是否串行 + * @param assigneeListExp 用户组表达 + * @param assigneeExp 用户标识 * @return */ @Override - public MultiInstanceActivityBehavior createMultiInstanceBehavior(String processInstanceId, boolean sequential, String assigneeListExp, String assigneeExp) { - ActivityImpl activityNode = this.getCurrentActivityNode(processInstanceId); - if(activityNode == null){ - return null; - } - UserTask currentNode = this.getCurrentUserTask(processInstanceId); + public MultiInstanceActivityBehavior createMultiInstanceBehavior(UserTask currentTask, ActivityImpl activityImpl, boolean sequential, + String assigneeListExp, String assigneeExp) { ProcessEngineConfigurationImpl processEngineConfiguration = (ProcessEngineConfigurationImpl) processEngine.getProcessEngineConfiguration(); /** * 创建解释器 */ UserTaskActivityBehavior userTaskActivityBehavior = processEngineConfiguration.getActivityBehaviorFactory() - .createUserTaskActivityBehavior(currentNode, ((UserTaskActivityBehavior) activityNode.getActivityBehavior()).getTaskDefinition()); + .createUserTaskActivityBehavior(currentTask, ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition()); MultiInstanceActivityBehavior behavior = null; if (sequential) { - behavior = new SequentialMultiInstanceBehavior(activityNode, userTaskActivityBehavior); + behavior = new SequentialMultiInstanceBehavior(activityImpl, userTaskActivityBehavior); } else { - behavior = new ParallelMultiInstanceBehavior(activityNode, userTaskActivityBehavior); + behavior = new ParallelMultiInstanceBehavior(activityImpl, userTaskActivityBehavior); } /** @@ -152,63 +163,39 @@ public class CounterSignServiceImpl implements CounterSignService { return behavior; } - private UserTask getCurrentUserTask(String processInstanceId) { - Task cueerntTask = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); - BpmnModel bpmnModel = repositoryService.getBpmnModel(cueerntTask.getProcessDefinitionId()); - org.activiti.bpmn.model.Process process = bpmnModel.getProcesses().get(0); - // 当前节点 - UserTask currentNode = (UserTask) process.getFlowElement(cueerntTask.getTaskDefinitionKey()); - return currentNode; - } - - /** - * 获取当前的activityImpl节点 - * - * @param processInstanceId processInstanceId - * @return - */ - private ActivityImpl getCurrentActivityNode(String processInstanceId){ - // 获取流程发布Id信息 - String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); - ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(definitionId); - ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); - - // 当前流程节点Id信息 - String activitiId = execution.getActivityId(); - // 获取流程所有节点信息 - List activitiList = processDefinitionEntity.getActivities(); - // 遍历所有节点信息 - for (ActivityImpl activityImpl : activitiList) { - String id = activityImpl.getId(); - if (activitiId.equals(id)) { - return activityImpl; - } - } - return null; - } - /** * 将 普通节点转换成为会签 任务 * - * @param taskId - * @param sequential - * @param data + * @param taskId 任务id + * @param sequential 是否串行 + * @param userIds 用户id */ @Override - public void covertToMultiInstance(String taskId, boolean sequential, Map data) { - + public void covertToMultiInstance(String taskId, boolean sequential, List userIds) { + this.covertToMultiInstance(taskId, sequential, ActivitiConstants.ASSIGNEE_USER_EXP, userIds); } /** * 将 普通节点转换成为会签 任务 * - * @param taskId - * @param sequential + * @param taskId 任务id + * @param sequential 是否串行 * @param assigneeExp 任务执行人表达式 - * @param data + * @param userIds 用户id */ @Override - public void covertToMultiInstance(String taskId, boolean sequential, String assigneeExp, Map data) { - + public void covertToMultiInstance(String taskId, boolean sequential, String assigneeExp, List userIds) { + UserTask currentTaskNode = activitiTaskService.getCurrentUserTaskByTaskId(taskId); + currentTaskNode.setAssignee(assigneeExp); + // 设置多实例属性 + currentTaskNode.setLoopCharacteristics(createMultiInstanceLoopCharacteristics(sequential)); + currentTaskNode.setAssignee(ActivitiConstants.ASSIGNEE_USER_EXP); + // 设置监听器 + // 这里需要注意一下,当用户节点设置了多实例属性后,设置监听器时是设置executionListeners而不是taskListeners。 + // 类要实现ExecutionListener或者JavaDelegate,普通用户节点实现TaskListener。 + // 还有多实例属性中loopCardinality和inputDataItem两个必须设置一个,这个在部署流程似有校验 + currentTaskNode.setExecutionListeners(Arrays.asList(new MultiInstanceloopListener())); + // 设置审批人 + currentTaskNode.setCandidateUsers(userIds); } }