`
crackajack_zg
  • 浏览: 52769 次
社区版块
存档分类
最新评论

activiti 选人的实现

阅读更多
activiti默认是不带有选人的功能的,它默认的是在调用complete 方法的时候自动根据下一个节点的 assignee属性或者candidate属性 设置下一节点的候选人或者 assginee。

由于项目的原因我们需要实现在上一个节点提交的时候设置就要从几个候选审批人员中选择一个或者几个审批人员,下面的代码写了个Junit 的demo。



package test.java.org.activiti.designer.test;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.FileInputStream;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.junit.Rule;
import org.junit.Test;

public class ProcessTest {

	private String filename = "E:\\workspace4.3\\kft-activiti-demo-no-maven\\resources\\diagrams\\test2.bpmn";

	@Rule
	public ActivitiRule activitiRule = new ActivitiRule();
	static RuntimeService runtimeService;
	static TaskService taskService;
	static IdentityService identityService;
	
	static RepositoryService repositoryService;
	
	
	//流程定义编号
	private String processDefinitionId ;
	//任务编号
	//private String taskId;
	//流程实例号
	private String processInstanceId;
	@Test
	public void mainTest() throws Exception {
		
		repositoryService = activitiRule.getRepositoryService();	
		runtimeService = activitiRule.getRuntimeService();
		taskService = activitiRule.getTaskService();

		ProcessTest ptm = new ProcessTest();
		//这里有个问题,runtimeService.startProcessInstanceByKey 这个方法直接就把流程流转到任务用户去了,没经过选人的操作
		//这里就变通一下处理,提交到一个无所谓的人,然后在调用方法修改这个人。
		String taskId;
		//返回的usertask的id
		taskId = ptm.startProcess();
		//**********流程启动成功
		//流程在第一个审批人哪里
		//taskId = ptm.getNextNodeId(1,"feng");
		//选人
		List<String> userList= ptm.getNextTaskUserByTaskId(taskId);
		//设置审批人
		ptm.setApproveUser(taskId, "feng");

		taskId = ptm.getNextNodeId(1,"feng");
		
		//第一个审批人提交流程  feng 为当前节点审批人,xiaozhang 为设置的下一节点审批人
		ptm.completeByAssignee("feng","xiaozhang");
		//************第一个人审批成功
		


		taskId = ptm.getNextNodeId(1,"xiaozhang");
		//选人
		userList= ptm.getNextTaskUserByTaskId(taskId);
		//第一个审批人提交流程
		ptm.completeByAssignee("xiaozhang","xiaoming");

		ptm.getNextNodeId(1,"xiaoming");
		
		//第二个审批人提交流程
		ptm.completeByAssignee("xiaoming","xiangwang");
		//************第二个人审批成功



	}
	//启动流程
	public String startProcess() throws Exception {
		
		repositoryService.createDeployment().addInputStream("test2.bpmn20.xml",new FileInputStream(filename)).deploy();
 		Map<String, Object> variableMap = new HashMap<String, Object>();
		variableMap.put("name", "Activiti");
		
		
		//启动流程
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("test2", variableMap);

		processDefinitionId = processInstance.getProcessDefinitionId();
		processInstance.getId();
		List<TaskEntity> tList =  ((org.activiti.engine.impl.persistence.entity.ExecutionEntity) processInstance).getTasks();
		
		this.setProcessInstanceId( processInstance.getId() );
		
		this.setProcessDefinitionId(processDefinitionId);
		
		if(tList.size()!=1) {
			System.err.println("start节点的输出路由不能有多个");
		}
		return tList.get(0).getId();

	}

	public void queryProcessInstance() {
		List<ProcessInstance> instanceList = runtimeService
				.createProcessInstanceQuery().processDefinitionKey("test")
				.list();
		//查询 流程实例
		for (ProcessInstance queryProcessInstance : instanceList) {
			queryProcessInstance.getActivityId();
			
			System.out.print("-----queryProcessInstance:"+queryProcessInstance.getActivityId());
			
			assertEquals(false, queryProcessInstance.isEnded());
			System.out.println("id " + queryProcessInstance.getId()
					+ ", ended=" + queryProcessInstance.isEnded()+",ProcessDefinitionId="+queryProcessInstance.getProcessDefinitionId());
		}
	}
	//根据assignee来查询用户
	public void queryTask(String assignee) {
		//startProcessInstance();
		
		// taskService.createTaskQuery().taskCandidateGroup("sales").singleResult();
		
		Task task= taskService.createTaskQuery().taskAssignee(assignee).singleResult();
		
		
		System.out.println("审批人为【"+assignee+"】的任务有:任务编号为【" + task.getId() + "】"+ task.getTaskDefinitionKey());

	}
	/**
	 * 
	 * @param queryType  查询类型1 根据 assignee 查询  2 根据candidateuser查询
	 * @param str
	 */
	public String getNextNodeId(int queryType,String str) {
		
		
		Task task = null;
		if(queryType==1) {
			task = taskService.createTaskQuery().taskAssignee(str).singleResult();
		}else if(queryType==2){
			task = taskService.createTaskQuery().taskCandidateUser(str).singleResult();

		}else if(queryType==3){
			task = taskService.createTaskQuery().taskCandidateGroup(str).singleResult();

		}
		
		List<FlowElement> list = getNextNode(task.getId());
		
		
		if(task==null) {
			return null;
		}
		
		
		for(FlowElement e :list) {
			//((org.activiti.bpmn.model.UserTask) e)
		}
		
		return task.getId();
			
	}
	/**
	 * 获取流程的下一个节点 且要经过规则引擎判断后的节点
	 * @param taskId
	 * @return
	 */
	private List<FlowElement> getNextNode(String taskId) {
		
		Task task = null;
		task = taskService.createTaskQuery().taskId(taskId).singleResult();
		if(task==null) {
			return null;
		}
		List<FlowElement> list = new ArrayList<FlowElement>();
		
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
		
		//当前活动节点
		String activitiId = processInstance.getActivityId();
		
		System.out.println("当前节点是【"+activitiId+"】");

		//pmmnModel 遍历节点需要它
    	BpmnModel bpmnModel =  repositoryService.getBpmnModel(task.getProcessDefinitionId());

    	List<Process> processList = bpmnModel.getProcesses();
    	
		//循环多个物理流程
		for(Process process:processList) {
			
			//返回该流程的所有任务,事件
 			Collection<FlowElement> cColl = process.getFlowElements();
 			//遍历节点
			for(FlowElement f :cColl) {
				
				
				//如果改节点是当前节点 者 输出该节点的下一个节点
				if(f.getId().equals(activitiId)) {
				
					List<SequenceFlow>  sequenceFlowList = new ArrayList<SequenceFlow>();
					//通过反射来判断是哪种类型
					if(f instanceof org.activiti.bpmn.model.StartEvent) {
						//开始事件的输出路由
						sequenceFlowList	= ((org.activiti.bpmn.model.StartEvent) f).getOutgoingFlows();
					}else if(f instanceof org.activiti.bpmn.model.UserTask) {
						
						sequenceFlowList	= ((org.activiti.bpmn.model.UserTask) f).getOutgoingFlows();
						
						
						for(SequenceFlow sf :sequenceFlowList)  {
							
							String targetRef = sf.getTargetRef();
							FlowElement ref = process.getFlowElement(targetRef);
							
						//	nextActivitiIdList.add(ref.getId());
							
							list.add(ref);
						}
						
					}else if(f instanceof org.activiti.bpmn.model.SequenceFlow) {
					
						
					}else if(f instanceof org.activiti.bpmn.model.EndEvent) {
						sequenceFlowList	= ((org.activiti.bpmn.model.EndEvent) f).getOutgoingFlows();
					}
					break;
				} 
					
			}
			
		}	
		return list;
	} 
	//流程流转到下一步
	public void completeByAssignee(String assignee,String nextUser) throws Exception {
		
		HashMap<String,Object> map = new HashMap<String,Object>();
		
		map.put("nextUser", nextUser);
		Task task = taskService.createTaskQuery().taskAssignee(assignee).singleResult();
		taskService.complete(task.getId(),map);
		System.out.println("完成任务 编号为【" + task.getId() + "】,名称为【"+task.getName()+"】的任务");
	}
	/**
	 * 设置某个节点的审批人员
	 * @param taskId
	 * @param user
	 */
	public void setApproveUser(String taskId,String user) {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		task.setAssignee(user);
		taskService.saveTask(task);
	}

	/**
	 * 取下一个节点的审批人
	 * @param taskId
	 * @return
	 */
	public List<String> getNextTaskUserByTaskId(String taskId) {
		List<String> list = new ArrayList<String>();
		
		List<FlowElement> fList = getNextNode(taskId);
		
		
		for(FlowElement u:fList){
			
			String str =  ((org.activiti.bpmn.model.UserTask) u).getAssignee(); 
			list.add(str);
		}
		return list ;
	}
	
	/**
	 * 找当前节点的候选审批人  供流程实例start后调用
	 * @param taskId
	 * @return
	 */
	public List<String> getThisTaskUser(String taskId) {
		List<String> list = new ArrayList<String>();
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		String taskUser = task.getAssignee();
		
		//*****************************根据taskUser的配置到自己的表里面去找数据
		
		list.add(taskUser);
		return list ;
	}
	public String getProcessDefinitionId() {
		return processDefinitionId;
	}

	public void setProcessDefinitionId(String processDefinitionId) {
		this.processDefinitionId = processDefinitionId;
	}

	public String getProcessInstanceId() {
		return processInstanceId;
	}

	public void setProcessInstanceId(String processInstanceId) {
		this.processInstanceId = processInstanceId;
	}
}


另外再绘制流程图的时候除了首节点,其余每个节点要设置listener ,可以设置一个公共的listener 传递不同的参数代码如:
package org.activiti.ext;


import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.TaskListener;
import org.apache.ibatis.annotations.Delete;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TaskUserQuery implements TaskListener{

	
	  /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static Logger logger = LoggerFactory.getLogger(TaskUserQuery.class);

	protected DataSource dataSource;

	
	
	private org.activiti.engine.impl.el.FixedValue orgLevel ;
	private org.activiti.engine.impl.el.FixedValue dutyNo ;
	public DataSource getDataSource() {
		return dataSource;
	}
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	/**
	 * 审批过程中找人的方法
	 * @param str 组名
	 * @return
	 * @throws SQLException
	 */
	public String getTaskUser(String str) throws SQLException {
		logger.debug("-------------------自定义找人----------------------------getTaskUser");
		
		Connection conn = dataSource.getConnection();
		
		Statement state = conn.createStatement();
		String queryTaskUserSql = "select id_ from act_id_user aiu where exists (select 1 from act_id_membership aim where aim.user_id_ = aiu.id_ and  aim.group_id_='"+str+"' )";
		
		ResultSet rs = state.executeQuery(queryTaskUserSql);
		rs.next();
		logger.debug("-------------------自定义找人----------------------------:返回的人是"+rs.getString(1));
		
		conn.close();
		state.close();
		return rs.getString(1);
		
	} 
	
	public List<String> getTaskUserList(String str) throws SQLException {
		logger.debug("-------------------自定义找人----------------------------getTaskUserList");
		List<String> taskUser = new ArrayList<String>();
		
		Connection conn = dataSource.getConnection();
		
		Statement state = conn.createStatement();
		String queryTaskUserSql = "select id_ from act_id_user aiu where exists (select 1 from act_id_membership aim where aim.user_id_ = aiu.id_ and  aim.group_id_='"+str+"' )";
		
		ResultSet rs = state.executeQuery(queryTaskUserSql);
		while(rs.next()) {
			taskUser.add(rs.getString(1));
		}
		logger.debug("------------------- 自定义找人----------------------------:返回的人是"+taskUser.toString());
		
		conn.close();
		state.close();
		return taskUser;
		
	} 
	@Override
	public void notify(DelegateTask delegateTask) {
		
		
		Map<String,Object> map = delegateTask.getVariables();
		String taskId = delegateTask.getId();
		
		System.out.println("in taskUserQuer class variable is:"+map.toString());
		System.out.println("in taskUserQuer class taskid is:"+taskId);
		System.out.println("in taskUserQuer class orgLevel is:"+orgLevel.getExpressionText());
		
		
		
		String id = delegateTask.getId();
		String s = delegateTask.getAssignee();
		//根据流程变量的内容设置下一个节点的审批人
		delegateTask.setAssignee(map.get("nextUser").toString());
		
		Map<String,Object> m1 = delegateTask.getExecution().getVariables();
		Map<String,Object> m2 = delegateTask.getVariablesLocal();
		
		
		
//		logger.debug("-----------------------------------------id is:"+id);
//	//	logger.debug("-----------------------------------------arg is:"+dutyNo.getExpressionText());
//		delegateTask.setAssignee(dutyNo.getExpressionText());
		
		// TODO Auto-generated method stub
//		logger.debug("----------------------设置选人 开始--------------------------");
//		delegateTask.setAssignee("admin");  
//		logger.debug("----------------------设置选人 结束--------------------------");
	}

}



整个选人过程的其实比较简单 是:提交流程的时候将下一审批人作为流程变量提交到流程引擎,流程引擎会调用如上代码块的notify 方法(当然需要在usertask上配置 配置下图) ,在notify方法内delegateTask.setAssignee设置下一个节点的审批人


  • 大小: 47.1 KB
分享到:
评论
3 楼 a418040445 2014-01-13  
crackajack_zg 写道
a418040445 写道
请问一下,你这个会判断连线上的条件没?
你给下个节点设人的时候,首先要知道 当前节点的后续节点, 然后还要知道 流程实例 会流转到哪个节点上去。

如 A 的后续节点是 B、C、D 3个节点,当然你的连线上有条件,可能还有默认连线等。你在A节点 点击 发送按钮 的时候设置下个节点的人 需要知道流程会流转到( B、C、D )哪个节点上?条件怎么判断的呢?

当某个节点的下一节点有多个的时候,可以通过bpmnModel 对象取出当前节点的后续SequenceFlow 你可以把条件写在SequenceFlow 上 ,那样就可以判断条件了。

我的意思是这样的:A后面的三个节点B (部门1下面人)、C(部门2下面人)、D(部门3下面人),对应的连线上条件分别是 ${pic==100} 走B节点, ${pic==200} 走C节点, ${pic==300}走D节点, pic 是表单上的某个字段 ,然后A节点这里 点击发送的时候 需要列出后面节点的人对不?  问题是 列哪个部门下的人?自己程序这边需要判断下连线上的条件(比如prc 是100,那肯定是列出部门1下面的人)就是要提前知道流程会走哪一根线。pic字段给流程引擎,它就会自己判断,我就是想调一下它判断的方法。
2 楼 crackajack_zg 2014-01-02  
a418040445 写道
请问一下,你这个会判断连线上的条件没?
你给下个节点设人的时候,首先要知道 当前节点的后续节点, 然后还要知道 流程实例 会流转到哪个节点上去。

如 A 的后续节点是 B、C、D 3个节点,当然你的连线上有条件,可能还有默认连线等。你在A节点 点击 发送按钮 的时候设置下个节点的人 需要知道流程会流转到( B、C、D )哪个节点上?条件怎么判断的呢?

当某个节点的下一节点有多个的时候,可以通过bpmnModel 对象取出当前节点的后续SequenceFlow 你可以把条件写在SequenceFlow 上 ,那样就可以判断条件了。
1 楼 a418040445 2013-12-23  
请问一下,你这个会判断连线上的条件没?
你给下个节点设人的时候,首先要知道 当前节点的后续节点, 然后还要知道 流程实例 会流转到哪个节点上去。

如 A 的后续节点是 B、C、D 3个节点,当然你的连线上有条件,可能还有默认连线等。你在A节点 点击 发送按钮 的时候设置下个节点的人 需要知道流程会流转到( B、C、D )哪个节点上?条件怎么判断的呢?

相关推荐

Global site tag (gtag.js) - Google Analytics