16 KiB
16 KiB
CSLAB-DCS-Web
DCS(分布式控制系统)跨平台可视化组态编辑器
面向工业控制场景的画布组态设计、数据绑定、实时仿真与运行监控平台,支持 Web、Electron、Tauri 三端部署。
目录
项目简介
CSLAB-DCS-Web 是一个 工业分布式控制系统可视化组态编辑器,采用 pnpm monorepo 架构。用户可在画布上拖放、编排工业控制组件(如 PID 控制器、阀门控制器、仪表等),配置数据绑定与表达式,并通过 WebSocket 实现运行时的实时数据推送和仿真监控。
核心能力
- 画布组态设计:基于可视化画布的工业控制界面设计,支持多图层、组件拖放、对齐辅助线、缩放漫游
- 丰富组件库:矩形、文本、数字显示、柱状图、按钮、PID 控制器、阀门控制器、画布切换器等
- 数据绑定与表达式:支持将组件属性绑定到运行时变量,内置表达式引擎(tokenizer → parser → evaluator)
- 条件样式:根据运行时条件动态切换组件样式
- 事件与动作:组件支持 click/dblclick 事件触发,执行自定义动作
- 实时运行监控:通过 WebSocket 连接运行时服务,RAF 帧批处理数据更新
- 仿真执行:对接 chemical-chaos 微服务,支持任务创建、启停、暂停/恢复
- 导入导出:画布/项目的导入导出,Zod schema 校验数据完整性
- 跨平台:Web 浏览器 / Electron 桌面 / Tauri 轻量桌面三端统一
技术栈
| 类别 | 技术 |
|---|---|
| 框架 | Vue 3 (Composition API + <script setup>) |
| 路由 | Vue Router 4(Hash 模式,兼容桌面端) |
| 状态管理 | Pinia 3 |
| UI 组件库 | Element Plus(中文本地化) |
| 原子化 CSS | UnoCSS |
| 组合式工具 | VueUse |
| HTTP 客户端 | ofetch |
| Schema 校验 | Zod |
| 构建工具 | Vite 6 / electron-vite |
| 桌面框架 | Electron 22 / Tauri 2 |
| 包管理器 | pnpm(workspace) |
| TypeScript | 5.9+(严格模式) |
| 代码规范 | ESLint + @antfu/eslint-config |
| 单元测试 | Vitest + @vue/test-utils + happy-dom |
| E2E 测试 | Playwright(Chromium) |
| 样式预处理 | SCSS |
| 图标 | FontAwesome 7 |
项目结构
cslab-dcs-web/
├── apps/ # 应用入口层
│ ├── web/ # Web 浏览器版
│ ├── electron/ # Electron 桌面版
│ └── tauri/ # Tauri 桌面版
│
├── packages/ # 共享包层
│ ├── core/ # 核心业务逻辑与 UI
│ │ └── src/
│ │ ├── api/ # API 服务层
│ │ ├── assets/ # 静态资源(字体、图片、样式)
│ │ ├── bootstrap/ # 应用初始化(Bridge、编辑器、路由状态同步)
│ │ ├── components/ # 组件库
│ │ │ └── editor/ # 编辑器组件
│ │ │ ├── canvas/ # 画布引擎(Stage、图层面板、属性面板、组件面板)
│ │ │ ├── components/# 可渲染组件(rect、text、number、bar、button、PID…)
│ │ │ ├── controls/ # UI 控件(输入框、颜色选择器、开关…)
│ │ │ ├── header/ # 顶部工具栏
│ │ │ └── ... # 运行时控制台、状态栏等
│ │ ├── composables/ # 组合式函数
│ │ ├── config/ # 运行时配置
│ │ ├── constants/ # 常量定义
│ │ ├── layout/ # 布局组件
│ │ ├── request/ # 请求层(HTTP / IndexedDB 双适配器)
│ │ ├── router/ # 路由配置
│ │ ├── stores/ # Pinia 状态管理
│ │ ├── utils/ # 工具函数
│ │ └── views/ # 页面视图
│ │
│ ├── bridge/ # 平台抽象桥接层
│ │ └── src/
│ │ ├── adapters/ # Web / Electron / Tauri 适配器
│ │ └── types.ts # IPlatformBridge 接口定义
│ │
│ └── schema/ # 数据模型与校验
│ └── src/
│ ├── dcs.ts # DCS 配置类型
│ ├── types.ts # 通用类型
│ └── validators.ts # Zod 校验器
│
├── tests/ # 测试
│ ├── e2e/ # Playwright E2E 测试
│ └── unit/ # Vitest 单元测试
│
├── references/ # 参考文档与竞品截图
├── eslint.config.js
├── vitest.config.ts
├── playwright.config.ts
├── tsconfig.base.json
├── pnpm-workspace.yaml
└── package.json
包职责说明
| 包名 | 描述 |
|---|---|
@cslab-dcs/core |
核心业务层——路由、Store、API、视图、组件、组合式函数,是应用的主体 |
@cslab-dcs/bridge |
平台抽象层——定义 IPlatformBridge 接口,提供文件操作、对话框、系统信息的跨平台实现 |
@cslab-dcs/schema |
数据模型层——Canvas、Layer、Component、Variable 的 Zod Schema 定义与校验 |
@cslab-dcs/web |
Web 入口——挂载 Vue 应用到浏览器 |
@cslab-dcs/electron |
Electron 入口——主进程 IPC、窗口管理、文件授权 |
@cslab-dcs/tauri |
Tauri 入口——Tauri Plugin API 绑定 |
环境要求
| 依赖 | 版本 |
|---|---|
| Node.js | >= 20.0.0 |
| pnpm | >= 9.0.0 |
| Rust(仅 Tauri) | latest stable |
快速开始
# 1. 安装依赖
pnpm install
# 2. 启动 Web 开发服务
pnpm dev:web
# 访问 http://localhost:5173/dcs-web#/
# 3. 或启动 Electron 桌面版
pnpm dev:electron
# 4. 或启动 Tauri 桌面版
pnpm dev:tauri
开发命令
开发
| 命令 | 说明 |
|---|---|
pnpm dev:web |
启动 Web 版开发服务器(端口 5173) |
pnpm dev:electron |
启动 Electron 桌面版 |
pnpm dev:tauri |
启动 Tauri 桌面版 |
构建
| 命令 | 说明 |
|---|---|
pnpm build:web |
构建 Web 生产包 |
pnpm build:electron:win |
构建 Windows Electron 安装包 |
pnpm build:tauri |
构建 Tauri 跨平台安装包 |
质量保障
| 命令 | 说明 |
|---|---|
pnpm format |
ESLint 自动修复 |
pnpm typecheck |
全包 TypeScript 类型检查 |
pnpm test |
运行单元测试 |
pnpm test:watch |
监听模式单元测试 |
pnpm test:coverage |
生成覆盖率报告 |
pnpm test:e2e |
运行 E2E 测试 |
pnpm test:e2e:ui |
E2E 测试(带 UI) |
构建与部署
Web 构建产物
pnpm build:web
# 输出目录:apps/web/dist/
构建产物为纯静态资源(HTML/JS/CSS),可直接部署到任意 Web 服务器或 CDN。
环境变量
| 变量 | 说明 |
|---|---|
VITE_API_BASE_URL |
后端 API 地址 |
VITE_BASE_URL |
前端部署路径 |
核心架构
分层架构
┌────────────────────────────────────────────┐
│ Views(页面视图) │
├────────────────────────────────────────────┤
│ Components(UI 组件层) │
├────────────────────────────────────────────┤
│ Composables(组合式函数层) │
├────────────────────────────────────────────┤
│ Pinia Stores(状态管理层) │
├────────────────────────────────────────────┤
│ API Layer(服务接口层) │
├────────────────────────────────────────────┤
│ Request Adapters(HTTP / IndexedDB 适配) │
├────────────────────────────────────────────┤
│ Platform Bridge(Web / Electron / Tauri) │
└────────────────────────────────────────────┘
路由
| 路由 | 页面 | 说明 |
|---|---|---|
/canvases |
画布列表 | 项目下的画布管理 |
/editor |
画布编辑器 | 核心组态编辑界面 |
/preview |
预览模式 | 只读画布预览 |
/runtime |
运行模式 | 实时仿真与监控 |
/settings |
设置 | 桌面端专属 |
/welcome |
欢迎页 | 桌面端专属 |
状态管理(Pinia Stores)
| Store | 职责 | 持久化 |
|---|---|---|
useAppStore |
主题、平台信息、应用版本 | — |
useUserStore |
JWT Token、设备类型、用户信息 | localStorage |
useProjectStore |
项目列表、当前项目、最近项目 | sessionStorage |
useCanvasStore |
画布列表、缩放级别、视口状态 | sessionStorage |
useLayerStore |
选中图层、图层列表、基础图层 | sessionStorage |
平台桥接(Bridge)
interface IPlatformBridge {
platform: 'web' | 'electron' | 'tauri'
file: IFileService // 读写文件、打开/保存对话框
dialog: IDialogService // 消息弹窗、确认弹窗
system: ISystemService // 应用版本、平台信息、打开外部链接
}
三端适配器各自实现该接口,上层业务代码无需关心平台差异。
功能模块
画布编辑器
- 画布引擎:支持缩放(最大 300%)、平移、网格对齐(10px)
- 画布尺寸:默认 1920×1080,最小 360×240,最大 20000×20000
- 图层管理:多选、分组、排序、锁定
- 属性面板:根据选中组件类型动态展示配置项
- 对齐辅助线:智能吸附对齐
- Minimap:画布缩略图导航
- 撤销/重做:完整的操作历史记录
- 自动保存:编辑内容自动持久化
可渲染组件
| 组件 | 说明 |
|---|---|
rect |
矩形/容器 |
text |
文本标签 |
number |
数字显示 |
bar |
柱状图 |
button |
可交互按钮 |
pidController |
PID 控制器面板 |
valveController |
阀门控制器 |
canvasSwitcher |
画布切换导航 |
custom |
自定义组件 |
数据绑定与表达式引擎
组件属性支持绑定到运行时变量,内置完整的表达式解析引擎:
表达式字符串 → Tokenizer(词法分析)→ Parser(语法分析)→ Evaluator(求值)
支持条件样式:根据表达式结果动态切换组件外观,支持优先级配置。
运行时监控
- WebSocket 实时数据推送
- RequestAnimationFrame 帧批处理,保证渲染性能
- 运行时控制台输出
- 手动控制面板
- PID 参数调节面板
- 阀门开度控制面板
组合式函数(Composables)
| 函数 | 职责 |
|---|---|
useBridge() |
获取平台桥接实例 |
useOperationLog() |
操作日志记录(上限 500 条) |
useRuntimeSocket() |
WebSocket 运行时连接与帧批更新 |
useDataConnection() |
数据连接管理与写入命令 |
useExportImport() |
画布/项目导入导出 |
useRuntimeConsole() |
运行时控制台日志 |
useComponentTemplates() |
组件模板存取(localStorage) |
数据模型
Canvas(画布)
{
id: string
projectId: string
name: string
description?: string
width: number // 默认 1920
height: number // 默认 1080
type: CanvasType
version: string
components: Layer[] // 组件/图层列表
vars?: Variable[] // 运行时变量
config?: CanvasConfig
thumbnail?: string // 缩略图
updatedAt: string
}
Layer(图层/组件)
{
id: string // UUID
type: ComponentType // rect | number | text | bar | button | ...
x: number // X 坐标
y: number // Y 坐标
width: number
height: number
config?: object // 组件特定配置
style?: object // CSS 样式
bindings?: Record<string, string | BindingExpression> // 数据绑定
tagNumber?: string // 设备标签号
events?: EventConfig[] // 事件处理器
conditionalStyles?: ConditionalStyle[] // 条件样式
}
所有数据模型均使用 Zod Schema 定义,提供运行时校验和 TypeScript 类型推导。
API 层
请求架构
采用 Repository 模式 + 双适配器:
- HTTP 适配器 → 对接
/cslab-server后端 - IndexedDB 适配器 → 浏览器本地存储(离线模式)
HTTP 客户端基于 ofetch,支持 JWT Token 自动刷新、401 会话过期处理、错误提示。
API 模块
| 模块 | 接口 |
|---|---|
| Project | getProjectListApi() / createProjectApi() / updateProjectApi() |
| Canvas | listCanvasesApi() / getCanvasByIdApi() / createCanvasApi() / updateCanvasApi() / saveCanvasComponentsApi() / duplicateCanvasApi() |
| Runtime | addJobApi() / stopJobApi() / pauseJobApi() / resumeJobApi() / getProjectJobApi() / pushFullDataApi() / getExecSequenceApi() |
| Dynamic Project | 动态项目更新 |
运行时 RPC
对接 chemical-chaos 微服务,通过 /v1/rpc/common/ 和 /v1/rpc/zero_rpc/ 端点进行仿真调度。
测试
单元测试
- 框架:Vitest + happy-dom + @vue/test-utils
- 位置:
tests/unit/ - 覆盖范围:Composables、Stores、Schema 校验、表达式引擎
pnpm test # 运行全部单元测试
pnpm test:watch # 监听模式
pnpm test:coverage # 覆盖率报告
E2E 测试
- 框架:Playwright(Chromium)
- 位置:
tests/e2e/ - 测试场景:画布编辑器操作、图层交互、页面导航
pnpm test:e2e # 运行 E2E 测试
pnpm test:e2e:ui # 带 UI 的 E2E 测试
CI/CD
项目配置了 Jenkins Pipeline,支持两套部署环境:
| 环境 | 配置文件 | 目标 |
|---|---|---|
| 开发环境(110) | Jenkinsfile.dev110 |
Windows 服务器部署 |
| 测试环境(139) | Jenkinsfile.dev139 |
Linux 服务器部署 |
Pipeline 流程
- 环境检查 → 验证 Node 22 / pnpm 版本
- 安装依赖 →
pnpm install - 构建 →
pnpm build:web - 部署 → SSH 拷贝静态资源到目标服务器
- 通知 → 企业微信 Webhook 通知构建结果
部署要点
- 构建产物:
apps/web/dist/下的静态文件 - 构建超时:15 分钟
- 跳过 Electron 二进制下载:
ELECTRON_SKIP_BINARY_DOWNLOAD=1 - 测试环境支持旧版本自动清理(>7 天)
License
Private — 内部项目