工作流技术(WorkFlow)

news2024/9/29 13:28:32

什么是工作流

1.使用编程语言完成一套固定的审批流程

例如请假审批流程

订单配送流程

入职,辞职审批流程

2.使用场景

业务类:合同审批流程、订单处理流程、出入库审批流程等。

行政类:请假流程、出差流程、用车流程、办公用品申请流程等。

财务类:报销流程、支付流程等。

客户服务类:售后跟踪、客户投诉等。

常见软件

  • 尤其在OA,ERP,CRM软件中使用较多

    • OA

      • 办公自动化(Office Automation)

    • ERP

      • 企业资源计划即 ERP (Enterprise Resource Planning)

    • CRM

      • 客户关系管理(Customer Relationship Management)

 工作流中的核心三要素

  • 流程名称

  • 流程绑定业务id

  • 各流程负责人

官网(https://www.activiti.org/)

activiti

  • Activiti 是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调度

  • BPM,Business Process Management 即业务流程管理) 的创建者 Tom Baeyens 离开 JBoss 之后建立的项目

  • BPMN 2.0其实也是一种类似于xml和html的一种标记语言,就是使用bpmn的规范来定义画流程图,最终形成一个bpmn文件

Springboot集成Activiti 

1.父工程pom下添加

 <dependency>
       <groupId>org.activiti</groupId>
       <artifactId>activiti-spring-boot-starter</artifactId>
       <version>7.1.0.M6</version>
</dependency>

<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2.注意: activiti7与spring security 强耦合因此两个依赖 必须都得引入 

3.yml中spring节点下增加配置

 spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
  activiti:
    #是否让activiti自动创建所有的历史表
    history-level: full
    #是否需要使用历史表,默认false不使用,而配置true是使用历史表
    db-history-used: true
    #流程自动部署,关闭,需要手动部署流程 服务启动的时候自动检查resources目录下的bpmn文件 如果为true自动部署流程
    check-process-definitions: false
    #关闭启动服务自动框架部署
    deployment-mode: never-fail

4.集成好之后activiti会自动 再项目连接的MySQL数据库下创建25张表 

Activiti开发流程 

1.画流程图模型

遵守BPMN的流程规范,使用BPMN的流程定义工具,通过 流程符号 把整个业务流程定义出来,将流程定义文件字节流保存到模型数据表中(Model)。每一个流程图都是一个.bpmn文件

2.部署流程定义

加载画好的流程定义文件,将它转换成流程定义数据(ProcessDefifinition),保存到流程定义数据表中

3.启动流程 

生成流程实例数据(ProcessInstance),生成第1个节点的任务数据(Task)

4.处理人审批流程节点任务 

完成任务审批,生成审批结果,生成下一节点任务数据。直至满足条件,流程走到结束节点。

流程图模型中的各种符号 

1.事件event符号

  • 开始事件(Start Event):表示流程的起点,通常用于触发流程的启动。

  • 中间事件(Intermediate Event):发生在流程中间的事件,可以根据需要划分为多种类型,如定时器事件、消息事件、信号事件等。

  • 结束事件(End Event):表示流程的结束点,通常用于触发流程的结束。

2.活动activity符号 

  • 任务(Task)是最基本的活动类型,表示一个简单的、可执行的工作单元

  • 常见符号

    • 1. 用户任务(User Task):表示需要由具体用户来执行的任务。在流程中,当流程执行到用户任务节点时,会生成一个待办任务,需要指定具体的执行人来完成任务。

    • 2. 服务任务(Service Task):通过调用外部服务或执行业务逻辑来完成任务的一种任务类型。可以调用Java类、Web服务、REST接口等来执行具体的任务操作。

    • 3. 接收任务(Receive Task):表示等待外部触发的任务,当接收到外部的信号或消息时,流程会继续执行下一步。可以用于等待外部系统的通知或事件触发。

    • 4. 发送任务(Send Task):表示发送消息或触发事件的任务类型。可以发送消息给外部系统或触发特定的事件,用于与外部系统进行交互。

    • 5. 业务规则任务(Business Rule Task):表示执行业务规则来完成任务的一种任务类型。可以通过规则引擎执行事先定义好的业务规则,用于根据特定条件做出决策。

