`

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 )哪个节点上?条件怎么判断的呢?

相关推荐

    activiti5.22 实现撤回操作

    本文将深入探讨如何在 Activiti 5.22 版本中实现撤回操作,确保这一功能的实现不影响流程设计,并且通过 ExecutionEntity 对象来管理任务的生命周期,以达到撤销并重新指定任务节点的目的。 Activiti 是一个开源的...

    springboot整合activiti5.22实现页面流程设计项目

    springboot整合activiti5.22实现页面流程设计项目,可直接启动,自动建表,调用接口http://localhost:8080/models/newModel,创建流程模型后,可直接访问http://localhost:8080/static/modeler.html?modelId=75001...

    Activiti5实现任务撤回,任意跳转(代码+注释 spring-activiti-withdraw.zip)

    activiti没有撤回,由于业务的需求需要实现撤回,在参考别人代码后以两种方式实现了任意节点的跳转。代码真实可用,如有问题可联系我 第一种方式: 1、获取当前节点,获取跳转节点 2、获取节点的所有流出流向,把...

    activiti代码实现审批流程的审批

    总结来说,利用Activiti实现审批流程的审批功能,主要涉及以下几个关键步骤: 1. 添加Spring-activiti依赖,配置流程引擎及相关bean。 2. 设计并部署流程定义文件(.bpmn)。 3. 编写Java Delegate类处理用户任务。 ...

    Activiti-5.4中实现会签

    下面我们将详细探讨如何在Activiti-5.4中实现会签以及相关的技术细节。 首先,理解会签的概念。在工作流中,会签是指一个任务可以被分配给多个用户或组,每个参与者都可以独立完成任务,而无需等待其他人的操作。在...

    Activiti多实例任务实现会签

    【标题】"Activiti多实例任务实现会签"是指在Activiti工作流引擎中,如何配置和使用多实例任务来实现会签功能。在企业级应用中,会签常常用于决策过程,要求多个参与者共同审批,只有当所有参与者都完成审批后,流程...

    Java web 集成Activiti 5.21实现工作流在线设计

    Java web 集成Activiti 5.21实现工作流在线设计,包含集成步骤文档,以及相关所需配置文件、jar包..................................................................

    activiti实现请假流程

    在本案例中,“activiti实现请假流程”指的是利用 Activiti 开源插件创建了一个具体的应用场景,即员工请假流程的自动化管理。 Activiti 的核心功能包括: 1. **流程定义**:使用 BPMN 2.0 标准的图形化建模工具,...

    JAVA SSM+Activiti实现用户信息管理、权限管理、OA审批流程统一操作系统

    Spring+SpringMVC+Activiti+mysql实现OA流程,支持多个机构同时使用 1、用户登录、退出、验证码校验 2、个人信息修改、密码修改 首页展示问题发布条数、通知条数、登录人数、新增用户数、发布内部招聘信息数点击展示...

    Jeecg集成activiti.docx

    Jeecg集成activiti.docx Jeecg集成activiti是一个关于如何将activiti集成到Jeecg平台上的指南。下面是从给定的文件中提取的相关知识点: 1. activiti项目结构:activiti项目是一个Maven项目,包含了数据库文件,...

    activiti6.0实现流程图片自定义颜色 当前任务为红色,走过的任务为绿色,自定义文字颜色连线文字显示

    本文将深入探讨如何在Activiti 6.0版本中实现流程图片的自定义颜色功能,以增强流程图的可读性和美观性。 首先,我们要理解流程图在Activiti中的作用。流程图是流程模型的可视化表示,它帮助用户理解并跟踪业务流程...

    基于Springboot +activiti实现的一个前后端分离的企业级OA管理系统(源码+数据库)

    基于Springboot +activiti实现的一个企业级OA管理系统(源码+数据库),项目经过测试,可完美运行!相关说明: ## 1. 库 &gt; 1. SpringBoot Web库 &gt; 2. Activiti 工作流库 &gt; 3. freemarker 模板 &gt; 4. rapid-core 扩展...

    SpringBoot整合Activiti7的实现代码

    Activiti7发布正式版之后,它与SpringBoot2.x已经完全支持整合开发。我们可以将Activiti7与SpringBoot整合开发的坐标引入到工程中,从而达到SpringBoot支持Activti7整合。 1.使用IDEA创建SpringBoot项目 在工程的...

    SpringBoot集成activiti modeler实现在线绘制流程图,完整代码demo

    在本项目中,我们将探讨如何将SpringBoot框架与Activiti Modeler集成,以实现在线绘制和管理业务流程图的功能。Activiti是一个流行的开源工作流引擎,它允许开发者设计、执行和管理业务流程。而Activiti Modeler是其...

    jeecgboot +activiti5.22集成

    此外,文件名称“jeecg-boot-activiti”可能包含了JeecgBoot与Activiti集成的示例代码或者配置文件,开发者可以通过研究这个文件来进一步了解和学习集成的具体实现。 总之,JeecgBoot与Activiti5.22的集成是企业级...

    Activiti-activiti-5.22.0 源码

    通过深入研究 Activiti 的源码,开发者不仅可以了解 BPMN 2.0 的实现细节,还可以学习到如何构建一个高效、灵活的工作流程引擎,这对于提升自身的业务流程管理和软件开发能力具有很大价值。同时,这也是对 Activiti ...

    activiti6.0 自定义流程路径颜色和任务颜色

    在这个类中,你可以实现自定义颜色的细节,比如根据不同的条件绘制不同颜色的任务和连线。 至于 `微信图片_20200509112823.png` 和 `微信图片_20200509112947.png`,它们很可能是示例流程图或者修改前后效果的对比...

    activiti modeler.zip_activiti_activiti-modeler_java_zip

    Activiti Modeler是一款基于Java开发的流程建模工具,它主要与Activiti BPMN(业务流程管理Notation)引擎紧密配合,为用户提供了...通过深入研究和使用这个工具,开发者可以提升工作效率,更好地实现业务流程自动化。

    activiti-选择代理人候选人候选组.rar

    压缩包内的"activiti6-选择代理人候选人候选组"很可能包含了实现这一功能的源代码文件或者配置文件。这些文件可能是对Activiti的API进行扩展或修改后的类,用于集成到 Activiti 流程引擎中,提供新的用户选择界面。...

Global site tag (gtag.js) - Google Analytics