目录

bpmn指定候选者

可以直接在节点写死候选者,多名候选者之间用逗号隔开

但是常见业务场景中,候选者并不会被写死,而是在节点用UEL表达式,根据业务需求传入候选者

代码通用部分

这里先给出后续代码需要用到的包和我个人封装好的函数

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//创建操作activity的核心对象 ProcessEngine 所有操作都需要用它完成
public ProcessEngine createProcessEngine(){
    //创建ProcessEngineConfiguration
    ProcessEngineConfiguration configuration =ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cgf.xml");
    //通过ProcessEngineConfiguration创建ProcessEngine,此时根据配置文件设置决定是否创建数据库的表或者更新表
    ProcessEngine processEngine =configuration.buildProcessEngine();
    System.out.println("创建完成:"+processEngine);
    return processEngine;
}

启动流程并设置流程变量

依据下图绘制了bpmn并设置好了UEL表达式,其中“创建”节点assignee使用了${assignee},“经理”节点candidate groups使用了${groups}

指定创建申请的责任人assignee为zhangsan,经理节点的候选者为a,b,c

// 启动流程时设置流程变量
@Test
public void startProcessInstance() {
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    // 流程id
    String processDefinitionKey = "duoren";

    // 定义流程变量
    Map<String, Object> variables = new HashMap<String, Object>();
    //候选者们放在数组中
    List<String> usr = new ArrayList<String>();
    usr.add("a");
    usr.add("b");
    usr.add("c");

    variables.put("assignee", "zhangsan");
    variables.put("groups", usr);

    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
    System.out.println(" 流 程 实 例 id:" + processInstance.getProcessInstanceId());
}

查询组任务

当流程实例从创建节点推进到经理节点时,a,b,c三人都可以查询到该流程实例

重点是使用了taskService.createTaskQuery().processDefinitionKey(流程id).taskCandidateGroup(候选人).list(),其中.taskCandidateGroup(候选人)代表查询candidate groups

此时流程实例没有指定责任人assignee,没有人能调用task.complete去推进任务

//根据获选人查询组任务 区别于根据assignee查询个人的所有任务
@Test
public void findGroupTaskList() {
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    // 流程id
    String processDefinitionKey = "duoren";
    // 任务候选人 节点上设置的所有候选人都能看到这个流程实例
    String candidateUser = "b";
    // 创建TaskService
    TaskService taskService = processEngine.getTaskService();
    //查询组任务
    List<Task> list = taskService.createTaskQuery()//
            .processDefinitionKey(processDefinitionKey)//
            .taskCandidateGroup(candidateUser)//根据候选人查询
            .list();
    for (Task task : list) {
        System.out.println("----------------------------");
        System.out.println("流程实例id: " + task.getProcessInstanceId());
        System.out.println("任务id: " + task.getId());
        System.out.println("任务负责人: " + task.getAssignee());
        System.out.println("任务名称: " + task.getName());
    }
}

拾取组任务

核心就是用taskService.claim(任务id, 责任人)将任务的assignee与指定责任人绑定

可以看得出这个函数并不存在鉴权,所以被指定的责任人即便不是当前节点列出的候选人也没问题,因此需要手动实现鉴权

组任务拾取后,该任务已有负责人,此时同处一个流程节点的其他候选人就看不到这个任务了 只有拾取了人物的人可以看到

假设b用户拾取了任务,此时b用户只能根据assignee查询个人的所有任务,看到刚才拾取的任务

@Test
public void claimTask(){
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    TaskService taskService = processEngine.getTaskService();
    //要拾取的任务id
    String taskId = "5002";
    //任务候选人id
    String userId = "b";
    //拾取任务
    //校验该用户有没有拾取任务的资格
    Task task = taskService.createTaskQuery()//
            .taskId(taskId)
            .taskCandidateGroup(userId)//根据候选人查询
            .singleResult();
    if(task!=null){
        taskService.claim(taskId, userId);
        System.out.println("任务拾取成功");
    }
}

附上b用户拾取组任务后,查询b用户的个人待办任务的代码

// 查询当前个人待执行的任务
@Test
public void findPersonalTaskList() {
    //创建ProcessEngine
    ProcessEngine processEngine = createProcessEngine();

    // 任务负责人
    String assignee = "b";
    // 创建TaskService
    TaskService taskService = processEngine.getTaskService();
    //下面的Task类是org.activiti.engine.task
    List<Task> list = taskService.createTaskQuery()
            .processDefinitionKey("duoren")
            .taskAssignee(assignee)
            .list();
    for (Task task : list) {
        System.out.println(" 流 程 实 例 id : " + task.getProcessInstanceId());
        System.out.println("任务id: " + task.getId());
        System.out.println("任务负责人: " + task.getAssignee());
        System.out.println("任务名称: " + task.getName());
    }
}

归还组任务

核心就是用taskService.claim(任务id, 责任人)将任务的assignee设置为null

可以看得出这个函数并不存在鉴权,所以在将任务的责任人设置为null前,需要手动确认当前操作用户是否是任务的责任人

如果用户拾取任务后归还任务 那么其他候选人就又能看到任务并拾取了

@Test
public void setAssigneeToGroupTask() {
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    // 查询任务使用TaskService
    TaskService taskService = processEngine.getTaskService();
    // 当前待办任务id
    String taskId = "5002";
    // 任务负责人
    String userId = "b";
    // 校验userId是否是taskId的负责人,如果是负责人才可以归还组任务
    Task task = taskService.createTaskQuery().taskId(taskId)
            .taskAssignee(userId).singleResult();
    if (task != null) {
        // 如果设置为null,归还组任务,该 任务没有负责人
        taskService.setAssignee(taskId, null);
    }
}

交接组任务

核心就是用taskService.claim(任务id, 责任人)将任务的assignee与另一个用户绑定

可以看得出这个函数并不存在鉴权,所以在将任务的责任人设置为其他用户前,需要手动确认当前操作用户是否是任务的责任人

@Test
public void setAssigneeToCandidateUser() {
    //创建ProcessEngine
    ProcessEngine processEngine =createProcessEngine();

    // 查询任务使用TaskService
    TaskService taskService = processEngine.getTaskService();
    // 当前待办任务
    String taskId = "5002";
    // 任务负责人
    String userId = "b";
    // 校验userId是否是taskId的负责人,如果是负责人才可以归还组任务
    Task task = taskService.createTaskQuery().taskId(taskId)
            .taskAssignee(userId).singleResult();
    if (task != null) {
        // 将此任务交给其它候选人办理该 任务
        String candidateuser = "a";
        taskService.setAssignee(taskId, candidateuser);
    }
}

原文地址:http://www.cnblogs.com/BRSblackshoot/p/16869492.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性