1.流程实例

一个流程实例包含所有的运行节点,可以利用这个对象获取当前流程实例的进度信息。

Activiti流程和业务关系:

 启动流程实例 并添加BusinessKey(业务标识)

流程定义部署在acti后,就可以在系统中通过activiti去管理该流程的执行,执行流程表示流程的一次执行。

比如部署系统出差流程后,入股哦某个用户要申请出差这时就需要执行这个流程,如果另外一个用户也要申请出差则也需要执行该流程,互不影响。

启动流程实例时,指定的businesskey,就会在act_ru_exection#流程实例的执行表中存储businesskey

businesskey:业务标识,主键,业务标识和流程实例一一对应。业务标识来源于业务系统。存储业务标识就是根据业务标识来关联查询业务系统的数据。

比如:出差流程启动一实例,就将出差单id作为业务表示存储到acti表中,将查询acti的流程实例信息就可以获取出差单的id从而关联查询业务系统数据库得到出差单信息。

    /**
     * 添加业务Key到Activiti表
     */
    @Test
    public void addBusinessKey() {
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //启动流程的过程中,添加BussinessKey
        //参数:流程定义的key;businessKey,存出差单的id
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection", "1001");
        //输出
        System.out.println("businessKey=" + instance.getBusinessKey());
    }

挂起,激活流程实例

全部流程实例挂起,将不允许启动新的流程实例,同时该流程定义下所有的流程实例将全部暂停执行。

2.个人任务

分配任务责任人

2.1固定分配

在业务流程建模时指定固定的任务负责人

2.1表达式分配

由于固定分配方式,任务只管一步一步执行,执行到每一个任务将按照bpmn的配置去分配任务负责人。

UEL表达式:activiti使用UEL表达式

编写代码配置负责人

    /**
     * 启动流程实例
     */
    @Test
    public void testStartProcess() {
        //1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取Runtimeservice
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //设定assignee的值,用来替换uel表达式
        HashMap<String, Object> assigneeMap = new HashMap<String, Object>();
        assigneeMap.put("assignee0", "创建人");
        assigneeMap.put("assignee1", "经理");
        assigneeMap.put("assignee2", "总经理");
        assigneeMap.put("assignee3", "财务");
        //3.根据流程定义的id启动流程‘
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection1", assigneeMap);
        //4.输出内容
        System.out.println("流程定义id:" + instance.getProcessDefinitionId());
        System.out.println("流程实例id:" + instance.getId());
        System.out.println("当前活动id:" + instance.getActivityId());
    }

2.3监听器分配

可以使用监听器来完成很多Activiti流程的业务。流程设计时就不需要指定assignee。任务监听器是发生对应的任务相关事件时执行自定义java逻辑或表达式。

Event的选项包含:

Create:任务创建后触发

Assignment:任务分配后触发

Delete:任务完成后触发

All:所有事件发生都触发

创建demo:08-使用监听器设置负责人_哔哩哔哩_bilibili

查询任务

2.4查询任务负责人的待办任务

见入门查询方法。

2.5关联businessKey

需求:在activiti实际应用时,查询代办任务可能要显示出业务系统的相关信息。

比如:查询待审批出差任务列表需要将出差单的日期,出差天数等信息显示。但是这些信息在业务系统中存在,而没有在activiti数据库中,所以无法通过activiti的api查询到出差信息

实现:在查询待办任务时,通过BusinessKey(业务标识)关联查询业务系统的出差单表,查询。

    /**
     * 获取任务负责人待办任务businessKey
     */
    @Test
    public void findProcessInstance() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("testListener")
                .taskAssignee("创建人")
                .singleResult();
        String processDefinitionId = task.getProcessDefinitionId();
        ProcessInstance instance = runtimeService.createProcessInstanceQuery()
                .processDefinitionId(processDefinitionId)
                .singleResult();
        String businessKey = instance.getBusinessKey();
        System.out.println("businessKey=" + businessKey);
    }

办理任务

在实际集中完成前需要校验负责人权限

    /**
     * 办理个人任务
     */
    @Test
    public void completTaskByCharge(){
        String taskId = "1005";
        String assingee = "经理";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        //完成任务前,需校验该负责人可以完成当期任务
        //校验方法:根据任务id和负责人查询当前任务,如果查到该用户有权限,就完成
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .taskAssignee(assingee)
                .singleResult();
        if(task!=null){
            taskService.complete(taskId);
            System.out.println("任务完成");
        }
    }

3.流程变量

3.1流程变量

流程运转需要流程变量,业务系统和acti结合时也需要流程变量,流程变量就是acti在管理工作流时根据管理需要而设置的变量。

比如:出差申请流程流转时如果出差天数大于3天则由总经理审核,否则由人事直接审核,出差天数就可以设置为流程变量,在流程流转中使用。

注意:虽然流程变量中可以存储业务数据可以通过acti的api查询流程变量从而实现查询业务数据,但是不建议这样,因为业务数据查询由业务系统负责,acti设置流程变量是为了流程执行需要而创建。

3.2流程变量类型

如果将pojo存储到流程变量中,必须实现序列化接口serializable,为了防止由于新增字段无法反序列化,需要生成SerialVersionUID。

3.3流程变量作用域

可以是一个流程实例或一个任务。或一个执行实例。

Globa变量

