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设置下一个节点的审批人
activiti 选人的实现的更多相关文章
- Activiti流程编辑器针对自定义用户角色表优化改造
本文目的: 针对自定义的用户.角色表,对Activiti的在线流程设计器进行优化改造,使之能直接在图形界面上完成对节点办理人.候选人.候选组的配置,不需要先去查数据库中的用户ID.角色ID等信息再填入 ...
- 流程开发Activiti 与SpringMVC整合实例
流程(Activiti) 流程是完成一系列有序动作的概述.每一个节点动作的结果将对后面的具体操作步骤产生影响.信息化系统中流程的功能完全等同于纸上办公的层级审批,尤其在oa系统中各类电子流提现较为明显 ...
- activiti工作流的web流程设计器整合视频教程 SSM和独立部署
本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流 ...
- activiti工作流的web流程设计器整合视频教程 SSM 和 独立部署
本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流 ...
- 文档分享-Activiti 5.16 用户手册
今天在翻看工作流相关的网页的时候,在开源中国上http://www.oschina.net/question/915507_149175发现activiti的中文文档:http://www.mossl ...
- 1. Activiti 运行时表信息总结
Activiti的后台是有数据库的支持,所有的表都以ACT_开头. 第二部分是表示表的用途的两个字母标识. 用途也和服务的API对应. ACT_RE_*: 'RE'表示repository. 这个前缀 ...
- Activiti学习(二)数据表结构
Activiti工作流引擎数据库表结构 数据库表的命名 Acitiviti数据库中表的命名都是以ACT_开头的.第二部分是一个两个字符用例表的标识.此用例大体与服务API是匹配的. l ...
- Activiti学习(一) 环境搭建
原料:Activiti5.4 MyEclipse 10 1.先将activiti文件夹放置myeclipse的安装目录dropins文件夹下2.将activiti文件夹里activiti.link中 ...
- Activiti工作流学习(三)Activiti工作流与spring集成
一.前言 前面Activiti工作流的学习,说明了Activiti的基本应用,在我们开发中可以根据实际的业务参考Activiti的API去更好的理解以及巩固.我们实际的开发中我们基本上都使用sprin ...
随机推荐
- BZOJ1041:[HAOI2008]圆上的整点(数论)
Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. Input 只有一个正整数n,n<=2000 000 000 Output 整点个数 Samp ...
- ucml 连接虚字段
- 为什么express中打开服务端只用listen即可
为什么express中打开服务端只用listen即可:http.createServer(app).listen()与app.listen()的区别 写法一: var app = r ...
- Bug 14143011 : ORA-19606: CANNOT COPY OR RESTORE TO SNAPSHOT CONTROL FILE
Bug 14143011 : ORA-19606: CANNOT COPY OR RESTORE TO SNAPSHOT CONTROL FILE [oracle@test]$ tail -f rma ...
- 3150luogu洛谷
若说代码 那真的是很水 但是 思想却有点意思 这道题是洛谷博弈论专题的第一道入门题, 然而刚开始我是不会做的, 毕竟是道入门题, 我博弈论还没入门呢. 这道题的做法就是: 如果m为偶数, 那么先手赢( ...
- docker数据卷管理及网络基础配置
数据卷 数据卷容器 数据卷迁移数据 端口映射 容器间通信 数据卷的管理 当需要查看容器内应用产生的数据或者把容器内数据备份及多个容器数据共享.有两种方式,数据卷以及数据卷容器. 数据卷 数据卷是一个可 ...
- struts2中ajax的使用
前面写过原生js实现ajax的博客,但是用起来不是太方便,jquery对原生的js进行了很好的封装,使用起来也更简单:但是在项目中使用了struts2,处理ajax却又不同,花了几天时间研究,终于解决 ...
- LeetCode202:Happy Number 。C#版,在vs2010中通过,leetcode中Wrong Answer
static List<int> nums = new List<int>(); public static bool IsHappy(int n) { int newint ...
- Oracle ORA-01940: 无法删除当前连接的用户
当我们要删除一个oracle的用户时,如果有其他人连接到数据库则会报以下错误: ORA-01940: 无法删除当前连接的用户 处理办法就是:将连接到当前用户的session给kill掉. 处理步骤如下 ...
- Luogu P1337 [JSOI2004]平衡点 / 吊打XXX
一道入门模拟退火的经典题,还是很考验RP的 首先我们发现神TM这道题又和物理扯上了关系,其实是一道求广义费马点的题目 首先我们可以根据物理知识得到,当系统处于平衡状态时,系统的总能量最小 又此时系统的 ...