精华内容
下载资源
问答
  • 基于以前做办公系统的经验,我就选择了activiti流程引擎,不过版本已经更新了好几个了,集成方式也变了。于是我开始找资料,大多都是后端集成的方式,包括前端代码也喜欢放在后端resources中,我感觉这种方式很不...

    一、背景

    最近因为项目需求,我们需要引入一个流程引擎框架。基于以前做办公系统的经验,我就选择了activiti流程引擎框架,不过版本已经更新了好几个了,前后端技术也更新了,集成方式也不同了。于是我开始找资料,发现大多都是后端集成的方式,包括前端代码也喜欢放在后端resources中,这是五年前的模式了,我感觉这种方式很不友好。况且,目前都采用前后端分离的架构模式,前端框架也比较成熟和流行,我们还把html放在后端,从前端、后端、部署三个层面都显的很鸡肋,后面零零散散找了一些资料,踩了很多坑,奋斗了几个晚上,终于集成完毕。因此写个博客记录一下,有描述不详细的地方,欢迎留言,我目前还留存一点记忆,可以解答,哈哈。

    二、前端集成

    2.1、搭建一个vue项目,将activiti6的前端代码放在public目录下(前端代码可以去官网下载)

    2.2、集成模型设计。新建一个vue文件,内容如下

    <template>
      <div style="position:relative;height: 100%;">
        <iframe
          id="iframe"
          :src="modelerUrl"
          frameborder="0"
          width="100%"
          height="720px"
          scrolling="auto"
        />
        <Spin v-if="modelerLoading" fix size="large" />
      </div>
    </template>
    
    <script>
    import { getToken } from '@/utils/auth'
    export default {
      name: 'ModelDefine',
      components: {},
    
      data() {
        return {
          modelerLoading: true,
          modelerUrl: '/static/modeler.html?modelId=' + this.$route.query.id + '&time=' + new Date().getTime()
        }
      },
      computed: {
        token() {
          return 'Bearer ' + getToken()
        }
      },
      created() {},
      mounted() {
        window.getMyVue = this
      },
      methods: {}
    }
    </script>
    <style lang="scss" scoped>
    .iframe {
      width: 100%;
      height: calc(100vh - 154px);
    }
    </style>
    

    结果如图:

    2.3、对接token。每个系统都有自己的登录逻辑,activiti前端支持对接项目的token。打开static/modeler.html添加一下代码

      <script>
        (
          function (open) {
            XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
              open.call(this, method, url, async, user, pass);  //this指XMLHttpRequest
              this.setRequestHeader("Authorization", window.parent.getMyVue.token); //mounted时传入的token
            };
          }
        )(XMLHttpRequest.prototype.open);
      </script>

    2.4、修改接口配置。activiti默认的api配置也是支持修改的,可以对应我们自己的业务系统的路由。打开static/editor-app/app-cfg.js

    完成上述几步,前端集成基本告一段落了,需要我们重写后台接口,完成模型的新建和保存。

    三、后端集成

    3.1、搭建一个springboot工程,本次使用的springboot2.4.2

    3.2、集成jar包

            <!-- activiti 流程引擎 -->
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-engine</artifactId>
                <version>6.0.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.mybatis</groupId>
                        <artifactId>mybatis</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-json-converter</artifactId>
                <version>6.0.0</version>
            </dependency>
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-spring-boot-starter-basic</artifactId>
                <version>6.0.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.xmlgraphics</groupId>
                <artifactId>batik-codec</artifactId>
                <version>1.7</version>
            </dependency>
            <dependency>
                <groupId>org.apache.xmlgraphics</groupId>
                <artifactId>batik-css</artifactId>
                <version>1.7</version>
            </dependency>
            <dependency>
                <groupId>org.apache.xmlgraphics</groupId>
                <artifactId>batik-svg-dom</artifactId>
                <version>1.7</version>
            </dependency>
            <dependency>
                <groupId>org.apache.xmlgraphics</groupId>
                <artifactId>batik-svggen</artifactId>
                <version>1.7</version>
            </dependency>

    3.3、配置activiti(springboot项目的yml文件)

    spring:
      activiti:
        check-process-definitions: false  # 自动检查、部署流程定义文件
        database-schema-update: true  # 自动更新数据库结构
        process-definition-location-prefix: classpath:/processes  # 流程定义文件存储目录

    3.4、重写新增模型接口

        /**
         * 新增模型
         * */
        @PostMapping("/add")
        public AjaxResult addModel(@RequestBody ModelEntityForAdd newModel){
            ObjectNode modelNode = objectMapper.createObjectNode();
            modelNode.put(MODEL_NAME, newModel.getName());
            modelNode.put(MODEL_DESCRIPTION, newModel.getDescription());
            modelNode.put(MODEL_REVISION, "1");
    
            Model model = repositoryService.newModel();
            model.setName(newModel.getName());
            model.setKey(newModel.getKey());
            model.setCategory(newModel.getCategory());
            model.setMetaInfo(modelNode.toString());
    
            repositoryService.saveModel(model);
            String id = model.getId();
    
            //完善ModelEditorSource
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.putPOJO("stencilset", stencilSetNode);
            repositoryService.addModelEditorSource(id, editorNode.toString().getBytes(StandardCharsets.UTF_8));
            return AjaxResult.success(id);
        }

    3.5、重写获取流程定义接口

    /**
         * 获取流程定义json数据
         *
         * @param modelId
         * @return
         */
        @GetMapping(value = "/{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(MODEL_NAME, model.getName());
                    }
                    modelNode.put(MODEL_ID, model.getId());
                    byte[] modelEditorSource = repositoryService.getModelEditorSource(model.getId());
                    ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(new String(modelEditorSource, StandardCharsets.UTF_8));
                    modelNode.putPOJO("model", editorJsonNode);
    
                } catch (Exception e) {
                    throw new ActivitiException("Error creating model JSON", e);
                }
            }
            return modelNode;
        }

    3.6、重写保存模型接口

    /**
         * 保存流程定义数据
         */
        @PutMapping(value = "/{modelId}/save")
        public void saveModel(@PathVariable String modelId, @RequestParam("name") String name, @RequestParam("json_xml") String json_xml,
                              @RequestParam("svg_xml") String svg_xml, @RequestParam("description") String description) {
            try {
                Model model = repositoryService.getModel(modelId);
    
                ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
    
                modelJson.put(MODEL_NAME, name);
                modelJson.put(MODEL_DESCRIPTION, description);
                model.setMetaInfo(modelJson.toString());
                model.setName(name);
                model.setVersion(model.getVersion() + 1);
                repositoryService.saveModel(model);
    
                repositoryService.addModelEditorSource(model.getId(), Objects.requireNonNull(json_xml.getBytes(StandardCharsets.UTF_8)));
    
                InputStream svgStream = new ByteArrayInputStream(Objects.requireNonNull(svg_xml.getBytes(StandardCharsets.UTF_8)));
                TranscoderInput input = new TranscoderInput(svgStream);
    
                PNGTranscoder transcoder = new PNGTranscoder();
                // Setup output
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                TranscoderOutput output = new TranscoderOutput(outStream);
    
                // Do the transformation
                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);
            }
        }

    完成上述三个接口,再结合前端,就基本完成了模型的创建、编辑、保存了。至于后续的模型部署、流程实例等等,网上都有很多资料了。

    展开全文
  • 宣传官网 http://xb.exrick.cn 在线Demo http://xboot.exrick.cn 开源版Github地址 https://github.com/Exrick/x-boot 开发文档 https://www.kancloud.cn/exrick/xboot/1009234 ... 集成Activ...
    • 宣传官网 http://xb.exrick.cn
    • 在线Demo http://xboot.exrick.cn
    • 开源版Github地址 https://github.com/Exrick/x-boot
    • 开发文档 https://www.kancloud.cn/exrick/xboot/1009234
    • 获取完整版 http://xpay.exrick.cn/pay?xboot
      在这里插入图片描述

    集成Activiti 5.22,考虑到文档资料较多未选用新版本(模型设计器改动较大)或Flowable

    整合Activiti 5.22

    • 添加依赖,因项目已使用Mybatis-Plus,需在这里排除其mybatis依赖
    <!-- Activiti -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-spring-boot-starter-basic</artifactId>
        <version>5.22.0</version>
        <exclusions>
            <exclusion>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- Activiti流程图 -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-diagram-rest</artifactId>
        <version>5.22.0</version>
    </dependency>
    <!-- Activiti在线设计 -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-modeler</artifactId>
        <version>5.22.0</version>
    </dependency>
    
    • 入口类排除Activiti的Security校验
    // Activiti5.22需要排除Security
    @SpringBootApplication(exclude = SecurityAutoConfiguration.class)
    public class XbootApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(XbootApplication.class, args);
        }
    }
    
    • 配置参考
    # 工作流
    spring:
        activiti:
          check-process-definitions: false
          db-identity-used: true
          # 自动生成Activiti相关表 第一次生成后建议关闭提高运行速度
          database-schema-update: true
          # 保存历史数据级别设置为full最高级别,便于历史数据的追溯
          history-level: full
    

    整合模型设计器

    • 下载Activiti 5.22源码Source Code
      https://github.com/Activiti/Activiti/tree/activiti-5.22.0
      https://github.com/Activiti/Activiti/releases/tag/activiti-5.22.0
      -> https://github.com/Activiti/Activiti/archive/activiti-5.22.0.zip
    • 进入modules目录,拷贝图中圈出所需文件
      https://github.com/Activiti/Activiti/tree/activiti-5.22.0/modules
    • 其中stencilset.json可到网上找汉化版本替换,并确认该文件是否放到了resources目录下,如果不是需要修改StencilsetRestResource.java中"stencilset.json"为"xxx/stencilset.json",因此按上图配置此处需替换为InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("static/stencilset.json");
    • 修改StencilsetRestResource.javaModelEditorJsonRestResource.javaModelSaveRestResource.java就是接口的请求路径前缀,加上@RequestMapping(“xxx”),XBoot中为/xboot/act
    • 接着修改对应app-cfg.js
    ACTIVITI.CONFIG = {'contextRoot' : '/xboot/act', };
    
    • 修改JsonpCallbackFilte.java加上@WebFilter("/xxx/*"),XBoot中为@WebFilter("/xboot/act/*")
    • ModelSaveRestResource.java参数修改
    public void saveModel(@PathVariable String modelId,
                          @RequestParam String name, @RequestParam String description,
                          @RequestParam String json_xml, @RequestParam String svg_xml)
    
    • 测试访问 localhost:8888/modeler.html?modelId=1会出现空白页,集成成功。由于modelId=1随意输入,后台并无id=1的数据,所以报错,具体新建一个模型的接口自行百度即可,当然也可付费获取完整版。
    展开全文
  • 宣传官网 http://xb.exrick.cn 在线Demo http://xboot.exrick.cn 开源版Github地址 https://github.com/Exrick/x-boot 开发文档 https://www.kancloud.cn/exrick/xboot/1009234 获取完整版 ... ...
    展开全文
  • 宣传官网 xb.exrick.cn 在线Demo xboot.exrick.cn 开源版Github地址 github.com/Exrick/x-bo… ... Stomp是一种简单(流)文本定向消息协议,提供了一个可互操作的链接格式。允许stomp客户端与任意sto...

    Stomp是一种简单(流)文本定向消息协议,提供了一个可互操作的链接格式。允许stomp客户端与任意stomp消息代理(Broker)进行交互。STOMP协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用。

    • 添加依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    复制代码
    • 配置类
    /**
     * @author Exrickx
     */
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
    
        /**
         * 注册stomp端点
         * @param registry
         */
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
    
            // 允许使用socketJs方式访问 即可通过http://IP:PORT/ws来和服务端websocket连接
            registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
        }
    
        /**
         * 配置信息代理
         * @param registry
         */
        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
    
            // 订阅Broker名称 user点对点 topic广播即群发
            registry.enableSimpleBroker("/user","/topic");
            // 全局(客户端)使用的消息前缀
            registry.setApplicationDestinationPrefixes("/app");
            // 点对点使用的前缀 无需配置 默认/user
            registry.setUserDestinationPrefix("/user");
        }
    }
    复制代码
    • 由于只做广播和点对点的消息推送,这里只用到订阅发布
        @Autowired
        private SimpMessagingTemplate messagingTemplate;
    
        // 广播
        messagingTemplate.convertAndSend("/topic/subscribe", "您收到了新的系统消息");
    
        // 通过用户ID实现点对点
        messagingTemplate.convertAndSendToUser(id,"/queue/subscribe", "您收到了新的消息");
    复制代码

    转载于:https://juejin.im/post/5cc1416e5188252e78449550

    展开全文
  • 宣传官网 http://xb.exrick.cn 在线Demo http://xboot.exrick.cn 开源版Github地址 https://github.com/Exrick/x-boot 开发文档 https://www.kancloud.cn/exrick/xboot/1009234 ... Stomp是一...
  • 代码介绍 -------------本商品为 :springcloud + Springboot 微服务\分布式 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮)后台框架 :springcloud Greenwich.SR1 + springboot 2.1.4 + activiti6.0.0 + ...
  • 代码介绍 ------------- 本框架为 :springcloud + Springboot 微服务\分布式 ...后台框架 :springcloud Greenwich.SR1 + springboot 2.1.4 + activiti6.0.0 + mybaits + maven + json 接口 前端页面 :html +vue....
  • 代码介绍 -------------本商品为 :springcloud + Springboot 微服务\分布式 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮)后台框架 :springcloud Greenwich.SR1 + springboot 2.1.4 + activiti6.0.0 + ...
  • 后台框架:springboot2.1.2+activiti6.0.0+mybaits+maven+接口前端页面:html +vue.js 形式 jqueryajax 异步跨域 json 格式数据交互 前后分离,前后台分开部署(特别注意,前端用的vue.js, 就是html页面引入vue.js...
  • 后台框架:springboot2.1.2+ activiti6.0.0+ mybaits+maven+接口 前端页面:html +vue.js 形式 jquery ajax 异步跨域 json 格式数据交互 前后分离,前后台分开部署 (特别注意,前端用的vue.js, 就是html页面引入vue...
  • Vue集成activity工作流

    万次阅读 2019-08-17 17:40:38
    由于activiti与系统应用主题样式出入较大,协商后决定将activiti的editor-app放在前台。 ps:内网开发,无图,凭记忆摘取主要内容。 步骤: 将activiti放在public即静态目录下。 通过iframe在相应的前台工作流...
  • 1.模型管理 :web在线流程设计器、预览流程xml、导出xml、部署流程 2.流程管理 :导入导出流程资源文件、查看流程图、根据流程实例反射出流程模型、激活挂起 3.运行中流程:查看流程信息、当前任务...
  • 代码介绍 -------------本商品为 :springcloud + Springboot 微服务\分布式 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮)后台框架 :springcloud Greenwich.SR1 + springboot 2.1.4 + activiti6.0.0 + ...
  • 代码介绍 -------------本商品为 :springcloud + Springboot 微服务\分布式 工作流 前后分离 + 跨域 版本 (权限控制到菜单和按钮)后台框架 :springcloud Greenwich.SR1 + springboot 2.1.4 + activiti6.0.0 + ...
  • 1.代码生成器: [正反双向] (单表、主表、明细表、树形表,快速开发利器) freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面、建表sql脚本、处理类、service等完整模块 2.多数据源:(支持同时连接无数个...

空空如也

空空如也

1 2 3
收藏数 58
精华内容 23
关键字:

vue集成activiti

vue 订阅