Springboot集成activiti7

news2024/11/22 15:07:27

在pom文件中添加SpringBoot集成Activiti7的依赖

<!--添加activiti和SpringBoot整合的依赖
    内置的MyBatis版本与外面的会有冲突,所以需要排除-->
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.0.0.SR1</version>
    <exclusions>
        <exclusion>
            <artifactId>mybatis</artifactId>
            <groupId>org.mybatis</groupId>
        </exclusion>
    </exclusions>
</dependency>

<!--activiti可以绘制流程的的依赖-->
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-image-generator</artifactId>
    <version>7.0.0.SR1</version>
</dependency>

配置application.yml配置文件**

spring:
  activiti:
    database-schema-update: true
    db-history-used: true
    history-level: full
    check-process-definitions: false
    use-strong-uuids: false
  • database-schema-update属性

    1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
    2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
    3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
    4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
    
  • db-history-used

    检测历史表是否存在 activiti7默认没有开启数据库历史记录,true启动数据库历史记录
    
  • history-level

    #记录历史等级 可配置的历史级别有none, activity, audit, full
    1.none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
    2.activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
    3.audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
    4.full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
    
  • check-process-definitions

    #校验流程文件,默认校验resources下的processes文件夹里的流程文件
    
  • use-strong-uuids

    是否使用UUID作为主键生成策略
    

排除Spring Security的自动装配

Activiti7默认和Spring Security集成了,但是如果我们的项目中使用的是Shiro,所以我们需要在项目中排除掉Spring Security的自动装配配置,否则我们的登录页会被覆盖

在启动类注解中排除

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
        SecurityAutoConfiguration.class,
        ManagementWebSecurityAutoConfiguration.class
})

流程定义列表

表设计

在这里插入图片描述
对应的实体

/**
 * 流程定义
 */
@Setter
@Getter
public class BpmnInfo {
    private Long id;

    private String bpmnName;            //流程(图)名称

    private String bpmnType;             //流程(图)类型
  
    private String bpmnPath;             //流程(图)路径

    private String deploymentId;         //流程部署id

    private String actProcessId;         //activity流程定义生成的主键

    private String actProcessKey;        //activity流程定义生成的key
    
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date deployTime;             //部署时间

    private String info;                 //描述信息

}

提供流程文件上传接口

这个版本允许部署zip压缩包形式,可以将流程图文件压缩,或和流程图图片一起压缩上传部署

//上传
@RequiresPermissions("system:bpmnInfo:upload")
@RequestMapping("/upload")
@ResponseBody
public AjaxResult upload(MultipartFile file)  {
    //文件上传操作:
    //1:文件输入流   2>文件输出流
    if(file != null && file.getSize() > 0){
        //上传的文件名
        String filename = file.getOriginalFilename();
        //获取文件名后缀
        String exp = FilenameUtils.getExtension(filename);
        if("zip".equalsIgnoreCase(exp)|| "bpmn".equalsIgnoreCase(exp)){
            //一般文件存在硬盘中,然后将路径存在数据库
            String upload = null;
            try {
                //上传成功之后,返回路径为: /upload/日期/随机文件名.bpmn
                upload = FileUploadUtils.upload("从spring配置文件中获取一个当前服务器的绝对路径", file);
                System.err.println(upload);
            } catch (IOException e) {
                e.printStackTrace();
                return AjaxResult.error("流程文件上传失败");
            }
            //上传成功之后返回文件路径,用于后面的保存
            return AjaxResult.success("上传成功", upload);
        }else{
            return AjaxResult.error("流程定义文件仅支持 bpmn 和 zip 格式!");
        }
    }else{
        return AjaxResult.error("不允许上传空文件!");
    }
}

提供部署流程接口

@RequiresPermissions("system:bpmnInfo:deploy")
@RequestMapping("/deploy")
@ResponseBody
public AjaxResult deploy(String bpmnPath, String bpmnType, String info) throws FileNotFoundException {
    bpmnInfoService.deploy(bpmnPath, bpmnType, info);
    return AjaxResult.success();
}

服务方法

//集成了spring boot里面的服务对象已经在容器里了,可以直接注入使用
@Autowired
private RepositoryService repositoryService;