3.网关Gateway符号 

  • 用于处理流程中的决策

  • 1. 排他网关(Exclusive Gateway):也称为XOR网关或基于数据的排他网关,用于在流程中创建决策点。当执行到达排他网关时,所有出口顺序流会按照它们定义的顺序进行计算。条件计算为true的顺序流会被选择用于继续流程。

    • 相当于if-else只走一个分支

  • 2. 包容网关(Inclusive Gateway):也称为AND网关或包容性决策网关,用于在流程中创建平行的路径。当执行到达包容网关时,所有出口顺序流同时进行计算,并且至少要有一个条件计算为true的顺序流被选择用于继续流程。

    • 只需要满足一个条件

  • 3. 综合网关(Complex Gateway):用于模拟复杂的同步行为。通过表达式激活条件描述精确的行为。

  • 4. 基于事件的网关(Event-based Gateway):基于事件的网关代表流程中的一个分支点,其中遵循网关的替代路径基于发生的事件,而不是使用流程数据对表达式的评估。

  • 5. 并行网关(Parallel Gateway):用于同步(组合)并行流并创建并行流。

具体流程 

1.部署流程

  • 把xml文件和图片写入到数据库当中

  • Java类

    • RepositoryService

      • 创建部署

        • createDeployment

      • 删除部署

        • deleteDeployment

  • 涉及表

    • ACT_RE_PROCDEF 新增数据: 流程定义数据

    • ACT_RE_DEPLOYMENT 新增数据: 流程部署数据

    • ACT_GE_BYTEARRAY 新增数据:将当前流程图绑定到此流程定义部署数据上

    • ACT_RE_MODEL 更新部署id

2.启动流程 

  • 读取部署好到表中的流程数据开启流程,创建流程审批模板实例

  • Java类

    • RuntimeService

      • startProcessInstanceByKey(String processDefinitionKey, String businessKey)

        • 参数:

          • 部署好的流程名称选模板

          • 唯一业务主键

  • 涉及到的表

    • ● act_hi_actinst 流程实例执行历史

    • ● act_hi_identitylink 流程的参与用户历史信息

    • ● act_hi_procinst 流程实例历史信息

    • ● act_hi_taskinst 流程任务历史信息

    • ● act_ru_execution 流程执行信息

    • ● act_ru_identitylink 流程的参与用户信息

    • ● act_ru_task 任务信息

3.操作流程 

  • Java类

    • TaskService

  • 负责人查询待办任务

    • TaskService

      • 查询单条代办查询

        • singleResult

      • 查询全部代办任务

        • list

      • 分页查询代办任务

        • listPage

      • 条件查询

        • 根据流程名称查询

          • processDefinitionKey

        • 根据负责人查询

          • taskAssignee

        • 根据流程绑定业务id查询

          • processInstanceBusinessKey

      • 模糊查询

        • 方法中带like

      • 精确查询

        • 方法中带equals

      • 范围查询

        • 方法中带after,before,group,in,between等

  • 完成

    • TaskSercive

      • complete(String taskId, Map<String,Object> variables, boolean localScope)

        • 可结束当前节点流程,标记为已完成,并且流程会自动开启下一个节点的任务。同时在结束时还可以把填写的数据,作为流程变量传递到下一个流程中

        • 参数

          • 任务id

          • 携带变量

          • 是否为全局变量,是则为全流程可见

  • 拒绝

    • RuntimeService

      • deleteProcessInstance(String processInstanceId, String deleteReason);

    • TaskSercive

      • deleteTask

  • 查询历史

    • HistoryService

      • processInstanceBusinessKey(String processInstanceBusinessKey)

      • taskId(String taskId)

      • taskAssignee(String taskAssignee) | taskAssigneeLike(String taskAssignee)

      • finished()

      • unfinished()

      • orderByHistoricTaskInstanceEndTime().desc()

      • taskName(String var1) | taskNameLike(String var1)

      • includeProcessVariables()

      • processVariableValueEquals(String variableName, Object variableValue)

      • processVariableValueNotEquals(String variableName, Object variableValue)

      • processVariableValueGreaterThan(String name, Object value)

      • processVariableValueLessThan(String name, Object value)

      • createHistoricTaskInstanceQuery

        • list()

业务流程梳理 

1.在web包resources下新建bpmn目录

看看自己是否装了这个插件

新建bpmn.xml文件

 2.右击通过你安装的插件中打开

3.开始画流程图

 

 

 根据判断执行走向

4.创建完成导出png图片

 

5.流程测试创建

package com.zzyl;


import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@SpringBootTest
public class TestActiviti {

    @Resource
    private RepositoryService repositoryService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private TaskService taskService;

    @Resource
    private HistoryService historyService;

