文章目录

  • Day02:流程中心 - 管理员操作
    • 今日学习目标:
  • 需求分析
  • 2. 在线设计器
    • 2.1. bpmn2.0规范
    • 2.2. bpmn-js框架
    • 2.3. 前端工程
      • 2.3.1 工程介绍
        • 目录结构:
      • 2.3.2 本地启动
      • 2.3.3 服务器启动
  • 3. 模型管理
    • 3.1 工程改造
      • 3.1.1. 更新pom文件
      • 3.1.2. 更新yml文件
      • 3.1.3. 清空数据库
      • 3.1.4. 导入公共类
    • 3.2. 模型管理
      • 3.2.1 需求分析
      • 3.2.2. 新增
      • 3.2.4. 删除
    • 3.3. 流程图管理
      • 3.3.1. 保存
      • 3.3.2. 查看
      • 3.3.3. 部署
    • 3.4. 流程定义管理
      • 3.4.1. 查询
      • 3.4.2. 删除
      • 3.4.3. 挂起
      • 3.4.4. 激活
    • 3.5. 下载流程图
      • 3.5.1. 下载文件
  • 总结

Day02:流程中心 - 管理员操作

今日学习目标:

  1. 掌握前端vue工程的编译、启动和部署
  2. 掌握模型、流程图、模型定义的含义和相互关系
  3. 掌握模型的基本操作:增、删、改、查
  4. 掌握流程图的操作:保存、部署、展示
  5. 掌握流程定义的操作:查询、删除、下载资源等
  6. 掌握流程定义的激活、挂起操作

需求分析

  1. 在流程审批系统中,管理员需要做的事情包括以下两类:
  • 设计流程图
  • 保存流程图、部署(发布)流程图


设计流程图有两种方式:

  • 一种是使用第一天讲解的方式,用actiBPMN设计一个流程图,把流程图上传到服务器上,然后进行保存、发布、使用。
  • 第二种方式是直接在系统中设计流程图,这种方式避免了上传流程图的过程,是主流的开发方式。

本项目采用的就是第二种方式,即在线流程设计。这个方式需要一个在线流程设计器,这是一种前端解决方案,有很多前端组件可以供我们选择使用。
注意:上图中大部分操作只需要在前端进行。

  1. 我们需要开发的是如何将前端框架生成的文件进行保存、部署、查询等操作。本质上是一些对象的增删改查。
  • 模型管理

    流程定义管理

2. 在线设计器

2.1. bpmn2.0规范

为什么一个mysql的数据库脚本,可以在不同公司的mysql数据库上执行?

答案是规范,也就是说这些mysql数据库,都遵循了相同的规范和标准,所以数据库实例是可以共用的。相同的例子还有:

  • 一个word文档,可以在不同的机器上打开,只要这些机器都安装了office程序
  • 一个pdf文件,可以在不同机器上打开,但是需要安装pdf阅读器
  • 一个java程序,可以在不同人的idea里打开


activiti的流程图,满足了bpmn2.0规范

我们将第一天设计的bpmn文件,保存成以下是一个符合bpmn2.0规范的xml文件,这个文件可以被其他bpmn设计器打开、解析。


