朋也的博客 » 首页 » 文章
作者:朋也
日期:2019-04-24
类别:activiti学习笔记
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
前言: 前面定义的那个流程图的请假代理人是
user1
部门经理审批代理人是user2
总经理审批代理人是user3
接着上一篇在springboot中启动的那个流程实例, 先启动一个流程
这里模拟一些请假的数据, 在实际项目中这些数据肯定都是存在数据库里的
private List<Map<String, Object>> data = new ArrayList<>();
@Before
public void init() {
for (int i = 0; i < 10; i++) {
Map<String, Object> map = new HashMap<>();
map.put("id", i + 1);
map.put("username", "员工" + i);
map.put("title", "请假" + i);
map.put("day", i);
data.add(map);
}
}
启动流程
链原接文:https://atjiu.github.io/2019/04/24/activiti-query-complete-task/
// spring自动将这些Service都初始化好了,直接使用 `@Autowired` 注解注入即可使用
@Autowired
private RuntimeService runtimeService;
@Test
public void startProcess() {
// 用户1发起了一个请假流程
ProcessInstance instance = runtimeService.startProcessInstanceByKey("AskLeave", "1");
System.out.println("Id: " + instance.getId());
}
查询任务使用的是 taskService
类来查的
用户 员工1
提交了一个请假任务, 提交请假
这个任务的代理人是 user1
, 所以这里用 user1来查询任务
@Autowired
private TaskService taskService;
@Test
public void queryTask() {
List<Task> tasks = taskService.createTaskQuery().taskAssignee("user1")
// 分页查询
// .listPage(firstResult, maxResults)
// 排序
// .orderByTaskCreateTime().desc()
// 如果你知道这个查询是一条记录的话, 可以使用 .singleResult() 方法来获取单一的记录
// .singleResult()
.list();
for (Task task : tasks) {
System.out.println(task.toString()); // Task[id=2505, name=提交请假]
}
}
上面查询到user1有一个任务, 任务的id是 2505, 然后就可以来完成任务了
@Test
public void completeTask() {
taskService.complete("2505");
}
调用一个方法就可以处理任务了, 是不是很简单 : )
user1完成任务后, 任务就走到下一个流程去了, 下一个流程是 部门经理审批
代理人是 user2, 这时候就可以用 user2来查询任务了,换句话说就是任务已经转到 user2 了, 后面的流程大致就是
user2查询任务 -> user2完成任务 -> user3查询任务 -> user3完成任务 -> 员工1请假流程结束
当代理人在处理任务的时候, 可以增加一些批注, 添加批注的方法如下
原链接文:https://atjiu.github.io/2019/04/24/activiti-query-complete-task/
@Test
public void completeTask() {
// 通过查询可以拿到user2的任务id是7502
String taskId = "7502";
// 选通过taskId查询任务
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
// 从任务里拿到流程实例id
String processInstanceId = task.getProcessInstanceId();
// 批注信息
String message = "同意";
Authentication.setAuthenticatedUserId("user2");
// 给任务添加批注
taskService.addComment(taskId, processInstanceId, message);
// 处理任务
taskService.complete(taskId);
}
注意: 在设置这个批注是谁批的时候, 这个用户名是通过 Authentication.setAuthenticatedUserId("user2");
设置的, 这样做的目的是为了线程安全, 挺奇葩的
查询批注要从当前流程的实例里查, 因为一个任务在代理人处理完后, 转到下一个代理人那时, 这个任务的id就变了, 虽然可以从历史记录里查, 但麻烦, 直接使用任务的流程实例id来查简单,方便, 可以获取当前请假流程的所有批注信息
@Test
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("-------------------------------");
}
}
前面说到了项目本身的业务逻辑跟activiti的关联靠的是 BusinessKey
来关联的, 那在流程执行的过程中怎么拿到这个数据呢?
可以从当前任务所属的流程实例里拿
@Test
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 状态
这一篇总结了任务的查询和处理, 回头想一下就知道, 现在代理人还写的是死数据, 这样固然不好, 下一篇来改成活的
另外, 本篇介绍了任务的查询方法, 其它的比如流程实例的获取
流程定义的获取
历史记录的获取
等查询方法都差不多, 自己写写代码就明白怎么用了, 主要还是要明白它们的执行顺序和表之间的关联关系
写博客不易,转载请保留原文链接,谢谢!