    @Test
    public void create() {
        //1.创建部署对象
        //2.读取要存在mysql中的bpmn文件和图片
        //3.部署
        repositoryService.createDeployment()
                .addClasspathResource("bpmn/学生请假流程.bpmn20.xml")
                .addClasspathResource("bpmn/diagram.png")
                //name一般和bpmn文件名称一样
                .name("学生请假流程")
                .deploy();
    }

    @Test
    public void delete() {
        //级联删除所有关联  表数据
        repositoryService.deleteDeployment("63f13c79-9407-11ee-adad-f0d7afd01b33",true);
    }

    @Test
    public void startProcess() {
        runtimeService.startProcessInstanceByKey("学生请假流程", "123455");
    }

    @Test
    public void queryRuntimeProcess() {
        List<Task> list = taskService.createTaskQuery().taskAssignee("张三")
                .list();
        list.forEach(v -> {
            log.info("获取任务执行的id:{}", v.getId());
            log.info("获取代办人:{}", v.getAssignee());
            log.info("获取业务id:{}", v.getBusinessKey());
        });
    }

    @Test
    public void completeApplicationTable() {
        //填写申请表并且完成申请表的代办
        HashMap<String, Object> map = new HashMap<>();
        map.put("username", "张三");
        map.put("reason", "中秋节回家吃月饼");
        map.put("startTime", "2024-09-09");
        map.put("endTime", "2024-09-20");
        map.put("days", 5);
        taskService.complete("3ba73dde-7279-11ef-8e5d-62df74cf4810",map,true);
    }

    @Test
    public void processNextComplete() {
        Task task = taskService.createTaskQuery().taskAssignee("l").singleResult();
        //获取任务节点传递的变量
        Map<String, Object> variables = taskService.getVariables(task.getId());
        log.info("代办任务id={}申请内容={}代办人={}", task.getId(), variables, task.getAssignee());

        //同意
        HashMap<String, Object> okReason = new HashMap<>();
        okReason.put("reason", "同意");
        okReason.put("remark", "但是课要补回来");
        taskService.complete(task.getId(), okReason, true);


//        HashMap<String, Object> map = new HashMap<>();
//        map.put("reason","拒绝");
//        map.put("remark","项目周期长不能让你猖狂");
//
//        runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"请假时间过长");


    }

    @Test
    public void queryHistoryProcess() {
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
                .finished().list();
        list.forEach(v -> {
            log.info("获取业务id={},获取流程名称={},获取流程开始时间={},获取流程结束时间={},拒绝原因={}",
                    v.getBusinessKey(), v.getProcessDefinitionName(),v.getStartTime(),v.getEndTime(),v.getDeleteReason());
        });
    }


    @Test//查询全部部署信息
    public void listDeployments() {
        List<Deployment> deployments = repositoryService.createDeploymentQuery().list();
        for (Deployment deployment : deployments) {
            System.out.println("Deployment ID: " + deployment.getId());
            System.out.println("Deployment Name: " + deployment.getName());
        }
    }
}

6.四个DI注入的作用

在 Activiti 中,RepositoryServiceRuntimeServiceTaskServiceHistoryService 是四个核心服务接口,分别用于不同的操作和功能。下面是它们的作用和常见用途:

1. RepositoryService

作用: 负责管理流程定义和部署相关的操作。

常见方法:

  • 部署流程: createDeployment()deploy() — 部署新的流程定义。
  • 删除部署: deleteDeployment(deploymentId, cascade) — 删除指定的部署,cascade 参数决定是否级联删除相关数据。
  • 查询流程定义: createProcessDefinitionQuery() — 查询流程定义的列表或特定定义。
  • 获取流程定义资源: getProcessDiagram() — 获取流程图的资源。

使用场景:

  • 部署新的流程定义到引擎中。
  • 查询、删除已部署的流程定义。
  • 更新和管理流程模型。

2. RuntimeService

作用: 负责管理正在运行的流程实例和任务相关的操作。

常见方法:

  • 启动流程实例: startProcessInstanceByKey(processDefinitionKey, businessKey) — 启动新的流程实例。
  • 获取流程实例: createProcessInstanceQuery() — 查询正在运行的流程实例。
  • 删除流程实例: deleteProcessInstance(processInstanceId, reason) — 删除正在运行的流程实例。

使用场景:

  • 启动新的流程实例以执行业务流程。
  • 查询和管理正在运行的流程实例。
  • 结束或取消正在运行的流程实例。

3. TaskService

