Activiti
一、环境准备
最近工作可能用到activiti工作流, 我们先在本地搭建Demo,我是用的若依项目现成代码, 具体地址奉上:
https://gitee.com/shenzhanwang/Spring-activiti?_from=gitee_search
第一步肯定是修改数据库配置, 跑脚本,然后改端口号,启动服务。
二、表结构分析
一共有20多张表, 比较常用重要的表为:
1.act_ru_execution 执行对象表
2.act_ru_task 用户任务表
3.act_hi_actinst 活动节点历史表
4.act_hi_procinst 流程实例历史表
5.act_hi_taskinst 历史任务表
三、图分析
1、流程key
一个2级审批流程如下:
首先我们需要配置一个流程的key 和名称,点击空白处:
然后我们选择一个用户活动,并且填写对应参数。
2、FORM_KEY
这里的自定义表单其实就是: FORM_KEY , 我们填的是前端路由,页面路径 《 purchase/purchasemanager》,也可以配置成接口路径,用于查询具体任务业务
http://localhost:9001/purchase/purchasemanager?taskid=70072
根据页面跳转
3、Agssignee
审批人,还是之前那张图 ,我们这里可以设置变量#{test1} 其实就是 你的审批人。
4、互斥/排他网关
5、Sequence flow condition
点击流转线条 可以增加条件 #{agree==true}:
四、代码分析
比较重要的service:
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
FormService formService;
启动流程:
HashMap<String, Object> variables = new HashMap<>();
variables.put("starter", purchase.getApplyer());
variables.put("purchasemanager", purchase.getPurchasemanager());
variables.put("finance", purchase.getFinance());
variables.put("pay", purchase.getPay());
variables.put("manager", purchase.getManager());
variables.put("money", Double.parseDouble(purchase.getTotal()));
runtimeService.startProcessInstanceByKey("purchase", String.valueOf(purchase.getId()), variables);
具体很多service的方法可以看看这个类:
FlowMonitorController
启动流程自定义测试:
public int test()
{
//int row = meetingMapper.insertMeeting(meeting);
// 启动会议流程
// identityService.setAuthenticatedUserId(meeting.getHost());
HashMap<String, Object> variables = new HashMap<>();
variables.put("host", "host");
variables.put("test1", "admin"); // 变量赋值
variables.put("test2", "admin"); // 变量赋值
// variables.put("people", Arrays.asList(person));
ProcessInstance meeting1 = runtimeService.startProcessInstanceByKey("test2", "36", variables);
return 0;
}
完成具体任务时候可以传参这样走对应分支:
前端代码,传入variables:
// 原来项目变量
var purchaseauditi = document.querySelector("input[name='purchaseauditi']:checked").value;
// 这个变量是我新增的
var agree = document.querySelector("input[name='agree']:checked").value;
后端代码,封装调用接口(网关流向控制案例):
// 在这里的 前端传入 variables中,我们自定义添加了agree这个变量, 控制着流程的走向, 如果这里是agree==true 那就会结合之前的网关走对应的分支
@ApiOperation("办理一个用户任务")
@RequestMapping(value = "/completeTask/{taskId}", method = RequestMethod.POST)
@ResponseBody
public AjaxResult completeTask(@PathVariable("taskId") String taskId, @RequestBody(required=false) Map<String, Object> variables) {
SysUser user = getSysUser();
String username = user.getLoginName();
taskService.setAssignee(taskId, username);
// 查出流程实例id
String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();
if (variables == null) {
taskService.complete(taskId);
} else {
// 添加审批意见
if (variables.get("comment") != null) {
taskService.addComment(taskId, processInstanceId, (String) variables.get("comment"));
variables.remove("comment");
}
taskService.complete(taskId, variables);
}
return AjaxResult.success();
}
}
五、总结
其实就是你在设计流程的时候, 先给流程一个key(流程唯一编码-流程名称), 然后选择一个 用户活动(需要填写你的FormKey和Assignee《审批人变量》), 然后选择一个网关,这里用互斥网关, 我们注入流转条件condition #{agree==true} 这个你可以让前端表单填写,你来输入。 最后2个分支不同条件。 这就完成了一个简单的审批流程~