基于mxgraph的web流程设计器(bpm)

本文介绍了一个基于mxGraph和JBPM的Web流程设计器的实现过程,包括自定义工具条、节点及复合节点的设计,并探讨了数据结构定义与转换等关键技术。

这段时间由于公司要做一个基于jbpm的服务产品(基于商业原因,产品细节不便透漏),需要一个基于web的流程设计器。外话是我是刚进公司的,当时项目组也正头疼,没得什么思路。我们选择了画图功能比较强大的mxgraph,实现web的流程设计器。很长一段时间,由于又要了解jbpm,又研究mxgraph,感觉压力特别大。特别是mxgraph,国内用的人不多,又没有中文文档,只能硬着头皮干了。有一段比较昏暗的日子,个人感情上的(不提了),工作上的压力。慢慢的在技术上的小突破,产品也有了思路。现在有点眉目了,产品也见了雏形,算是对自己最大的安慰了。经过这一段,感觉自己长大了很多。在感情上算是从那一段走出来了,明显感觉自己成熟多了,不再是那个一根茎的样子。在技术上也学到了很多东西,对jbpmmxgraph都有了一定了解。自己的想法在产品中得到验证,从数据中抽象出结构,到产品架构,到代码优化。这两方面的技术,在我都算是新东西,从无到有,也让我更加自信自己的能力吧,哈哈。拉远了,这里主要说说mxgraph吧。

magraph在画图和流程处理方面,真的是不错。浏览器支持比较好,扩展性强,而且是纯js的,给基于web的画图提供了强大的工具。当然如果要用的好,得有一定的文档阅读能力和js等前端开发能力。流程设计器这块主要使用了mxgraph的画图工具,涉及uiconfigtoolbar,port等。实现了自定义工具条,自定义节点,复合节点(graph.xml和引用)。其中的数据结构定义和mxgraph.xml转成jpdl.xml是精华(用到面向对象和数据结构的东西)。还是,上图吧,呵呵。

主流程设计界面:

https://img-my.youkuaiyun.com/uploads/201302/02/1359795171_8666.jpg

复合节点定义:

https://img-my.youkuaiyun.com/uploads/201302/02/1359795556_7403.jpg

复合结点在工流程中的表现:

https://img-my.youkuaiyun.com/uploads/201302/02/1359795556_6036.jpg

由于写东西的水平有限,这里只是介绍了实现的基本思路,当然这一块的使用也在不断完善中。希望能对在这一块迷惘的同志有点帮助;希望有感兴趣的人一讨论; 更加希望得到前辈好的建议。

注:平时不经常在csdn,如果有问题或者有好建议可以给我发邮件:shanzhu.es@gmail.com.

### 使用 Gin 框架实现 CRUD(增删改查)操作 #### 创建项目结构并初始化依赖项 为了使用 GinGORM 来处理 CRUD 操作,首先需要设置好 Go 项目的环境。安装必要的包: ```bash go mod init example.com/gin-crud-demo go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/sqlite ``` #### 定义数据模型 定义 `Product` 结构体作为数据库中的表模型[^2]。 ```go type Product struct { gorm.Model Code string Price uint } ``` #### 初始化数据库连接 建立与 SQLite 数据库的连接,并自动迁移模式以创建相应的表格。 ```go import ( "gorm.io/driver/sqlite" "gorm.io/gorm" ) func InitDB() *gorm.DB { db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) if err != nil { panic("failed to connect database") } // 自动迁移模式 db.AutoMigrate(&Product{}) return db } ``` #### 设置路由和控制器逻辑 编写 HTTP API 路由以及对应的业务逻辑函数来完成 CRUD 功能。 ```go package main import ( "net/http" "github.com/gin-gonic/gin" ) var DB = InitDB() // 获取所有产品列表 func GetProducts(c *gin.Context) { var products []Product result := DB.Find(&products) if result.Error != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error}) return } c.JSON(http.StatusOK, products) } // 添加新产品 func CreateProduct(c *gin.Context) { var input Product if err := c.ShouldBindJSON(&input); err == nil { createErr := DB.Create(&input).Error if createErr != nil { c.JSON(http.StatusBadRequest, gin.H{"error": createErr}) return } c.JSON(http.StatusOK, input) } else { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } } // 更新指定ID的产品信息 func UpdateProduct(c *gin.Context) { id := c.Params.ByName("id") var product Product if err := DB.Where("id = ?", id).First(&product).Error; err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"}) return } updateErr := DB.Model(&product).Updates(Product{Code: c.PostForm("code"), Price: c.PostFormUint("price")}).Error if updateErr != nil { c.JSON(http.StatusBadRequest, gin.H{"error": updateErr}) return } c.JSON(http.StatusOK, product) } // 删除指定ID的产品记录 func DeleteProduct(c *gin.Context) { id := c.Params.ByName("id") var product Product d := DB.Delete(&product, id) if d.Error != nil { c.JSON(http.StatusBadRequest, gin.H{"error": d.Error}) return } c.JSON(http.StatusOK, gin.H{"id #" + id: "deleted"}) } func SetupRouter() *gin.Engine { r := gin.Default() apiV1 := r.Group("/api/v1") { apiV1.GET("/products", GetProducts) apiV1.POST("/products", CreateProduct) apiV1.PUT("/products/:id", UpdateProduct) apiV1.DELETE("/products/:id", DeleteProduct) } return r } func main() { router := SetupRouter() router.Run(":8080") } ``` 此代码片段展示了如何利用 Gin 框架配合 GORM ORM 库执行基本的数据持久化任务——即所谓的 CRUD 操作。每种操作都对应着 RESTful 风格下的不同 URL 地址及其请求方法[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值