activities:流程任务管理TaskService

在绘制流程定义模型时,针对节点固定分配办理人进行办理此节点任务。

查询指定办理人或候选人的待办任务

@Autowired
TaskService taskService;
​
@Test
public void getWaitTask() {
    //办理人
    String assignee = "wsy";
    List<Task> list = taskService.createTaskQuery()
            //.taskAssignee(assignee) //指定办理人
            .taskCandidateOrAssigned(assignee) //作为候选人或者是办理人
            .orderByTaskCreateTime()
            .desc()
            .list();
​
    for (Task task : list) {
        System.out.println("流程实例id: " + task.getProcessInstanceId());
        System.out.println("任务id: " + task.getId());
        System.out.println("(节点)任务名称: " + task.getName());
        System.out.println("任务办理人: " + task.getAssignee());
        System.out.println("流程定义id: " + task.getProcessDefinitionId());
    }
}

UEL表达式分配-任务办理人

由于固定分配任务办理人,执行到每一个任务,按照的是绘制的 bpmn 流程定义模型中配置的去分配任务负责人,即每个节点任务都是固定办理人。
也可以使用 UEL 表达式动态分配办理人, UEL(Unified Expression Language)即 统一表达式语言,UEL 是java EE6 规范的一部分。
activiti 支持两种 UEL 表达式: UEL-value 和 UEL-method。

启动流程实例:分配流程定义中的流程变量值(就可以动态的获取到办理人)

public class User {
​
    public User(String username) {
        this.username = username;
    }
​
    private String username;
​
    public String getUsername() {
        return username;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                 '}';
    }
}
@Service("userService")
public class UserService {
​
    /**
     * 返回办理人
     * @return zdx
     */
    public String getUsername() {
        return "ddd";
    }
}
@Service("deptService")
public class DeptService {
​
    /**
     * 通过用户id查询上级领导作为办理人
     * @param userId userId
     * @return wll
     */
    public String findManageByUserId(String userId) {
        System.out.println("DeptService.findManageByUserId 查询userId "+userId+"的上级领导作为办理人");
        return "ccc";
    }
}
@Autowired
TaskService taskService;
​
@Test
public void startProcInstSetAssginessUEL() {
    //流程定义唯一标识key
    String processKey = "leave1";
    //业务侧id
    String businessKey = "9999";
​
    Map<String, Object> variables = new HashMap<>();
    variables.put("assigness1","www");
​
    //User user = new User("ddd");
    Map<String, Object> map = new HashMap<>();
    map.put("username","ddd");
    variables.put("user",map);
    variables.put("userId","aaa");
    //启动流程实例(流程定义id,业务id,流程变量)
    ProcessInstance pi = runtimeService.startProcessInstanceByKey(processKey, businessKey, variables);
    //runtimeService.startProcessInstanceByKey(processKey, variables);  不需要和业务侧绑定
​
    System.out.println("启动流程实例成功:"+pi.getProcessInstanceId());
}

完成动态办理人相关的任务

@Autowired
TaskService taskService;
​
@Test
public void compleatTask(){
    String taskId = "46f3e82f-b75b-11ed-ac7f-38f3abe10e1d";
    // 查询任务,进行处理
    Task task = taskService.createTaskQuery().taskId(taskId)
            .singleResult();
    if (null == task) {
        System.out.println("任务已完成!");
    }
​
    taskService.complete(taskId);
}

TaskListener 任务监听器

流程图绘制模型

public class CustomTaskListener implements TaskListener {
​
    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("任务id:" + delegateTask.getId()
                + ",任务名称" + delegateTask.getName()
                + ",触发事件名称" + delegateTask.getEventName());
        if ("总裁审批".equals(delegateTask.getName()) && "create".equalsIgnoreCase(delegateTask.getEventName())) {
            //当任务创建后指定任务办理人
            delegateTask.setAssignee("tr");
        }
    }
}
重复上面的流程启动以及办理,走到总裁审批之后...控制台打印如下
2023-02-28 20:03:37.018 DEBUG 18804 --- [uire-timer-jobs] o.a.e.i.p.e.T.selectTimerJobsToExecute   : ==> Parameters: 2023-02-28 20:03:35.246(Timestamp), 1(Integer), 0(Integer)
任务id:dac6535e-b75f-11ed-930a-38f3abe10e1d,任务名称总裁审批,触发事件名称create

获取当前任务的下一节点任务信息