作用: 负责管理任务的操作,主要涉及任务的创建、查询、分配和完成。

常见方法:

  • 创建任务查询: createTaskQuery() — 查询任务的列表或特定任务。
  • 完成任务: complete(taskId, variables) — 完成指定的任务,并可传递流程变量。
  • 分配任务: setAssignee(taskId, userId) — 为任务指定处理人。

使用场景:

  • 查询当前待办任务和处理任务。
  • 完成任务并更新流程变量。
  • 分配和重新分配任务。

4. HistoryService

作用: 负责管理历史数据和流程实例的历史记录。

常见方法:

  • 查询历史流程实例: createHistoricProcessInstanceQuery() — 查询已完成的流程实例。
  • 查询历史任务: createHistoricTaskInstanceQuery() — 查询已完成的任务历史记录。
  • 获取历史数据: getHistoricVariableInstance(variableId) — 获取历史变量的值。

使用场景:

  • 查询和分析已完成的流程实例和任务。
  • 获取流程执行的历史数据和相关信息。
  • 监控和审计业务流程的历史记录。

总结

  • RepositoryService: 用于部署、管理和删除流程定义及相关资源。
  • RuntimeService: 用于启动、查询和管理正在运行的流程实例。
  • TaskService: 用于处理任务,包括创建查询、完成任务和任务分配。
  • HistoryService: 用于查询和管理流程实例和任务的历史记录。

这些服务接口共同帮助你在 Activiti 引擎中完成从流程定义、运行到历史记录的全面管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2136969.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代理IP设置后IP不变?可能的原因及解决方法

在使用代理IP时&#xff0c;有时会遇到代理设置后IP地址却没有变化的情况。这种问题可能会让人感到困惑&#xff0c;但其实背后有多种原因。本文将详细探讨这些原因&#xff0c;并提供相应的解决方法&#xff0c;帮助你顺利解决问题。 可能的原因 代理IP设置后IP地址不变的原…

智慧人居视音频解决方案探究和技术实现

智慧人居技术背景 智慧人居是一种利用先进技术和智能化系统&#xff0c;旨在提升居住环境的舒适性、便捷性和安全性的新型居住模式。随着物联网、大数据、人工智能等技术的不断发展&#xff0c;智慧人居正朝着更加智能化、个性化、集成化的方向发展。 智慧人居通过集成各种智…

【数据结构与算法 | 灵神题单 | 合并链表篇】力扣2, 21, 445, 2816

1. 力扣2&#xff1a;两数相加 1.1 题目&#xff1a; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可…

房产销售系统:SpringBoot技术应用案例

第二章关键技术的研究 2.1相关技术 房产销售系统是在Java MySQL开发环境的基础上开发的。Java是一种服务器端脚本语言&#xff0c;易于学习&#xff0c;实用且面向用户。全球超过35&#xff05;的Java驱动的互联网站点使用Java。MySQL是一个数据库管理系统&#xff0c;因为它的…

Blender/3ds Max/C4D哪个软件好?

在3D建模和动画制作领域&#xff0c;Blender、3ds Max和Cinema 4D&#xff08;C4D&#xff09;都是备受赞誉的软件。每个软件都有其独特的优势和特点&#xff0c;选择哪个软件取决于用户的具体需求和个人偏好。今天&#xff0c;成都渲染101云渲染就来分析一些这三款软件的情况&…

滑动窗口算法—最小覆盖子串

题目 ”最小覆盖子串“问题&#xff0c;难度为Hard&#xff0c;题目如下&#xff1a; 给你两个字符串 S 和 T&#xff0c;请你在 S 中找到包含 T 中全部字母的最短子串。如果 S 中没有这样一个子串&#xff0c;则算法返回空串&#xff0c;如果存在这样一个子串&#xff0c;则可…

GANs-生成对抗网络

参考&#xff1a; https://mp.weixin.qq.com/s?__bizMjM5ODIwNjEzNQ&mid2649887403&idx3&snf61fc0e238ffbc56a7f1249b93c20690&chksmbfa0f632460e035f00be6cc6eb09637d91614e4c31da9ff47077ca468caad1ee27d08c04ca32&scene27 https://cloud.tencent.com…

pywinauto install ~

1. 下载最新的python, Download Python | Python.org 博主用的版本是&#xff1a; python-3.12.6-amd64.exe 2. 安装python. (略) 3. 配置环境变量&#xff1a; 点击环境变量&#xff0c;并编辑PATH变量&#xff0c; 后面3条是新加的。 4. 安装pywinauto, 打开CMD输入 pip …