@Override
public void deploy(String bpmnPath, String bpmnType, String info) throws FileNotFoundException {
    //1:判断参数是否合法
    //2:部署流程
    //获得文件相对路径
    String lowStr = bpmnPath.toLowerCase();
    //文件流: 读取之前上传的流程文件
    //@Cleanup
    FileInputStream stream = new FileInputStream(new File("之前从spring配置文件中获取一个当前服务器的绝对路径", bpmnPath));
    //FileInputStream(绝对路径 + bpmnPath);拼成这个文件的绝对路径
    Deployment deploy = null;
    
    if(lowStr.endsWith("zip")){
    	//zip文件
        deploy = repositoryService.createDeployment()
            .addZipInputStream(new ZipInputStream(stream))
            .deploy();
    }else if(lowStr.endsWith("bpmn")){
    	//bpmn文件
        deploy = repositoryService.createDeployment()
            //参数1:资源名称(使用路径作为名称), 参数2:流程文件流
            .addInputStream(bpmnPath, stream)
            .deploy();
    }

    if(deploy  == null){
        throw new BusinessException("部署失败");
    }
    //3:创建流程定义对象-自己建表
    BpmnInfo bpmnInfo = new BpmnInfo();
    bpmnInfo.setInfo(info);
    bpmnInfo.setBpmnType(bpmnType);
    bpmnInfo.setDeploymentId(deploy.getId());
    bpmnInfo.setDeployTime(deploy.getDeploymentTime());

    //activiti7生成的流程定义表
    //获取activiti中流程定义对象的: ActProcessId  ActProcessKey
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .deploymentId(deploy.getId())
        .latestVersion()
        .singleResult();
    //部署对象无法获取name, 使用定义对象获取name(当初画流程图时指定名称)
    bpmnInfo.setBpmnName(processDefinition.getName());
    bpmnInfo.setActProcessId(processDefinition.getId());
    bpmnInfo.setActProcessKey(processDefinition.getKey());

	//保存流程图信息
    bpmnInfoMapper.insert(bpmnInfo);

}

流程定义文件删除

@RequiresPermissions("business:bpmnInfo:delete")
@RequestMapping("/delete")
@ResponseBody
public AjaxResult delete(Long id){
    bpmnInfoService.delete(id);
    return AjaxResult.success();
}

服务类

@Override
public void delete(Long id) {
    BpmnInfo bpmnInfo = this.get(id);
    bpmnInfoMapper.deleteByPrimaryKey(id);
	//删除本地保存的流程文件...省略
	
	//获取该流程的所有流程实例
    List<ProcessInstance> list = runtimeService.createProcessInstanceQuery()
            .processDefinitionKey(bpmnInfo.getActProcessKey())
            .list();
            
    for (ProcessInstance instance : list) {
        	//删除与流程实例绑定的业务信息
        }
    }
    
    //删除流程部署对象,连带删除流程定义
    repositoryService.deleteDeployment(bpmnInfo.getDeploymentId(), true);
}

查看流程文件

/**
 * 查看资源
 */
@RequiresPermissions("business:bpmnInfo:readResource")
@RequestMapping( "/readResource")
@ResponseBody
public void readResource(String deploymentId, String type , HttpServletResponse response) throws IOException {
    InputStream inputStream  =  bpmnInfoService.getResoucceByType(deploymentId, type);
    IOUtils.copy(inputStream,response.getOutputStream());

}

服务类

@Override
public InputStream getResoucceByType(String deploymentId, String type) {

    ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
            .deploymentId(deploymentId).latestVersion().singleResult();
            
    if("xml".equalsIgnoreCase(type)){
        return repositoryService.getResourceAsStream(deploymentId, definition.getResourceName());
    }else if("png".equalsIgnoreCase(type)){
        BpmnModel model = repositoryService.getBpmnModel(definition.getId());
        //利用上面绘制流程图依赖的api绘制图片
        ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        //generateDiagram(流程模型,需要高亮的节点,需要高亮的线条,后面三个参数都表示是字体)
        InputStream inputStream = generator.generateDiagram(model, Collections.EMPTY_LIST, Collections.EMPTY_LIST,"宋体","宋体","宋体");
        return inputStream;
    }
    return null;
}

