package io.hmit.modules.activiti.service; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import io.hmit.common.constant.Constant; import io.hmit.common.exception.ErrorCode; import io.hmit.common.exception.HmitException; import io.hmit.common.page.PageData; import io.hmit.common.service.impl.BaseServiceImpl; import io.hmit.common.utils.MessageUtils; import io.hmit.modules.activiti.dto.TaskDTO; import io.hmit.modules.security.user.SecurityUser; import io.hmit.modules.sys.service.SysRoleUserService; import org.activiti.engine.HistoryService; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.delegate.Expression; import org.activiti.engine.history.HistoricActivityInstance; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.history.HistoricTaskInstance; import org.activiti.engine.impl.RepositoryServiceImpl; import org.activiti.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.activiti.engine.impl.persistence.entity.ExecutionEntity; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.pvm.PvmTransition; import org.activiti.engine.impl.pvm.process.ActivityImpl; import org.activiti.engine.impl.pvm.process.TransitionImpl; import org.activiti.engine.impl.task.TaskDefinition; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.activiti.engine.task.TaskInfo; import org.activiti.engine.task.TaskQuery; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; /** * 任务管理 * * @author Jone */ @Service public class ActTaskService extends BaseServiceImpl { @Autowired protected TaskService taskService; @Autowired protected HistoryService historyService; @Autowired protected RepositoryService repositoryService; @Autowired protected RuntimeService runtimeService; @Autowired private SysRoleUserService sysRoleUserService; /** * 根据参数获取当前运行的任务信息 * * @param params * @return */ public PageData<TaskDTO> page(Map<String, Object> params) { String userId = (String) params.get("userId"); Integer curPage = 1; Integer limit = 10; if (params.get(Constant.PAGE) != null) { curPage = Integer.parseInt((String) params.get(Constant.PAGE)); } if (params.get(Constant.LIMIT) != null) { limit = Integer.parseInt((String) params.get(Constant.LIMIT)); } TaskQuery taskQuery = taskService.createTaskQuery(); if (StringUtils.isNotEmpty(userId)) { taskQuery.taskAssignee(userId); } if (StringUtils.isNotEmpty((String) params.get("taskName"))) { taskQuery.taskNameLike("%" + (String) params.get("taskName") + "%"); } if (StringUtils.isNotEmpty((String) params.get("isRoleGroup")) && "1".equals(params.get("isRoleGroup"))) { List<Long> listRoles = sysRoleUserService.getRoleIdList(SecurityUser.getUserId()); List<String> listStr = new ArrayList<>(); for (Long role : listRoles) { listStr.add(role.toString()); } listStr.add(SecurityUser.getUserId().toString()); if (!listStr.isEmpty()) { taskQuery.taskCandidateGroupIn(listStr); } else { return new PageData<>(new ArrayList<>(), 0); } } taskQuery.orderByTaskCreateTime().desc(); List<Task> list = taskQuery.listPage((curPage - 1) * limit, limit); List<TaskDTO> listDto = new ArrayList<>(); for (Task task : list) { TaskDTO dto = new TaskDTO(); this.convertTaskInfo(task, dto); listDto.add(dto); } return new PageData<>(listDto, (int) taskQuery.count()); } /** * 获取任务详情信息 * * @param id * @return */ public TaskDTO taskDetail(String id) { Task task = taskService.createTaskQuery().taskId(id).singleResult(); TaskDTO dto = new TaskDTO(); this.convertTaskInfo(task, dto); return dto; } /** * 签收任务 * * @param taskId */ public void claimTask(String taskId) { String userId = SecurityUser.getUserId().toString(); Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (StringUtils.isNotEmpty(task.getAssignee())) { throw new HmitException(ErrorCode.TASK_CLIME_FAIL); } taskService.claim(taskId, userId); } /** * 释放任务 * * @param taskId */ public void unclaimTask(String taskId) { Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); String procInstId = task.getProcessInstanceId(); String processDefinitionId = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId) .singleResult().getProcessDefinitionId(); ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId); ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult(); String activitiId = execution.getActivityId(); List<ActivityImpl> activitiList = def.getActivities(); List<String> lstGroupId = new ArrayList<>(); for (ActivityImpl activityImpl : activitiList) { if (activitiId.equals(activityImpl.getId())) { TaskDefinition taskDef = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition(); Set<Expression> groupIds = taskDef.getCandidateGroupIdExpressions(); for (Expression exp : groupIds) { lstGroupId.add(exp.getExpressionText()); } } } if (lstGroupId.isEmpty()) { throw new HmitException(ErrorCode.UNCLAIM_ERROR_MESSAGE); } taskService.unclaim(taskId); } /** * 处理任务 * * @param taskId * @param comment */ public void completeTask(String taskId, String comment) { String userId = SecurityUser.getUserId().toString(); Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (StringUtils.isNotEmpty(task.getAssignee())) { taskService.setAssignee(taskId, userId); } if (StringUtils.isNotEmpty(comment)) { taskService.addComment(taskId, task.getProcessInstanceId(), comment); } taskService.complete(taskId); } /** * 任务转办 * * @param taskId * @param depositorId * @param assignee */ public void changeTaskAssignee(String taskId, String depositorId, String assignee) { taskService.setOwner(taskId, depositorId); taskService.setAssignee(taskId, assignee); } /** * 获取流程参数 * * @param taskId * @param variableName * @return */ public Map<String, Object> getTaskVariables(String taskId, String variableName) { Map<String, Object> map = null; if (StringUtils.isNotBlank(variableName)) { Object value = taskService.getVariable(taskId, variableName); if (null != value) { map = new HashMap<>(); map.put(variableName, value); } } else { map = taskService.getVariables(taskId); } return map; } /** * 更新任务变量 * * @param taskDTO */ public void updateTaskVariable(TaskDTO taskDTO) { taskService.setVariables(taskDTO.getTaskId(), taskDTO.getParams()); } /** * 根据任务ID判断是否为多实例任务 * * @param taskId * @return */ private boolean isMultiInstance(String taskId) { boolean flag = false; Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (task != null) { // 获取流程定义id String processDefinitionId = task.getProcessDefinitionId(); ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId); // 根据活动id获取活动实例 ActivityImpl activityImpl = processDefinitionEntity.findActivity(task.getTaskDefinitionKey()); if ((activityImpl).getActivityBehavior() instanceof ParallelMultiInstanceBehavior) { ParallelMultiInstanceBehavior behavior = (ParallelMultiInstanceBehavior) activityImpl.getActivityBehavior(); if (behavior != null && behavior.getCollectionExpression() != null) { flag = true; } } } return flag; } /** * 删除任务下的所有变量 * * @param taskId * @return */ public void deleteTaskVariables(String taskId) { Collection<String> currentVariables = taskService.getVariablesLocal(taskId).keySet(); taskService.removeVariables(taskId, currentVariables); } public void deleteTaskVariable(String taskId, String variableName, String scope) { if (StringUtils.isNotEmpty(scope)) { if ("global".equals(scope.toLowerCase())) { Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); runtimeService.removeVariable(task.getExecutionId(), variableName); } else if ("local".equals(scope.toLowerCase())) { taskService.removeVariable(taskId, variableName); } } else { taskService.removeVariable(taskId, variableName); } } /** * 任务回退至上一用户任务节点 * * @param taskId * @return */ @Transactional(rollbackFor = Exception.class) public void doBackPreviousTask(String taskId, String comment) { Map<String, Object> variables = null; HistoricTaskInstance currTask = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult(); if (this.isMultiInstance(taskId)) { throw new HmitException(ErrorCode.BACK_PROCESS_PARALLEL_ERROR); } ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(currTask.getProcessInstanceId()).singleResult(); ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService) .getDeployedProcessDefinition(currTask.getProcessDefinitionId()); ActivityImpl currActivity = processDefinitionEntity.findActivity(currTask.getTaskDefinitionKey()); List<ActivityImpl> canBackActivitys = new ArrayList<>(); this.getCanBackUpActivitys(currActivity, canBackActivitys); if (canBackActivitys.isEmpty()) { throw new HmitException(ErrorCode.SUPERIOR_NOT_EXIST); } List<PvmTransition> originPvmTransitionList = new ArrayList<PvmTransition>(); List<PvmTransition> pvmTransitionList = currActivity.getOutgoingTransitions(); for (PvmTransition pvmTransition : pvmTransitionList) { originPvmTransitionList.add(pvmTransition); } pvmTransitionList.clear(); List<HistoricActivityInstance> historicActivityInstances = historyService .createHistoricActivityInstanceQuery().activityType("userTask") .processInstanceId(processInstance.getId()) .finished().orderByHistoricActivityInstanceEndTime().desc().list(); List<ActivityImpl> backActivitys = new ArrayList<>(); for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { for (ActivityImpl activity : canBackActivitys) { if (historicActivityInstance.getActivityId().equals(activity.getId())) { boolean flag = false; for (ActivityImpl activity1 : backActivitys) { if (activity.getId().equals(activity1.getId())) { flag = true; break; } } if (!flag) { backActivitys.add(activity); } } } } if (backActivitys.isEmpty()) { throw new HmitException(ErrorCode.SUPERIOR_NOT_EXIST); } List<TransitionImpl> transitionList = new ArrayList<>(); for (ActivityImpl activity : backActivitys) { TransitionImpl transition = currActivity.createOutgoingTransition(IdWorker.get32UUID()); transition.setDestination(activity); transitionList.add(transition); } variables = processInstance.getProcessVariables(); List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()) .taskDefinitionKey(currTask.getTaskDefinitionKey()).list(); for (Task task : tasks) { String commentMode = MessageUtils.getMessage(ErrorCode.ROLLBACK_MESSAGE); if (StringUtils.isNotEmpty(comment)) { commentMode += "[" + comment + "]"; } taskService.addComment(task.getId(), task.getProcessInstanceId(), commentMode); taskService.complete(task.getId(), variables); } currActivity.getOutgoingTransitions().clear(); for (PvmTransition pvmTransition : originPvmTransitionList) { currActivity.getOutgoingTransitions().add(pvmTransition); } for (ActivityImpl activity : backActivitys) { List<PvmTransition> incomingTransitions = activity.getIncomingTransitions(); Iterator<PvmTransition> iterator = incomingTransitions.iterator(); while (iterator.hasNext()) { PvmTransition pvmTransition = iterator.next(); for (TransitionImpl transition : transitionList) { if (transition.getId().equals(pvmTransition.getId())) { iterator.remove(); } } } } } private void getCanBackUpActivitys(ActivityImpl currActivity, List<ActivityImpl> rtnList) { List<PvmTransition> incomingTransitions = currActivity.getIncomingTransitions(); for (PvmTransition pvmTransition : incomingTransitions) { TransitionImpl transitionImpl = (TransitionImpl) pvmTransition; ActivityImpl activityImpl = transitionImpl.getSource(); String type = (String) activityImpl.getProperty("type"); if ("parallelGateway".equals(type)) { // 并行路线 if (activityImpl.getOutgoingTransitions().size() > 1) { throw new HmitException(ErrorCode.BACK_PROCESS_HANDLEING_ERROR); } this.getCanBackUpActivitys(activityImpl, rtnList); } else if ("startEvent".equals(type)) { return; } else if ("userTask".equals(type)) { rtnList.add(activityImpl); } else if ("exclusiveGateway".equals(type)) { this.getCanBackUpActivitys(activityImpl, rtnList); } else if ("inclusiveGateway".equals(type)) { if (activityImpl.getOutgoingTransitions().size() > 1) { return; } this.getCanBackUpActivitys(activityImpl, rtnList); } } } @Transactional(rollbackFor = Exception.class) public void endProcess(String taskId, String comment) { if (isMultiInstance(taskId)) { throw new HmitException(ErrorCode.END_PROCESS_PARALLEL_ERROR); } Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); List<Task> tasks = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()) .taskDefinitionKey(task.getTaskDefinitionKey()).list(); if (tasks.size() > 1) { throw new HmitException(ErrorCode.END_PROCESS_HANDLEING_ERROR); } ActivityImpl endActivity = findActivitiImpl(taskId, "end"); if (endActivity == null) { return; } if (StringUtils.isEmpty(endActivity.getId())) { if (!StringUtils.isEmpty(task.getOwner())) { taskService.resolveTask(task.getId()); } taskService.addComment(task.getId(), task.getProcessInstanceId(), comment); taskService.complete(taskId); } else { ActivityImpl currActivity = findActivitiImpl(taskId, null); List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>(); List<PvmTransition> pvmTransitionList = currActivity .getOutgoingTransitions(); for (PvmTransition pvmTransition : pvmTransitionList) { oriPvmTransitionList.add(pvmTransition); } pvmTransitionList.clear(); TransitionImpl newTransition = currActivity.createOutgoingTransition(); ActivityImpl pointActivity = findActivitiImpl(taskId, endActivity.getId()); newTransition.setDestination(pointActivity); if (StringUtils.isNotEmpty(task.getOwner())) { taskService.resolveTask(task.getId()); } String message = MessageUtils.getMessage(ErrorCode.END_PROCESS_MESSAGE); comment = message + "[" + comment + "]"; taskService.addComment(task.getId(), task.getProcessInstanceId(), comment); taskService.complete(taskId); pointActivity.getIncomingTransitions().remove(newTransition); List<PvmTransition> pvmTransitionListC = currActivity.getOutgoingTransitions(); pvmTransitionListC.clear(); for (PvmTransition pvmTransition : oriPvmTransitionList) { pvmTransitionListC.add(pvmTransition); } } } private ActivityImpl findActivitiImpl(String taskId, String activityId) { Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (task == null) { return null; } ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId()); if (processDefinition == null) { throw new HmitException(ErrorCode.NONE_EXIST_PROCESS); } if (StringUtils.isEmpty(activityId)) { activityId = task.getTaskDefinitionKey(); } if ("END".equals(activityId.toUpperCase())) { for (ActivityImpl activityImpl : processDefinition.getActivities()) { String type = (String) activityImpl.getProperty("type"); if ("endEvent".equals(type)) { return activityImpl; } } } ActivityImpl activityImpl = processDefinition.findActivity(activityId); return activityImpl; } /** * 转换Task对象 * * @param task * @param dto */ private void convertTaskInfo(Task task, TaskDTO dto) { dto.setTaskId(task.getId()); dto.setTaskName(task.getName()); dto.setActivityId(task.getExecutionId()); dto.setAssignee(task.getAssignee()); dto.setProcessDefinitionId(task.getProcessDefinitionId()); ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult(); dto.setProcessDefinitionName(processDefinition.getName()); dto.setProcessDefinitionKey(processDefinition.getKey()); HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); dto.setStartTime(processInstance.getStartTime()); dto.setBusinessKey(processInstance.getBusinessKey()); dto.setProcessInstanceId(task.getProcessInstanceId()); dto.setOwner(task.getOwner()); dto.setCreateTime(task.getCreateTime()); dto.setDueDate(task.getDueDate()); } /** * 驳回至第一个用户任务 * * @param taskId */ @Transactional(rollbackFor = Exception.class) public void backToFirst(String taskId, String comment) { if (this.isMultiInstance(taskId)) { throw new HmitException(ErrorCode.REJECT_PROCESS_PARALLEL_ERROR); } Map variables = null; HistoricTaskInstance currTask = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult(); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(currTask.getProcessInstanceId()).singleResult(); ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService) .getDeployedProcessDefinition(currTask.getProcessDefinitionId()); if (processDefinitionEntity == null) { throw new HmitException(ErrorCode.NONE_EXIST_PROCESS); } List<Task> tasks = taskService.createTaskQuery().processInstanceId(currTask.getProcessInstanceId()) .taskDefinitionKey(currTask.getTaskDefinitionKey()).list(); if (tasks.size() > 1) { throw new HmitException(ErrorCode.REJECT_PROCESS_HANDLEING_ERROR); } ActivityImpl currActivity = processDefinitionEntity.findActivity(currTask.getTaskDefinitionKey()); List<PvmTransition> originPvmTransitionList = new ArrayList<>(); List<PvmTransition> pvmTransitionList = currActivity.getOutgoingTransitions(); for (PvmTransition pvmTransition : pvmTransitionList) { originPvmTransitionList.add(pvmTransition); } pvmTransitionList.clear(); List<HistoricActivityInstance> historicActivityInstances = historyService .createHistoricActivityInstanceQuery().activityType("userTask") .processInstanceId(processInstance.getId()) .finished().orderByHistoricActivityInstanceEndTime().asc().list(); TransitionImpl transitionImpl = null; if (historicActivityInstances.size() > 0) { ActivityImpl lastActivity = processDefinitionEntity.findActivity(historicActivityInstances.get(0).getActivityId()); transitionImpl = currActivity.createOutgoingTransition(); transitionImpl.setDestination(lastActivity); } else { throw new HmitException(ErrorCode.SUPERIOR_NOT_EXIST); } variables = processInstance.getProcessVariables(); for (Task task : tasks) { String commentMode = MessageUtils.getMessage(ErrorCode.REJECT_MESSAGE); if (StringUtils.isNotEmpty(comment)) { commentMode += "[" + comment + "]"; } taskService.addComment(task.getId(), task.getProcessInstanceId(), commentMode); taskService.complete(task.getId(), variables); } currActivity.getOutgoingTransitions().remove(transitionImpl); for (PvmTransition pvmTransition : originPvmTransitionList) { pvmTransitionList.add(pvmTransition); } } public void completeTaskByVariables(TaskDTO taskDTO) { if (null != taskDTO.getParams()) { Set keySet = taskDTO.getParams().keySet(); Iterator iterator = keySet.iterator(); while (iterator.hasNext()) { String key = (String) iterator.next(); this.setTaskVariable(taskDTO.getTaskId(), key, taskDTO.getParams().get(key)); } } this.completeTask(taskDTO.getTaskId(), taskDTO.getComment()); } private void setTaskVariable(String taskId, String key, Object value) { TaskInfo taskInfo = taskService.createTaskQuery().taskId(taskId).singleResult(); runtimeService.setVariable(taskInfo.getExecutionId(), key, value); } }