高达平台 - 全链路低代码解决方案
本期作者
傅嘉伟
哔哩哔哩资深开发工程师
背景
建设低代码平台的目的,就是通过可视化的方式,加上可复用的建设能力,用较少的投入、以较快的速度来交付应用程序。
我们通过aPaaS架构思路,复用已经实现了的开发能力,解构业务模型,形成更通用的能力,对业务进行快速编排。实现低代码,甚至部分无代码的快速定制应用。将开发模式从做加法,改进为做乘法,48小时内快速定制大部分基础应用。
我们不单需要解决今天的可见需求,同时还需要解决明天潜在的问题。实现更少的投入,更聪明的办法,建设更好的产品,产生更大的价值。
整体架构
我们一直在思考,如何通过简单的架构图,来方便的描述出高达的整体架构,看了一眼我们现有的复杂架构图,我们认为贴出这样一张图不会让大家更加清楚我们的架构,反而会变得非常迷茫,因此考虑到高达的组件过于庞大,中间的逻辑实在过多,我们使用一张非常简单的架构图来进行描述。
就像所有的网站一样,高达分为三个部分:页面,逻辑,数据用户通过页面,访问API接口,APi接口一方面处理大量的业务逻辑,另一方面对内部和外部的数据进行处理
更进一步的:在实现了基本的 可搭建 能力之外,高达提供了大量 好搭,易搭,速搭的能力,包括内外部数据管理,服务编排等重要能力
高达平台-六大引擎
数据管理引擎 | 服务编排引擎 |
外部连接器引擎 | 发布管理引擎 |
前端页面引擎 | |
报表引擎 | |
我们改变了原有的开发模式
一些业务的单个页面,我们仅通过10分钟即可完成该页面从数据库建设,后端逻辑搭建,前端页面搭建,到最终的发布上线
核心逻辑
1. 数据管理-元数据
后端逻辑
高达的数据管理我们使用业务模型进行列的管理,而并非数据库模型的方式,例如varchar,int,datetime等,因为配置的同学可能并不了解这是什么意思。因此,我们决定使用一种更加容易理解的业务模型进行数据的管理。
同时业务模型也可以将大量的业务逻辑进行封装,让用户不会感知,举个例子:
员工类型:会底层会将选择的员工转换为员工ID,整个高达全链路的数据传递中,用户并不会感知有这个ID的存在。
地理位置类型:会通过高德地图的组件进行坐标的管理,将最终的经纬度存储在数据库里,但是用户全程看到的都是一个坐标。
附件类型:会自动向BFS进行上传,并记录下文件下载路径,整个逻辑都是自动化完成的,用户只会看到最终文件的上传与下载
前端逻辑
同时最终界面的搭建,可以直接生成最终的界面表单,来提升整体的效率。将一个后端数据表,自动生成前端的增删改查,是一个非常容易的步骤,只需要将增删改查组件拖入界面中,选择对应的元数据表即可。
我们也可以针对页面做字段做更细化的管理
目前我们已经支持的字段类型如下:
1. 基础类型:单行文本,多行文本,数字,日期,单选,多选,布尔
2. 业务类型:人员,部门,地理位置,附件
3. 关联类型:单向关联,双向关联
4. 系统字段:编号,创建人,创建时间,更新人,更新时间
当然未来根据业务场景,我们还会继续增加各种各样的数据类型
数据表关联
当配置关联类型字段时,我们会在底层创建中间表,来实现表之间关联,包括一对多,多对多,多对一等关系
外部数据源管理
管理数据库:高达为达到连接外部数据能力的需求,对外部数据源进行了管理,这里的账号密码部分都为AES2.0逐行秘钥进行加密。
数据表关联:在添加完数据源后,可以数据管理中添加进行数据表关联,便于后续直接对外部数据进行管理。
数据管理:外部数据添加后,在增删改查空间中选择外部数据源,可以在用户端一键完成增删改查的需求
2. 服务编排
我们整体通过逻辑编排的方式进行管理
接口管理
首先针对API,我们可以管理他的分组,名字,请求类型,以及服务间认证方式,其中服务间调用认证我们目前支持JWT,OAuth2,bilibiliToken三种方式
实现逻辑:我们会分别针对这三种不同的认证方式,开启三个不同的入口,并将开启三种认证方式的接口注册到分别的入口上
编排逻辑
创建接口之后,我们将所有的代码逻辑,区分了六大块类型:
逻辑控制:循环,分之,退出循环,继续循环,退出程序
变量管理:设置变量,编码转换
数据管理:针对数据的增删改查
服务调用:连接器,调用流程(待开发)
消息通知:短信,企微,邮件
高级:自定义脚本,加密(待开发),多线程(待开发),文件操作(待开发),SQL管理(待开发)
其中,只有逻辑控制类型的节点,才会对整条链路的走向造成改变,除此之外,所有节点都是从上往下运行。
图形的方案
为什么我们选择树形图?
DAG-有向图:如果不使用树形图,可以随意拖动节点的位置,看似灵活,但实际上,我们每个节点在图中的位置会随着管理员的不同,变得越发混乱。
空间利⽤率低,复杂逻辑难以看懂
随意连线容易导致逻辑混乱(goto)
容易死循环
树形图:经过大量的讨论于研究,决定在服务编排中使用树形图,树形图有以下优点
展现简洁,不会出现交叉连线
可折叠分⽀,容易实现复杂逻辑
可以转成等价的代码,开发者易懂
DSL编码
我们并不会将配置的逻辑,直接转换成代码,我们会在配置后,生成DSL编码作为中间层进行存储,DSL可以向上转换为界面上的配置显示,也可以向下转换为真实的运行代码。
这里源代码的显示我们会将用于处理错误,和日志记录的代码进行隐藏,但是点击【显示完整代码】的按钮后,将会显示完整代码
DSL转换逻辑:通过DSL作为中间层进行转换
代码模板化
伪代码层,我们通过MagicScript(https://github.com/magic-script)引擎来实现,可以将我们预编写好的代码,进行实时执行。
早期我们使用字符串拼接的方式来拼接MagicScript代码,但是经过一段时间的尝试,我们发现这种方式开发成本过高,使用起来也非常麻烦。
因此我们开始转向模板化的方式,我们研究了freeMaker(http://freemarker.foofun.cn/)的方式,并通过参数来传入对应的关键字,这样,我们代码本体的开发,就与正常写代码没有区别,可以大大提升我们的开发效率,以及后期的使用效率。
变量管理
所有的代码逻辑,对变量的管理,无论是类型,还是公式的计算,都是非常核心的部分。
公式计算器:我们精心设计了整个公式计算器,来非常方便的通过鼠标来完成核心计算逻辑的运行,我们可以在左边预设的逻辑中选择需要运行的逻辑,然后在中间【字段】列表中,选择当前上下文环境的所有变量,这里我们会对字典&映射类型,进行结构,直接获取字典下某个key的值,右边可以看到最终的公式,也可以通过键盘来手动输入
编码的转换:我们单独抽出了节点来进行转换,其中包括base64编码,URI编码,JSON编码的转换
数据映射
我们可以针对数据进行三种类型的映射,当需要将1替换为启用,2替换为禁用:
1. 字符串映射:"121" 需要替换为 "启用禁用启用"
2. 数组映射:[1,2,1]需要替换为[ "启用", " 禁用", "启用"]
3. 字典映射:{a: 1, b: 2}需要替换为{a: "启用", b: "禁用"}
我们将这类映射逻辑进行抽象,抽出单独节点,用于解决该类数据映射逻辑
调试
项目早期,我们针对调试功能做了大量的讨论,为了可以在整个API配置的过程中,可以进行充分的测试以及排错,我们大量的设计了调试的能力,来便于配置着进行调试。
其中除了看到调试的结果之外,我们会针对流程中每个节点的成功失败,耗时,当前的上下文作用域变量,进行管理。
当鼠标放在运行日志的每一行时,该行日志实际运行节点,都会进行交互提示。
其他
1. 节点的复制与粘贴:我们经常会对一段代码进行复制功能
2. 行列切换:由于正常显示器的尺寸,宽度是比高度要大的,当出现大部分单条路线的逻辑时,分支较少情况,可以进行横向的显示。
3. 注释:我们可以一键显示/隐藏全量的日志
4. 操作日志:我们分别针对当前的本次操作,以及历史保存的版本进行了日志的保存,可以随时进行回滚,以及发布
当前本地:可以通过右上角的【操作日志】按钮,查看每一次变更的内容
版本:当每次右上角点击【保存】按钮后,都会生成一个版本,可以通过【历史版本】按钮对某一次版本进行发布
5. 接口文档
通过【接口文档】按钮,可以针对接口,自动化的生成接口的文档,方便前端,或者外部系统对API进行调用
连接器
术语说明
连接器:先解释一下什么是连接器,连接器是用于连接外部资源,包括HTTP,HTTPS,discovery等外部API,我们可以提前定义好外部API的认证方式
动作:单个连接器下我们可以定义大量动作,每个动作相当于该调用方的多个API的地址
例如:我们可以针对企业微信开发一个连接器,其中发送文本消息就是该连接器的一个动作
基本信息
创建连接器之后,我们需要分别设置连接器的基本信息,包括说明,域名,协议,认证方式
认证方式可以获取获取到一串token,并且可以在未来的访问中,定义token放在哪个位置,包括header头,URL参数,body体中
动作
我们可以为一个连接器定义多个动作,每个动作代表一个请求接口,定义URL,请求方式,入参等,同时可以提前定义好入参的值,也可以定义为动态值,在后续调用侧(页面,服务编排)中进行传入
请求测试
可以针对请求进行测试,并针对返回信息进行解构,并定义多个返回参数的中文含义,最终在页面,或者服务编排中调用时,将会直接使用该中文定义进行操作,并且无需关注该字段在返回JSON中的位置。
前端页面
我们定义了企微发送消息的连接器,需要接受两个参数,1接受用户,2发送内容,我们可以在按钮上绑定一个连接器事件,并将两个入参绑定到最终的页面元素上,即可完成绑定
4. 页面搭建
创建页面
页面管理中,我们可以针对目录和页面进行管理,同时也可以通过拖动,对整个菜单的位置进行调整。
我们可以创建本地页面,也可以通过iframe嵌入外部页面
页面配置
前端组件层面,我们分成了三种类型
定制组件:经过开发,高度整合的整套组件
原子组件:按钮,输入框,文本等50+个最基本单元的组件,可以通过这类组件搭建出几乎所有页面效果
自定义组件:与其他部门合作实现的前端组件库,以及
搭建模块
页面核心模块,底层为阿里的Low-Code Engine:https://lowcode-engine.cn/site/docs/guide/quickStart/intro
依赖于通过该组件,封装了大量底层搭建逻辑,同时我们针对组件,事件,数据等模块进行了大量的二开,来满足我们更高封装度的低代码要求
发布管理
高达我们可以针对页面与接口进行发布,但是数据层面,类似于我们生产的开发模式,表和列修改都会立刻生效。
页面发布
页面发布管理中,我们可以看到当前
线上的版本:最后一次发布的版本
可发布页面:基于线上版本,出现修改的页面
历史版本:历史上每一次发布的页面
针对这些版本和页面,我们可以进行发布和回滚操作
接口发布
服务编排中,可以针对接口进行版本的发布与回滚
高度封装的可搭建能力
1. 触发器
往往我们在数据进行变更的时候,都会进行一些外部接口的同步,因此我们提供了数据触发器的能力,在数据变更的前后进行服务编排或者连接器的调用
触发时机:我们可以配置触发器触发的表,以及时机,目前支持新增,修改,删除三种场景
触发条件:我们可以提供过滤器,来过滤触发时候的判断条件
触发动作:我们可以分别选择触发的连接器还是服务编排,并将当前本次数据变更的内容作为参数传入触发动作
出参管理:最后,我们可以根据服务编排与连接器的返回信息,再次将内容回写到数据表中
2. 数据视图
往往我们并不会直接调用单独一张表的数据,我们会需要对多张表进行整合,汇总,行列计算等操作,形成一张数据更加全面的表,因此我们提供了数据视图的能力,整体原理类似于数据库的存储过程。
视图数据:我们可以对一张或者多张关联表的数据进行拼接整合
行列计算:这个过程中,我们可以将一列,或者一行的数据进行行列计算,具体行列计算的含义如下:
行列计算字段我们也提供了丰富的数据库计算公式,提升开发效率
过滤筛选:视图底部,我们提供了视图的筛选能力,同时筛选的参数,可以当场指定,也可以从调用视图的接口处进行获取
实现原理:与服务编排的理念一致,我们会将这段配置生成一段DSL,通过DSL可以生成最终的SQL,也可以还原微最初的视图配置。
页面端:当我们创建一个饼图时,我们可以再右侧选择对应的视图来选择数据源,同时设定对应的分类字段和值字段,最后我们可以在左上角,添加筛选控件,对视图本身进行筛选。
3. 定时任务
定时任务可以对服务编排的接口做定时任务处理,可以方便的配置定时器,失败通知等功能。
应用配置
应用配置是对高达当前应用的整体性配置,包括基础信息维护、菜单管理、字典管理、权限管理、通知管理、外部数据源管理
1. 基础信息
基础信息中可以对项目名称、图标和描述等信息进行修改,同时支持对前端SDK(lunar,oa酱,水印)接入做配置;
2. 菜单管理
菜单管理里可以对搭建项目的整体外层框架进行配置,包括:
菜单位置:可以是左右模式,上下模式,也可以是顶部菜单栏
主题配色:目前支持暗色系主题和明亮主体
logo:左上角的显示logo,默认为bilibili
首页信息:设置不输入PATH的情况首页地址
3. 字典管理
在高达项目中,可以创建K/V类型字典,也可以创建树状结构字典
字典管理分为两个部分:全局字典与项目字典
1. 全局的字典:全局字典可以被项目关联,例如性别,国家,银行等通用字典,都可以作为全局字典使用。
2. 项目层级的字典:项目中可以套用全局字典,也可以创建项目自身的字典,项目字典不会被其他项目所调用。
4. 权限管理
对于高达配置的C端页面,可以进行全量页面的权限配置,高达默认会提供两种角色:超级管理员、默认角色,同时也可以添加其他更多自定义角色的管理。
超级管理员:拥有所有页面的权限且页面权限不可更改,用户可以添加;
默认角色:用户是全体员工且不可更改,对应的页面权限可以修改;
5. 通知管理
服务编排等多个场景中,发送短信、邮件、企微消息的通知,此处维护了各类通知的模板。
业务接入
高达自从上线至今,已经承接 26 个平台的搭建任务,其中包括包括人事,财务,法务,采购,行政,主站等各类系统,按照页面和接口数量结算,节约了300~400人日的资源投入。高达在一定程度上证明了全链路低代码系统的可行性,其中包含:
增删改查表单类:
通知管理类的系统:HR通知系统
问卷调研类系统:晋升问卷
中台管理+接口API类型:节假日管理
高达自己搭建自己的页面:高达项目管理
企微工具:服务号侧边栏
以上是今天的分享内容,如果你有什么想法或疑问,欢迎大家在留言区与我们互动,如果喜欢本期内容的话,欢迎点个“在看”吧!
往期精彩指路