![在这里插入图片描述](https://img-blog.csdnimg.cn/9be8287cb6284ddd9c53c2048ad04c45.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2k56Ss,size_20,color_FFFFFF,t_70,g_se,x_16)

2.2. bpmn-js框架

在线流程设计器是一个前端的框架,可以方便的集成到我们的项目的前端工程中。
bpmn-js是一个BPMN2.0的工具包和web建模器
JavaScript编写,轻松嵌入到任何web应用。
既可以是web查看器也可以是web建模器。
官网:https://bpmn.io/toolkit/bpmn-js/
源码:https://github.com/bpmn-io/bpmn-js
案例:https://bpmn.io/toolkit/bpmn-js/examples/
演示:https://demo.bpmn.io/

2.3. 前端工程

2.3.1 工程介绍

流程中心的前端工程使用的是vue框架,集成了bpmn-js框架。

目录结构:


服务端口:

前端工程有两种启动方式,本地源代码启动和服务器端部署启动。本地源码启动需要在本机安装nodejs,并执行编译命令。服务器端启动则可以直接将编译后的程序部署到nginx服务器中。

为简便起见,推荐使用服务器端启动。

2.3.2 本地启动

  • 编译
npm install

启动

npm run serve

访问

2.3.3 服务器启动

通过以下方式部署生产环境

  • 生成
npm run build

前端工程中的dist目录中的文件拷贝到Nginx的工程目录、改名

修改nginx.conf文件

 location /api {proxy_pass   http://127.0.0.1:8090/;}

启动Nginx、页面访问

3. 模型管理

3.1 工程改造

前端工程师开发的前端项目,需要后端工程提供服务,我们在第一天项目基础上进行改造。改造完成后,进行前文需求分析章节里提到的功能接口的开发。

3.1.1. 更新pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.itheima</groupId><artifactId>itcast-workflow</artifactId><version>0.0.1</version><name>${project.artifactId}</name><description>itcast-workflow</description><packaging>jar</packaging><properties><java.version>1.8</java.version><activiti.version>7.1.0.M6</activiti.version><knife4j.version>3.0.2</knife4j.version><spring-cloud.version>2020.0.3</spring-cloud.version><spring-plugin.version>2.0.0.RELEASE</spring-plugin.version><jwt.version>0.9.1</jwt.version><druid.version>1.2.6</druid.version><mybatis-plus.version>3.4.2</mybatis-plus.version><mybatis.version>3.5.6</mybatis.version><fastjson.version>1.2.62</fastjson.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>RELEASE</version><scope>compile</scope></dependency><!-- Activiti --><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>${activiti.version}</version></dependency><dependency><groupId>org.activiti</groupId><artifactId>activiti-image-generator</artifactId><version>${activiti.version}</version></dependency><!--    mysql   --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--   mybatis   --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!--    druid   --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>5.0.7</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>${knife4j.version}</version><exclusions><exclusion><groupId>org.springframework.plugin</groupId><artifactId>spring-plugin-core</artifactId></exclusion><exclusion><groupId>org.springframework.plugin</groupId><artifactId>spring-plugin-metadata</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.plugin</groupId><artifactId>spring-plugin-core</artifactId><version>${spring-plugin.version}</version></dependency><dependency><groupId>org.springframework.plugin</groupId><artifactId>spring-plugin-metadata</artifactId><version>${spring-plugin.version}</version></dependency><!-- md5 工具类 --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jwt.version}</version></dependency><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies><repositories><repository><id>itheima</id><name>itheima</name><url>http://repo.itheima.net/repository/maven-public/</url></repository></repositories><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

3.1.2. 更新yml文件

server:port: 8090spring:application:name: 流程审批中心datasource: # JDBC配置druid:url: jdbc:mysql://localhost:3306/itcast_workflow?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=trueusername: rootpassword: root# 连接池配置(通常来说只需要修改initial-size,min-idle,mac-active)initial-size: 1max-active: 20min-idle: 1#  获取连接等待的超时时间max-wait: 60000#打开PSCache,并且指定每个连接上PSCache的大小pool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 20validation-query: SELECT 'x'test-on-borrow: falsetest-on-retur: falsetest-while-idle: true# 配置间隔多久进行一次检查,检查需要关闭的空闲连接,单位毫秒time-between-eviction-runs-millis: 60000# 配置一个连接在连接池中最小的生存时间,单位毫秒min-evictable-idle-time-millis: 300000# 配置多个英文逗号分割filters: statactiviti:db-history-used: true  #使用历史表,如果不配置,则工程启动后可以检查数据库,只建立了17张表,历史表没有建立history-level: full    #记录全部历史操作database-schema-update: true   #自动建表#    flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常。#    true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建。#    create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)。#    drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎check-process-definitions: false # 自动部署验证设置:true-开启(默认)、false-关闭  在resource目录下添加processes文件夹,并且文件夹不能为空#    main:#      allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册database-schema: atc  #置建表策略,如果没有表,自动创建表  修改这个地方为大写#关闭springAutoDeployment自动部署流程定义deployment-mode: never-failmain:allow-bean-definition-overriding: true
swagger:enabled: truemybatis-plus:configuration:map-underscore-to-camel-case: trueauto-mapping-behavior: fulllog-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:id-type: ID_WORKER

3.1.3. 清空数据库

删除数据库中所有的表

3.1.4. 导入公共类

common包和config包是一些基础公共的类,导入到项目里。

  1. Result类:这个类是用于封装给前端的返回一个统一的对象,这个对象便于前端统一解析和处理
  2. SpringContextHolder:spring上下文的工具类,包含获取bean、设置bean、判断bean等方法
  3. WorkflowException:统一封装运行时异常
  4. ConfigurationSupport:webmvc的配置类,实现Swagger的配置类和一些方法的实现
  5. ExceptionConfiguration:
  6. MybatisPlusConfig:mybatisplus的分页插件

3.2. 模型管理

3.2.1 需求分析


模型管理是针对模型对象的一些操作,这些将是我们开发的接口:

  • 保存模型对象的基本信息
  • 保存模型对象的流程图
  • 查询模型对象的列表
  • 删除模型对象
  • 部署模型对象
  • 查询部署后生成的流程定义
  • 挂起模型对象
  • 启用挂起的模型对象

因为我们使用的是Activiti框架,此框架提供了一系列实体对象,如模型类:org.activiti.engine.repository.Model。

在本项目中对于一个Activiti对象的增删改查操作,开发过程是:

DTO:模型传输对象**(如:ModelDTO),dto的字段是根据产品原型得到的。

  • 前端到后端的数据传输对象
  • 分页查询返回的结果

导入DTO对象:

3.2.2. 新增


ModelerController

package com.itheima.activiti.controller.modeler;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.activiti.common.Result;
import com.itheima.activiti.dto.modeler.ModelDTO;
import com.itheima.activiti.service.modeler.ModelerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@Slf4j
@RestController
@RequestMapping("/modeler")
@Api(tags = "模型管理")
public class ModelerController {@AutowiredModelerService modelerService;/*** 保存流程模型* @param modelDTO* @return*/@PostMapping@ApiOperation(value = "新增模型")public Result save(@RequestBody ModelDTO modelDTO){//调用服务的方法modelerService.save(modelDTO);return Result.success();}
}

ModelerService:

package com.itheima.activiti.service.modeler;import com.itheima.activiti.dto.modeler.ModelDTO;public interface ModelerService {/*** 保存模型*/String save(ModelDTO modelDTO);
}

ModelerServiceImpl

package com.itheima.activiti.service.modeler.impl;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.itheima.activiti.dto.modeler.ModelDTO;
import com.itheima.activiti.service.modeler.ModelerService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ModelQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.stream.Collectors;@Service
public class ModelerServiceImpl implements ModelerService {@AutowiredRepositoryService repositoryService;@AutowiredObjectMapper objectMapper;@Overridepublic String save(ModelDTO modelDTO) {//创建activiti模型对象Model model = repositoryService.newModel();//设置模型的基本属性model.setKey(modelDTO.getKey());model.setName(modelDTO.getName());//设置模型的mateInfoObjectNode objectNode = objectMapper.createObjectNode();objectNode.put("name", modelDTO.getName());objectNode.put("description", modelDTO.getDescription());objectNode.put("reversion", model.getVersion());model.setMetaInfo(objectNode.toString());//保存模型repositoryService.saveModel(model);return model.getId();}
}
### 3.2.3. 列表
![在这里插入图片描述](https://img-blog.csdnimg.cn/e5399a489b30487687be217fad0ff91a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a2k56Ss,size_20,color_FFFFFF,t_70,g_se,x_16)
**ModelerController**:```java/*** 分页查询、搜索**/@GetMapping("/page")@ApiOperation(value = "分页模型")public Result<Page<ModelDTO>> page(ModelDTO modelDTO,@RequestParam(required = false, defaultValue = "1") int page,@RequestParam(required = false, defaultValue = "10") int pageSize){log.info("page = {}, pageSize = {}", page, pageSize);Page<ModelDTO> list = modelerService.page(modelDTO, page, pageSize);return Result.success(list);}

ModelService:

 /*** 分页查询页面设计的模型* @param modelDTO* @param page* @param pageSize* @return*/Page<ModelDTO> page(ModelDTO modelDTO, int page, int pageSize);

ModelerServiceImpl

页面上的信息包含:模型的属性,和最新的流程定义的版本号。所以需要查询两类数据:模型 + 流程定义

@Overridepublic Page<ModelDTO> page(ModelDTO modelDTO, int page, int pageSize) {//从前端传入对象中,获取key和nameString key = modelDTO.getKey();String name = modelDTO.getName();//创建模型的查询对象ModelQuery modelQuery = repositoryService.createModelQuery().orderByModelName().desc();//设置查询条件if(StringUtils.isNotEmpty(key)){modelQuery.modelKey(key);}if(StringUtils.isNotEmpty(name)){modelQuery.modelName(name);}//返回查询数量long total = modelQuery.count();//返回查询结果List<Model> list = modelQuery.listPage((page - 1) * pageSize, pageSize);//定义分页对象Page<ModelDTO> pageResult = new Page(page, pageSize, total);//遍历查询结果,返回ModelDTOList<ModelDTO> modelDTOList = list.stream().map(item -> {ModelDTO dto = new ModelDTO();BeanUtils.copyProperties(item, dto);//设置流程定义的属性//获取流程定义ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(item.getKey()).latestVersion().singleResult();if(processDefinition == null){dto.setVersion(null);}else{dto.setVersion(processDefinition.getVersion()); //当前部署的流程的版本dto.setProcessDefinitionId(processDefinition.getId());//流程定义的iddto.setProcessDefinitionSuspended(processDefinition.isSuspended());//流程的状态}return dto;}).collect(Collectors.toList());pageResult.setRecords(modelDTOList);return pageResult;}

3.2.4. 删除


ModelerController

 /*** 删除模型*/@DeleteMapping@ApiOperation(value = "删除模型")public Result delete(String id){modelerService.delete(id);return Result.success();}

ModelerService:

 /*** 删除模型* @param id 模型id*/void delete(String id);

ModelerServiceImpl

@Overridepublic void delete(String id) {repositoryService.deleteModel(id);}

3.3. 流程图管理

  • 模型包括基本信息和流程图,流程图相关操作有保存、查看、部署。流程图是符合bpmn2.0规范文件,本质上是一个xml文件。
  • 使用前端组件bpmn.js来设计和展示流程图,在本项目中,对该组件进行了改造。
  • 保存流程图在ModelerService中

3.3.1. 保存


ModelerController

 /*** 保存模型的流程图*/@PostMapping("/xml")@ApiOperation("保存流程图")public Result<ModelDTO> saveXml(@RequestBody ModelDTO modelDTO){log.info("ModelDTO: {}",modelDTO);modelerService.saveXml(modelDTO);return Result.success(modelDTO);}

ModelerService:

 /*** 保存流程图*/void saveXml(ModelDTO modelDTO);

ModelerServiceImpl

 @Overridepublic void saveXml(ModelDTO modelDTO) {//保存模型if(StringUtils.isEmpty(modelDTO.getId())){String id = this.save(modelDTO);modelDTO.setId(id);}try {//保存流程图repositoryService.addModelEditorSource(modelDTO.getId(), modelDTO.getContent().getBytes("utf-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}}

3.3.2. 查看


ModelerService:

 /*** 根据模型的id获取流程图*/String getXmlById(String id);

ModelerServiceImpl:

 @Overridepublic String getXmlById(String id) {byte[] content = repositoryService.getModelEditorSource(id);if(content == null){    //新建时return "";}else{return new String(content);}}

ModelerController

 /*** 查询流程图的内容* @param id* @return*/@GetMapping("/xml/{id}")@ApiOperation(value = "查询流程图")public Result getXmlById(@PathVariable String id){log.info("流程图id:{}", id);String content = modelerService.getXmlById(id);return Result.success(content);}

3.3.3. 部署

  • 将流程模型(流程图)发布、部署到Activiti服务中
  • 部署模型后,生成一个版本的流程定义(ProcessDefinition,数据库表是:ACT_RE_MODEL)

流程部署的传输对象(已导入):

@Data
@ApiModel("部署流程")
public class DeployDTO {@ApiModelProperty("模型主键")private String modelId;
}

DeployService

package com.itheima.activiti.service.activiti;public interface DeployService {/*** 部署模型* @param id* @return*/void deploy(String id);
}

DeployServiceImpl:

package com.itheima.activiti.service.activiti.impl;​import com.itheima.activiti.service.activiti.DeployService;import org.activiti.engine.RepositoryService;import org.activiti.engine.repository.Model;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;​@Servicepublic class DeployServiceImpl implements DeployService {    @Autowired    RepositoryService repositoryService;​    @Override    public void deploy(String id) {        //根据模型id,获取模型对象        Model model = repositoryService.getModel(id);        //根据模型id,获取模型资源        byte[] content = repositoryService.getModelEditorSource(id);​        //部署模型        repositoryService.createDeployment()                .key(model.getKey())                .name(model.getName())                .addString(model.getName() + ".bpmn20.xml", new String(content))                .deploy();    }}

DeployController:

package com.itheima.activiti.controller.activiti;import com.itheima.activiti.common.Result;
import com.itheima.activiti.dto.activiti.DeployDTO;
import com.itheima.activiti.service.activiti.DeployService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/deploy")
@Api(tags = "流程部署")
public class DeployController {@Autowiredprivate DeployService deployService;@PostMapping@ApiOperation(value="部署", notes = "传入模型id")public Result deploy(@RequestBody DeployDTO deployDTO){deployService.deploy(deployDTO.getModelId());return Result.success();}
}

3.4. 流程定义管理

将流程图部署(发布)到activiti引擎后,将会生成流程定义对象(ProcessDefinition),对应的数据库表是:ACT_RE_PROCDEF

3.4.1. 查询


根据流程定义列表,创建dto对象(已导入):

package com.itheima.activiti.dto.activiti;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.time.LocalDateTime;@Data
@ApiModel("流程定义")
public class ProcessDefinitionDTO {@ApiModelProperty("流程定义Id")private String id;@ApiModelProperty("流程定义名称")private String name;@ApiModelProperty("流程定义的key")private String key;@ApiModelProperty("流程定义的版本")private Integer version;@ApiModelProperty("资源名称bpmn文件")private String resourceName;@ApiModelProperty("资源名称png文件")private String diagramResourceName;@ApiModelProperty("部署对象ID")private String deploymentId;@ApiModelProperty("部署时间")private LocalDateTime deploymentTime;@ApiModelProperty("挂起状态")private Boolean suspended;
}

DeployController:

 @GetMapping("/page")@ApiOperation(value = "分页")public Result<Page<ProcessDefinitionDTO>> page(ProcessDefinitionDTO processDefinitionDTO,@RequestParam(required = false, defaultValue = "1") int page,@RequestParam(required = false, defaultValue = "10") int pageSize) {return Result.success(deployService.page(processDefinitionDTO, page, pageSize));}

DeployService:

 /*** 分页/搜索流程定义* @param processDefinitionDTO* @param page* @param pageSize* @return*/Page<ProcessDefinitionDTO> page(ProcessDefinitionDTO processDefinitionDTO, int page, int pageSize);

DeployServiceImpl:

@Overridepublic Page<ProcessDefinitionDTO> page(ProcessDefinitionDTO pdDTO, int page, int pageSize) {//创建流程定义的查询对象ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();//设置查询条件:key、versionif(StringUtils.isNotBlank(pdDTO.getKey())){query.processDefinitionKey(pdDTO.getKey());}if(null != pdDTO.getVersion()){query.processDefinitionVersion(pdDTO.getVersion());}//分页查询流程定义List<ProcessDefinition> list = query.listPage((page - 1) * pageSize, pageSize);//返回分页的流程定义dto:复制对象属性、设置部署时间List<ProcessDefinitionDTO> pdDtoList = null;if(null != list && list.size() > 0){//将流程定义转换成dto对象pdDtoList = list.stream().map(item ->{ProcessDefinitionDTO dto = new ProcessDefinitionDTO();//复制对象属性BeanUtils.copyProperties(item, dto);//查询此流程定义的部署时间Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(item.getDeploymentId()).singleResult();//设置dto的部署时间dto.setDeploymentTime(LocalDateTime.ofInstant(deployment.getDeploymentTime().toInstant(), ZoneId.systemDefault()));return dto;}).collect(Collectors.toList());}//查询总数long total = query.count();//分页返回dtoPage<ProcessDefinitionDTO> pageResult = new Page(page, pageSize, total);pageResult.setRecords(pdDtoList);return pageResult;}

3.4.2. 删除


DeployController:

 @DeleteMapping@ApiOperation(value = "删除流程", notes = "流程id")public Result delete(@RequestParam List<String> ids) {deployService.removeByIds(ids);return Result.success("删除成功");}

DeployService:

 /*** 根据部署id,删除流程定义* @param ids:部署id的列表*/void removeByIds(List<String> ids);

DeployServiceImpl:

 @Overridepublic void removeByIds(List<String> ids) {for (int i = 0; i < ids.size(); i++) {repositoryService.deleteDeployment(ids.get(i));}}

3.4.3. 挂起

挂起时,无法从此流程定义创建流程实例,类似于暂停某个制度的执行。

DeployController:

 @PutMapping("suspend/{id}")@ApiOperation("挂起流程")@ApiImplicitParam(name = "id", value = "流程ID", paramType = "query", dataType = "String")public Result suspend(@PathVariable("id") String id) {deployService.suspend(id);return Result.success();}

DeployService:

 /*** 挂起* @param id*/void suspend(String id);

DeployServiceImpl:

 @Overridepublic void suspend(String id) {repositoryService.suspendProcessDefinitionById(id, true, null);}

3.4.4. 激活


DeployController:

 @PutMapping("active/{id}")@ApiOperation("激活流程")@ApiImplicitParam(name = "id", value = "流程ID", paramType = "query", dataType = "String")public Result active(@PathVariable("id") String id) {deployService.active(id);return Result.success();}

DeployService:

 /*** 激活* @param id*/void active(String id);

**

 /*** 激活* @param id*/void active(String id);

DeployServiceImpl:

 @Overridepublic void active(String id) {repositoryService.activateProcessDefinitionById(id, true, null);}

3.5. 下载流程图

查看下载流程图功能比较复杂,代码供参考,不做开发要求。

核心实现类是ActivitiProcessDiagramCanvas.java和ActivitiProcessDiagramGenerator.java,需要提前导入代码文件夹中的diagram包。

3.5.1. 下载文件


DeployController:

@GetMapping(value = "resource")@ApiOperation("获取资源文件")@ApiImplicitParams({@ApiImplicitParam(name = "deploymentId", value = "部署ID", paramType = "query", dataType="String"),@ApiImplicitParam(name = "resourceName", value = "资源名称", paramType = "query", dataType="String")})public void resource(String deploymentId, String resourceName, @ApiIgnore HttpServletResponse response) throws Exception {InputStream resourceAsStream = deployService.getResourceAsStream(deploymentId, resourceName);IOUtils.copy(resourceAsStream, response.getOutputStream());}

DeployService:

 /*** 获取流程资源,返回数据流* @param deploymentId* @param resourceName* @return*/InputStream getResourceAsStream(String deploymentId, String resourceName);

DeployServiceImpl:

 @Overridepublic InputStream getResourceAsStream(String deploymentId, String resourceName) {InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, resourceName);return resourceAsStream;}

3.5.2. 下载图片

DeployController:

 @GetMapping(value = "svg")@ApiOperation("获取图片文件")public void svg(String deploymentId,@ApiIgnore HttpServletResponse response) throws Exception {InputStream resourceAsStream = deployService.svg(deploymentId);response.setHeader("Content-Type", "image/svg+xml");response.setHeader("Cache-Control", "no-store, no-cache");IOUtils.copy(resourceAsStream, response.getOutputStream());}

DeployService:

 /*** 获取流程图片* @param deploymentId* @return*/InputStream svg(String deploymentId);

DeployServiceImpl:

@Overridepublic InputStream svg(String deploymentId) {ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());ProcessDiagramGenerator diagramGenerator = new ActivitiProcessDiagramGenerator();InputStream inputStream = diagramGenerator.generateDiagram(bpmnModel, new ArrayList<>());return inputStream;}

总结

  1. 基本概念

    • 流程模型、流程定义
    • 流程模型和流程定义的操作
    • 开发流程
  2. 流程模型的基本操作
    • 保存、分页查询、删除
  3. 流程图的操作
    • 保存、查看、部署
  4. 流程定义的操作
    • 查询、删除、挂起和激活

跟铁拐李李老师学习工作流的第二天相关推荐

  1. 跟着李老师学习操作系统笔记(一、什么是操作系统)

    1.计算机专业要干什么? 用计算机帮助人们解决一些实际问题. 2. 什么是操作系统? 是计算机硬件和应用软件之间的一层软件. a:方便我们使用硬件,如使用显存. b:高效的使用硬件 3.管理哪些硬件: ...

  2. 焱老师带你学习MYSQL系列 第二篇 (MYSQL 数据结构)

    相关系列链接 焱老师带你学习MYSQL系列 第六篇 (MYSQL是如何实现锁的) 焱老师带你学习MYSQL系列 第五篇 (MYSQL事务隔离级别是如何实现的) 焱老师带你学习MYSQL系列 第四篇 ( ...

  3. 1 跟李沐老师学习深度学习(介绍监督【分类回归】、非监督【聚类】)

    目录 在回归中,我们训练一个回归函数来输出一个数值: 而在分类中,我们训练一个分类器,它的输出即为预测的类别. 把关键章节标注了出来~(由于第一章我当年看过视频了,所以就没再看一遍,而是浏览了笔记) ...

  4. 李老师用计算机,西安数学天才何布凡,心算比计算机还快,幼年却被诊断为“智障”...

    如果不用计算器,也不用稿纸,一道6位数乘以6位数的数学题能算出来吗,用时多久才可以计算出答案? 不用计算器估计是天方夜谭,常人用稿纸列竖式大约需要十几分钟,而且还有可能计算错误,然而 一个10岁的男孩 ...

  5. 对照 python_乐高Spike词语模式与Python模式对照01李老师积木大讲堂 第151期

    快乐分享!快乐学习!大家好!我是李航! 最近准备挖个新坑,spike系列 以大家熟悉的scratch模式与python对照讲解. 因为我对于python也是初学者,所以这个系列叫:陪李老师一起学spi ...

  6. 【华为云技术分享】《跟唐老师学习云网络》 - Bridge网桥

    [摘要] 跟唐老师学习云网络,已经进入到虚拟化的世界啦.Bridge是网络虚拟化中非常重要的一种设备,快来一起学习Linux-Bridge的作用吧. 一.什么是Linux-Bridge 咱们直接说人话 ...

  7. 【华为云技术分享】《跟唐老师学习云网络》 — IP和掩码

    [摘要] 我们下面接着上次第二篇开启讲解IP和掩码知识,如有疑问点欢迎下方评论一起交流. 一.主机的门牌号(IP地址) 当接入到网络里面的主机数量越来越多,每台主机都需要的门牌号(IP地址)数量就越来 ...

  8. pink老师学习之Echarts

    pink老师学习之Echarts 可视化面板介绍 ​ 应对现在数据可视化的趋势,越来越多企业需要在很多场景(营销数据,生产数据,用户数据)下使用,可视化图表来展示体现数据,让数据更加直观,数据特点更加 ...

  9. 查询姓李老师的mysql_day41:MYSQL:select查询练习题

    目录 1.表结构 2.建表和插入数据 #创建班级表 create table class( cid int primary key auto_increment, caption varchar(32 ...

  10. 国科大学习资料–模式识别--第二次作业

    国科大学习资料–模式识别–第二次作业(刘成林老师主讲) 题目

最新文章

  1. 利用jdt快速实现pmd的功能
  2. 【硬核书】矩阵代数基础
  3. 1370亿参数、接近人类水平,谷歌重磅推出对话AI模型LaMDA
  4. 如何实现拼音与汉字的互相转换
  5. 基于SDP的提议/应答(offer/answer)模型简介
  6. python 计算两个日期相差多少个月
  7. 启明云端分享|盘一盘ESP32为啥那么惹人爱呢?
  8. 用户关系表 存储_如何解决oracle 19c中创建用户报错的故障
  9. iOS------App之间传递数据的几种方式
  10. 【数据结构与算法】浅析堆栈以及数据结构的堆和栈
  11. Qt中图像的显示与基本操作
  12. 51单片机呼吸灯c语言程序,用51单片机的呼吸灯程序
  13. 和平精英怎么玩?智能找图、鼠标滚轮宏按键玩吃鸡还能匹配手机?
  14. vs2010中svn使用教程_vs2010+ Ankhsvn使用详解
  15. java分割图片为九宫格
  16. 163vip邮箱全面体验测评分享
  17. Vue项目中出现Loading chunk {n} failed问题的解决方法
  18. 美国有毒有害物质TSCA测试费用多少
  19. Planbar 2018 新功能 BIM 加密狗更新
  20. 【小程序】腾讯云服务配置小程序流程

热门文章

  1. 聊天别被人家说的“职业技术”忽悠了
  2. 【Luat-esp32c3】4.3 文件系统——加载jpeg图片并拆包
  3. 3D游戏场景模型制作的细节与技巧
  4. android u盘怎么打开文件夹图标不显示不出来了,U盘图标显示不正常怎么办,U盘图标怎么显示出来...
  5. ActiveMQ简介
  6. deepin装oracle,deepin安装Oracle jdk8,以及添加add-apt-repository命令支持
  7. 安卓真机如何连接本地服务器_Android真机连接本地服务器安装部署方法
  8. 基于Python OpenCV的车牌识别智能计费系统设计
  9. 改变鼠标样式的两种方法
  10. Win11、10下安装enspHCL,解决兼容问题