查看某个流程审核到哪个节点图片

//根据流程定义id获取流程模型
BpmnModel model = repositoryService.getBpmnModel(bpmnInfo.getActProcessId());
//根据流程实例id找到正在执行的任务
Task task = taskService.createTaskQuery().processInstanceId(流程实例id).singleResult();
//获取需要高亮的位置
List<String> activeActivityIds = runtimeService.getActiveActivityIds(task.getExecutionId());
//绘制当前节点高亮流程图
inputStream = generator.generateDiagram(model, activeActivityIds,
                                                Collections.EMPTY_LIST,
                                                "宋体","宋体","宋体");

审核撤销

@RequestMapping(value = "/cancelApply")
@ResponseBody
public AjaxResult cancelApply(Long id) throws IOException {
    carPackageAuditService.cancelApply(id);
    return AjaxResult.success();
}

服务类

@Override
    public void cancelApply(Long id) {
        //满足撤销状态
        //与该流程已经产生的信息删除
        
        //流程实例删除
        runtimeService.deleteProcessInstance(流程实例id, "删除理由");
    }

审核通过与拒绝在这里插入图片描述

在执行这个节点时才知道用户点的是同意或拒绝,所以我们要给这两个分支线路上的流程变量赋值,才能完成这个节点

//设置审核操作的同意与否参数
taskService.setVariable(task.getId(), "auditStatus",auditStatus);

查询是否还有下一个节点

//获取下一个节点
    Task nextTask = taskService.createTaskQuery().processInstanceId(audit.getInstanceId()).singleResult();
    if(nextTask != null){
         //还有下一个节点任务
    }

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

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

相关文章

毕业设计-深度学习身份证号码检测识别-python-opencv

目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科…

Spring Security HTTP认证

本文内容来自王松老师的《深入浅出Spring Security》&#xff0c;自己在学习的时候为了加深理解顺手抄录的&#xff0c;有时候还会写一些自己的想法。 HTTP提供了用户权限控制和认证的通用方式&#xff0c;这种认证方式通过HTTP请求头来提供认证信息&#xff0c;而不是通过表单…

[附源码]计算机毕业设计基于Springboot校园运动会管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

opencv c++ 霍夫圆检测

1、原理 a&#xff09;对某点&#xff0c;以其为圆心的圆为无数&#xff08;一圈圈的圆&#xff09;&#xff0c;将其从x-y平面坐标系上转换到r-θ极坐标系上后&#xff0c;则变成了以r、θ为自变量&#xff0c;为固定值&#xff0c;x、y为因变量的式子&#xff1a; b&#xff…

一文带你走进JS语法(最全笔记)

目录 基本语法 1.引入方式 2.注释 3.输入输出语句 4.变量和常量 5.原始数据类型 6.运算符 7.流程控制语句 8.数组 9.函数 DOM 1.概述 2.元素对象的操作 3.元素内属性操作 4.元素内文本操作 事件 面向对象 1.定义类的方式 2.继承 内置对象 1.Number对象 2…

matlab贝叶斯隐马尔可夫hmm模型实现

贝叶斯隐马尔可夫模型是一种用于分割连续多变量数据的概率模型。该模型将数据解释为一系列隐藏状态生成。每个状态都是重尾分布的有限混合&#xff0c;具有特定于状态的混合比例和共享的位置/分散参数。 相关视频&#xff1a;马尔可夫链原理可视化解释与R语言区制转换Markov r…

java面试总结

文章目录JVM类的加载过程类加载器有哪些什么是双亲委派双亲委派的好处如何打破双亲委派java内存模型栈帧的结构java堆的分代设计对象内存分配对应的GC为什么需要Survivor区?只有Eden不行吗&#xff1f;为什么要有两个Survivor区对象创建过程对象内存布局对象头Mark Word对象大…

提高 K8S 容器运行时的可观察性最佳方法之一

当谈到云原生可观察性时&#xff0c;可能每个人都会提到OpenTelemetry (OTEL)&#xff0c;因为社区需要依赖标准来将所有集群组件开发指向到同一方向。OpenTelemetry 使我们能够将日志、指标&#xff08;metrics&#xff09;、跟踪&#xff08;traces&#xff09;和其他上下文信…

