当前位置: 首页 > news >正文

Flowable 与 bpmn.io@7.0 完整集成示例 Demo

Flowable 与 bpmn.io@7.0 完整集成示例 Demo

下面是一个完整的前后端集成示例,包含前端使用 bpmn.js 7.0 和与 Flowable 后端交互的实现。

1. 后端实现 (Spring Boot + Flowable)

1.1 添加依赖 (pom.xml)

<dependencies><!-- Spring Boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Flowable --><dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>6.7.0</version></dependency><!-- 其他必要依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
</dependencies>

1.2 应用配置 (application.yml)

server:port: 8080spring:datasource:url: jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1username: sapassword:driver-class-name: org.h2.Driverh2:console:enabled: truepath: /h2-consoleflowable:async-executor-activate: falsedatabase-schema-update: true

1.3 控制器 (FlowableController.java)

@RestController
@RequestMapping("/api")
public class FlowableController {@Autowiredprivate RepositoryService repositoryService;@Autowiredprivate RuntimeService runtimeService;// 部署流程@PostMapping("/deploy")public ResponseEntity<?> deployProcess(@RequestParam("file") MultipartFile file) {try {Deployment deployment = repositoryService.createDeployment().addBytes(file.getOriginalFilename(), file.getBytes()).deploy();return ResponseEntity.ok(Map.of("deploymentId", deployment.getId(),"deploymentName", deployment.getName(),"deploymentTime", deployment.getDeploymentTime()));} catch (Exception e) {return ResponseEntity.badRequest().body(e.getMessage());}}// 获取流程定义XML@GetMapping("/process-definition/{id}/xml")public ResponseEntity<?> getProcessDefinitionXml(@PathVariable String id) {try {ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());String xml = IOUtils.toString(resourceAsStream, StandardCharsets.UTF_8);return ResponseEntity.ok(xml);} catch (Exception e) {return ResponseEntity.badRequest().body(e.getMessage());}}// 获取流程定义列表@GetMapping("/process-definitions")public ResponseEntity<?> getProcessDefinitions() {List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().latestVersion().list();List<Map<String, Object>> result = processDefinitions.stream().map(pd -> Map.of("id", pd.getId(),"name", pd.getName(),"key", pd.getKey(),"version", pd.getVersion(),"deploymentId", pd.getDeploymentId())).collect(Collectors.toList());return ResponseEntity.ok(result);}
}

1.4 安全配置 (SecurityConfig.java)

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.cors().and().csrf().disable().authorizeRequests().antMatchers("/api/**").authenticated().and().httpBasic();}@BeanCorsConfigurationSource corsConfigurationSource() {CorsConfiguration configuration = new CorsConfiguration();configuration.setAllowedOrigins(Arrays.asList("*"));configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));configuration.setAllowedHeaders(Arrays.asList("*"));UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", configuration);return source;}
}

2. 前端实现 (React + bpmn.js)

2.1 项目初始化

npx create-react-app flowable-bpmn-demo
cd flowable-bpmn-demo
npm install bpmn-js@7.0.0 axios

2.2 BPMN 编辑器组件 (BpmnEditor.js)

import React, { useEffect, useRef, useState } from 'react';
import BpmnModeler from 'bpmn-js/lib/Modeler';
import 'bpmn-js/dist/assets/diagram-js.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
import axios from 'axios';
import './BpmnEditor.css';const BpmnEditor = () => {const containerRef = useRef(null);const modelerRef = useRef(null);const [processDefinitions, setProcessDefinitions] = useState([]);const [selectedDefinition, setSelectedDefinition] = useState(null);const [xml, setXml] = useState('');// 初始化建模器useEffect(() => {if (containerRef.current && !modelerRef.current) {modelerRef.current = new BpmnModeler({container: containerRef.current,keyboard: { bindTo: document }});// 创建新流程图createNewDiagram();}// 加载流程定义列表loadProcessDefinitions();return () => {if (modelerRef.current) {modelerRef.current.destroy();}};}, []);// 创建新流程图const createNewDiagram = async () => {try {const result = await modelerRef.current.createDiagram();console.log('Diagram created');} catch (err) {console.error('Could not create diagram', err);}};// 加载流程定义列表const loadProcessDefinitions = async () => {try {const response = await axios.get('http://localhost:8080/api/process-definitions', {auth: {username: 'admin',password: 'test'}});setProcessDefinitions(response.data);} catch (error) {console.error('Error loading process definitions:', error);}};// 加载特定流程定义const loadProcessDefinition = async (definitionId) => {try {const response = await axios.get(`http://localhost:8080/api/process-definition/${definitionId}/xml`,{auth: {username: 'admin',password: 'test'}});await modelerRef.current.importXML(response.data);setXml(response.data);setSelectedDefinition(definitionId);} catch (error) {console.error('Error loading process definition:', error);}};// 保存当前流程图const saveDiagram = async () => {try {const { xml } = await modelerRef.current.saveXML({ format: true });setXml(xml);const formData = new FormData();const blob = new Blob([xml], { type: 'text/xml' });formData.append('file', blob, 'process.bpmn');const response = await axios.post('http://localhost:8080/api/deploy', formData, {headers: {'Content-Type': 'multipart/form-data'},auth: {username: 'admin',password: 'test'}});alert(`Deployed successfully! Deployment ID: ${response.data.deploymentId}`);loadProcessDefinitions();} catch (error) {console.error('Error saving diagram:', error);}};return (<div className="bpmn-editor-container"><div className="toolbar"><button onClick={createNewDiagram}>New Diagram</button><button onClick={saveDiagram}>Save/Deploy</button><select value={selectedDefinition || ''}onChange={(e) => loadProcessDefinition(e.target.value)}><option value="">Load Process Definition</option>{processDefinitions.map((pd) => (<option key={pd.id} value={pd.id}>{pd.name || pd.key} (v{pd.version})</option>))}</select></div><div className="canvas" ref={containerRef}></div><div className="xml-viewer"><h3>BPMN XML</h3><textarea value={xml} onChange={(e) => setXml(e.target.value)}rows="20"/></div></div>);
};export default BpmnEditor;

