mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-02 15:50:47 +08:00
216 lines
6.4 KiB
Markdown
216 lines
6.4 KiB
Markdown
# 📘 自述文档:基于 .NET 8 的流程可视化框架
|
||
|
||
## 🧩 项目介绍
|
||
|
||
本项目是一个基于 **.NET 8** 的流程可视化框架,
|
||
|
||
- 全部运行依赖、运行环境、编辑器均为 **开源**,
|
||
- 支持 **二次开发**,适合用于嵌入式、工控、数据流程自动化等场景。
|
||
|
||
📺 **Bilibili 视频更新**:不定期更新项目相关内容,可前往我的 [Bilibili 主页](https://space.bilibili.com/33526379) 查看。
|
||
|
||
---
|
||
|
||
## 🗓️ 计划任务(更新于 2025 年 7 月 28 日)
|
||
|
||
- ✅ 正在完善“**流程图转 C# 代码**”功能
|
||
- 🔥 构思 **热更新机制**
|
||
- 🔧 多客户端 **远程控制逻辑**设计中
|
||
|
||
---
|
||
|
||
## 🖌️ 如何绘制流程?
|
||
|
||
### 🛠️ 准备工作
|
||
|
||
1. 编译 `Serein.Workbench` 项目,确保工作台可运行。
|
||
2. 新建一个类库项目,并添加对 `Serein.Library` 的引用(也可通过 Negut 获取)。
|
||
|
||
### ✨ 开始绘图
|
||
|
||
1. 在类库项目中添加一个类,使用 `[DynamicFlow]` 特性标记类。
|
||
2. 使用 `[NodeAction]` 特性标记方法。
|
||
3. 编译项目并将生成的 DLL 拖入工作台左侧“类库”面板中。
|
||
4. 工作台自动解析并加载所有节点方法。
|
||
|
||
### 🎨 绘制节点流程
|
||
|
||
1. 在工作台中新建一个画布。
|
||
2. 从左侧类库面板中拖拽方法到画布上生成节点。
|
||
3. 在节点连接器之间拖拽生成连线,表示数据/控制流。
|
||
4. 可重复添加、连接多个节点构建完整流程。
|
||
|
||
### ▶️ 运行流程
|
||
|
||
- **从起始节点运行**:
|
||
- 设置某节点为“起始节点” → 点击“运行” → 选择“从当前画布运行”
|
||
- **从指定节点运行**:
|
||
- 框选单个节点 → 按 `F5` 运行
|
||
- **运行所有画布**:
|
||
- 在“运行”菜单中选择“运行所有画布”
|
||
|
||
### 💾 保存/加载项目
|
||
|
||
- **保存项目**:`视图` → `保存项目` → 选择保存路径
|
||
- **加载项目**:`视图` → `加载本地项目` → 选择项目文件
|
||
|
||
### 🪵 查看输出日志
|
||
|
||
- 在 `视图` → `输出窗口` 中查看异常、日志与调试信息
|
||
|
||
---
|
||
|
||
## 🧱 如何让方法成为流程节点?
|
||
|
||
- 使用 `[NodeAction]` 特性标记方法
|
||
- 指定合适的节点类型(如 Action、Flipflop、Script 等)
|
||
|
||
---
|
||
|
||
## 📚 关键接口说明
|
||
|
||
### IFlowContext(流程上下文)
|
||
|
||
> 节点之间数据传递的核心接口,由运行环境自动注入。
|
||
|
||
#### 🔑 核心特点
|
||
|
||
- 全局单例环境接口,支持注册/获取实例(IoC 模式)
|
||
- 每个流程实例中上下文隔离,防止脏数据产生
|
||
|
||
#### 🔍 常用属性
|
||
|
||
| 属性 | 类型 | 描述 |
|
||
| ----------------- | -- | ---------------------- |
|
||
| `RunState` | 枚举 | 表示流程运行状态(初始化、运行中、运行完成) |
|
||
| `NextOrientation` | 枚举 | 指定下一个分支(成功、失败、异常) |
|
||
| `Exit()` | 方法 | 提前终止当前流程 |
|
||
|
||
---
|
||
|
||
## 🧾 DynamicNodeType 枚举说明
|
||
|
||
### 1️⃣ 控件不生成节点(生命周期方法)
|
||
|
||
| 枚举值 | 描述 |
|
||
| --------- | ----------------------------- |
|
||
| `Init` | 程序启动时最先执行,适合进行类初始化等操作 |
|
||
| `Loading` | 所有 DLL 的 Init 执行完毕后调用,适合业务初始化 |
|
||
| `Exit` | 程序关闭时调用,适合释放线程/关闭服务 |
|
||
|
||
> 参数均为 `IFlowContext`,返回值支持异步,但框架不处理其结果。
|
||
|
||
### 2️⃣ 基础节点类型
|
||
|
||
#### 📎 FlowCall(流程接口节点)
|
||
|
||
- 实现跨画布复用逻辑
|
||
- 支持参数共享模式(全局同步)或参数独立模式(本地隔离)
|
||
|
||
#### 💡 Script(脚本节点)
|
||
|
||
- 使用 AST 抽象语法树动态编译运行
|
||
- 内置 `global()`、`now()` 等函数,参考 `Serein.Library.ScriptBaseFunc` 类中成员方法。
|
||
- 在代码中调用 `SereinScript.AddStaticFunction("your function name", MethodInfo);` 注册更多的内置方法。
|
||
|
||
示例:
|
||
|
||
```csharp
|
||
// 入参是一个对象,入参名称是 "info" ,包含Var、Data属性。
|
||
// 自定义类
|
||
class Info{
|
||
string PlcName;
|
||
string Content;
|
||
string LogType;
|
||
DateTime LogTime;
|
||
}
|
||
plc = global("JC-PLC"); // 获取全局数据节点中的数据
|
||
log = new Info() {
|
||
Content = plc + " " + info.Var + " - 状态 Value : " + info.Data,
|
||
PlcName = plc.Name,
|
||
LogType = "info",
|
||
LogTime = now(),
|
||
};
|
||
return log;
|
||
```
|
||
|
||
#### 🌐 GlobalData(全局数据节点)
|
||
|
||
- 获取/共享运行时跨节点数据
|
||
- 表达式使用:`global("DataKey")`
|
||
|
||
### 3️⃣ 从 DLL 生成控件的节点
|
||
|
||
#### ⚙️ Action
|
||
|
||
- 最基础的节点类型,入参自动匹配,返回值支持异步
|
||
|
||
#### 🔁 Flipflop(触发器)
|
||
|
||
- 可响应外部事件或超时触发
|
||
- 支持状态返回(成功、失败、取消)与触发源类型(外部、超时)
|
||
|
||
#### 🧠 ExpOp(表达式节点)
|
||
|
||
- 提取对象的子属性、字段、数组、字典值
|
||
- 示例:`@Get .Array[22]` 或 `@Get .Dict["key"]`
|
||
|
||
#### 🔍 ExpCondition(条件表达式节点)
|
||
|
||
- 条件判断节点,支持布尔/数值/文本逻辑判断
|
||
|
||
示例:
|
||
|
||
```text
|
||
条件表达式:.Age > 18 && data.Age < 35
|
||
注意,右侧出现的“data”是表达式数据的默认名称,假如你需要在表达式里其他地方使用入参数据时,就可以使用“data”。
|
||
|
||
或 .Text.StartsWith("1100") // 判断文本是否以1100开头
|
||
```
|
||
|
||
#### 🖼️ UI(嵌入控件)
|
||
|
||
- 显示自定义 `UserControl` 到工作台
|
||
- 返回实现 `IEmbeddedContent` 接口的对象
|
||
|
||
示例代码片段:
|
||
|
||
```csharp
|
||
await context.Env.UIContextOperation.InvokeAsync(() => {
|
||
var userControl = new UserControl();
|
||
adapter = new WpfUserControlAdapter(userControl, userControl);
|
||
});
|
||
return adapter;
|
||
public class WpfUserControlAdapter : IEmbeddedContent
|
||
{
|
||
private readonly UserControl userControl;
|
||
private readonly IFlowControl flowControl;
|
||
public WpfUserControlAdapter(UserControl userControl, IFlowControl flowControl)
|
||
{
|
||
this.userControl = userControl;
|
||
this.flowControl= flowControl;
|
||
}
|
||
public IFlowControl GetFlowControl()
|
||
{
|
||
return flowControl;
|
||
}
|
||
public object GetUserControl()
|
||
{
|
||
return userControl;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ 总结
|
||
|
||
- 该框架提供灵活的流程编辑、运行与二次扩展能力
|
||
- 支持脚本、全局数据、子流程等高级功能
|
||
- 适用于 AGV 调度、PLC 自动化、图形化逻辑控制等场景
|
||
|
||
---
|
||
|
||
> 本文档适用于开发者快速上手和参考具体接口用法。如需进一步了解,请关注项目演示视频或参与社区讨论。
|
||
|