Ingenious-Designer-Layui:工作流设计器的前端实现
本文详细介绍了基于LayUI框架的工作流设计器前端实现方案,涵盖核心模块集成、拖拽式界面设计、连线管理与流转规则以及JSON导入导出功能。通过深度集成LayUI框架,项目提供了高效、灵活的工作流设计解决方案。
LayUI框架的深度集成
Ingenious-Designer-Layui 通过深度集成 LayUI 框架,为开发者提供了一套高效、易用的工作流设计器前端实现方案。以下将从核心模块、配置管理和扩展功能三个方面,详细介绍 LayUI 框架在项目中的深度集成。
核心模块集成
LayUI 的核心模块通过 layui.use 和 layui.config 方法进行加载和配置。例如,在 component/layui/layui.js 中,LayUI 的初始化代码如下:
layui.use(['layer', 'form', 'table'], function() {
var layer = layui.layer;
var form = layui.form;
var table = layui.table;
// 模块初始化逻辑
});
通过这种方式,项目可以按需加载 LayUI 的模块,避免不必要的资源浪费。
配置管理
项目中的配置管理通过 pear.config 实现,支持动态加载和覆盖默认配置。例如,在 component/pear/module/admin.js 中,配置文件的路径和实现逻辑如下:
this.configurationPath = "pear.config.yml";
// 获取 pear.config 实现
function getConfigImplementation() {
return require(this.configurationPath);
}
通过这种方式,开发者可以灵活地管理项目配置,满足不同环境的需求。
扩展功能
LayUI 的扩展功能通过自定义模块实现。例如,项目中集成了以下自定义模块:
| 模块名称 | 功能描述 |
|---|---|
pear.js | 核心模块,提供基础功能 |
iconfont.js | 图标字体管理 |
dtree.js | 树形结构组件 |
fullscreen.js | 全屏功能支持 |
messageCenter.js | 消息中心功能 |
这些模块通过 pear.use 方法加载,例如:
pear.use(['dtree', 'fullscreen'], function() {
// 模块初始化逻辑
});
集成流程图
以下是通过 Mermaid 绘制的 LayUI 框架集成流程图:
通过以上方式,Ingenious-Designer-Layui 实现了与 LayUI 框架的深度集成,为开发者提供了高效、灵活的工作流设计器前端解决方案。
拖拽式界面设计与实现
Ingenious-Designer-Layui 的工作流设计器采用了拖拽式界面设计,极大地提升了用户体验和开发效率。本节将详细介绍其实现原理和核心代码。
核心组件与模型
设计器的拖拽功能主要依赖于 LogicFlow 的节点模型和视图。以下是自定义节点 CustomModel 和 CustomView 的实现:
class CustomModel extends RectNodeModel {
static extendKey = 'CustomModel';
constructor(data, graphModel) {
super(data, graphModel);
if (data.properties) {
let temporaryStyle = data.properties.style ?? {};
this.width = temporaryStyle.width ? temporaryStyle.width : 120;
this.height = temporaryStyle.height ? temporaryStyle.height : 40;
}
}
getTextStyle() {
const style = super.getTextStyle();
const properties = super.getProperties();
style.color = properties.color ?? '#000000';
return style;
}
getNodeStyle() {
const style = super.getNodeStyle();
const properties = super.getProperties();
if (this.properties.state === 'active') {
style.stroke = '#00ff00';
} else if (this.properties.state === 'history') {
style.stroke = '#ff0000';
} else {
style.fill = properties.theme ?? '#FFFFFF';
style.stroke = properties.stroke ?? '#000000';
style.strokeWidth = properties.stroke_width ?? 2;
}
return style;
}
}
class CustomView extends RectNode {
static extendKey = 'CustomNode';
getLabelShape() {
const { model } = this.props;
const { x, y, width, height } = model;
const style = model.getNodeStyle();
return h(
'svg',
{
x: x - width / 2 + 5,
y: y - height / 2 + 5,
width: 30,
height: 30,
viewBox: '0 0 1274 1024',
},
h('path', {
fill: style.stroke,
d: 'M882.527918 434.149934c-2.234901-5.303796-7.311523-8.853645-13.059434-9.138124l-61.390185-3.009544c-6.635117-20.973684-15.521508-41.175795-26.513864-60.282968l42.051745-47.743374c...',
})
);
}
getShape() {
const { model } = this.props;
const { x, y, width, height, radius } = model;
const style = model.getNodeStyle();
return h('g', {}, [
h('rect', {
x: x - width / 2,
y: y - height / 2,
rx: radius,
ry: radius,
width,
height,
...style,
}),
this.getLabelShape(),
]);
}
}
const Custom = {
type: 'ingenious:custom',
view: CustomView,
model: CustomModel,
};
拖拽功能实现
拖拽功能的核心是通过监听鼠标事件来实现节点的移动和放置。以下是关键步骤:
- 事件监听:监听
mousedown、mousemove和mouseup事件。 - 节点移动:在
mousemove事件中更新节点的位置。 - 放置节点:在
mouseup事件中完成节点的放置。
样式与交互优化
为了提高用户体验,设计器对节点的样式和交互进行了优化:
- 动态样式:根据节点的状态(如
active或history)动态调整样式。 - 标签显示:通过
getLabelShape方法自定义节点的标签显示。
表格:节点属性配置
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
width | number | 120 | 节点宽度 |
height | number | 40 | 节点高度 |
color | string | #000000 | 文本颜色 |
theme | string | #FFFFFF | 节点填充颜色 |
stroke | string | #000000 | 节点边框颜色 |
stroke_width | number | 2 | 节点边框宽度 |
总结
通过 LogicFlow 的扩展机制,Ingenious-Designer-Layui 实现了高度灵活的拖拽式界面设计。开发者可以轻松自定义节点样式和行为,满足复杂的工作流设计需求。
连线管理与流转规则
在Ingenious-Designer-Layui中,连线管理与流转规则是工作流设计器的核心功能之一。通过连线,用户可以定义节点之间的逻辑关系,而流转规则则决定了工作流在不同条件下的执行路径。本节将详细介绍连线的定义、配置以及流转规则的实现方式。
连线的定义与配置
连线(Transition)是工作流中节点之间的连接线,用于表示节点之间的流转关系。在项目中,连线通过transition.js文件定义,其核心属性如下:
type: 'ingenious:transition',
properties: {
id: 'string',
display_name: 'string',
type: 'string',
width: 'number',
height: 'number',
theme: 'string',
stroke: 'string',
color: 'string',
stroke_width: 'number',
pre_interceptors: 'array',
post_interceptors: 'array',
expr: 'string'
}
属性说明
| 属性名 | 类型 | 描述 |
|---|---|---|
id | string | 连线的唯一标识符。 |
display_name | string | 连线的显示名称,用于界面展示。 |
type | string | 连线类型,固定为ingenious:transition。 |
width | number | 连线的宽度。 |
height | number | 连线的高度。 |
theme | string | 连线的主题样式。 |
stroke | string | 连线的描边颜色。 |
color | string | 连线的填充颜色。 |
stroke_width | number | 连线的描边宽度。 |
pre_interceptors | array | 连线执行前的拦截器列表,用于前置条件检查。 |
post_interceptors | array | 连线执行后的拦截器列表,用于后置处理。 |
expr | string | 连线的条件表达式,用于动态决定是否允许流转。 |
流转规则的实现
流转规则通过expr属性实现,它是一个条件表达式,用于动态判断是否允许节点之间的流转。例如:
expr: '${status} === "approved"'
上述表达式表示只有当status变量的值为"approved"时,才允许通过该连线流转。
拦截器的使用
拦截器(Interceptors)是流转规则的重要组成部分,分为前置拦截器(pre_interceptors)和后置拦截器(post_interceptors)。它们可以用于以下场景:
- 前置拦截器:在连线执行前进行权限检查或数据验证。
- 后置拦截器:在连线执行后进行日志记录或数据更新。
示例:连线与流转规则
以下是一个完整的连线配置示例,展示了如何定义一条带有条件表达式和拦截器的连线:
{
id: 'transition_1',
display_name: 'Approval Transition',
type: 'ingenious:transition',
width: 2,
height: 2,
theme: 'default',
stroke: '#1890ff',
color: '#ffffff',
stroke_width: 1,
pre_interceptors: ['checkPermission'],
post_interceptors: ['logTransition'],
expr: '${status} === "approved"'
}
流程图示例
通过Mermaid流程图,可以更直观地展示连线与流转规则的关系:
总结
连线管理与流转规则是工作流设计器的关键功能,通过灵活的配置和条件表达式,可以实现复杂的业务逻辑流转。开发者可以根据实际需求,自定义连线的样式、拦截器和条件表达式,以满足不同场景的需求。
JSON导入导出功能
在Ingenious-Designer-Layui中,JSON的导入导出功能是实现工作流设计器数据交互的核心能力之一。通过JSON格式,用户可以轻松地将设计好的工作流保存到本地,或者从外部导入已有的工作流配置,从而实现快速迁移和复用。
功能概述
JSON导入导出功能主要包括以下两部分:
- 导出功能:将当前设计器中的工作流数据转换为JSON格式,并支持下载到本地。
- 导入功能:解析上传的JSON文件,将其转换为设计器可识别的数据结构,并加载到画布中。
实现细节
导出功能
导出功能的核心是将设计器中的节点和边线数据序列化为JSON格式。以下是一个典型的导出流程:
关键代码示例:
function exportToJSON() {
const graphData = lf.getGraphData();
const jsonStr = JSON.stringify(graphData, null, 2);
const blob = new Blob([jsonStr], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'workflow.json';
a.click();
}
导入功能
导入功能的核心是将上传的JSON文件解析为设计器可识别的数据结构,并加载到画布中。以下是一个典型的导入流程:
关键代码示例:
function importFromJSON(file) {
const reader = new FileReader();
reader.onload = (event) => {
try {
const jsonData = JSON.parse(event.target.result);
lf.render(jsonData);
} catch (error) {
console.error('Invalid JSON file:', error);
}
};
reader.readAsText(file);
}
数据格式说明
工作流的JSON数据通常包含以下字段: | 字段名 | 类型 | 描述 | |----------------|----------|--------------------------| | nodes | Array | 节点列表 | | edges | Array | 边线列表 | | properties | Object | 工作流的全局属性 |
节点和边线的数据结构示例:
{
"nodes": [
{
"id": "node1",
"type": "task",
"x": 100,
"y": 100,
"properties": {
"name": "Task 1",
"assignee": "user1"
}
}
],
"edges": [
{
"id": "edge1",
"sourceNodeId": "node1",
"targetNodeId": "node2",
"properties": {
"condition": "approval"
}
}
]
}
注意事项
- 数据验证:在导入JSON文件时,务必验证数据的完整性和合法性,避免因格式错误导致设计器崩溃。
- 兼容性:确保导出的JSON格式与后端API或其他工具的兼容性。
- 性能优化:对于大型工作流,建议分块处理数据,避免一次性加载过多节点导致性能问题。
通过JSON导入导出功能,用户可以高效地管理和迁移工作流配置,提升开发效率。
总结
Ingenious-Designer-Layui通过LayUI框架的深度集成和灵活的扩展机制,实现了高效的工作流设计器前端方案。从核心模块加载到拖拽式界面设计,再到连线管理和JSON数据交互,该项目为开发者提供了全面的功能支持,能够满足复杂工作流设计的需求。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



