【2023最新Activiti7全网最全】3、Activiti7基本操作

2023-05-16

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 流程资源的下载 

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

解决方案:

jdbc对blob类型处理clob类型数据读取出来就可以了。
使用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的基本操作就介绍到这儿,下篇开始给大家讲解如何具体的来使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【2023最新Activiti7全网最全】3、Activiti7基本操作 的相关文章

  • VSCode使用Remote VSCode插件进行远端文件同步

    写在前面 最近在云端申请了服务器进行DL训练 xff0c 使用ssh的方式进行远端的登陆 xff0c 但是两端的代码同步是一个比较大的问题 xff0c 当然 xff0c 最笨的方法可以双端走git的方式进行 xff0c 但是其实这样也好麻烦
  • lin通信过程的理解

    uart接收和发送消息时 xff0c 都会产生中断 xff0c 即产生中断信号 xff0c 运行一次中断服务函数 中断函数中根据寄存器的标志位 xff0c 首先判断是否收到头部报文 xff0c 再 根据PID判断是lin传送还是lin接受
  • ESKF(error-state Kalman Filter)总结

    写在前面 前段时间看了一下ESKF的相关知识 xff0c VIO中 xff08 VINS xff09 用的还是挺多的 xff0c 特此总结 先验知识 四元数 四元数的基本表示形式 xff0c 这个还是蛮重要的 xff0c 主要有以下几种表示
  • AI-IMU Dead-Reckoning论文总结

    AI IMU Dead Reckoning Martin 论文出处 论文 xff1a https arxiv org abs 1904 06064 代码 xff1a https github com mbrossar ai imu dr 整
  • Unity VR游戏开发干货教程:优化VR体验

    简介 对于VR应用来说 xff0c 如果想要让用户获得好的用户体验 xff0c 特别是免除恶心眩晕的困扰 xff0c 在VR开发中进行优化是必不可少的 xff0c 惟其如此才能达到我们期望的游戏运行帧速 和其它平台上的开发不同 xff0c
  • kali-linux docker桌面版部署

    Dockerfile 构建镜像参考 kali desktop kali docker 桌面版Dockerfile 部署方式 docker run privileged name kali desktop p 5901 5901 p 6080
  • C语言isalpha函数介绍、示例和实现

    文章目录 1 包含头文件2 函数声明3 功能说明4 示例5 自定义的isalpha函数的实现方法6 获取视频教程7 版权声明 isalpha函数用于判断字符是否为字母 xff08 a z和A Z xff09 在本文中 xff0c 我们先来介
  • C语言isalnum函数介绍、示例和实现

    文章目录 1 包含头文件2 函数声明3 功能说明4 示例5 自定义的isalnum函数的实现方法6 获取视频教程7 版权声明 C语言isalnum函数用于判断字符是否为字母 xff08 a z和A Z xff09 或数字 xff08 0 9
  • 企业对C/C++程序员的技能要求

    一个人应该具备对事物的思考能力 xff0c 否则容易被忽悠 对大部分未入门或刚入门的菜鸟来说 xff0c 很难搞明白C语言能做什么和C程序员在做什么这两个问题 如果你打算种菜 xff0c 必须先了解行情 xff08 包括销量和价钱 xff0
  • HBase详解(对hbase集群搭建、读写流程、hbase的javaApi等细致入微的讲解与保姆级的图解)

    学HBase的意义是什么 我本想用MySQL来与HBase作比较 xff0c 但发现他们两者毫无可比性 xff0c 因为两者运用领域不同 xff0c 各自有各自的优点 xff0c 就好比爬山穿登山鞋 xff0c 潜水穿脚蹼一般 一门技术的兴
  • 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2” 原因

    使用VS2012版本引用外部的lib进行编译时候提示 xff1a 1 gt libprotobuf lib common obj error LNK2038 检测到 ITERATOR DEBUG LEVEL 的不匹配项 值 0 不匹配值 2
  • 写给大侄女

    老姑从你上高中开始 xff0c 就想写点东西给大侄女看 xff0c 不过老姑理科出身 xff0c 文笔比较差 不知道该不该提你在学校看手机的事情 xff0c 老姑没有责备你的意思 xff0c 只是和你探讨一下 xff0c 毕竟谁没有年轻的时
  • centos安装lspci工具

    背景 由于centos6 3迷你安装版上没有带lspci工具 在定制内核时 无法用此工具查询硬件相关信息 具体步骤如下 1 下载 pci包 xff1a http www kernel org pub software utils pciut
  • 软件性能测试方法论

    软件性能测试过程详解与案例分析 xff08 段念 编著 xff09 学习笔记三 1 SEI负载测试计划过程 SEI load Testing Planning Process是一个关注于负载测试计划的方法 xff0c 其目标是产生 清晰 易
  • 2011年总结&2012年展望

    再有几天就2012了 xff0c 工作三年多了 xff0c 之前也没写过总结 xff0c 感觉总结这东西写写也挺好的 xff0c 可以思考下过去和未来 xff0c 留个底 xff0c 可以作为日后的对比 xff1b 总结我的2011年 xf
  • Linux查看端口使用状态、关闭端口方法

    前提 xff1a 首先你必须知道 xff0c 端口不是独立存在的 xff0c 它是依附于进程的 某个进程开启 xff0c 那么它对应的端口就开启了 xff0c 进程关闭 xff0c 则该端口也就关闭了 下次若某个进程再次开启 xff0c 则
  • 查找列表中某个值的位置(python)

    p 61 list index value list为列表的名字 value为查找的值 p为value在list的位置 以下内容引自 xff1a http www linuxidc com Linux 2012 01 51638 htm P
  • python 等待一定时间后继续执行其后的程序

    简单示例 xff1a import time print 39 11 39 time sleep 10 print 39 22 39 先打印11 xff0c 等待10秒后 xff0c 打印22
  • Linux下用于查看系统当前登录用户信息的4种方法

    作为系统管理员 xff0c 你可能经常会 xff08 在某个时候 xff09 需要查看系统中有哪些用户正在活动 有些时候 xff0c 你甚至需要知道他 xff08 她 xff09 们正在做什么 本文为我们总结了4种查看系统用户信息 xff0
  • TCP:三次握手,URG、ACK、PSH、RST、SYN、FIN 含义

    TCP SYN ACK FIN RST PSH URG简析 三次握手Three way Handshake 一个虚拟连接的建立是通过三次握手来实现的 1 B gt SYN gt A 假如服务器A和客户机B通讯 当A要和B通信时 xff0c

随机推荐