转置卷积与反卷积的区分

transposed convolution&#xff08;转置卷积&#xff09;和deconvolution&#xff08;反卷积&#xff09;是两个完全不同的概念。 deconvolution为“inverse of convolution”、“inverse filter”&#xff0c;翻译为反卷积、解卷积。在信号处理中&#xff0c;反卷积是指从卷积…

一家电子元件企业终止,业绩规模小,疑似通过收购调节收入利润

贝特电子终止原因如下&#xff1a;首先&#xff0c;报告期内贝特电子营收较低&#xff0c;收购东莞博钺股权可能构成重大资产重组&#xff0c;且假如扣除报告期内来自东莞博钺的净利润&#xff0c;贝特电子的净利润恐怕不符合深交所上市标准&#xff1b;其次&#xff0c;交易所…

彩漩科技亮相第一届人工智能教育应用论坛,入选TOP30榜单,展示创新教育科技产品

近日&#xff0c;由中国教育发展战略学会人工智能与机器人教育专业委员会指导&#xff0c;北京教育信息化产业联盟主办的第一届人工智能教育应用论坛暨 AI 教育科技成果展在北京隆重举办。本次活动以“AI 强校大时代 —— 用新质生产力打造金钥匙强校”为主题&#xff0c;汇聚了…

C++速通LeetCode简单第12题-二叉树的直径

递归&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}…

链表的快速排序(C/C++实现)

一、前言 大家在做需要排名的项目的时候&#xff0c;需要把各种数据从高到低排序。如果用的快速排序的话&#xff0c;处理数组是十分简单的。因为数组的存储空间的连续的&#xff0c;可以通过下标就可以简单的实现。但如果是链表的话&#xff0c;内存地址是随机分配的&#xf…

并发控制全解析

在数据库操作中&#xff0c;并发控制 是确保数据一致性和事务隔离性的关键。然而&#xff0c;多个事务的并发操作可能导致数据不一致&#xff0c;破坏数据库的ACID特性。本文将深入探讨并发操作可能带来的问题&#xff0c;并介绍常见的并发控制技术。 1. 并发操作带来的挑战 …

注册接口参数校验

前面只是开发了注册接口&#xff0c;没有对注册用户名、密码长度进行任何限制&#xff0c;因此我们还需要对注册接口参数进行校验。 参数校验框架Spring Validation 引入Spring Validation起步依赖 在pom.xml文件引入依赖 <!-- validation依赖--> <dependenc…

【实践】应用访问Redis突然超时怎么处理?

目录标题 问题描述分析过程查看监控数据系统监控指标JVM监控指标Redis监控指标分析应用异常单机异常规律集群异常规律统计超时的key 初步结论验证结论访问Redis链路slowlogRedis单节点info all定位redis节点定位异常keybigkeystcpdump定位大key影响 经验总结 问题描述 某产品线…

CORS漏洞及其防御措施:保护Web应用免受攻击

1. 背景- 什么是CORS&#xff1f; 在当今互联网时代&#xff0c;Web 应用程序的架构日益复杂。一个后端服务可能对应一个前端&#xff0c;也可能与多个前端进行交互。跨站资源共享&#xff08;CORS&#xff09;机制在这种复杂的架构中起着关键作用&#xff0c;但如果配置不当&…

Vue 中常用的基础指令

一. 什么是 Vue 指令 指令的定义和作用 指令是通过 Vue 实例的directives选项进行定义的。在指令的定义中&#xff0c;需要提供一个bind函数&#xff0c;它在指令第一次绑定到元素时被调用&#xff0c;可以执行一些初始化的操作。还可以提供update函数&#xff0c;它在指令所…

性能测试-跨线程组使用变量(十四)

说明&#xff1a; 两个线程组相当于两个函数&#xff0c;比如A线程组使用json提取器提取的“city”变量&#xff0c;在B线程组中不能使用&#xff08;相当于是局部变量&#xff09;jmeter中&#xff0c;没有全局变量&#xff0c;环境变量 解决方法&#xff1a; 添加两个线程…

源码运行springboot2.2.9.RELEASE

1 环境要求 java 8 maven 3.5.2 2 下载springboot源码 下载地址 https://github.com/spring-projects/spring-boot/releases/tag/v2.2.9.RELEASE 3 修改配置 修改spring-boot-2.2.9.RELEASE/pom.xml 修改spring-boot-2.2.9.RELEASE/spring-boot-project/spring-boot-tools…