Activiti6-学习笔记(02)-工作流程
启动一个请假流程
// spring自动将这些Service都初始化好了,直接使用 @Autowired 注解注入即可使用
@Autowired
private RuntimeService runtimeService;
@Autowired
private IdentityService identityService;
public void startProcess() {
// 在画流程图的时候,给流程图起的名字
String processDefinitionKey = "leave";
// 业务逻辑中的id
String businessKey = "1";
String applyUserId = "user1";
// 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
identityService.setAuthenticatedUserId(applyUserId);
// user1发起了一个请假流程
ProcessInstance instance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey);
}
查询任务
查询任务使用的是 taskService 类来查的
用户user1提交了一个请假任务, 需要部门领导审批,审批这个任务的代理人是 user2, 所以这里用 user2来查询任务
@Autowired
private TaskService taskService;
public void queryTask() {
List<Task> tasks = taskService
.createTaskQuery()
.taskAssignee("user2")
// 分页查询
// .listPage(firstResult, maxResults)
// 排序
// .orderByTaskCreateTime().desc()
// 如果你知道这个查询是一条记录的话, 可以使用 .singleResult() 方法来获取单一的记录
// .singleResult()
.list();
for (Task task : tasks) {
System.out.println(task.toString()); // Task[id=2505, name=提交请假]
}
}
处理任务
上面查询到user1有一个任务, 任务的id是 2505, 然后就可以来完成任务了
调用一个方法就可以处理任务了, 是不是很简单 : )
user2完成任务后, 任务就走到下一个流程去了, 下一个流程是 人事审批 代理人是 user3, 这时候就可以用 user3来查询任务了,换句话说就是任务已经转到 user3 了,后面的流程大致就是
user3查询任务 -> user3完成任务 -> user1请假流程结束
批注
当代理人在处理任务的时候, 可以增加一些批注, 添加批注的方法如下
public void completeTask() {
// 通过查询可以拿到user3的任务id是7502
String taskId = "7502";
// 选通过taskId查询任务
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
// 从任务里拿到流程实例id
String processInstanceId = task.getProcessInstanceId();
// 批注信息
String comment = "同意";
Authentication.setAuthenticatedUserId("user3");
// 给任务添加批注
taskService.addComment(taskId, processInstanceId, comment);
// 处理任务
taskService.complete(taskId);
}
注意: 在设置这个批注是谁批的时候, 这个用户名是通过 identityService.setAuthenticatedUserId(ShiroUtils.getLoginName());
设置的, 这样做的目的是为了线程安全, 挺奇葩的
查询批注
查询批注要从当前流程的实例里查, 因为一个任务在代理人处理完后, 转到下一个代理人那时, 这个任务的id就变了, 虽然可以从历史记录里查, 但麻烦, 直接使用任务的流程实例id来查简单,方便, 可以获取当前请假流程的所有批注信息
public void queryTask() {
List<Task> tasks = taskService.createTaskQuery().taskAssignee("user3")
// 分页查询
// .listPage(firstResult, maxResults)
// 排序
// .orderByTaskCreateTime().desc()
.list();
for (Task task : tasks) {
List<Comment> comments = taskService.getProcessInstanceComments(task.getProcessInstanceId());
System.out.println("任务ID: " + task.getId());
for (Comment comment : comments) {
System.out.println("批注人: " + comment.getUserId());
System.out.println("批注信息: " + comment.getFullMessage());
System.out.println("批注时间: " + comment.getTime());
}
System.out.println("-------------------------------");
}
}
怎么获取BusinessKey
前面说到了项目本身的业务逻辑跟activiti的关联靠的是 BusinessKey 来关联的, 那在流程执行的过程中怎么拿到这个数据呢?
可以从当前任务所属的流程实例里拿
public void getBusinessKey() {
// user2 处理了任务, 任务转到 user3 任务id也变成了 10003, 可以使用user3来查询任务获取到
String taskId = "10003";
// 通过任务id来查询任务
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
// 通过任务里的流程实例id获取当前任务所属的流程实例信息
ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(task
.getProcessInstanceId()).singleResult();
// 从流程实例信息中拿到 businessKey
String businessKey = instance.getBusinessKey();
System.out.println("businessKey: " + businessKey);
}
注意: 获取流程实例用的是 runtimeService , 因为流程没有结束一直都是 runtime 状态
总结
本篇介绍了任务的查询方法, 其它的比如流程实例的获取、流程定义的获取、历史记录的获取等查询方法都差不多, 自己写写代码就明白怎么用了, 主要还是要明白它们的执行顺序和表之间的关联关系。