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级审批流程如下:

activi java审批流 activiti审批流_赋值

首先我们需要配置一个流程的key 和名称,点击空白处:

activi java审批流 activiti审批流_赋值_02

然后我们选择一个用户活动,并且填写对应参数。

2、FORM_KEY

activi java审批流 activiti审批流_赋值_03

这里的自定义表单其实就是: FORM_KEY , 我们填的是前端路由,页面路径 《 purchase/purchasemanager》,也可以配置成接口路径,用于查询具体任务业务

http://localhost:9001/purchase/purchasemanager?taskid=70072

activi java审批流 activiti审批流_自定义_04

根据页面跳转

3、Agssignee

审批人,还是之前那张图 ,我们这里可以设置变量#{test1} 其实就是 你的审批人。

activi java审批流 activiti审批流_赋值_05

4、互斥/排他网关

activi java审批流 activiti审批流_启动流程_06

5、Sequence flow condition

点击流转线条 可以增加条件 #{agree==true}:

activi java审批流 activiti审批流_赋值_07

四、代码分析

比较重要的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个分支不同条件。 这就完成了一个简单的审批流程~