@Autowired
TaskService taskService;
@Autowired
RepositoryService repositoryService;
​
@Test
public void getNextNodeInfo() {
    //获取当前任务信息
    String taskId = "fbf6cc06-b816-11ed-a313-38f3abe10e1d";
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    //从当前任务信息中获取此流程定义id
    String definitionId = task.getProcessDefinitionId();
    // 拿到流程定义id后可获取此bpmnModel对象
    BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionId);
    //通过任务定义key,来获取当前节点信息
    FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
    //获取当前节点的连线信息
    List<SequenceFlow> outgoingFlows = ((FlowNode) flowElement).getOutgoingFlows();
    //当前节点的所有下一节点出口
    for (SequenceFlow flow : outgoingFlows) {
        //下一节点的目标元素
        FlowElement element = flow.getTargetFlowElement();
        if (element instanceof UserTask) {
            System.out.println("节点id" + element.getId());
            System.out.println("节点名称" + element.getName());
        }else {
            if (element instanceof EndEvent) {
                break;
            }
        }
    }
}

任务完成后动态设置下一任务办理人

@Autowired
TaskService taskService;
​
@Test
public void completeTaskSetNextAssignee() {
    //查询任务
    String taskId = "fbf6cc06-b816-11ed-a313-38f3abe10e1d";
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    //完成任务
    taskService.complete(taskId);
    //查询下一任务
    List<Task> tasks = taskService.createTaskQuery()
            .processInstanceId(task.getProcessInstanceId())
            .list();
    //设置下一任务办理人
    if (CollectionUtil.isNotEmpty(tasks)) {
        for (Task t : tasks) {
            //分配任务办理人
            taskService.setAssignee(t.getId(), "wll");
        }
    }
}

候选人组任务需求分析和绘制流程图

绘制候选人任务流程图模型

候选任务办理步骤如下:
  1. 查询候选任务

    候选人不能立即办理任务,要先查询指定候选人的待办任务

  2. 拾取任务(claim)

    该任务的所有候选人都能拾取,变成个人任务,对应这个候选人就变成该任务的办理人

    拾取后如果不想办理该业务?

    就是将已经拾取的个人业务归还到组里边

    如何拾取后转接给别人办理任务?

    直接针对任务设置目标办理人

  3. 查询个人任务

    查询方式同个人任务部分,根据assignee查询用户负责的个人任务

  4. 办理任务


启动流程
@Autowired
RuntimeService runtimeService;
​
@Test
public void startProcessInstance() {
    runtimeService.startProcessInstanceByKey("testGroupTask");
}

查询候选任务

@Autowired
TaskService taskService;
​
@Test
public void getGroupTaskList() {
    List<Task> tasks = taskService.createTaskQuery()
            .processDefinitionKey("testGroupTask")
            .taskCandidateUser("wkh") //候选人
            .list();
​
    for (Task task : tasks) {
        System.out.println("任务id:" + task.getId());
        System.out.println("任务名称:" + task.getName());
        System.out.println("办理人:" + task.getAssignee());
    }
}

拾取候选任务(注意:即使拾取任务的办理人不在候选人中,也可以进行拾取成功的所以最好在拾取之前判断时是否为当前任务的候选人>)

@Autowired
TaskService taskService;
​
@Test
public void claimTask() {
    String taskId = "97595c20-b825-11ed-b29c-38f3abe10e1d";
    String userId = "wkhaaa";
    // 注意:即使拾取任务的办理人不在候选人中,也可以进行拾取成功的
    // 所以最好在拾取之前判断时是否为当前任务的候选人
/*    List<IdentityLink> identityLinks = taskService.getIdentityLinksForTask(taskId);
    for (IdentityLink identityLink : identityLinks) {
        System.out.println("候选分组的用户id:" + identityLink.getUserId());
    }*/
    taskService.claim(taskId, userId);
}

任务办理人归还组任务中(直接将办理人设置为null 即归还到组任务中)

@Autowired
TaskService taskService;
​
@Test
public void assigneeToGroupTask() {
    String taskId = "97595c20-b825-11ed-b29c-38f3abe10e1d";
    //办理人
    String assignee = "wkhaaa";
    //查询办理人任务
    Task tasks = taskService.createTaskQuery()
            .processDefinitionKey("testGroupTask")
            .taskAssignee(assignee)
            .singleResult();
    //归还到组任务中
    if (null != tasks) {
        //直接将办理人设置为null 即归还到组任务中
        taskService.setAssignee(taskId,null);
    }
}

转办任务

@Autowired
TaskService taskService;
​
@Test
public void turnTask() {
    String taskId = "97595c20-b825-11ed-b29c-38f3abe10e1d";
    //办理人
    String assignee = "wkh";
    //候选人
    String candidateuser = "zdx";
    //查询办理人任务
    Task tasks = taskService.createTaskQuery()
            .processDefinitionKey("testGroupTask")
            .taskAssignee(assignee)
            .taskId(taskId)
            .singleResult();
​
    //将任务转办各给其他用户
    if (null != tasks) {
        taskService.setAssignee(taskId, candidateuser);
    }
}

任务处理

@Autowired
TaskService taskService;
​
@Test
public void completeTask() {
    String taskId = "97595c20-b825-11ed-b29c-38f3abe10e1d";
    taskService.complete(taskId);
}