文章目录

  • 1. 引入依赖
  • 2. Activiti配置
  • 3. 整合流程设计器
  • 3.1下载流程设计器
  • 3.2 汉化
  • 3.3 修改配置
  • 4.流程设计器后端服务
  • 5. Activiti乱码配置
  • 6.启动类
  • 7.测试
  • 代码地址


开发工具使用IDE,基于Springboot项目搭建
Activiti整合流程设计器是5.22版本包内的工具,6.0以上没有。不过使用无异,直接用它就行了。它可以是我们快速构建Activiti流程图,方便使用,便于管理。
本文不止整合Activiti流程设计器,也包含Springboot整合Activiti

1. 引入依赖

pom.xml
这里只列出核心pom,像数据库,springboot等其他依赖自己添加

<!-- activiti -->
		<properties>
			<activiti.version>6.0.0</activiti.version>
		</properties>
	
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>${activiti.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>${activiti.version}</version>
        </dependency>

2. Activiti配置

# activiti配置
  activiti:
    # true  代表没有表就自动创建
    database-schema-update: true
    # 记录级别,默认audit
    history-level: full
    # (可选)自动部署验证设置:true-开启(默认)、false-关闭
    check-process-definitions: false
    # (可选)默认流程定义文件存放目录
    process-definition-location-prefix: classpath:/processes/

3. 整合流程设计器

3.1下载流程设计器

activiti-5.22.0下载地址

链接:https://pan.baidu.com/s/1FEznQtYvTx-qiAB7_MUoJQ
提取码:a56t

下载官方activiti-5.22.0的包,解压wars下面的activiti-explorer.war,把diagram-viewer、editor-app、modeler.html复制到Springboot项目的static目录下,这个是activiti的在线设计器,modeler.html是主界面。

springboot3 流程引擎 springboot整合activiti流程设计器_json

3.2 汉化

stencilset.json下载地址

链接:https://pan.baidu.com/s/15koYuOoV42PIHQeB4RsHbw
提取码:qnxd

下载stencilset.json,放在Springboot项目的static目录下

3.3 修改配置

在editor-app/app-cfg.js中contextRoot是编辑器的后台服务的url,去掉activiti-explorer

springboot3 流程引擎 springboot整合activiti流程设计器_springboot3 流程引擎_02


改成

springboot3 流程引擎 springboot整合activiti流程设计器_springboot3 流程引擎_03

4.流程设计器后端服务

  1. StencilsetRestResource 获取编辑器组件及配置项信息。
  2. ModelEditorJsonRestResource 根据modelId获取model的节点信息,编辑器根据返回的json进行绘图。
  3. ModelSaveRestResource 编辑器制图之后,将节点信息以json的形式提交给这个Controller,然后由其进行持久化操作。

将以下ActManageController.java类复制你的项目
@RequestMapping("/service") 是跟editor-app/app-cfg.js中contextRoot对应的

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.it.cloud.common.xss.XssHttpServletRequestWrapper;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @author 司马缸砸缸了
 * @date 2019/8/23 15:40
 * @description activiti editor管理类
 */
@RestController
@RequestMapping("/service")
public class ActManageController {
    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    private RepositoryService repositoryService;

    /**
     * stencilset:获取编辑器组件及配置项信息
     *
     * @return stencilset.json
     */
    @RequestMapping("/editor/stencilset")
    public String getStencilset() {
        InputStream stencilsetStream = this.getClass().getResourceAsStream("/static/stencilset.json");
        try {
            return IOUtils.toString(stencilsetStream, "utf-8");
        } catch (Exception e) {
            throw new ActivitiException("Error while loading stencil set", e);
        }
    }

    /**
     * 模型详情
     *
     * @param modelId
     * @return
     */
    @RequestMapping("/model/{modelId}/json")
    public ObjectNode getEditorJson(@PathVariable String modelId) {
        ObjectNode modelNode = null;

        Model model = repositoryService.getModel(modelId);

        if (model != null) {
            try {
                if (StringUtils.isNotEmpty(model.getMetaInfo())) {
                    modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
                } else {
                    modelNode = objectMapper.createObjectNode();
                    modelNode.put("name", model.getName());
                }
                modelNode.put("modelId", model.getId());
                ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(
                        new String(repositoryService.getModelEditorSource(model.getId()), "utf-8"));
                modelNode.set("model", editorJsonNode);

            } catch (Exception e) {
                throw new ActivitiException("Error creating model JSON", e);
            }
        }
        return modelNode;
    }

    /**
     * 保存
     *
     * @param modelId
     * @param name
     * @param jsonXml
     * @param svgXml
     * @param description
     */
    @RequestMapping("/model/{modelId}/save")
    @RequiresPermissions("act:manage:save")
    public void saveModel(@PathVariable String modelId, @RequestParam("name") String name,
                          @RequestParam("json_xml") String jsonXml, @RequestParam("svg_xml") String svgXml,
                          @RequestParam("description") String description, HttpServletRequest request) {
        HttpServletRequest orgRequest = XssHttpServletRequestWrapper.getOrgRequest(request);
        try {
            // 因为添加了html过滤,直接通过参数得不到html符号(XssFilter)
            svgXml = orgRequest.getParameterMap().get("svg_xml")[0];
            Model model = repositoryService.getModel(modelId);
            ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
            modelJson.put("name", name);
            modelJson.put("description", description);
            model.setMetaInfo(modelJson.toString());
            model.setName(name);
            repositoryService.saveModel(model);
            repositoryService.addModelEditorSource(model.getId(), jsonXml.getBytes(StandardCharsets.UTF_8));

            InputStream svgStream = new ByteArrayInputStream(svgXml.getBytes(StandardCharsets.UTF_8));
            TranscoderInput input = new TranscoderInput(svgStream);
            PNGTranscoder transcoder = new PNGTranscoder();
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            TranscoderOutput output = new TranscoderOutput(outStream);
            transcoder.transcode(input, output);
            final byte[] result = outStream.toByteArray();
            repositoryService.addModelEditorSourceExtra(model.getId(), result);
            outStream.close();
        } catch (Exception e) {
            throw new ActivitiException("Error saving model", e);
        }
    }
}

5. Activiti乱码配置

ActivitiConfig.java

import org.activiti.engine.*;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.io.IOException;

/**
 * 工作流配置
 *
 * @author 司马缸砸缸了
 */
@Component
public class ActivitiConfig implements ProcessEngineConfigurationConfigurer {

    /**
     * 解決工作流生成图片乱码问题
     *
     * @param processEngineConfiguration processEngineConfiguration
     */
    @Override
    public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
        processEngineConfiguration.setActivityFontName("宋体");
        processEngineConfiguration.setAnnotationFontName("宋体");
        processEngineConfiguration.setLabelFontName("宋体");
    }

}

6.启动类

排除SecurityAutoConfiguration,不然启动会报错

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)

7.测试

需要数据库中已经存在model记录,才可以看到效果,只要替换modelId就可以了。

访问 http:localhost:8080/modeler.html?modelId=25001

springboot3 流程引擎 springboot整合activiti流程设计器_spring_04


以上代码我已经整合到IT-CLOUD项目中