zoukankan      html  css  js  c++  java
  • 2021全网最全Activiti7教程03(Activiti7基本操作-欢迎收藏)

      Activiti作为工作流的首选,希望本系列文章能给大家带来帮助

    全网最详细Activiti系列文章,强烈建议收藏加关注哦!

    Activiti基本操作讲解

    1 流程的部署

      将上面在设计器中定义的流程部署到activiti数据库中,就是我们讲的流程部署。
    通过调用Activiti的api将流程定义的bpmn和png两个文件一个一个添加部署到activiti中,还可以将两个文件打车zip包部署。

    1.1 单个文件部署

      分别将bpmn文件和png图片分别部署

        /**
         * 实现文件的单个部署
         */
        @Test
        public void test03(){
            // 1.获取ProcessEngine对象
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 2.获取RepositoryService进行部署操作
            RepositoryService service = engine.getRepositoryService();
            // 3.使用RepositoryService进行部署操作
            Deployment deploy = service.createDeployment()
                    .addClasspathResource("bpmn/evection.bpmn") // 添加bpmn资源
                    .addClasspathResource("bpmn/evection.png") // 添加png资源
                    .name("出差申请流程")
                    .deploy();// 部署流程
            // 4.输出流程部署的信息
            System.out.println("流程部署的id:" + deploy.getId());
            System.out.println("流程部署的名称:" + deploy.getName());
        }
    

      日志中查看到相关的输出信息
    在这里插入图片描述

    1.2 部署zip文件

      将bpmn文件和png文件两个打包为一个zip文件,统一上传
    在这里插入图片描述

        /**
         * 通过一个zip文件来部署操作
         */
        @Test
        public void test04(){
            // 定义zip文件的输入流
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/evection.zip");
            // 对 inputStream 做装饰
            ZipInputStream zipInputStream = new ZipInputStream(inputStream);
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = engine.getRepositoryService();
            Deployment deploy = repositoryService.createDeployment()
                    .addZipInputStream(zipInputStream)
                    .name("出差申请流程")
                    .deploy();
            // 4.输出流程部署的信息
            System.out.println("流程部署的id:" + deploy.getId());
            System.out.println("流程部署的名称:" + deploy.getName());
        }
    
    

      上传后的数据库中的数据和单个文件上传其实是一样的。

    1.3 操作数据表

      流程定义部署后操作activiti中的三张表

      act_re_deployment: 流程定义部署表,每部署一次就增加一条记录
    在这里插入图片描述
      act_re_procdef :流程定义表,部署每个新的流程定义都会在这张表中增加一条记录

    在这里插入图片描述
      act_ge_bytearray :流程资源表,流程部署的 bpmn文件和png图片会保存在该表中

    在这里插入图片描述

    2 启动流程实例

      流程定义部署在Activiti后就可以通过工作流管理业务流程,也就是说上边部署的出差申请流程可以使用了。
      针对该流程,启动一个流程表示发起一个新的出差申请单,这就相当于Java类和Java对象的关系,类定义好了后需要new创建一个对象使用,当然可以new出多个对象来,对于出差申请流程,张三可以发起一个出差申请单需要启动一个流程实例。

        /**
         * 启动一个流程实例
         */
        @Test
        public void test05(){
            // 1.创建ProcessEngine对象
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 2.获取RuntimeService对象
            RuntimeService runtimeService = engine.getRuntimeService();
            // 3.根据流程定义的id启动流程
            String id= "evection";
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(id);
            // 4.输出相关的流程实例信息
            System.out.println("流程定义的ID:" + processInstance.getProcessDefinitionId());
            System.out.println("流程实例的ID:" + processInstance.getId());
            System.out.println("当前活动的ID:" + processInstance.getActivityId());
        }
    

    输出内容:
    在这里插入图片描述

    启动流程实例涉及到的表结构

    act_hi_actinst 流程实例执行历史
    act_hi_identitylink 流程的参与用户的历史信息
    act_hi_procinst 流程实例历史信息
    act_hi_taskinst 流程任务历史信息
    act_ru_execution 流程执行信息
    act_ru_identitylink 流程的参与用户信息
    act_ru_task 任务信息

    3 任务查找

      流程启动后,任务的负责人就可以查询自己当前能够处理的任务了,查询出来的任务都是当前用户的待办任务

        /**
         * 任务查询
         */
        @Test
        public void test06(){
            String assignee ="zhansan";
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 任务查询 需要获取一个 TaskService 对象
            TaskService taskService = engine.getTaskService();
            // 根据流程的key和任务负责人 查询任务
            List<Task> list = taskService.createTaskQuery()
                    .processDefinitionKey("evection")
                    .taskAssignee(assignee)
                    .list();
            // 输出当前用户具有的任务
            for (Task task : list) {
                System.out.println("流程实例id:" + task.getProcessInstanceId());
                System.out.println("任务id:" + task.getId());
                System.out.println("任务负责人:" + task.getAssignee());
                System.out.println("任务名称:" + task.getName());
            }
        }
    
    

    输出结果
    在这里插入图片描述

    4 流程任务处理

      任务负责人查询出来了待办的人,选择任务进行处理,完成任务

        /**
         * 流程任务的处理
         */
        @Test
        public void test07(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            TaskService taskService = engine.getTaskService();
            Task task = taskService.createTaskQuery()
                    .processDefinitionKey("evection")
                    .taskAssignee("zhansan")
                    .singleResult();
            // 完成任务
            taskService.complete(task.getId());
        }
    

      zhangsan处理了这个操作后,流程就流转到了 lisi处
    在这里插入图片描述

      然后就是不同的用户登录,然后查询任务处理任务,直到任务流程走完。

    5 流程定义的查询

      查询流程相关的信息,包括流程的定义,流程的部署,流程定义的版本

        /**
         * 查询流程的定义
         */
        @Test
        public void test08(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = engine.getRepositoryService();
            // 获取一个 ProcessDefinitionQuery对象 用来查询操作
            ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
            List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("evection")
                    .orderByProcessDefinitionVersion() // 安装版本排序
                    .desc() // 倒序
                    .list();
            // 输出流程定义的信息
            for (ProcessDefinition processDefinition : list) {
                System.out.println("流程定义的ID:" + processDefinition.getId());
                System.out.println("流程定义的name:" + processDefinition.getName());
                System.out.println("流程定义的key:" + processDefinition.getKey());
                System.out.println("流程定义的version:" + processDefinition.getVersion());
                System.out.println("流程部署的id:" + processDefinition.getDeploymentId());
            }
        }
    

    输出结果

    流程定义的ID:evection:1:12504
    流程定义的name:出差申请单
    流程定义的key:evection
    流程定义的version:1
    流程部署的id:12501
    

    6 流程的删除

        /**
         * 删除流程
         */
        @Test
        public void test09(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = engine.getRepositoryService();
            // 删除流程定义,如果该流程定义已经有了流程实例启动则删除时报错
            repositoryService.deleteDeployment("12501");
            // 设置为TRUE 级联删除流程定义,及时流程有实例启动,也可以删除,设置为false 非级联删除操作。
            //repositoryService.deleteDeployment("12501",true);
        }
    

    注意:项目开发中级联删除操作的权限一般只开发给超级管理员使用。

    7 流程资源的下载

      现在我们的流程资源文件已经上传到了数据库中,如果其他用户想要查看这些资源,可以从数据库中把这些资源下载到本地。

    解决方案:

    1. jdbc对blob类型处理clob类型数据读取出来就可以了。
    2. 使用activiti的api来实现操作。

    使用activiti的api来操作我们需要添加commons-io的依赖

            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.6</version>
            </dependency>
    

    实现代码

        /**
         * 读取数据库中的资源文件
         */
        @Test
        public void test10() throws Exception{
            // 1.得到ProcessEngine对象
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 2.获取RepositoryService对象
            RepositoryService repositoryService = engine.getRepositoryService();
            // 3.得到查询器
            ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionKey("evection")
                    .singleResult();
            // 4.获取流程部署的id
            String deploymentId = definition.getDeploymentId();
            // 5.通过repositoryService对象的相关方法 来获取图片信息和bpmn信息
            // png图片
            InputStream pngInput = repositoryService
                    .getResourceAsStream(deploymentId, definition.getDiagramResourceName());
            // bpmn 文件的流
            InputStream bpmnInput = repositoryService
                    .getResourceAsStream(deploymentId, definition.getResourceName());
            // 6.文件的保存
            File filePng = new File("d:/evection.png");
            File fileBpmn = new File("d:/evection.bpmn");
            OutputStream pngOut = new FileOutputStream(filePng);
            OutputStream bpmnOut = new FileOutputStream(fileBpmn);
    
            IOUtils.copy(pngInput,pngOut);
            IOUtils.copy(bpmnInput,bpmnOut);
    
            pngInput.close();
            pngOut.close();
            bpmnInput.close();
            bpmnOut.close();
        }
    

    8 流程历史信息查看

      即使流程定义已经被删除了,流程执行的实例信息通过前面的分析,依然保存在Activiti的act_hi_* 的相关表结构中,所以我们还是可以查询流程的执行的历史信息,可以通过HistoryService来查看

        /**
         * 流程历史信息查看
         */
        @Test
        public void test11(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 查看历史信息我们需要通过 HistoryService来实现
            HistoryService historyService = engine.getHistoryService();
            // 获取 actinst 表的查询对象
            HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
            instanceQuery.processDefinitionId("evection:1:12504");
            instanceQuery.orderByHistoricActivityInstanceStartTime().desc();
            List<HistoricActivityInstance> list = instanceQuery.list();
            // 输出查询的结果
            for (HistoricActivityInstance hi : list) {
                System.out.println(hi.getActivityId());
                System.out.println(hi.getActivityName());
                System.out.println(hi.getActivityType());
                System.out.println(hi.getAssignee());
                System.out.println(hi.getProcessDefinitionId());
                System.out.println(hi.getProcessInstanceId());
                System.out.println("-----------------------");
            }
        }
    

    输出结果

    usertask3
    总经理审批
    userTask
    wangwu
    evection:1:12504
    15001
    -----------------------
    usertask2
    经理审批
    userTask
    lisi
    evection:1:12504
    15001
    -----------------------
    usertask1
    创建请假单
    userTask
    zhansan
    evection:1:12504
    15001
    -----------------------
    startevent1
    Start
    startEvent
    null
    evection:1:12504
    15001
    -----------------------
    

    Activiti的基本操作就介绍到这儿,下篇开始给大家讲解如何具体的来使用。欢迎关注点赞加收藏哦 V_V

  • 相关阅读:
    JIRA Activity Stream连接到FishEye时路径不对
    职业分析
    Doublechecked locking解析
    Wireshark基本介绍和学习TCP三次握手
    插入排序算法
    Event.observe
    前端开发工程师如何在2013年里提升自己
    addEventListener(转)
    最好的HTML 5编码教程和参考手册分享
    XSRF 的攻击与防范
  • 原文地址:https://www.cnblogs.com/dengpengbo/p/15142930.html
Copyright © 2011-2022 走看看