流程变量的默认作用域是流程实例。当一个流程变量的作用域为流程实例时,成为global变量。

注意:Global变量:userId(变量名),创建人(变量值)

3.4流程变量使用方法

1.在属性上使用UEL表达式:可在assignee处设置,比如${assignee}

2.在连线上使用UEL表达式:可在连线上设置,决定流程走向,比如${price<100}

3.5使用Global变量控制流程

需求:员工创建出差单,由部门经理审核通过后出差三天以下由财务直接审批,3天上由总经理审批,再由财务审批。

流程定义:

设置global流程变量:

1.创建pojo对象。

2.启动流程时设置变量

    //启动流程设置流程变量
    @Test
    public void testStartProcess() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        String key = "myEvection2";
        //设置流程变量
        Evection evection = new Evection();
        HashMap<String, Object> variables = new HashMap<String, Object>();
        evection.setNum(2d);  //设置出差日期
        variables.put("evection", evection);  //把流程变量的pojo放入map
        variables.put("assignee0", "创建人");
        variables.put("assignee1", "部门经理");
        variables.put("assignee2", "总经理");
        variables.put("assignee3", "财务");

        ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, variables);
        System.out.println(instance.getId());
    }

3.任务办理时设置变量

注意:通过当前任务设置,需指定当前任务id,如果不存在则抛异常。任务办理时可map设置多个变量。

    //测试任务办理时添加流程变量
    @Test
    public void testCompletTask2() {
        String key = "myEvection2";
        String assignee = "创建人";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //设置流程变量
        Evection evection = new Evection();
        evection.setNum(2d);
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("evection", evection);

        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(assignee)
                .singleResult();
        if (task != null) {
            taskService.complete(task.getId(),map);  //根据任务id完成任务,在完成任务时设置流程变量
        }
    }

4.通过当前流程实例设置:通过流程实例id设置全局变量,该流程实例必须未执行完成。

注意:executionId必须当前未结束流程实例的执行id,通常此id设置流程实例的id也可通过runtimeService.getVariable()获取变量。

    //通过当前流程实例设置
    @Test
    public void setGlobalVariableByExectionId(){
        String exectionId = "";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        Evection evection = new Evection();
        evection.setNum(3d);

        runtimeService.setVariable(exectionId,"evection",evection);  //通过流程实例id设置流程变量
//        runtimeService.setVariable(exectionId, variables);  //一次设置多个变量
    }

5.通过当前任务设置

注意:任务id必须是当前待办id,act_ru_task存在

    //通过当前任务设置
    @Test
    public void setGlobalVariableByTaskId(){
        String taskId = "4102";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        Evection evection = new Evection();
        taskService.setVariable(taskId,"evection",evection);
    }

3.6设置local流程控制

4.组任务

4.1需求:在流程定义在任务节点的assignee固定设置任务负责人,在流程定义时将参与者固定设置在.bpmn文件中,如果临时任务负责人变更则需要修改流程定义,系统可扩展性差。

针对这种情况可以设置多个候选人。

4.2设置任务候选人

4.3组任务办理流程

a.查询组任务

指定候选人,查询该候选人当前待办。候选人不能立即办理。

b.拾取组任务

该组任务的所有候选人都能拾取。将候选人的组任务,变成个人任务。原来候选人就变成了该任务的负责人。

如果拾取后不想办理该任务?需将已经拾个人任务归还组里面,将个人任务变成组任务。

c.查询个人任务

d.办理个人任务

查询组任务

    //查询组任务
    @Test
    public void findGroupTaskList(){
        String key = "testCandidate";
        String candidateUser = "候选人";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidateUser)  //根据候选人查询任务
                .list();
        for (Task task : taskList) {
            System.out.println("流程实例id" + task.getProcessDefinitionId());
            System.out.println("任务id" + task.getId());
            System.out.println("任务负责人" + task.getAssignee());
        }
    }

拾取任务

    //拾取任务
    @Test
    public void claimTask() {
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();
        String taskId = "6001";
        String userId = "候选人";
        //拾取任务,都可以拾取,需校验资格
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .taskCandidateUser(userId)
                .singleResult();
        if (task != null) {
            taskService.claim(taskId, userId);
            System.out.println("拾取成功");
        }
    }

归还任务

    //归还任务
    @Test
    public void assigneeToGroupTask() {
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();
        String taskId = "6001";
        String assignee = "负责人";
        //根据key和负责人查询
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .taskAssignee(assignee)
                .singleResult();
        if (task != null) {
            taskService.setAssignee(taskId, null);
            System.out.println("拾取成功");
        }
    }

任务交接

    //任务交接
    @Test
    public void setAssigneeToCandidateUser() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        String taskId = "6001";
        String userId = "负责人";
        String candidateUser = "其他候选人";
        //校验userId是都是taskid的负责人,如果是负责人才可以归还组任务
        Task task = taskService
                .createTaskQuery()
                .taskId(taskId)
                .taskAssignee(userId)
                .singleResult();
        if (task != null) {
            taskService.setAssignee(taskId, candidateUser);
        }
    }

5.网关

5.1排他网关

5.2并行网关

 并行网关代码测试:08-并行网关流程定义-测试_哔哩哔哩_bilibili

5.3包含网关

包含网关测试:11-包含网关测试_哔哩哔哩_bilibili

5.4事件网关

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