• Activiti进阶


    1.流程实例

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

    Activiti流程和业务关系:

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

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

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

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

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

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

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

    挂起,激活流程实例

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

    2.个人任务

    分配任务责任人

    2.1固定分配

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

    2.1表达式分配

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

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

    编写代码配置负责人

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

    2.3监听器分配

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

    Event的选项包含:

    Create:任务创建后触发

    Assignment:任务分配后触发

    Delete:任务完成后触发

    All:所有事件发生都触发

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

    查询任务

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

    见入门查询方法。

    2.5关联businessKey

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

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

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

    1. /**
    2. * 获取任务负责人待办任务businessKey
    3. */
    4. @Test
    5. public void findProcessInstance() {
    6. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    7. TaskService taskService = processEngine.getTaskService();
    8. RuntimeService runtimeService = processEngine.getRuntimeService();
    9. Task task = taskService.createTaskQuery()
    10. .processDefinitionKey("testListener")
    11. .taskAssignee("创建人")
    12. .singleResult();
    13. String processDefinitionId = task.getProcessDefinitionId();
    14. ProcessInstance instance = runtimeService.createProcessInstanceQuery()
    15. .processDefinitionId(processDefinitionId)
    16. .singleResult();
    17. String businessKey = instance.getBusinessKey();
    18. System.out.println("businessKey=" + businessKey);
    19. }

    办理任务

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

    1. /**
    2. * 办理个人任务
    3. */
    4. @Test
    5. public void completTaskByCharge(){
    6. String taskId = "1005";
    7. String assingee = "经理";
    8. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    9. TaskService taskService = processEngine.getTaskService();
    10. //完成任务前,需校验该负责人可以完成当期任务
    11. //校验方法:根据任务id和负责人查询当前任务,如果查到该用户有权限,就完成
    12. Task task = taskService.createTaskQuery()
    13. .taskId(taskId)
    14. .taskAssignee(assingee)
    15. .singleResult();
    16. if(task!=null){
    17. taskService.complete(taskId);
    18. System.out.println("任务完成");
    19. }
    20. }

    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.启动流程时设置变量

    1. //启动流程设置流程变量
    2. @Test
    3. public void testStartProcess() {
    4. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    5. RuntimeService runtimeService = processEngine.getRuntimeService();
    6. String key = "myEvection2";
    7. //设置流程变量
    8. Evection evection = new Evection();
    9. HashMap variables = new HashMap();
    10. evection.setNum(2d); //设置出差日期
    11. variables.put("evection", evection); //把流程变量的pojo放入map
    12. variables.put("assignee0", "创建人");
    13. variables.put("assignee1", "部门经理");
    14. variables.put("assignee2", "总经理");
    15. variables.put("assignee3", "财务");
    16. ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, variables);
    17. System.out.println(instance.getId());
    18. }

    3.任务办理时设置变量

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

    1. //测试任务办理时添加流程变量
    2. @Test
    3. public void testCompletTask2() {
    4. String key = "myEvection2";
    5. String assignee = "创建人";
    6. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    7. //设置流程变量
    8. Evection evection = new Evection();
    9. evection.setNum(2d);
    10. HashMap map = new HashMap();
    11. map.put("evection", evection);
    12. TaskService taskService = processEngine.getTaskService();
    13. Task task = taskService.createTaskQuery()
    14. .processDefinitionKey(key)
    15. .taskAssignee(assignee)
    16. .singleResult();
    17. if (task != null) {
    18. taskService.complete(task.getId(),map); //根据任务id完成任务,在完成任务时设置流程变量
    19. }
    20. }

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

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

    1. //通过当前流程实例设置
    2. @Test
    3. public void setGlobalVariableByExectionId(){
    4. String exectionId = "";
    5. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    6. RuntimeService runtimeService = processEngine.getRuntimeService();
    7. Evection evection = new Evection();
    8. evection.setNum(3d);
    9. runtimeService.setVariable(exectionId,"evection",evection); //通过流程实例id设置流程变量
    10. // runtimeService.setVariable(exectionId, variables); //一次设置多个变量
    11. }

    5.通过当前任务设置

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

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

    3.6设置local流程控制

    4.组任务

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

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

    4.2设置任务候选人

    4.3组任务办理流程

    a.查询组任务

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

    b.拾取组任务

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

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

    c.查询个人任务

    d.办理个人任务

    查询组任务

    1. //查询组任务
    2. @Test
    3. public void findGroupTaskList(){
    4. String key = "testCandidate";
    5. String candidateUser = "候选人";
    6. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    7. TaskService taskService = processEngine.getTaskService();
    8. List taskList = taskService.createTaskQuery()
    9. .processDefinitionKey(key)
    10. .taskCandidateUser(candidateUser) //根据候选人查询任务
    11. .list();
    12. for (Task task : taskList) {
    13. System.out.println("流程实例id" + task.getProcessDefinitionId());
    14. System.out.println("任务id" + task.getId());
    15. System.out.println("任务负责人" + task.getAssignee());
    16. }
    17. }

    拾取任务

    1. //拾取任务
    2. @Test
    3. public void claimTask() {
    4. ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
    5. TaskService taskService = defaultProcessEngine.getTaskService();
    6. String taskId = "6001";
    7. String userId = "候选人";
    8. //拾取任务,都可以拾取,需校验资格
    9. Task task = taskService.createTaskQuery()
    10. .taskId(taskId)
    11. .taskCandidateUser(userId)
    12. .singleResult();
    13. if (task != null) {
    14. taskService.claim(taskId, userId);
    15. System.out.println("拾取成功");
    16. }
    17. }

    归还任务

    1. //归还任务
    2. @Test
    3. public void assigneeToGroupTask() {
    4. ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
    5. TaskService taskService = defaultProcessEngine.getTaskService();
    6. String taskId = "6001";
    7. String assignee = "负责人";
    8. //根据key和负责人查询
    9. Task task = taskService.createTaskQuery()
    10. .taskId(taskId)
    11. .taskAssignee(assignee)
    12. .singleResult();
    13. if (task != null) {
    14. taskService.setAssignee(taskId, null);
    15. System.out.println("拾取成功");
    16. }
    17. }

    任务交接

    1. //任务交接
    2. @Test
    3. public void setAssigneeToCandidateUser() {
    4. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    5. TaskService taskService = processEngine.getTaskService();
    6. String taskId = "6001";
    7. String userId = "负责人";
    8. String candidateUser = "其他候选人";
    9. //校验userId是都是taskid的负责人,如果是负责人才可以归还组任务
    10. Task task = taskService
    11. .createTaskQuery()
    12. .taskId(taskId)
    13. .taskAssignee(userId)
    14. .singleResult();
    15. if (task != null) {
    16. taskService.setAssignee(taskId, candidateUser);
    17. }
    18. }

    5.网关

    5.1排他网关

    5.2并行网关

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

    5.3包含网关

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

    5.4事件网关

  • 相关阅读:
    TextRCNN、TextCNN、RNN
    Pytorch总结四之 多层感知机原理及简洁实现
    JS-谈谈你所理解的闭包
    全网最详细单细胞保姆级分析教程(二) --- 多样本整合
    如何使用 Node.js 发送电子邮件全解和相关工具推荐
    【一、定制搭建-Arm平台的QT交叉编译环境】
    【QED】血压高的天依
    01背包问题
    django表单的使用说明
    MySQL基础十八章
  • 原文地址:https://blog.csdn.net/xy294636185/article/details/126202988