@nywqs/scada-engine 1.1.28 → 1.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -601
- package/dist/assets/dataProcessor.worker-DerLDc7p.js +1 -0
- package/dist/scada-engine.css +1 -1
- package/dist/scada-engine.es.js +11544 -10943
- package/dist/scada-engine.umd.js +156 -26
- package/dist/src/components/BasicPropertiesTab.d.ts +2 -2
- package/dist/src/scada-components/registry.d.ts +61 -4
- package/dist/src/utils/animationScheduler.d.ts +85 -0
- package/dist/src/utils/canvasLayerManager.d.ts +88 -0
- package/dist/src/utils/dataBindingService.d.ts +15 -0
- package/dist/src/utils/index.d.ts +4 -0
- package/dist/src/utils/nodeOperations.d.ts +1 -1
- package/dist/src/utils/viewportCulling.d.ts +63 -0
- package/dist/src/utils/workerManager.d.ts +57 -0
- package/dist/src/views/workflow/components/ElementSelector.d.ts +2 -10
- package/dist/src/views/workflow/services/canvasElementService.d.ts +4 -4
- package/dist/src/views/workflow/types/element.d.ts +16 -0
- package/dist/src/workers/dataProcessor.worker.d.ts +21 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,25 +1,33 @@
|
|
|
1
|
-
# @nywqs/scada-engine
|
|
2
1
|
|
|
3
|
-
[](https://www.npmjs.com/package/@nywqs/scada-engine)
|
|
4
|
-
[](https://github.com/leoncheng2030/scada-engine/blob/main/LICENSE)
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
# @nywqs/scada-engine
|
|
4
|
+
|
|
5
|
+
基于 AntV X6 + Vue 3 的自研 SCADA 组态引擎。旨在为工业物联网(IIoT)提供高性能、可扩展的可视化组态解决方案,支持拖拽式界面设计、实时数据绑定及复杂的流程编排。
|
|
7
6
|
|
|
8
7
|
## 特性
|
|
9
8
|
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- 📱 **自适应**:画布自动适配不同屏幕尺寸
|
|
9
|
+
- 🛠 **可视化编辑器**:基于 AntV X6 构建的专业级图形编辑能力,支持节点拖拽、连线编排、框选复制等操作。
|
|
10
|
+
- 📦 **丰富组件库**:
|
|
11
|
+
- **基础组件**:矩形、圆形、文本等基础矢量图形。
|
|
12
|
+
- **IoT 组件**:支持 ECharts 图表(仪表盘、折线图)、3D 设备模型(电机、管道、阀门、储罐等)、指示灯、开关等工业控件。
|
|
13
|
+
- 🔗 **多源数据集成**:内置服务层,支持 WebSocket、MQTT、HTTP 请求及 SSE(Server-Sent Events)等多种实时数据接入方式。
|
|
14
|
+
- 🎨 **动画引擎**:内置独立的动画调度器(AnimationScheduler)与动画引擎(AnimationEngine),支持脉冲、闪烁、旋转等节点特效。
|
|
15
|
+
- ⚙️ **流程编排**:内置可视化工作流编辑器(Workflow Editor),支持通过逻辑节点(条件判断、定时器、HTTP 请求、自定义代码)编排复杂业务流程。
|
|
16
|
+
- 🔐 **授权与安全**:基于 ECDSA P-256 + SHA-256 的数字签名授权机制,保障软件使用安全。
|
|
17
|
+
- 🚀 **性能优化**:支持视口裁剪(Viewport Culling)技术,在保证视觉效果的同时优化大数据量场景下的渲染性能。
|
|
20
18
|
|
|
21
19
|
## 安装
|
|
22
20
|
|
|
21
|
+
### 环境要求
|
|
22
|
+
|
|
23
|
+
确保你的项目中已安装以下依赖:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install vue@^3.4.0 vue-router@^4.6.0 @antv/x6@^2.18.0 echarts@^5.5.0 pinia@^2.1.0
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 安装引擎
|
|
30
|
+
|
|
23
31
|
```bash
|
|
24
32
|
npm install @nywqs/scada-engine
|
|
25
33
|
# 或
|
|
@@ -28,654 +36,158 @@ pnpm add @nywqs/scada-engine
|
|
|
28
36
|
yarn add @nywqs/scada-engine
|
|
29
37
|
```
|
|
30
38
|
|
|
31
|
-
### Peer Dependencies
|
|
32
|
-
|
|
33
|
-
请确保已安装以下依赖:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
npm install vue@^3.4.0 vue-router@^4.6.0 @antv/x6@^2.18.0 echarts@^5.5.0 pinia@^2.1.0
|
|
37
|
-
```
|
|
38
|
-
|
|
39
39
|
## 快速开始
|
|
40
40
|
|
|
41
|
-
###
|
|
41
|
+
### 1. 全局注册
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
npm install @nywqs/scada-engine@latest
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### 全局注册
|
|
43
|
+
在你的应用入口文件(如 `main.ts`)中引入并注册组件:
|
|
48
44
|
|
|
49
45
|
```typescript
|
|
50
46
|
import { createApp } from 'vue'
|
|
51
47
|
import ScadaEngine from '@nywqs/scada-engine'
|
|
52
|
-
import '@nywqs/scada-engine/dist/scada-engine.css'
|
|
48
|
+
import '@nywqs/scada-engine/dist/scada-engine.css' // 引入样式
|
|
49
|
+
import App from './App.vue'
|
|
53
50
|
|
|
54
51
|
const app = createApp(App)
|
|
55
52
|
app.use(ScadaEngine)
|
|
56
53
|
app.mount('#app')
|
|
57
54
|
```
|
|
58
55
|
|
|
59
|
-
###
|
|
56
|
+
### 2. 在组件中使用
|
|
57
|
+
|
|
58
|
+
最核心的组件是 `ScadaCanvas`,它承载了画布编辑器和预览功能。
|
|
60
59
|
|
|
61
60
|
```vue
|
|
62
61
|
<template>
|
|
63
|
-
<div class="
|
|
62
|
+
<div class="scada-container">
|
|
64
63
|
<ScadaCanvas
|
|
64
|
+
ref="canvasRef"
|
|
65
|
+
:auth-code="authCode"
|
|
65
66
|
@node-click="handleNodeClick"
|
|
66
|
-
@node-update="handleNodeUpdate"
|
|
67
67
|
/>
|
|
68
68
|
</div>
|
|
69
69
|
</template>
|
|
70
70
|
|
|
71
|
-
<script setup lang="ts">
|
|
72
|
-
import { ScadaCanvas } from '@nywqs/scada-engine'
|
|
73
|
-
import '@nywqs/scada-engine/dist/scada-engine.css'
|
|
74
|
-
|
|
75
|
-
const handleNodeClick = (node: any) => {
|
|
76
|
-
console.log('Node clicked:', node)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const handleNodeUpdate = (data: any) => {
|
|
80
|
-
console.log('Node updated:', data)
|
|
81
|
-
}
|
|
82
|
-
</script>
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## 组件列表
|
|
86
|
-
|
|
87
|
-
### 核心组件
|
|
88
|
-
|
|
89
|
-
- `ScadaCanvas`:画布组件(核心),支持编辑和预览模式
|
|
90
|
-
- `PropertyPanel`:属性面板,配置节点和连线属性
|
|
91
|
-
- `ComponentLibrary`:组件库面板,拖拽添加组件
|
|
92
|
-
- `CanvasConfigPanel`:画布配置面板
|
|
93
|
-
- `Header`:顶部工具栏
|
|
94
|
-
|
|
95
|
-
### 辅助组件
|
|
96
|
-
|
|
97
|
-
- `BindingCard`:数据绑定卡片,配置设备数据点绑定
|
|
98
|
-
- `EventCard`:事件配置卡片,配置交互事件
|
|
99
|
-
- `BasicPropertiesTab`:基础属性标签页
|
|
100
|
-
- `DataPropertiesTab`:数据属性标签页
|
|
101
|
-
- `EdgePropertiesTab`:连线属性标签页
|
|
102
|
-
- `AttributeConfigDialog`:属性配置对话框
|
|
103
|
-
- `CustomCodeDialog`:自定义代码对话框
|
|
104
|
-
- `DevicePointSelector`:设备数据点选择器
|
|
105
|
-
- `MappingConfigurator`:映射配置器
|
|
106
|
-
- `WorkflowSelectorDialog`:流程选择对话框
|
|
107
|
-
|
|
108
|
-
### 内置组件库
|
|
109
|
-
|
|
110
|
-
#### 基础组件(basic)
|
|
111
|
-
- 矩形(rect)
|
|
112
|
-
- 圆形(circle)
|
|
113
|
-
- 文本(text)
|
|
114
|
-
|
|
115
|
-
#### IoT组件(iot)
|
|
116
|
-
- 仪表盘(gauge):支持ECharts仪表盘展示
|
|
117
|
-
- 指示灯(light):支持开关状态指示
|
|
118
|
-
- 开关(switch):支持设备控制
|
|
119
|
-
|
|
120
|
-
#### 画布配置
|
|
121
|
-
- 画布尺寸:支持多种预设尺寸(1920x1080、1366x768等)和自定义尺寸
|
|
122
|
-
- 背景设置:支持颜色、图片背景
|
|
123
|
-
- 网格配置:支持网格显示、类型、大小设置
|
|
124
|
-
- 缩放控制:支持画布缩放和自适应屏幕
|
|
125
|
-
- 参考线:支持对齐参考线
|
|
126
|
-
- 磁吸功能:支持节点磁吸对齐
|
|
127
|
-
|
|
128
|
-
## API
|
|
129
|
-
|
|
130
|
-
### ScadaCanvas 组件 API
|
|
131
|
-
|
|
132
|
-
`ScadaCanvas` 组件通过 `defineExpose` 暴露了一系列核心方法,供外部编程调用:
|
|
133
|
-
|
|
134
|
-
```vue
|
|
135
|
-
<template>
|
|
136
|
-
<ScadaCanvas ref="canvasRef" />
|
|
137
|
-
</template>
|
|
138
|
-
|
|
139
71
|
<script setup lang="ts">
|
|
140
72
|
import { ref } from 'vue'
|
|
141
73
|
import { ScadaCanvas } from '@nywqs/scada-engine'
|
|
142
74
|
|
|
143
75
|
const canvasRef = ref()
|
|
76
|
+
const authCode = '你的授权码' // 商业版本需要
|
|
144
77
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
canvasRef.value?.save()
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const handleCustomExport = () => {
|
|
151
|
-
canvasRef.value?.export()
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const handleCustomImport = () => {
|
|
155
|
-
canvasRef.value?.import()
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const handleGetData = () => {
|
|
159
|
-
const data = canvasRef.value?.getCanvasData()
|
|
160
|
-
console.log('画布数据:', data)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const handleLoadData = (jsonData: any) => {
|
|
164
|
-
const success = canvasRef.value?.loadCanvasData(jsonData)
|
|
165
|
-
if (success) {
|
|
166
|
-
console.log('加载成功')
|
|
167
|
-
}
|
|
78
|
+
const handleNodeClick = (node) => {
|
|
79
|
+
console.log('点击了节点:', node.id)
|
|
168
80
|
}
|
|
169
81
|
</script>
|
|
170
82
|
```
|
|
171
83
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
| 方法名 | 参数 | 返回值 | 说明 |
|
|
175
|
-
|--------|------|--------|------|
|
|
176
|
-
| `save()` | - | `void` | 保存画布数据到 localStorage |
|
|
177
|
-
| `import()` | - | `void` | 触发文件选择,导入 JSON 数据 |
|
|
178
|
-
| `export()` | - | `void` | 导出画布数据为 JSON 文件 |
|
|
179
|
-
| `preview()` | - | `void` | 跳转到预览页面 |
|
|
180
|
-
| `workflow()` | - | `void` | 打开流程编排弹窗 |
|
|
181
|
-
| `zoomIn()` | - | `void` | 放大画布 |
|
|
182
|
-
| `zoomOut()` | - | `void` | 缩小画布 |
|
|
183
|
-
| `clearAll()` | - | `void` | 清空画布所有元素 |
|
|
184
|
-
| `getGraph()` | - | `Graph \| null` | 获取 X6 Graph 实例 |
|
|
185
|
-
| `getCanvasData()` | - | `object \| null` | 获取画布完整数据 |
|
|
186
|
-
| `loadCanvasData(data)` | `data: any` | `boolean` | 加载画布数据 |
|
|
84
|
+
## 目录结构
|
|
187
85
|
|
|
188
|
-
|
|
86
|
+
项目采用了清晰的模块划分:
|
|
189
87
|
|
|
190
|
-
```typescript
|
|
191
|
-
{
|
|
192
|
-
version: string // 版本号
|
|
193
|
-
timestamp: string // 时间戳
|
|
194
|
-
config: object // 画布配置
|
|
195
|
-
cells: array // X6 画布元素
|
|
196
|
-
nodes: array // 节点数据
|
|
197
|
-
edges: array // 连线数据
|
|
198
|
-
}
|
|
199
88
|
```
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
<script setup lang="ts">
|
|
222
|
-
import { ref } from 'vue'
|
|
223
|
-
import { ScadaCanvas } from '@nywqs/scada-engine'
|
|
224
|
-
|
|
225
|
-
const canvasRef = ref()
|
|
226
|
-
|
|
227
|
-
const handleSave = () => {
|
|
228
|
-
canvasRef.value?.save()
|
|
229
|
-
console.log('已保存')
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const handleExport = () => {
|
|
233
|
-
canvasRef.value?.export()
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const handleImport = () => {
|
|
237
|
-
canvasRef.value?.import()
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const handleGetData = () => {
|
|
241
|
-
const data = canvasRef.value?.getCanvasData()
|
|
242
|
-
console.log('画布数据:', data)
|
|
243
|
-
|
|
244
|
-
// 可以将数据发送到服务器
|
|
245
|
-
// await api.saveCanvas(data)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const handleZoomIn = () => {
|
|
249
|
-
canvasRef.value?.zoomIn()
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const handleZoomOut = () => {
|
|
253
|
-
canvasRef.value?.zoomOut()
|
|
254
|
-
}
|
|
255
|
-
</script>
|
|
89
|
+
src/
|
|
90
|
+
├── components/ # 核心 UI 组件
|
|
91
|
+
│ ├── Header.vue # 顶部工具栏
|
|
92
|
+
│ ├── Footer.vue # 底部版权栏
|
|
93
|
+
│ ├── ScadaCanvas.vue # 核心画布组件
|
|
94
|
+
│ └── ...
|
|
95
|
+
├── scada-components/ # 业务组件库
|
|
96
|
+
│ ├── basic/ # 基础图形组件 (rect, circle, text)
|
|
97
|
+
│ ├── iot/ # IoT 设备组件 (gauge, motor, tank...)
|
|
98
|
+
│ ├── canvas/ # 画布配置管理
|
|
99
|
+
│ └── registry.ts # 组件注册表
|
|
100
|
+
├── views/workflow/ # 流程编排模块
|
|
101
|
+
├── services/ # 数据服务层
|
|
102
|
+
│ ├── websocketService.ts
|
|
103
|
+
│ ├── mqttService.ts
|
|
104
|
+
│ └── ...
|
|
105
|
+
├── utils/ # 工具函数与引擎核心
|
|
106
|
+
│ ├── animationEngine.ts # 动画引擎
|
|
107
|
+
│ ├── authCrypto.ts # 授权加密模块
|
|
108
|
+
│ └── viewportCulling.ts # 视口优化
|
|
109
|
+
└── styles/ # 样式文件
|
|
256
110
|
```
|
|
257
111
|
|
|
258
|
-
|
|
112
|
+
## 核心概念
|
|
259
113
|
|
|
260
|
-
|
|
261
|
-
import { componentRegistry } from '@nywqs/scada-engine'
|
|
114
|
+
### 画布 (ScadaCanvas)
|
|
262
115
|
|
|
263
|
-
|
|
264
|
-
|
|
116
|
+
画布是整个系统的核心,提供以下能力:
|
|
117
|
+
- **编辑模式**:用于设计组态画面。
|
|
118
|
+
- **预览模式**:用于运行展示,隐藏编辑 UI。
|
|
119
|
+
- **数据绑定**:支持将设备点位(Point)绑定到组件属性,实时更新显示。
|
|
265
120
|
|
|
266
|
-
|
|
267
|
-
const basicComponents = componentRegistry.getComponentsByCategory('basic')
|
|
268
|
-
```
|
|
121
|
+
### 组件注册系统 (ComponentRegistry)
|
|
269
122
|
|
|
270
|
-
|
|
123
|
+
引擎使用了懒加载注册机制来优化性能。
|
|
124
|
+
- 支持按分类(`basic`, `iot`)获取组件列表。
|
|
125
|
+
- 支持动态注册新组件。
|
|
271
126
|
|
|
272
|
-
|
|
273
|
-
import { canvasConfigManager } from '@nywqs/scada-engine'
|
|
127
|
+
### 数据服务 (Data Services)
|
|
274
128
|
|
|
275
|
-
|
|
276
|
-
|
|
129
|
+
引擎不强制绑定特定后端,提供了灵活的数据接入适配器:
|
|
130
|
+
- **WebSocket**:适用于高频实时数据。
|
|
131
|
+
- **MQTT**:适用于物联网消息订阅。
|
|
132
|
+
- **HTTP**:适用于请求-响应式查询。
|
|
133
|
+
- **SSE**:适用于服务器推送事件。
|
|
277
134
|
|
|
278
|
-
|
|
279
|
-
canvasConfigManager.updateSize({ width: 1920, height: 1080 })
|
|
280
|
-
```
|
|
135
|
+
### 流程引擎 (Workflow Engine)
|
|
281
136
|
|
|
282
|
-
|
|
137
|
+
内置的可视化脚本系统,允许用户在画布上通过图形化节点编写逻辑,无需编写大量代码即可实现:
|
|
138
|
+
- 定时触发任务
|
|
139
|
+
- 条件判断分支
|
|
140
|
+
- HTTP 外部请求
|
|
141
|
+
- 自定义 JavaScript 代码执行
|
|
283
142
|
|
|
284
|
-
|
|
285
|
-
import type {
|
|
286
|
-
EventConfig,
|
|
287
|
-
BindingConfig,
|
|
288
|
-
ComponentConfig,
|
|
289
|
-
ComponentCategory,
|
|
290
|
-
Device,
|
|
291
|
-
DevicePoint,
|
|
292
|
-
DeviceList,
|
|
293
|
-
PointDataType,
|
|
294
|
-
PointAccessMode
|
|
295
|
-
} from '@nywqs/scada-engine'
|
|
296
|
-
|
|
297
|
-
// 设备点位相关枚举
|
|
298
|
-
import {
|
|
299
|
-
DeviceStatus,
|
|
300
|
-
DeviceType,
|
|
301
|
-
PointDataType,
|
|
302
|
-
PointAccessMode
|
|
303
|
-
} from '@nywqs/scada-engine'
|
|
304
|
-
```
|
|
143
|
+
## API 参考
|
|
305
144
|
|
|
306
|
-
|
|
145
|
+
### ScadaCanvas 方法
|
|
307
146
|
|
|
308
|
-
|
|
147
|
+
通过 `ref` 可以直接调用画布的操作方法:
|
|
309
148
|
|
|
310
|
-
|
|
149
|
+
| 方法 | 说明 |
|
|
150
|
+
|------|------|
|
|
151
|
+
| `save()` | 保存当前画布数据到 LocalStorage |
|
|
152
|
+
| `export()` | 导出当前画布为 JSON 文件 |
|
|
153
|
+
| `import()` | 触发文件选择器导入 JSON |
|
|
154
|
+
| `getCanvasData()` | 获取画布完整数据对象(包含节点、连线和配置) |
|
|
155
|
+
| `zoomIn()` / `zoomOut()` | 放大/缩小画布 |
|
|
156
|
+
| `clearAll()` | 清空画布 |
|
|
311
157
|
|
|
312
|
-
|
|
313
|
-
<template>
|
|
314
|
-
<ScadaCanvas
|
|
315
|
-
:device-data="deviceData"
|
|
316
|
-
:data-source="dataConfig"
|
|
317
|
-
/>
|
|
318
|
-
</template>
|
|
158
|
+
### 数据结构示例
|
|
319
159
|
|
|
320
|
-
|
|
321
|
-
import { ScadaCanvas } from '@nywqs/scada-engine'
|
|
160
|
+
`getCanvasData()` 返回的结构大致如下:
|
|
322
161
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"version": "1.0",
|
|
165
|
+
"config": {
|
|
166
|
+
"width": 1920,
|
|
167
|
+
"height": 1080,
|
|
168
|
+
"grid": true
|
|
169
|
+
},
|
|
170
|
+
"cells": [
|
|
326
171
|
{
|
|
327
|
-
id:
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
name: '当前温度',
|
|
334
|
-
value: 25.5,
|
|
335
|
-
dataType: 'number',
|
|
336
|
-
unit: '°C'
|
|
337
|
-
}
|
|
338
|
-
]
|
|
172
|
+
"id": "node-1",
|
|
173
|
+
"type": "rect",
|
|
174
|
+
"x": 100,
|
|
175
|
+
"y": 100,
|
|
176
|
+
"label": "电机",
|
|
177
|
+
"data": { "binding": "device_01_status" }
|
|
339
178
|
}
|
|
340
179
|
]
|
|
341
180
|
}
|
|
342
|
-
|
|
343
|
-
// 数据源配置
|
|
344
|
-
const dataConfig = {
|
|
345
|
-
type: 'websocket', // 或 'mqtt', 'http', 'sse'
|
|
346
|
-
url: 'ws://localhost:8080/device-data',
|
|
347
|
-
interval: 1000 // 更新间隔(毫秒)
|
|
348
|
-
}
|
|
349
|
-
</script>
|
|
350
181
|
```
|
|
351
182
|
|
|
352
|
-
|
|
183
|
+
## 许可证
|
|
353
184
|
|
|
354
|
-
|
|
355
|
-
<template>
|
|
356
|
-
<ScadaCanvas ref="scadaRef" />
|
|
357
|
-
</template>
|
|
358
|
-
|
|
359
|
-
<script setup lang="ts">
|
|
360
|
-
import { ref, onMounted } from 'vue'
|
|
361
|
-
import { ScadaCanvas } from '@nywqs/scada-engine'
|
|
362
|
-
|
|
363
|
-
const scadaRef = ref()
|
|
364
|
-
|
|
365
|
-
// 获取设备数据并更新到画布
|
|
366
|
-
const updateDeviceData = async () => {
|
|
367
|
-
// 从主应用的API获取设备数据
|
|
368
|
-
const deviceData = await fetchDeviceDataFromAPI()
|
|
369
|
-
|
|
370
|
-
// 通过暴露的方法更新到画布组件
|
|
371
|
-
scadaRef.value?.updateDeviceData(deviceData)
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
onMounted(() => {
|
|
375
|
-
// 定时更新设备数据
|
|
376
|
-
setInterval(updateDeviceData, 1000)
|
|
377
|
-
})
|
|
378
|
-
</script>
|
|
379
|
-
```
|
|
185
|
+
本项目采用 MIT 许可证。内置的组件库和引擎功能可以免费用于学习和非商业项目。
|
|
380
186
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
```vue
|
|
384
|
-
<template>
|
|
385
|
-
<ScadaCanvas
|
|
386
|
-
@data-request="handleDataRequest"
|
|
387
|
-
@data-update="handleDataUpdate"
|
|
388
|
-
/>
|
|
389
|
-
</template>
|
|
390
|
-
|
|
391
|
-
<script setup lang="ts">
|
|
392
|
-
import { ScadaCanvas } from '@nywqs/scada-engine'
|
|
393
|
-
|
|
394
|
-
// 当画布需要数据时触发
|
|
395
|
-
const handleDataRequest = (requestData: any) => {
|
|
396
|
-
// 根据请求参数获取对应设备数据
|
|
397
|
-
const deviceData = getDeviceData(requestData.deviceIds)
|
|
398
|
-
|
|
399
|
-
// 返回数据给画布
|
|
400
|
-
return deviceData
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// 当画布数据更新时触发
|
|
404
|
-
const handleDataUpdate = (updatedData: any) => {
|
|
405
|
-
// 将更新的数据发送到主应用的设备系统
|
|
406
|
-
updateDeviceValues(updatedData)
|
|
407
|
-
}
|
|
408
|
-
</script>
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### 4. 数据格式要求
|
|
412
|
-
|
|
413
|
-
设备数据应遵循以下格式:
|
|
414
|
-
|
|
415
|
-
```typescript
|
|
416
|
-
interface DeviceData {
|
|
417
|
-
devices: Array<{
|
|
418
|
-
id: string // 设备唯一标识
|
|
419
|
-
name: string // 设备名称
|
|
420
|
-
status: 'online' | 'offline' | 'error' | 'maintenance'
|
|
421
|
-
points: Array<{
|
|
422
|
-
id: string // 点位唯一标识
|
|
423
|
-
name: string // 点位名称
|
|
424
|
-
value: any // 点位值
|
|
425
|
-
dataType: 'number' | 'boolean' | 'string'
|
|
426
|
-
unit?: string // 单位
|
|
427
|
-
quality: 'good' | 'bad' | 'uncertain' // 数据质量
|
|
428
|
-
updateTime: string // 更新时间
|
|
429
|
-
}>
|
|
430
|
-
}>
|
|
431
|
-
}
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
推荐使用事件绑定方式或数据绑定配置,这两种方式可以实现主应用与SCADA引擎的双向数据同步,既灵活又高效。
|
|
435
|
-
|
|
436
|
-
## 使用示例
|
|
437
|
-
|
|
438
|
-
### 完整编辑器应用
|
|
439
|
-
|
|
440
|
-
```vue
|
|
441
|
-
<template>
|
|
442
|
-
<div class="scada-editor">
|
|
443
|
-
<Header
|
|
444
|
-
@save="handleSave"
|
|
445
|
-
@export="handleExport"
|
|
446
|
-
@preview="handlePreview"
|
|
447
|
-
/>
|
|
448
|
-
|
|
449
|
-
<div class="editor-body">
|
|
450
|
-
<ComponentLibrary />
|
|
451
|
-
|
|
452
|
-
<ScadaCanvas
|
|
453
|
-
ref="canvasRef"
|
|
454
|
-
@node-select="handleNodeSelect"
|
|
455
|
-
/>
|
|
456
|
-
|
|
457
|
-
<PropertyPanel
|
|
458
|
-
v-if="selectedNode"
|
|
459
|
-
:selected-node="selectedNode"
|
|
460
|
-
@update-node="handleUpdateNode"
|
|
461
|
-
/>
|
|
462
|
-
</div>
|
|
463
|
-
</div>
|
|
464
|
-
</template>
|
|
465
|
-
|
|
466
|
-
<script setup lang="ts">
|
|
467
|
-
import { ref } from 'vue'
|
|
468
|
-
import {
|
|
469
|
-
Header,
|
|
470
|
-
ComponentLibrary,
|
|
471
|
-
ScadaCanvas,
|
|
472
|
-
PropertyPanel
|
|
473
|
-
} from '@nywqs/scada-engine'
|
|
474
|
-
import '@nywqs/scada-engine/dist/scada-engine.css'
|
|
475
|
-
|
|
476
|
-
const canvasRef = ref()
|
|
477
|
-
const selectedNode = ref(null)
|
|
478
|
-
|
|
479
|
-
const handleNodeSelect = (node: any) => {
|
|
480
|
-
selectedNode.value = node
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const handleUpdateNode = (data: any) => {
|
|
484
|
-
// 更新节点数据
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
const handleSave = () => {
|
|
488
|
-
// 保存逻辑
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
const handleExport = () => {
|
|
492
|
-
// 导出逻辑
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
const handlePreview = () => {
|
|
496
|
-
// 预览逻辑
|
|
497
|
-
}
|
|
498
|
-
</script>
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
### 软件授权使用
|
|
502
|
-
|
|
503
|
-
本软件默认在底部显示版权信息。如需隐藏或修改版权信息,必须使用有效的数字签名令牌与公钥。
|
|
504
|
-
|
|
505
|
-
#### 获取授权
|
|
506
|
-
|
|
507
|
-
请联系作者获取:
|
|
508
|
-
1. **授权令牌 (Token)**:包含公司名、有效期等信息的签名串。
|
|
509
|
-
2. **公钥 (Public Key)**:用于验证签名的 `public.pem` 文件内容。
|
|
510
|
-
|
|
511
|
-
- 邮箱:nywqs@outlook.com
|
|
512
|
-
- 电话:18637762001
|
|
513
|
-
|
|
514
|
-
#### 使用方式
|
|
515
|
-
|
|
516
|
-
在使用 `ScadaCanvas` 组件时,需同时传入 `auth-code`(令牌)与 `public-key-pem`(公钥内容)。
|
|
517
|
-
|
|
518
|
-
```vue
|
|
519
|
-
<template>
|
|
520
|
-
<ScadaCanvas
|
|
521
|
-
:auth-code="licenseToken"
|
|
522
|
-
:public-key-pem="publicKey"
|
|
523
|
-
:custom-footer="{
|
|
524
|
-
copyright: '© 2025 您的公司',
|
|
525
|
-
license: '商业授权使用',
|
|
526
|
-
contact: '联系方式: support@yourcompany.com'
|
|
527
|
-
}"
|
|
528
|
-
/>
|
|
529
|
-
</template>
|
|
530
|
-
|
|
531
|
-
<script setup lang="ts">
|
|
532
|
-
// 填入从授权方获取的 Token 字符串
|
|
533
|
-
const licenseToken = 'eyJh...<完整Token字符串>'
|
|
534
|
-
|
|
535
|
-
// 填入 public.pem 的完整内容
|
|
536
|
-
const publicKey = `-----BEGIN PUBLIC KEY-----
|
|
537
|
-
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
538
|
-
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
539
|
-
xxxxxxxx==
|
|
540
|
-
-----END PUBLIC KEY-----`
|
|
541
|
-
</script>
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
**授权模式说明**
|
|
545
|
-
- 未提供有效 Token 或 公钥验证失败:显示默认版权信息
|
|
546
|
-
- 验证通过 + 无 customFooter:隐藏 Footer
|
|
547
|
-
- 验证通过 + customFooter:显示自定义 Footer
|
|
548
|
-
|
|
549
|
-
**授权验证机制**
|
|
550
|
-
采用 ECDSA P-256 + SHA-256 数字签名技术。前端仅持有公钥进行验签,无法伪造授权。
|
|
551
|
-
|
|
552
|
-
控制台会输出授权验证信息:
|
|
553
|
-
```javascript
|
|
554
|
-
✅ 授权验证成功
|
|
555
|
-
🏛️ 授权公司: ACME Corp
|
|
556
|
-
📅 有效期至: 2026-12-31
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
## 预览模式
|
|
560
|
-
|
|
561
|
-
ScadaCanvas 组件支持预览模式,用于在运行时展示组态画面:
|
|
562
|
-
|
|
563
|
-
```vue
|
|
564
|
-
<template>
|
|
565
|
-
<ScadaCanvas
|
|
566
|
-
:preview-mode="true"
|
|
567
|
-
:auth-code="authCode"
|
|
568
|
-
/>
|
|
569
|
-
</template>
|
|
570
|
-
|
|
571
|
-
<script setup lang="ts">
|
|
572
|
-
import { ref, onMounted } from 'vue'
|
|
573
|
-
import { ScadaCanvas } from '@nywqs/scada-engine'
|
|
574
|
-
|
|
575
|
-
const authCode = ref('your-auth-code')
|
|
576
|
-
|
|
577
|
-
// 预览模式特性:
|
|
578
|
-
// 1. 隐藏编辑工具栏和组件库
|
|
579
|
-
// 2. 禁止节点移动和编辑
|
|
580
|
-
// 3. 仅显示画布和组件
|
|
581
|
-
// 4. 支持动画自动播放
|
|
582
|
-
// 5. 支持实时数据更新
|
|
583
|
-
</script>
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
## 开发
|
|
587
|
-
|
|
588
|
-
```bash
|
|
589
|
-
# 克隆项目
|
|
590
|
-
git clone https://github.com/yourusername/scada-engine.git
|
|
591
|
-
|
|
592
|
-
# 安装依赖
|
|
593
|
-
npm install
|
|
594
|
-
|
|
595
|
-
# 启动开发服务器
|
|
596
|
-
npm run dev
|
|
597
|
-
|
|
598
|
-
# 构建库
|
|
599
|
-
npm run build:lib
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
## 发布到 npm
|
|
603
|
-
|
|
604
|
-
```bash
|
|
605
|
-
# 1. 登录 npm
|
|
606
|
-
npm login
|
|
607
|
-
|
|
608
|
-
# 2. 构建库
|
|
609
|
-
npm run build:lib
|
|
610
|
-
|
|
611
|
-
# 3. 发布(首次发布公开包)
|
|
612
|
-
npm publish --access public
|
|
613
|
-
|
|
614
|
-
# 4. 后续版本更新
|
|
615
|
-
npm version patch # 补丁版本 1.0.0 -> 1.0.1
|
|
616
|
-
npm version minor # 次版本 1.0.0 -> 1.1.0
|
|
617
|
-
npm version major # 主版本 1.0.0 -> 2.0.0
|
|
618
|
-
npm publish
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
## 版本管理建议
|
|
622
|
-
|
|
623
|
-
- patch (1.0.x):Bug 修复、小改进
|
|
624
|
-
- minor (1.x.0):新功能、向后兼容
|
|
625
|
-
- major (x.0.0):破坏性更新、重大重构
|
|
626
|
-
|
|
627
|
-
## 版本历史
|
|
628
|
-
|
|
629
|
-
完整的版本更新记录请查看 [CHANGELOG.md](./CHANGELOG.md)
|
|
630
|
-
|
|
631
|
-
### 1.1.27 (2025-01-16)
|
|
632
|
-
- 修复 `ScadaCanvas.vue` 中 `calculateContainerSize` 函数的 TypeScript 类型声明
|
|
633
|
-
- 为函数添加明确的返回类型注解,消除 TS6133 警告
|
|
634
|
-
|
|
635
|
-
### 1.1.26 (2025-01-16)
|
|
636
|
-
- 创建版本更新历史记录文档 CHANGELOG.md
|
|
637
|
-
- 建立版本发布规范和记录模板
|
|
638
|
-
|
|
639
|
-
### 1.1.20 (2026-01-06)
|
|
640
|
-
- 画布自适应缩放:支持不同分辨率设备自动适配显示
|
|
641
|
-
- 组件库折叠展开:基础组件和IoT组件分组可收缩
|
|
642
|
-
- 组件库三列布局:优化组件展示,更紧凑的空间利用
|
|
643
|
-
- 画布自定义尺寸:支持800-7680px宽度,600-4320px高度
|
|
644
|
-
- 设备点位类型导出:完整的Device、DevicePoint等类型定义
|
|
645
|
-
|
|
646
|
-
### 1.1.11 (2025-12-30)
|
|
647
|
-
- 修复预览按钮事件触发问题
|
|
648
|
-
- 优化路由跳转逻辑
|
|
649
|
-
- 添加详细调试日志
|
|
650
|
-
|
|
651
|
-
### 1.1.10 (2025-12-30)
|
|
652
|
-
- 添加预览事件支持
|
|
653
|
-
- 优化事件触发机制
|
|
654
|
-
|
|
655
|
-
### 1.0.0
|
|
656
|
-
- 初始版本发布
|
|
657
|
-
- 基础组态编辑功能
|
|
658
|
-
- 支持基础组件和IoT组件
|
|
659
|
-
|
|
660
|
-
## 贡献
|
|
661
|
-
|
|
662
|
-
欢迎提交 Issue 和 Pull Request!
|
|
663
|
-
|
|
664
|
-
## 许可协议
|
|
665
|
-
|
|
666
|
-
本项目采用 **MIT 许可协议**,详见 [LICENSE](LICENSE) 文件。
|
|
667
|
-
|
|
668
|
-
- 允许商业使用、修改、分发
|
|
669
|
-
- 需保留版权声明与许可文本
|
|
670
|
-
- 软件按“原样”提供,无任何担保
|
|
671
|
-
|
|
672
|
-
如需商业授权,请联系作者。
|
|
187
|
+
**商业授权**:如需将本引擎用于商业产品并隐藏底部版权标识,请联系作者获取数字签名授权。
|
|
673
188
|
|
|
674
189
|
## 作者
|
|
675
190
|
|
|
676
|
-
**
|
|
677
|
-
|
|
678
|
-
- 📧 邮箱:nywqs@outlook.com
|
|
679
|
-
- 📱 电话:18637762001
|
|
191
|
+
- **nywqs**
|
|
680
192
|
|
|
681
|
-
|
|
193
|
+
如有问题或建议,欢迎提交 Issue 或联系作者。
|