2.3 样式文件 (BpmnEditor.css)

.bpmn-editor-container {display: flex;flex-direction: column;height: 100vh;
}.toolbar {padding: 10px;background: #f5f5f5;border-bottom: 1px solid #ddd;
}.toolbar button, .toolbar select {margin-right: 10px;padding: 5px 10px;
}.canvas {flex: 1;height: 60%;border: 1px solid #ccc;
}.xml-viewer {height: 30%;padding: 10px;border-top: 1px solid #ddd;
}.xml-viewer textarea {width: 100%;height: calc(100% - 30px);font-family: monospace;
}

2.4 主应用组件 (App.js)

import React from 'react';
import './App.css';
import BpmnEditor from './BpmnEditor';function App() {return (<div className="App"><header className="App-header"><h1>Flowable + bpmn.js Integration Demo</h1></header><main><BpmnEditor /></main></div>);
}export default App;

3. 运行说明

3.1 启动后端

  1. 启动 Spring Boot 应用
  2. Flowable 会自动创建必要的数据库表
  3. 后端将在 http://localhost:8080 运行

3.2 启动前端

  1. 运行 npm start
  2. 前端将在 http://localhost:3000 运行
  3. 使用默认凭据登录 (admin/test)

4. 功能说明

  1. 新建流程图:创建空白的 BPMN 流程图
  2. 保存/部署:将当前流程图保存并部署到 Flowable
  3. 加载流程:从 Flowable 加载已部署的流程定义
  4. XML 查看/编辑:查看和编辑 BPMN XML

5. 扩展建议

  1. 添加 Flowable 特定属性面板
  2. 集成 Flowable 表单设计器
  3. 添加流程实例启动和监控功能
  4. 实现更完善的用户认证和授权

这个完整示例展示了如何将 bpmn.js 7.0 与 Flowable 后端集成,实现流程建模、部署和管理的完整功能。

相关文章:

  • 解决IntelliJ IDEA配置文件(application.properties)中文注释变成乱码的问题
  • 明远智睿2351开发板:四核1.4G处理器——开启高效能Linux系统新纪元
  • 耀百岁中医养生与上海隽生中医药研究中心达成战略合作——共筑中医养生科研创新高地
  • 【JavaEE】-- MyBatis操作数据库(1)
  • spring中使用netty-socketio部署到服务器(SSL、nginx转发)
  • STM32F103C8T6 HAL库 U盘模式(MSC)
  • Pycharm(十五)面向对象程序设计基础
  • Linux 内核中 cgroup 子系统 cpuset 是什么?
  • 【专题刷题】滑动窗口(三)
  • 【系统架构设计师】嵌入式微处理器
  • 2025-04-22| Docker: --privileged参数详解
  • Ansys Zemax | 在 MATLAB 中使用 ZOS-API 的技巧
  • 最美丽的区间
  • Trino分布式 SQL 查询引擎
  • [Java · 铢积寸累] 数据结构 — 数组类型 - 概念引入
  • 【数据结构和算法】5. 堆栈和队列
  • 算法基础_数据结构【KMP + Trie 树 + 并查集 】
  • postgreSQL 如何使用 dblink
  • 微信小程序拖拽排序有效果图
  • 机器人进阶---视觉算法(六)傅里叶变换在图像处理中怎么用
  • 被指违反代理协议遭南航暂停售票资格, 去哪儿网:今起恢复
  • 西藏艺术来到黄浦江畔,“隐秘之门”艺术展外滩三号开幕
  • 徐州沛县一村委会因无资质处理固废,被环保部门罚款19万元
  • 夜读丨“看看世界”本身就是一种意义
  • 2025年世界互联网大会亚太峰会人工智能大模型论坛举行
  • 聚餐醉酒后骑车撞树身亡、家属起诉共饮者赔44万,法院已判