|
@@ -0,0 +1,262 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright (c) 2016, FPX and/or its affiliates. All rights reserved.
|
|
|
|
+ * Use, Copy is subject to authorized license.
|
|
|
|
+*/
|
|
|
|
+package com.qmth.cqb.flow.serviceImpl;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+
|
|
|
|
+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.UserTaskActivityBehavior;
|
|
|
|
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
|
|
|
|
+import org.activiti.engine.impl.pvm.PvmActivity;
|
|
|
|
+import org.activiti.engine.impl.pvm.PvmTransition;
|
|
|
|
+import org.activiti.engine.impl.pvm.process.ActivityImpl;
|
|
|
|
+import org.activiti.engine.impl.task.TaskDefinition;
|
|
|
|
+import org.activiti.engine.repository.ProcessDefinition;
|
|
|
|
+import org.activiti.engine.repository.ProcessDefinitionQuery;
|
|
|
|
+import org.activiti.engine.runtime.Execution;
|
|
|
|
+import org.activiti.engine.task.DelegationState;
|
|
|
|
+import org.activiti.engine.task.Task;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.util.Assert;
|
|
|
|
+
|
|
|
|
+import com.qmth.cqb.flow.model.TaskModel;
|
|
|
|
+import com.qmth.cqb.flow.model.WorkFlowModel;
|
|
|
|
+import com.qmth.cqb.flow.service.ComTaskService;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @Title: 任务处理service
|
|
|
|
+ * @Description:TODO
|
|
|
|
+ * @Company:4px
|
|
|
|
+ * @author chenken
|
|
|
|
+ * @date 2016年6月24日
|
|
|
|
+ * @since v1.0.0
|
|
|
|
+ */
|
|
|
|
+@Service("comTaskService")
|
|
|
|
+public class ComTaskServiceImpl implements ComTaskService{
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private TaskService taskService;
|
|
|
|
+ @Resource
|
|
|
|
+ private RepositoryService repositoryService;
|
|
|
|
+ @Resource
|
|
|
|
+ private RuntimeService runtimeService;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<TaskModel> findPersonalTaskList(String assignee,String category) throws Exception {
|
|
|
|
+ Assert.hasText(assignee, "任务办理人assignee不能为空");
|
|
|
|
+ List<TaskModel> taskModelList = new ArrayList<TaskModel>();
|
|
|
|
+ List<Task> taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
|
|
|
|
+ if(taskList.size()>0){
|
|
|
|
+ for(Task task:taskList){
|
|
|
|
+ String processDefinitionId = task.getProcessDefinitionId();
|
|
|
|
+ ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId);
|
|
|
|
+ if(StringUtils.isNotBlank(category)){
|
|
|
|
+ processDefinitionQuery = processDefinitionQuery.processDefinitionCategory(category);
|
|
|
|
+ }
|
|
|
|
+ ProcessDefinition processDefinition = processDefinitionQuery.singleResult();
|
|
|
|
+ if(processDefinition!=null){
|
|
|
|
+ taskModelList.add(new TaskModel(task,processDefinition));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return taskModelList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<TaskModel> findClaimTask(String roleId,String category){
|
|
|
|
+ Assert.hasText(roleId, "任务办理角色roleId不能为空");
|
|
|
|
+ List<TaskModel> taskModelList = new ArrayList<TaskModel>();
|
|
|
|
+ List<Task> taskList = taskService.createTaskQuery().taskCandidateGroup(roleId).active().list();
|
|
|
|
+ if(taskList.size()>0){
|
|
|
|
+ for(Task task:taskList){
|
|
|
|
+ String processDefinitionId = task.getProcessDefinitionId();
|
|
|
|
+ ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId);
|
|
|
|
+ if(StringUtils.isNotBlank(category)){
|
|
|
|
+ processDefinitionQuery = processDefinitionQuery.processDefinitionCategory(category);
|
|
|
|
+ }
|
|
|
|
+ ProcessDefinition processDefinition = processDefinitionQuery.singleResult();
|
|
|
|
+ if(processDefinition!=null){
|
|
|
|
+ TaskModel taskModel = new TaskModel(task,processDefinition);
|
|
|
|
+ taskModel.setTaskRole(roleId);
|
|
|
|
+ taskModelList.add(taskModel);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return taskModelList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 完成任务
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public void completeTask(WorkFlowModel workFlowModel) throws Exception {
|
|
|
|
+ /**
|
|
|
|
+ * 验证
|
|
|
|
+ */
|
|
|
|
+ Assert.hasText(workFlowModel.getTaskId(), "任务ID不能为空");
|
|
|
|
+ Assert.hasText(workFlowModel.getAssignee(), "当前操作人不能为空");
|
|
|
|
+
|
|
|
|
+ String taskId = workFlowModel.getTaskId();
|
|
|
|
+
|
|
|
|
+ Map<String, Object> variables = workFlowModel.getVariables();
|
|
|
|
+ //当前节点操作人
|
|
|
|
+ variables.put("assignee", workFlowModel.getAssignee());
|
|
|
|
+ //如果有分支,设置分支条件
|
|
|
|
+ variables.put("condition", workFlowModel.getCondition());
|
|
|
|
+ //下一节点操作人如果为null,任务会分派给角色领取
|
|
|
|
+ if(StringUtils.isBlank(workFlowModel.getNextOperator())){
|
|
|
|
+ variables.put("operator",null);
|
|
|
|
+ }else{
|
|
|
|
+ variables.put("operator",workFlowModel.getNextOperator());
|
|
|
|
+ }
|
|
|
|
+ Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
|
|
|
|
+ //如果任务处于委派状态,须调用特定的委派回归处理方法
|
|
|
|
+ if(task.getDelegationState() == DelegationState.PENDING){
|
|
|
|
+ taskService.resolveTask(taskId, variables);
|
|
|
|
+ }else{
|
|
|
|
+ taskService.complete(taskId, variables);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 领取任务
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public void claimTask(String taskId,String assignee) {
|
|
|
|
+ Assert.hasText(taskId, "任务ID不能为空");
|
|
|
|
+ Assert.hasText(assignee, "任务领取人不能为空");
|
|
|
|
+ taskService.claim(taskId, assignee);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void completeTaskByProcInstId(String procInstId,Map<String, Object> variables) throws Exception{
|
|
|
|
+ String assignee = variables.get("assignee")+"";
|
|
|
|
+ if(StringUtils.isNotBlank(assignee)){
|
|
|
|
+ Task task = taskService.createTaskQuery()
|
|
|
|
+ .processInstanceId(procInstId)
|
|
|
|
+ .taskAssignee(assignee)
|
|
|
|
+ .active()
|
|
|
|
+ .singleResult();
|
|
|
|
+ if (task!=null) {
|
|
|
|
+ taskService.complete(task.getId(), variables);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 委派任务
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public void delegateTask(String taskId, String delegateUserId) {
|
|
|
|
+ Assert.hasText(taskId, "任务ID不能为空");
|
|
|
|
+ Assert.hasText(delegateUserId, "被委派人不能为空");
|
|
|
|
+
|
|
|
|
+ taskService.delegateTask(taskId, delegateUserId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<TaskModel> findAssigneedOrClaimTask(String assignee,String groupId, String category) throws Exception {
|
|
|
|
+ List<TaskModel> taskModelList = new ArrayList<TaskModel>();
|
|
|
|
+ taskModelList.addAll(findPersonalTaskList(assignee, category));
|
|
|
|
+ taskModelList.addAll(findClaimTask(groupId, category));
|
|
|
|
+ return taskModelList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public TaskDefinition nextTaskDefinition(String processInstanceId,String activitiId,String elString) {
|
|
|
|
+ String id = null;
|
|
|
|
+ TaskDefinition task = null;
|
|
|
|
+ ProcessDefinitionEntity processDefinitionEntity = null;
|
|
|
|
+ String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
|
|
|
|
+ processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
|
|
|
|
+ //获取当前流程所有节点信息
|
|
|
|
+ List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();
|
|
|
|
+ //遍历所有节点信息
|
|
|
|
+ for(ActivityImpl activityImpl : activitiList){
|
|
|
|
+ id = activityImpl.getId();
|
|
|
|
+ // 找到当前节点信息
|
|
|
|
+ if (activitiId.equals(id)) {
|
|
|
|
+ //获取下一个节点信息
|
|
|
|
+ task = nextTaskDefinition(activityImpl,activitiId,elString,processInstanceId);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return task;
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 下一个任务节点信息,
|
|
|
|
+ *
|
|
|
|
+ * 如果下一个节点为用户任务则直接返回,
|
|
|
|
+ *
|
|
|
|
+ * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值,
|
|
|
|
+ * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务信息
|
|
|
|
+ * @param ActivityImpl activityImpl 流程节点信息
|
|
|
|
+ * @param String activityId 当前流程节点Id信息
|
|
|
|
+ * @param String elString 排他网关顺序流线段判断条件, 例如排他网关顺序留线段判断条件为${money>1000}, 若满足流程启动时设置variables中的money>1000, 则流程流向该顺序流信息
|
|
|
|
+ * @param String processInstanceId 流程实例Id信息
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId){
|
|
|
|
+ PvmActivity ac = null;
|
|
|
|
+ Object s = null;
|
|
|
|
+ //如果遍历节点为用户任务并且节点不是当前节点信息
|
|
|
|
+ if("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())){
|
|
|
|
+ //获取该节点下一个节点信息
|
|
|
|
+ TaskDefinition taskDefinition = ((UserTaskActivityBehavior)activityImpl.getActivityBehavior()).getTaskDefinition();
|
|
|
|
+ return taskDefinition;
|
|
|
|
+ }else{
|
|
|
|
+ //获取节点所有流向线路信息
|
|
|
|
+ List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
|
|
|
|
+ List<PvmTransition> outTransitionsTemp = null;
|
|
|
|
+ for(PvmTransition tr : outTransitions){
|
|
|
|
+ ac = tr.getDestination(); //获取线路的终点节点
|
|
|
|
+ //如果流向线路为排他网关
|
|
|
|
+ if("exclusiveGateway".equals(ac.getProperty("type"))){
|
|
|
|
+ outTransitionsTemp = ac.getOutgoingTransitions();
|
|
|
|
+ //如果网关路线判断条件为空信息
|
|
|
|
+ if(StringUtils.isEmpty(elString)) {
|
|
|
|
+ //获取流程启动时设置的网关判断条件信息
|
|
|
|
+ elString = getGatewayCondition(ac.getId(), processInstanceId);
|
|
|
|
+ }
|
|
|
|
+ //如果排他网关只有一条线路信息
|
|
|
|
+ if(outTransitionsTemp.size() == 1){
|
|
|
|
+ return nextTaskDefinition((ActivityImpl)outTransitionsTemp.get(0).getDestination(), activityId, elString, processInstanceId);
|
|
|
|
+ }else if(outTransitionsTemp.size() > 1){ //如果排他网关有多条线路信息
|
|
|
|
+ for(PvmTransition tr1 : outTransitionsTemp){
|
|
|
|
+ s = tr1.getProperty("conditionText"); //获取排他网关线路判断条件信息
|
|
|
|
+ //判断el表达式是否成立
|
|
|
|
+ if(elString.equals(s)){
|
|
|
|
+ return nextTaskDefinition((ActivityImpl)tr1.getDestination(), activityId, elString, processInstanceId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else if("userTask".equals(ac.getProperty("type"))){
|
|
|
|
+ return ((UserTaskActivityBehavior)((ActivityImpl)ac).getActivityBehavior()).getTaskDefinition();
|
|
|
|
+ }else{
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 查询流程启动时设置排他网关判断条件信息
|
|
|
|
+ * @param String gatewayId 排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息
|
|
|
|
+ * @param String processInstanceId 流程实例Id信息
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private String getGatewayCondition(String gatewayId, String processInstanceId) {
|
|
|
|
+ Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
|
|
|
|
+ return runtimeService.getVariable(execution.getId(), gatewayId)+"";
|
|
|
|
+ }
|
|
|
|
+}
|