内容爆炸时代,如何打造品牌经营的“弹药库”?

&#x1f446;点击一键预约本周三主题直播&#x1f446;2017年&#xff0c;华为总裁办发布《华为之熵&#xff0c;光明之矢》的内部学习邮件&#xff0c;将热力学中“熵”的概念应用到企业管理中&#xff0c;成为被人们津津乐道的“熵减哲学”。对于“熵”的概念&#xff0c;大…

[附源码]计算机毕业设计基于vuejs的文创产品销售平台app

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]计算机毕业设计甜品购物网站Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【OpenCV-Python】教程:4-2 Harris角点检测

OpenCV Python Harris 角点检测 【目标】 理解Harris角点检测背后的概念&#xff1b;cv2.cornerHarris(), cv2.cornerSubPix() 【理论】 上一章节中&#xff0c;我们看到在图像中每个方向变化都很大的区域就是角点&#xff0c;一个早期的尝试是由 Chris Harris & Mike …

关闭图片窗口

关闭图片窗口 结果演示 概述 通过事件的绑定来实现&#xff0c;关闭网页中某个图片窗口的效果。 构建HTML框架 <body><div class"box">图片<img src"https://upload-bbs.mihoyo.com/upload/2021/03/11/73281682/f810fbc2e4806aab8176e96feee…

关于数据分析知识的干货分享

数据分析的出现是因为人类难以理解海量数据所呈现出来的信息&#xff0c;不能从中找到相应的规律来对现实中的事物进行对应&#xff0c;我们都知道数据有很高的价值&#xff0c;但不能利用的价值&#xff0c;没有任何意义。 为了解决这一问题&#xff0c;数据分析在长期的数据…

超透镜与超表面全息

超透镜和超表面因其操纵电磁场的独特特性而在科学上声名鹊起&#xff0c;如今它们的制造已经变得可行。但它们的设计难度远远超过了传统镜片&#xff0c;因为必须考虑到纳米级构件的特性。 VirtualLab Fusion的优势  统一的平台&#xff1a;具有将纳米级构建模块和大尺…

JAVA-GUI工具的编写-----事件篇

上一节介绍了HTTP以及HTTPS请求&#xff0c;那么这里我们就接着讲解事件与请求联动。 关于POC以及EXP最大的区别就是&#xff0c;EXP是附带利用功能&#xff0c;而POC仅仅是检测功能&#xff0c;所以这里我们需要动起来&#xff0c;GUI小工具能用上的事件功能其实就两个&#…

【vue3】代码自动格式化和volar卡顿问题解决

一、格式化策略 用eslint做代码检查和格式化是很方便的东西&#xff1b; 这里我们使用vscode完成这些操作&#xff1b; 在代码保存的时候&#xff0c;顺便完成格式化操作 1)装上eslint和prettier插件 2)装完插件之后&#xff0c;我们需要配置一下 打开 文件 > 首选项 >…

为什么阿里巴巴建议HashMap初始化时需要指定容量大小?

为什么阿里巴巴建议HashMap初始化时需要指定容量大小&#xff1f; 为什么&#xff1f; 关于集合类&#xff0c;《阿里巴巴Java开发手册》中写道&#xff1a; 我们先来写一段代码在JDK 1.7 &#xff08;jdk1.7.0_80&#xff09;下面来分别测试下&#xff0c;在不指定初始化容量…

Docker harbor私有仓库部署与管理

Docker harbor私有仓库部署与管理Docker harbor私有仓库部署与管理一、Docker 私有仓库1、下载registry镜像2、修改配置文件/etc/docker/daemon.json &#xff0c;添加私有仓库配置&#xff0c;修改完后重启docker3、创建私有仓库容器4、推送镜像到私有仓库中5、查看当前仓库的…

使用 Lua 脚本和海康 VisionMaster 进行 TCP 通信

说明&#xff1a;因任务需求&#xff0c;需要进行海康VisionMaster服务端和Lua脚本客户端进行TCP通信传输数据。因为之前从未接触过Lua语言&#xff0c;所以也趁机学习一波。 内容Lua教程手册LuaSocket使用方法一方法二报错&#xff1a;“attempt to compare number with strin…