IoT管理平台入门指南:从概念到部署
本文档面向有 HTML/CSS/JavaScript + Flask 基础的初学者,用最通俗的大白话解释工业物联网平台的方方面面。
一、先理解这个项目到底是什么
1.1 一句话总结
这个项目不是单一的网站,而是两个独立的管理系统装在同一台服务器里,通过不同的网址访问:
| 系统 | 类比理解 | 访问地址 |
|---|---|---|
| DC3 IoT 管理平台 | 工厂设备的"大管家"(管设备、管数据、管驱动) | http://服务器IP:3000 |
| SCADA 组态系统 | 工厂设备的"监控大屏"(拖拽画图、实时看数据) | http://服务器IP:3001 |
关键理解:两个系统各自有各自的数据库、各自的后端程序、各自的前端页面。它们只是住在同一台服务器的不同房间里,互相不串门。
1.2 用你熟悉的东西做类比
你已经会写 Flask 网站了,想象一下你熟悉的结构:
浏览器 → Flask (Python) → SQLite/MySQL → 返回数据 → 浏览器显示
这个项目的本质和上面一样,只是每个环节都升级成了专业工具:
浏览器 → Vue 前端 → Nginx 代理 → Java 后端 → 数据库 → 返回数据
| 你熟悉的 | 这个项目用的 | 为什么换 |
|---|---|---|
| Flask (Python) | Spring Boot (Java) | 企业级、能扛高并发、微服务方便团队分工 |
| Jinja2 模板返回 HTML | Vue 3 前端独立渲染 | 前端体验像 App,响应更快 |
| SQLite | PostgreSQL + MySQL + Redis | 功能更强、分工更细 |
直接运行 python app.py |
Docker 容器运行 | 一次打包,到处运行,环境不冲突 |
1.3 两个子系统的详细拆解
SCADA 组态系统(简单理解版)
SCADA 是工业领域的术语,意思是"监控与数据采集"。你可以把它理解成:
一个可以让管理员拖拽画图做出监控界面的系统。
比如工厂里有很多水泵、电机、温度计:
- 管理员在 SCADA 里拖一个"水泵"图标到画布上
- 把这个图标和真实的设备数据绑定
- 保存后,运行状态下这个水泵图标会实时显示转速、温度
- 如果温度超标,图标变红报警
技术实现:
- 前端用 maotu 组态引擎(专门画工业监控图的工具)
- 后端是单一的 Java 程序(Spring Boot)
- 数据库用 MySQL 存用户信息、组态项目、设备列表
- 用 Redis 存用户登录状态(谁在线、登录了多久)
- 用 WebSocket 推送实时数据(数据变了主动推给前端,不用前端一直问)
DC3 IoT 管理平台(简单理解版)
DC3 是设备管理平台,你可以把它理解成:
一个注册、管理、监控所有工业设备的后台系统。
它的核心功能是三层:
第一层:驱动层(和设备说话)
- 工厂里的设备说不同的"方言"(MQTT、Modbus、OPC UA 等)
- DC3 内置了各种"翻译员"(驱动),负责和设备通信
- 驱动把设备数据读上来,交给上层处理
第二层:管理层(管设备的户口)
- 每个设备都要在系统里"登记户口":名称、型号、位置、参数
- 设备的每个"测点"(温度、压力、转速)也要登记
- 这些配置存在 PostgreSQL 数据库里
第三层:数据层(存和处理数据)
- 设备每秒产生大量数据,普通数据库存不下、查得慢
- 时序数据库(TDengine/InfluxDB)专门存这种"时间-数值"数据
- 数据层还负责报警:温度超了 80 度?发通知!
为什么 DC3 用微服务架构?
你可以理解成:一个工厂里,如果所有活都让一个人干(单体应用),会很累,而且一个人感冒了全厂停工。
微服务就是分工:
- 认证中心(auth):只管登录、权限、谁是谁
- 管理中心(manager):只管设备的增删改查
- 数据中心(data):只管数据处理、存储、报警
- 网关(gateway):像前台接待员,所有请求先找它,它再转给具体部门
每个服务独立运行,互不干扰。一个崩了,其他还能干活。
1.4 数据是怎么流的?(一张图看懂)
SCADA 系统的数据流
┌─────────────┐ ┌─────────────┐ ┌─────────────────┐
│ 你的浏览器 │────▶│ Nginx:3001 │────▶│ SCADA Java后端 │
│ (看监控大屏) │◀────│ (反向代理) │◀────│ (端口 8887) │
└─────────────┘ └─────────────┘ └────────┬────────┘
│
┌─────────────────────────────┘
│
┌─────▼─────┐ ┌──────────┐
│ MySQL 8.0 │ │ Redis 6 │
│ (存数据) │ │ (存缓存) │
└───────────┘ └──────────┘
每一步发生了什么:
1. 你打开 http://服务器:3001
2. Nginx 把前端的 HTML/CSS/JS 文件发给你,浏览器渲染出页面
3. 你点击登录,前端发请求到 /prod-api/login
4. Nginx 收到 /prod-api/ 开头的请求,转发给后端的 Java 程序
5. Java 程序查 MySQL 验证账号密码,生成 JWT Token
6. Token 存到 Redis(这样下次你来,系统知道你是谁)
7. 后续你点"设备管理",Java 程序查 MySQL 返回设备列表
8. 你打开"组态预览",Java 程序通过 WebSocket 主动推送实时数据
DC3 系统的数据流
┌─────────────┐ ┌─────────────┐ ┌─────────────────┐
│ 你的浏览器 │────▶│ Nginx:3000 │────▶│ Gateway:8000 │
│ (管设备后台) │◀────│ (反向代理) │◀────│ (API网关) │
└─────────────┘ └─────────────┘ └────────┬────────┘
│
┌──────────────┬──────────────┼──────────────┐
│ │ │ │
┌─────▼─────┐ ┌────▼─────┐ ┌────▼─────┐ ┌────▼─────┐
│ Auth │ │ Manager │ │ Data │ │ Driver │
│ :8300 │ │ :8400 │ │ :8500 │ │ (各种驱动) │
└─────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
┌─────▼─────┐ ┌────▼─────┐ ┌────▼─────┐ ┌────▼─────┐
│ PostgreSQL│ │ PostgreSQL│ │ PostgreSQL│ │ RabbitMQ │
│ (用户/权限)│ │ (设备配置)│ │ (规则/报警)│ │ (消息队列)│
└───────────┘ └───────────┘ └───────────┘ └──────────┘
每一步发生了什么:
1. 你打开 http://服务器:3000
2. Nginx 给你发前端页面
3. 你登录,请求到 /api/v3/auth/token/generate
4. Gateway 收到请求,看路径里有 /auth/,转发给 Auth 服务 (8300)
5. Auth 服务查 PostgreSQL 的 dc3_auth 库,验证成功返回 Token
6. 你要看设备列表,请求到 /api/v3/manager/device/list
7. Gateway 转发给 Manager 服务 (8400)
8. Manager 查 PostgreSQL 的 dc3_manager 库,返回设备列表
9. 驱动(如 MQTT 驱动)通过 RabbitMQ 把设备实时数据送到 Data 服务
10. Data 服务处理后,写入 InfluxDB/TDengine 时序数据库
二、架构层面的大概念
2.1 单体应用 vs 微服务
单体应用(Monolithic)
类比:一家小餐馆,老板一个人兼任厨师、服务员、收银员。
所有功能都在一个程序里:
- 用户登录、设备管理、数据查询、报表生成……全部写在一个 Flask 项目里。
- 优点:简单,开发快。
- 缺点:功能越来越多时,代码膨胀,一个人改登录功能可能不小心把设备管理搞崩。
本项目中的例子:SCADA 系统就是一个单体应用(iot-scada-api)。
微服务架构(Microservices)
类比:一家连锁酒店集团,分成不同的部门:
- 前台部(负责接待/登录)
- 客房部(负责房间/设备管理)
- 餐饮部(负责数据处理)
每个部门独立运营,互不干扰。但对外有一个总机(网关),客人打电话到总机,总机转接到具体部门。
本项目中的例子:DC3 系统是微服务架构:
- auth 服务:专门负责登录认证
- manager 服务:专门管设备
- data 服务:专门处理采集的数据
- gateway 服务:总机/网关,统一接收请求再分发
| 对比 | 单体应用 | 微服务 |
|---|---|---|
| 代码量 | 一个项目 | 多个独立项目 |
| 部署 | 启动一个程序 | 启动多个程序 |
| 协作 | 容易冲突 | 团队可以各自负责一个服务 |
| 复杂度 | 低 | 高(需要解决服务间通信) |
| 故障影响 | 一处崩全部崩 | 一个服务崩不影响其他 |
2.2 前后端分离
你已经熟悉的(非前后端分离):
Flask 用 render_template() 直接返回 HTML 页面,后端把页面都拼好了给浏览器。
前后端分离(现代主流):
- 后端只提供 API 接口(返回纯数据,通常是 JSON 格式)。
- 前端是一个独立的程序(Vue 项目),用 JavaScript 请求 API 获取数据,然后在浏览器里动态渲染页面。
类比:
- 非分离:餐厅厨房直接把菜端到你桌上(后端返回完整 HTML)。
- 分离:餐厅只提供食材清单(JSON 数据),你自己在家按照菜谱做(前端 Vue 自己渲染页面)。
好处:
- 前端和后端可以完全用不同的技术栈。
- 前端可以做成类似手机 App 的体验(单页应用 SPA)。
- 一套后端 API 可以同时给网页、手机 App、小程序用。
2.3 API 接口:REST 和 gRPC
REST API
你最熟悉的概念:Flask 里写 @app.route('/users', methods=['GET']),这就是 REST API。
REST 是一种设计风格:
- 用 URL 表示资源(/devices 表示设备)
- 用 HTTP 方法表示操作(GET 获取、POST 创建、PUT 更新、DELETE 删除)
- 数据用 JSON 格式传输
本项目中的例子:SCADA 系统用的是 REST API。
gRPC
类比:REST 像寄明信片(文本,人人能读但速度慢),gRPC 像打电话(二进制,效率高但双方需要约定好协议)。
- gRPC 是 Google 开发的高性能远程调用框架。
- 用 Protobuf(协议缓冲区)定义数据结构,自动生成代码。
- 基于 HTTP/2,支持流式传输。
- 缺点:浏览器不直接支持,主要用于服务之间内部通信。
本项目中的例子:DC3 的微服务之间用 gRPC 通信(比如 auth 服务查询 manager 服务的数据)。
三、前端技术栈详解
3.1 Vue.js(Vue 3)
类比:jQuery 像手工工具,Vue 像电动工具套装。
你已经会用 JavaScript 操作 DOM:document.getElementById('box').innerHTML = 'hello'。
Vue 是一种前端框架,核心思想:
- 数据驱动:你只需要改数据,Vue 自动帮你更新页面。
- 组件化:把页面拆成独立的"乐高积木"(组件),比如导航栏组件、表格组件、图表组件,拼起来就是一个页面。
- 单文件组件(.vue):一个文件里同时包含 HTML 模板、JavaScript 逻辑、CSS 样式。
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
data() {
return { message: 'Hello Vue!' }
}
}
</script>
<style>
div { color: red; }
</style>
Vue 3 的新特性:
- 使用 Composition API(组合式 API),逻辑可以更灵活地组织。
- 性能更好,包体积更小。
3.2 TypeScript(TS)
类比:JavaScript 像 Python(动态类型,灵活但容易出错),TypeScript 像 Java(静态类型,严谨但能提前发现错误)。
TypeScript = JavaScript + 类型系统。
// JavaScript
function add(a, b) {
return a + b // 不知道 a 和 b 应该是什么类型
}
// TypeScript
function add(a: number, b: number): number {
return a + b // 明确告诉编译器:a 和 b 必须是数字,返回值也是数字
}
好处:
- 写代码时编辑器能提示你哪里类型不对。
- 重构代码更安全(改名一个地方,相关的地方会自动检查)。
- 大型项目必备。
本项目中的例子:DC3 前端用 TypeScript,SCADA 前端用普通 JavaScript。
3.3 Vite
类比:Vite 像汽车的涡轮增压器,让开发体验飞速提升。
Vite 是一个前端构建工具,替代了 older 的 Webpack。
它做什么:
- 开发时:启动极快(秒级),修改代码后页面瞬间更新(热更新 HMR)。
- 打包时:把 Vue/TS 代码编译成浏览器能理解的纯 HTML/CSS/JS,做代码压缩、合并、优化。
配置文件:vite.config.ts(DC3)或 vite.config.js(SCADA)。
3.4 Element Plus
类比:像 Bootstrap,但是专门为 Vue 3 设计的一套 UI 组件库。
提供现成的、好看的组件:
- 按钮、表格、表单、对话框、日期选择器、下拉菜单……
你只需要:
<template>
<el-button type="primary">点击我</el-button>
<el-table :data="tableData">...</el-table>
</template>
就能得到一个好看的、有交互效果的按钮和表格,不用自己写 CSS。
3.5 状态管理:Vuex vs Pinia
问题:多个组件怎么共享数据?
类比:
- 没有状态管理:每个组件像独立的办公室,传文件需要一层层递交(props 层层传递)。
- 有状态管理:有一个公共的"档案室",任何办公室都能直接存取。
Vuex
- Vue 官方老牌状态管理库。
- 概念:State(数据)、Mutations(修改数据的方法)、Actions(异步操作)。
- 本项目 DC3 前端使用 Vuex。
Pinia
- Vuex 的下一代替代品,更简单、更轻量。
- 用法更接近普通 JavaScript。
- 本项目 SCADA 前端使用 Pinia。
3.6 Axios
你已经熟悉的概念:JavaScript 里用 fetch() 发网络请求。
Axios 是一个HTTP 请求库,比 fetch 更好用:
- 自动转换 JSON 数据
- 支持请求/响应拦截器(比如统一加 Token、统一处理错误)
- 支持取消请求
import axios from 'axios'
axios.get('/api/devices').then(res => {
console.log(res.data)
})
3.7 ECharts / AntV G2Plot
类比:像 Python 的 Matplotlib/Plotly,但是专门用于网页。
数据可视化图表库:
- ECharts:百度开源,功能极其丰富(折线图、柱状图、地图、雷达图……)。
- AntV G2Plot:阿里开源,开箱即用,配置更简单。
本项目用来做设备数据的大屏展示、趋势图等。
四、后端技术栈详解
4.1 Spring Boot
类比:Flask 是轻量级框架,Spring Boot 是 Java 世界里的"重型但功能齐全的框架"。
Spring Boot 是 Java 最流行的 Web 开发框架:
- 内置 Tomcat 服务器(像 Flask 内置开发服务器,但是生产级)。
- 自动配置:写很少的配置就能跑起来。
- 约定大于配置:按照它的目录结构和命名规范,很多东西自动生效。
核心概念:
- Controller:处理 HTTP 请求(类似 Flask 的 @app.route)。
- Service:业务逻辑层。
- Mapper/Repository:数据库访问层。
- Entity/POJO:数据模型类(类似 Python 的 dataclass)。
4.2 Spring Cloud
类比:Spring Boot 是单个饭店的运营手册,Spring Cloud 是连锁饭店的管理体系。
Spring Cloud 是微服务架构的一整套解决方案,包含:
- 服务注册与发现:新开个分店,自动登记到总部(Nacos)。
- 网关(Gateway):客人统一打电话给总机,总机转接。
- 负载均衡:多个相同的服务,自动分配请求。
- 配置中心:统一管理所有服务的配置。
本项目中的例子:DC3 使用 Spring Cloud,SCADA 只用 Spring Boot(单体不需要)。
4.3 Nacos
类比:像企业的通讯录 + 公告栏系统。
Nacos 是阿里的开源产品,两个核心功能:
- 服务注册与发现:每个微服务启动时"报到",其他服务可以"查通讯录"找到它。
- 配置中心:统一管理配置文件,修改一处,所有服务自动更新。
4.4 Maven
类比:Python 里的 pip,但是更强大、更规范。
Maven 是 Java 的项目构建和依赖管理工具:
- pom.xml 文件声明项目信息和依赖(类似 Python 的 requirements.txt,但更复杂)。
- 自动下载 jar 包(Java 的库文件)。
- 编译代码、运行测试、打包成可执行文件。
常用命令:
mvn clean package # 清理 + 编译 + 打包
4.5 MyBatis / MyBatis Plus
类比:Python 里你用 SQLAlchemy 或原生的 cursor.execute() 操作数据库,MyBatis 就是 Java 世界的 ORM 工具。
MyBatis
- 把 Java 方法和 SQL 语句映射起来。
- 你在 XML 文件里写 SQL,MyBatis 帮你执行并映射结果到 Java 对象。
MyBatis Plus
- MyBatis 的增强版。
- 提供了通用的 CRUD 方法(增删改查),不用写 SQL。
- 支持分页、代码生成等功能。
4.6 Lombok
类比:Python 的 @dataclass 装饰器,自动生成重复的代码。
Java 需要写很多"样板代码"(getter、setter、构造函数等),Lombok 用注解自动生成:
@Data // 自动生成 getter/setter/toString/equals/hashCode
public class User {
private String name;
private Integer age;
}
4.7 MapStruct
类比:像 Python 里的字典转换或 Pydantic 模型转换。
用于自动转换不同类型的对象(比如数据库实体转 DTO 传输对象),避免手写转换代码。
4.8 JWT(JSON Web Token)
类比:像游乐园的"通票手环",你登录后拿到一个 Token,之后所有请求都带着它,服务器一看就知道你是谁。
认证流程:
1. 用户输入账号密码 → 服务器验证 → 返回 JWT Token。
2. 前端把 Token 存起来(通常放内存或 localStorage)。
3. 后续请求在 HTTP Header 里带上 Token:Authorization: Bearer <token>。
4. 服务器验证 Token 的有效性(签名、过期时间)。
本项目:
- DC3 用自定义的请求头(X-Auth-Token)。
- SCADA 用标准 JWT(Authorization: Bearer ***)。
4.9 Spring Security
类比:像大楼的安保系统,控制谁能进哪个门。
Spring Security 是 Java 的安全框架:
- 认证(Authentication):你是谁?(查账号密码)
- 授权(Authorization):你能做什么?(管理员能删数据,普通用户只能看)
- 防止 CSRF、XSS 等攻击。
本项目中的例子:SCADA 系统使用 Spring Security。
4.10 Druid
类比:数据库连接池像一个"预热的游泳池",不用每次都重新接水管放水。
数据库连接是昂贵资源,Druid 是阿里开源的数据库连接池:
- 维护一组预先建立好的数据库连接。
- 请求来时取一个用,用完放回。
- 带监控功能,可以看 SQL 执行情况和性能。
4.11 Quartz
类比:像 Linux 的 cron 定时任务,或者 Python 的 schedule 库。
Quartz 是 Java 的定时任务调度框架:
- 每隔 5 分钟执行一次数据同步。
- 每天早上 8 点发送报表。
- 支持复杂的调度规则(Cron 表达式)。
本项目中的例子:SCADA 系统用 Quartz 做定时任务。
4.12 Swagger (springfox)
类比:像自动生成的 API 文档网站,类似 Python FastAPI 自带的 /docs 页面。
后端在代码里写注解,Swagger 自动生成:
- 所有接口列表
- 请求参数说明
- 响应格式示例
- 甚至可以直接在页面上调试接口
五、数据库与中间件
5.1 关系型数据库:PostgreSQL / MySQL
你已经熟悉的概念:像 SQLite,但功能更强大、支持并发。
| 特性 | PostgreSQL | MySQL |
|---|---|---|
| 本项目用途 | DC3 主数据库 | SCADA 数据库 |
| 特点 | 功能最丰富,支持复杂查询 | 简单快速,使用广泛 |
| 数据组织 | 表、行、列,用 SQL 操作 | 同上 |
两者都是关系型数据库,用 SQL 语言操作数据。
5.2 时序数据库:TDengine / InfluxDB
问题:IoT 设备每秒产生大量数据(温度、湿度、电压……),用传统数据库存储和查询会很慢。
类比:普通数据库像Excel表格,时序数据库像专门记录"时间-数值"的日志本。
时序数据库专门为时间序列数据优化:
- 数据按时间顺序写入。
- 查询时通常按时间范围查("最近一小时的数据")。
- 支持数据压缩和过期自动删除。
| 数据库 | 特点 |
|---|---|
| TDengine | 国产开源,专为物联网设计,性能极高 |
| InfluxDB | 业界最流行的时序数据库,生态丰富 |
本项目中的例子:DC3 采集的设备传感器数据存储在时序数据库中。
5.3 文档数据库:MongoDB
类比:关系数据库像填固定格式的表格,MongoDB 像自由格式的笔记本(JSON 文档)。
MongoDB 存储的是 BSON(类似 JSON)文档,没有固定的表结构:
{
"deviceId": "D001",
"properties": { "temp": 25, "humidity": 60 },
"tags": ["factory1", "lineA"]
}
适合存储结构不固定、灵活的数据。
5.4 Redis(缓存)
类比:像电脑的内存条,速度极快但断电丢失(默认)。
Redis 是一个内存中的键值数据库:
- 速度比 PostgreSQL/MySQL 快 100 倍以上。
- 适合存临时数据:用户会话、热点数据、验证码、排行榜……
- 支持设置过期时间(比如验证码 5 分钟后自动删除)。
为什么用缓存:
- 数据库查询慢 → 第一次查完后把结果放 Redis。
- 下次直接从 Redis 取,极大提升响应速度。
5.5 消息队列:RabbitMQ
类比:像医院的叫号系统,病人(消息)在队列里等待,医生(消费者)依次处理。
解决的问题:
- 系统 A 产生大量数据,系统 B 处理不过来 → 先放到队列里缓冲。
- 系统 A 和系统 B 不需要同时在线(解耦)。
- 一个任务可以分给多个工人并行处理。
工作流程:
1. 生产者(Producer)发送消息到队列。
2. 队列(Queue)暂存消息。
3. 消费者(Consumer)从队列取出消息处理。
本项目中的例子:DC3 的设备数据通过 RabbitMQ 在不同服务之间传递。
六、容器化与部署
6.1 Docker
类比:像"集装箱"标准化运输。
问题:你的程序在 Windows 能跑,到 Linux 服务器上可能因为环境不同跑不起来("在我电脑上好好的")。
Docker 解决什么:
- 把程序 + 运行环境(操作系统、依赖库、配置)打包成一个镜像(Image)。
- 镜像在任何地方运行结果都一样。
- 运行中的镜像叫容器(Container)。
关键概念:
- 镜像(Image):只读的模板,类似安装盘。
- 容器(Container):镜像的运行实例,类似装好的系统。
- Dockerfile:描述怎么构建镜像的脚本。
6.2 Docker Compose
类比:像乐高的搭建说明书,一次指令搭建一整套场景。
一个系统有多个服务(前端、后端、数据库、缓存……),Docker Compose 用一个 docker-compose.yml 文件定义:
- 有哪些服务
- 每个服务用哪个镜像
- 端口怎么映射
- 服务之间怎么连接
一键启动整个系统:
docker compose up -d # -d 表示后台运行
本项目中的例子:
- docker-compose-env.yml:启动基础设施(数据库、缓存等)。
- docker-compose.yml:启动应用服务(网关、各微服务、前端)。
6.3 Nginx / 反向代理
你已经熟悉的概念:Flask 开发服务器监听一个端口(如 127.0.0.1:5000)。
Nginx 是什么:
- 高性能的 Web 服务器/反向代理服务器。
- 能同时处理几万个并发连接。
正向代理 vs 反向代理
- 正向代理:你(客户端)通过代理访问外网(代理代表你)。
- 反向代理:外网请求通过代理访问内部服务器(代理代表服务器)。
本项目中的反向代理作用:
用户访问 http://服务器:3000
↓
Nginx(端口 3000)
↓
如果是静态文件(HTML/CSS/JS)→ 直接返回
如果是 API 请求 /api/xxx → 转发给 dc3-gateway:8000
这样用户只感知到一个地址,实际上背后有多个服务。
6.4 环境变量与 Profile
你已经熟悉的概念:Python 的 os.environ.get('SECRET_KEY')。
环境变量:在程序外部设置配置,不用改代码。
Profile(Spring 的概念):
- application.yml:通用配置
- application-dev.yml:开发环境配置(连本地数据库)
- application-pro.yml:生产环境配置(连线上数据库)
启动时通过环境变量 NODE_ENV=pro 切换。
七、IoT / SCADA 专用概念
7.1 IoT(物联网)
物联网 = 各种物理设备(传感器、机器、电器)连接到互联网,可以采集数据或远程控制。
本项目中的场景:
- 工厂里的温度传感器、电表、PLC 控制器……
- 它们通过网络把数据发到平台。
- 平台存储、展示、分析这些数据。
7.2 SCADA(监控与数据采集)
类比:像工厂的"中控室大屏幕"。
SCADA 是工业领域的专用系统:
- 采集:从设备读取数据(温度、压力、开关状态)。
- 监控:在屏幕上实时显示设备状态和数值。
- 控制:远程发送指令(比如打开某个阀门)。
- 报警:数据异常时告警(温度过高!)。
7.3 组态
类比:像搭积木或做 PPT,不用写代码就能做出监控画面。
"组态"是工业软件的概念:
- 从工具箱拖一个"泵"图标到画布上。
- 把这个图标绑定到真实的设备数据点。
- 运行后,图标会实时显示泵的状态(运转中/停止)。
本项目中的例子:SCADA 系统的组态编辑器,让用户拖拽组件设计监控大屏。
7.4 工业通信协议
类比:不同国家的人说不同语言,协议就是"翻译规则"。
设备要和平台通信,必须约定好"怎么说":
| 协议 | 用途 | 类比 |
|---|---|---|
| MQTT | 轻量级的物联网消息协议 | 像发短信:简短、省电、适合弱网环境 |
| OPC UA | 工业自动化标准协议 | 像商务英语:正式、功能全面、跨平台 |
| Modbus TCP | simplest 工业协议 | 像手势语:简单、老旧但广泛支持 |
| PLC S7 | 西门子 PLC 专用协议 | 像方言:只适用于西门子设备 |
本项目中的例子:DC3 系统内置了这些协议的"驱动"(Driver),负责和设备对话。
7.5 驱动(Driver)
类比:像打印机的驱动程序,让电脑能和硬件对话。
在 IoT 平台中:
- 驱动负责通过特定协议连接设备。
- 采集设备数据并上传到平台。
- 接收平台的指令下发给设备。
本项目中的例子:dc3-driver-mqtt 是 MQTT 协议的驱动服务。
八、系统架构详解
8.1 整体架构图
┌─────────────────────────────────────────────────────────────┐
│ 前端层 (Web/Client) │
│ iot-management-platform-web (Vue 3 + TypeScript) │
└────────────────────────┬────────────────────────────────────┘
│ HTTP/WebSocket
┌────────────────────────▼────────────────────────────────────┐
│ 网关层 (Gateway) │
│ dc3-gateway (Spring Cloud Gateway + Nginx) │
└────────────────────────┬────────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────────┐
│ 服务中心 (Center) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Auth │ │ Manager │ │ Data │ │
│ │ 认证服务 │ │ 管理服务 │ │ 数据服务 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────────┬────────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────────┐
│ 驱动层 (Driver) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ MQTT │ │ OPC UA │ │ Modbus │ │ Virtual │ │
│ │ 驱动 │ │ 驱动 │ │ TCP 驱动 │ │ 虚拟驱动 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
8.2 后端项目结构
iot-management-platform-backend/
├── dc3-api/ # API 接口模块
│ ├── dc3-api-auth/ # 认证 API
│ ├── dc3-api-data/ # 数据 API
│ ├── dc3-api-driver/ # 驱动 API
│ └── dc3-api-manager/ # 管理 API
├── dc3-center/ # 服务中心模块
│ ├── dc3-center-auth/ # 认证服务
│ ├── dc3-center-data/ # 数据服务
│ ├── dc3-center-manager/ # 管理服务
│ └── dc3-center-single/ # 单体服务
├── dc3-common/ # 公共模块
│ ├── dc3-common-api/ # 公共 API
│ ├── dc3-common-auth/ # 认证工具
│ ├── dc3-common-dal/ # 数据访问层
│ ├── dc3-common-driver/ # 驱动工具
│ ├── dc3-common-manager/ # 管理工具
│ ├── dc3-common-model/ # 数据模型
│ ├── dc3-common-mqtt/ # MQTT 工具
│ ├── dc3-common-redis/ # Redis 工具
│ ├── dc3-common-rabbitmq/# RabbitMQ 工具
│ └── ...
├── dc3-driver/ # 驱动模块
│ ├── dc3-driver-mqtt/ # MQTT 驱动
│ ├── dc3-driver-opc-ua/ # OPC UA 驱动
│ ├── dc3-driver-opc-da/ # OPC DA 驱动
│ ├── dc3-driver-modbus-tcp/ # Modbus TCP 驱动
│ ├── dc3-driver-plcs7/ # PLC S7 驱动
│ └── dc3-driver-virtual/ # 虚拟驱动
├── dc3-gateway/ # 网关服务
├── deploy/ # 部署配置
├── pom.xml # 父 POM
└── .env/ # 环境变量配置
8.3 各服务端口配置
| 服务 | HTTP 端口 | gRPC 端口 | 说明 |
|---|---|---|---|
| dc3-center-auth | 8200 | - | 认证服务 |
| dc3-center-manager | 8400 | 9400 | 管理服务 |
| dc3-center-data | 8300 | - | 数据服务 |
| dc3-gateway | 8000 | - | 网关服务 |
8.4 服务启动顺序
- 基础设施(PostgreSQL, Redis, RabbitMQ)
- dc3-center-auth(认证服务)
- dc3-center-manager(管理服务)
- dc3-center-data(数据服务)
- dc3-gateway(网关服务)
- 各类驱动服务
8.5 前端技术架构
目录结构
src/
├── api/ # API 接口定义
│ ├── attribute.ts # 属性 API
│ ├── device.ts # 设备 API
│ ├── dictionary.ts # 字典 API
│ ├── driver.ts # 驱动 API
│ ├── info.ts # 信息 API
│ ├── point.ts # 点位 API
│ ├── profile.ts # 模板 API
│ ├── rule.ts # 规则 API
│ └── token.ts # Token API
├── components/ # 公共组件
│ ├── card/ # 卡片组件
│ │ ├── base/ # 基础卡片
│ │ ├── blank/ # 空白卡片
│ │ ├── detail/ # 详情卡片
│ │ └── title/ # 标题卡片
│ ├── error/ # 错误页面组件
│ ├── layout/ # 布局组件
│ └── particles/ # 粒子效果组件
├── config/ # 配置文件
│ ├── axios/ # Axios 配置
│ ├── constant/ # 常量配置
│ ├── entity/ # 实体定义
│ ├── env/ # 环境配置
│ ├── plugins/ # 插件配置
│ ├── router/ # 路由配置
│ └── types/ # TypeScript 类型定义
└── views/ # 页面
├── device/ # 设备管理
├── driver/ # 驱动管理
├── home/ # 首页
├── login/ # 登录
└── point/ # 点位管理
核心技术
- Vue 3: 采用 Composition API
- TypeScript: 类型安全
- Element Plus: UI 组件库
- Axios: HTTP 客户端
- Pinia: 状态管理
- Vue Router: 路由管理
- Vite: 构建工具
- Sass: CSS 预处理器
- ECharts/G2Plot: 图表库
九、部署原理(为什么要这样做)
9.1 为什么要用 Docker?
问题:你以前跑 Flask,直接 python app.py 就行。为什么这里要用 Docker?
答案:这个项目太复杂了,有 10+ 个程序要同时跑:
- 2 个前端(Vue 编译后的静态文件)
- 2 个后端(SCADA 单体 + DC3 多个微服务)
- 4+ 个数据库(PostgreSQL、MySQL、Redis、MongoDB、InfluxDB...)
- 消息队列(RabbitMQ)
不用 Docker 的问题:
- Java 程序要装 JDK,Node 前端要装 Node.js,数据库要各自安装配置
- 它们之间还要配置网络连接(后端怎么找到数据库?IP 是多少?端口是多少?)
- 换一台服务器,所有配置重来一遍
用 Docker 的好处:
- 每个程序打包成一个"集装箱"(镜像),里面包含了运行所需的一切(代码 + 环境 + 配置)
- 像乐高积木一样,一条命令启动/停止
- 换服务器?把集装箱搬过去就行,里面的东西不变
9.2 为什么要分两次启动?
第一次启动基础设施:docker-compose-env.yml
PostgreSQL ← DC3 的数据库
Redis ← DC3 的缓存
RabbitMQ ← DC3 的消息队列
MongoDB ← DC3 的文档数据库
MySQL ← SCADA 的数据库
Redis ← SCADA 的缓存
这些就像地基,必须先打好。房子(应用服务)才能盖上去。
第二次启动应用服务:docker-compose.yml
Gateway、Auth、Manager、Data ← DC3 后端
SCADA Server ← SCADA 后端
Nginx (DC3 Web) ← DC3 前端
Nginx (SCADA Web) ← SCADA 前端
9.3 为什么需要构建?
你拿到的源码是"原材料",需要加工成"成品"才能运行:
| 原材料 | 加工工具 | 成品 |
|---|---|---|
| Vue 前端源码 | npm + Vite | dist/ 目录(HTML/CSS/JS) |
| Java 后端源码 | Maven | target/*.jar(可运行程序) |
构建过程类比:
- Vue 源码就像设计图纸,Vite 是加工厂,把图纸变成浏览器能看的网页
- Java 源码就像建筑蓝图,Maven 是施工队,把蓝图变成可运行的程序
9.4 Nginx 是干什么的?
类比:Nginx 像酒店的前台接待员。
- 客人(浏览器)来到酒店(服务器),只认识一个地址
http://服务器:3000 - 前台根据客人的需求,引导到不同的部门:
- 要静态页面(HTML/CSS/JS)→ 直接给文件
- 要 API 数据(
/api/xxx)→ 转给后端的 Java 程序
为什么需要它:
- 前端和后端可以用不同技术栈
- 一个 Nginx 可以服务多个系统
- 可以做负载均衡、缓存、HTTPS 等高级功能
十、部署操作指南(一步一步跟着做)
10.1 环境要求
硬件要求
- CPU: 4 核以上(推荐 8 核)
- 内存: 8GB 以上(推荐 16GB)
- 磁盘: 50GB 以上可用空间
- 网络: 稳定的网络连接(用于拉取镜像)
软件要求
- 操作系统: Linux (Ubuntu 20.04+, CentOS 7+) / Windows 10+ / macOS
- Docker: 20.10.0 及以上版本
- Docker Compose: 2.0.0 及以上版本
10.2 安装必要工具
Step 1:安装 Docker
Docker 是运行容器的工具,相当于集装箱的搬运工。
# 更新软件源
sudo apt-get update
# 安装 Docker
sudo apt-get install -y docker.io
# 验证安装
docker --version
# 应该输出类似:Docker version 29.1.3
Step 2:安装 Docker Compose
Docker Compose 是同时管理多个容器的工具,相当于集装箱的调度员。
# 下载 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.27.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 赋予执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
# 应该输出:Docker Compose version v2.27.1
Step 3:配置 Docker 镜像加速器(中国大陆服务器必须做)
Docker Hub 在国外,直接下载很慢或超时。配置国内镜像加速器:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
EOF
sudo systemctl restart docker
Step 4:安装 Java(JDK)
DC3 后端需要 Java 21,SCADA 后端需要 Java 17。
# 同时安装两个版本
sudo apt-get install -y openjdk-21-jdk openjdk-17-jdk
# 验证
java -version
# 默认会显示 Java 21
Step 5:安装 Maven
Maven 是 Java 项目的构建工具,相当于 Java 世界的 pip。
sudo apt-get install -y maven
# 验证
mvn -version
Step 6:安装 Node.js 和 pnpm
# Node.js 通常系统已预装,检查版本
node --version
# 需要 >= 18.0.0
# 安装 pnpm(SCADA 前端用它管理依赖)
sudo npm install -g pnpm
# 验证
pnpm --version
10.3 获取项目代码
假设项目代码已经放在服务器上,路径是 /home/你的用户名/Projects/iot-platform/。
cd /home/你的用户名/Projects/iot-platform/
目录结构应该是这样的:
iot-platform/
├── iot-management-platform-backend/ # DC3 后端源码
├── iot-management-platform-web/ # DC3 前端源码
├── iot-scada-api/ # SCADA 后端源码
├── iot-scada-web/ # SCADA 前端源码
├── deploy/ # 部署配置
│ ├── docker-compose-env.yml # 基础设施编排
│ ├── docker-compose.yml # 应用服务编排(原版)
│ ├── docker-compose-scada.yml # 我们实际用的简化版
│ ├── auth/ # DC3 Auth Dockerfile
│ ├── gateway/ # DC3 Gateway Dockerfile
│ ├── manager/ # DC3 Manager Dockerfile
│ ├── data/ # DC3 Data Dockerfile
│ ├── mqtt/ # DC3 MQTT Dockerfile
│ ├── nginx/ # DC3 Web Nginx 配置
│ │ ├── nginx.conf
│ │ └── html/ # 构建后的前端文件放这里
│ └── scada/ # SCADA 配置
│ ├── Dockerfile
│ ├── nginx.conf
│ ├── init.sql # SCADA 数据库初始化脚本
│ └── html/ # 构建后的前端文件放这里
└── ...
10.4 构建前端(把源码变成浏览器能看的网页)
构建 SCADA 前端
# 进入 SCADA 前端目录
cd /home/你的用户名/Projects/iot-platform/iot-scada-web/
# 安装依赖(第一次需要,类似 pip install -r requirements.txt)
pnpm install
# 如果提示需要批准构建脚本
pnpm approve-builds esbuild vue-demi vue-echarts
# 生产构建
pnpm build:prod
# 构建完成后,dist/ 目录下会生成 HTML/CSS/JS 文件
构建完成后,复制到部署目录:
# 创建目录(如果不存在)
mkdir -p /home/你的用户名/Projects/iot-platform/deploy/scada/html
# 清空旧文件
rm -rf /home/你的用户名/Projects/iot-platform/deploy/scada/html/*
# 复制新构建的文件
cp -r /home/你的用户名/Projects/iot-platform/iot-scada-web/dist/* \
/home/你的用户名/Projects/iot-platform/deploy/scada/html/
构建 DC3 前端
# 进入 DC3 前端目录
cd /home/你的用户名/Projects/iot-platform/iot-management-platform-web/
# 安装依赖
npm install
# 生产构建
npm run build
# 构建完成后,dist/ 目录下会生成文件
复制到部署目录:
mkdir -p /home/你的用户名/Projects/iot-platform/deploy/nginx/html
rm -rf /home/你的用户名/Projects/iot-platform/deploy/nginx/html/*
cp -r /home/你的用户名/Projects/iot-platform/iot-management-platform-web/dist/* \
/home/你的用户名/Projects/iot-platform/deploy/nginx/html/
10.5 构建后端(把 Java 源码变成可运行程序)
构建 SCADA 后端
# 进入 SCADA 后端目录
cd /home/你的用户名/Projects/iot-platform/iot-scada-api/
# 切换到 Java 17(SCADA 用 Java 17 编译更稳定)
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
# 构建
mvn clean package -DskipTests
# 构建成功后,JAR 文件在:
# ruoyi-admin/target/iot-scada.jar
复制到部署目录:
cp /home/你的用户名/Projects/iot-platform/iot-scada-api/ruoyi-admin/target/iot-scada.jar \
/home/你的用户名/Projects/iot-platform/deploy/scada/iot-scada.jar
构建 DC3 后端(可选,如果缺少数据库则无法运行)
# 进入 DC3 后端目录
cd /home/你的用户名/Projects/iot-platform/iot-management-platform-backend/
# 默认 Java 21 即可
# 构建(首次需要下载大量依赖,可能需要 10-20 分钟)
mvn -U -e -B clean package -DskipTests -P dev
# 构建成功后,各服务的 JAR 文件在对应目录的 target/ 下:
# dc3-gateway/target/dc3-gateway.jar
# dc3-center/dc3-center-auth/target/dc3-center-auth.jar
# dc3-center/dc3-center-manager/target/dc3-center-manager.jar
# dc3-center/dc3-center-data/target/dc3-center-data.jar
# dc3-center/dc3-center-single/target/dc3-center-single.jar
# ... 等等
复制到部署目录:
# 以 gateway 为例
cp /home/你的用户名/Projects/iot-platform/iot-management-platform-backend/dc3-gateway/target/dc3-gateway.jar \
/home/你的用户名/Projects/iot-platform/deploy/gateway/dc3-gateway.jar
# auth
cp /home/你的用户名/Projects/iot-platform/iot-management-platform-backend/dc3-center/dc3-center-auth/target/dc3-center-auth.jar \
/home/你的用户名/Projects/iot-platform/deploy/auth/dc3-center-auth.jar
# manager
cp /home/你的用户名/Projects/iot-platform/iot-management-platform-backend/dc3-center/dc3-center-manager/target/dc3-center-manager.jar \
/home/你的用户名/Projects/iot-platform/deploy/manager/dc3-center-manager.jar
# data
cp /home/你的用户名/Projects/iot-platform/iot-management-platform-backend/dc3-center/dc3-center-data/target/dc3-center-data.jar \
/home/你的用户名/Projects/iot-platform/deploy/data/dc3-center-data.jar
⚠️ 注意:DC3 后端构建出来的 JAR 文件需要数据库才能运行。如果数据库没准备好,启动会报错。
10.6 修改配置(让程序知道数据库在哪里)
SCADA 后端配置修改
问题:SCADA 后端的配置文件中,数据库和 Redis 地址硬编码了开发环境地址(如 127.0.0.1 或远程公网 IP),在 Docker 容器中不适用。
修改 1:application.yml(Redis 地址)
文件路径:iot-scada-api/ruoyi-admin/src/main/resources/application.yml
找到 Redis 配置部分:
# 原来
redis:
host: 127.0.0.1
port: 6379
# 改为(读取环境变量,默认回退到 127.0.0.1)
redis:
host: ${REDIS_HOST:127.0.0.1}
port: 6379
password: ${REDIS_PASSWORD:***}
修改 2:application-druid.yml(数据库地址)
文件路径:iot-scada-api/ruoyi-admin/src/main/resources/application-druid.yml
找到数据库配置部分:
# 原来(硬编码了远程地址)
master:
url: jdbc:mysql://117.89.85.67:3306/maotu-scada?...
username: maotu-scada
password: maotu-scada
# 改为(读取环境变量)
master:
url: jdbc:mysql://${DATABASE_HOST:127.0.0.1}:3306/${DATABASE_NAME:scada}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: ${DATABASE_PASSWORD:***}
修改后需要重新构建 JAR(见 10.5 节)。
DC3 前端 Nginx 配置修改(如果 DC3 后端未部署)
如果 DC3 后端无法部署(缺少数据库),Nginx 配置中引用 dc3-gateway 会导致容器不断重启。
文件路径:deploy/nginx/nginx.conf
注释掉 API 代理部分:
# 注释掉这段,因为 dc3-gateway 没有运行
# location ^~ /api/ {
# proxy_pass http://dc3-gateway:8000/api/;
# }
10.7 启动部署
方案 A:只部署 SCADA + DC3 前端(当前实际可行的方案)
创建一个精简的 docker-compose-scada.yml:
services:
# SCADA 数据库
iot-scada-mysql:
image: mysql:8.0.24
container_name: iot-scada-mysql
environment:
- MYSQL_ROOT_PASSWORD=***
volumes:
# 初始化脚本:容器第一次启动时自动执行
- ./scada/init.sql:/docker-entrypoint-initdb.d/init.sql
# 数据持久化:即使容器删除,数据还在
- ./mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
interval: 5s
timeout: 10s
retries: 60
networks:
- dc3net
# SCADA 缓存
iot-scada-redis:
image: redis:6.2.6
container_name: iot-scada-redis
networks:
- dc3net
# SCADA 后端
iot-scada-server:
build:
context: ./scada/
dockerfile: ./Dockerfile
image: iot-scada-server:2025.2.1
container_name: iot-scada-server
environment:
REDIS_HOST: iot-scada-redis
DATABASE_NAME: scada
DATABASE_HOST: iot-scada-mysql
DATABASE_PASSWORD: ***
healthcheck:
test: ["CMD-SHELL", "wget --quiet --tries=1 --spider http://localhost:8887 || exit 1"]
interval: 5s
timeout: 10s
retries: 60
volumes:
- ./scada/logs:/app/logs
- ./scada/uploadPath:/app/uploadPath
networks:
- dc3net
# 等 MySQL 健康检查通过后再启动
depends_on:
iot-scada-mysql:
condition: service_healthy
# SCADA 前端
iot-scada-web:
image: nginx:stable-alpine
restart: always
ports:
- '3001:80'
container_name: iot-scada-web
volumes:
- ./scada/log:/var/log/nginx
- ./scada/nginx.conf:/etc/nginx/nginx.conf
- ./scada/html:/usr/share/nginx/html
networks:
- dc3net
depends_on:
- iot-scada-server
# DC3 前端(只有静态页面)
dc3-web:
image: nginx:stable-alpine
restart: always
ports:
- '3000:80'
container_name: dc3-web
volumes:
- ./nginx/log:/var/log/nginx
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/html:/usr/share/nginx/html
networks:
- dc3net
# 所有容器共享同一个网络,可以通过容器名互相访问
networks:
dc3net:
driver: bridge
启动命令:
cd /home/你的用户名/Projects/iot-platform/deploy/
# 启动所有服务
sudo docker-compose -f docker-compose-scada.yml up -d
-d 表示后台运行(detach 模式)。
方案 B:完整部署(需要 DC3 数据库)
如果你拿到了 DC3 的 PostgreSQL 初始化脚本(dc3.sql),可以按以下步骤:
Step 1:准备 DC3 数据库
# 创建存放初始化脚本的目录
mkdir -p /home/你的用户名/Projects/iot-platform/deploy/postgres-init
# 把拿到的 dc3.sql 放进去
cp /path/to/dc3.sql /home/你的用户名/Projects/iot-platform/deploy/postgres-init/
Step 2:修改 docker-compose-env.yml
把 PostgreSQL 服务从 pnoker/dc3-postgres:2025.2.dev 改为标准镜像,并挂载初始化脚本:
services:
postgres:
image: postgres:15 # 改用标准镜像
restart: always
ports:
- '35432:5432'
environment:
- POSTGRES_USER=dc3
- POSTGRES_PASSWORD=***
- POSTGRES_DB=dc3
volumes:
- postgres:/var/lib/postgresql/data
- ./postgres-init:/docker-entrypoint-initdb.d # 挂载初始化脚本
networks:
- dc3net
volumes:
postgres:
Step 3:先启动基础设施
cd /home/你的用户名/Projects/iot-platform/deploy/
sudo docker-compose -f docker-compose-env.yml up -d
Step 4:等待数据库初始化完成
PostgreSQL 容器第一次启动时会自动执行 /docker-entrypoint-initdb.d/ 下的 SQL 脚本,创建所有表和数据。这个过程可能需要 1-5 分钟。
Step 5:启动应用服务
sudo docker-compose -f docker-compose.yml up -d
10.8 验证服务状态
# 查看所有容器运行状态
docker compose ps
# 或者查看特定服务状态
docker compose -f docker-compose-env.yml ps
docker compose -f docker-compose.yml ps
10.9 访问系统
- DC3 IoT 管理平台: http://服务器IP:3000
- SCADA 组态系统: http://服务器IP:3001
10.10 停止所有服务
# 停止应用服务
docker compose -f docker-compose.yml down
# 停止基础设施服务(数据库、缓存、消息队列)
docker compose -f docker-compose-env.yml down
注意: 使用
down命令会停止并删除容器,但数据卷(volumes)会保留。如需同时删除数据卷,请添加-v参数(慎用!):
bash docker compose -f docker-compose-env.yml down -v
十一、开发工具与工程化
11.1 ESLint
类比:像语文作文的自动批改工具。
ESLint 是 JavaScript/TypeScript 的代码检查工具:
- 检查语法错误。
- 检查代码风格(比如是否用了分号、缩进几个空格)。
- 检查潜在 Bug(比如定义了变量没使用)。
11.2 Prettier
类比:像 Word 的"自动排版"功能。
Prettier 是代码格式化工具:
- 不管你怎么写的,保存后自动按统一风格排版。
- 解决团队协作中的"代码风格之争"。
本项目中的 DC3 前端 Prettier 配置:
- 4 空格缩进
- 单引号
- 不要分号
- 一行最长 180 字符
11.3 Husky + lint-staged
类比:像考试前的自动检查,提交代码前自动跑一遍检查。
- Husky:Git 钩子工具,在
git commit前自动执行脚本。 - lint-staged:只检查本次提交修改的文件。
流程:
git commit -m "xxx"
↓
Husky 触发 pre-commit 钩子
↓
lint-staged 对改动的文件运行 ESLint + Prettier
↓
有问题 → 阻止提交,提示修改
没问题 → 正常提交
11.4 Git / Git 工作流
你已经熟悉的概念:git add、git commit、git push。
补充概念:
- 分支(Branch):从主代码线分叉出来独立开发,完成后合并回去。
- .gitignore:告诉 Git 哪些文件不要跟踪(如 node_modules/、*.log)。
十二、Java 特有概念
12.1 JDK / JRE / JVM
| 术语 | 全称 | 类比 | 作用 |
|---|---|---|---|
| JDK | Java Development Kit | Python 安装包 + pip | Java 开发工具包(写代码必备) |
| JRE | Java Runtime Environment | Python 解释器 | Java 运行环境(只运行不开发) |
| JVM | Java Virtual Machine | Python 解释器内核 | Java 虚拟机,运行字节码 |
字节码:Java 代码编译成 .class 文件(不是机器码),JVM 负责解释/编译执行。
"一次编写,到处运行":编译好的 Java 程序只要有 JVM 就能跑,不管底层是 Windows 还是 Linux。
12.2 JAR 文件
类比:像 Python 的 .zip 打包文件,包含了程序的所有类和资源。
Spring Boot 用 spring-boot-maven-plugin 打包成可执行 JAR:
java -jar myapp.jar # 直接运行,不需要额外配置 Tomcat
12.3 Spring Boot Actuator
类比:像汽车的仪表盘,显示发动机转速、油量等健康指标。
提供生产环境的监控端点:
- /actuator/health:服务是否健康
- /actuator/metrics:内存使用、请求数量等指标
十三、网络与安全概念
13.1 HTTP / HTTPS / TLS
你已经熟悉的概念:浏览器地址栏的 http://。
- HTTP:明文传输,数据可能被窃听或篡改。
- HTTPS:HTTP + TLS/SSL 加密,数据安全传输。
- TLS/SSL:加密协议,像给信件加上密码锁。
本项目现状:目前使用 HTTP,没有配置 HTTPS。
13.2 CORS(跨域资源共享)
你已经遇到过的问题:前端在 http://localhost:5173,后端在 http://localhost:5000,浏览器报"跨域错误"。
原因:浏览器的同源策略(Same-Origin Policy)限制不同域名/端口的请求。
解决方案:
- 开发时:Vite 代理或 Nginx 反向代理(让浏览器以为请求的是同域)。
- 生产时:后端配置 CORS 响应头,允许特定域名访问。
13.3 WebSocket
你已经熟悉的概念:HTTP 是"一问一答"(请求 → 响应)。
WebSocket:
- 建立一次连接后,服务器可以主动推送数据给客户端。
- 适合实时场景:聊天、股票行情、设备实时数据推送。
本项目中的例子:SCADA 系统用 WebSocket 推送实时设备数据到前端大屏。
十四、学习路径建议
如果你要逐步理解并参与这个项目,建议按以下顺序学习:
第一阶段:巩固基础
- 深入学 JavaScript(ES6+:箭头函数、Promise、async/await、解构赋值)
- 学 Vue 3 基础(选项式 API 和组合式 API)
- 理解 npm/pnpm(包管理)
第二阶段:理解现代前端工程
- 学 TypeScript 基础类型系统
- 理解 Vite 和前端构建流程
- 学 Element Plus 常用组件
- 理解 Axios 和 HTTP 拦截器
第三阶段:理解后端
- 学 Java 基础语法(如果你要做后端)
- 理解 Spring Boot 的 Controller/Service/Mapper 分层
- 学 MyBatis Plus 的基本 CRUD
第四阶段:理解部署与运维
- 学 Docker 基础和常用命令
- 理解 Docker Compose 的编排逻辑
- 学 Nginx 反向代理配置
- 理解日志排查和容器调试
第五阶段:深入 IoT 领域
- 了解 MQTT 协议和消息发布订阅模型
- 学习工业通信协议(Modbus、OPC UA)的基础概念
- 理解时序数据库的数据模型
- 学习 SCADA 组态系统的设计思路
十五、总结
这个项目是一个完整的工业物联网平台,包含:
| 系统 | 用途 | 技术特点 |
|---|---|---|
| DC3 IoT 管理平台 | 设备管理、数据采集、报警处理 | 微服务架构、Vue 3 + TS、Spring Cloud |
| SCADA 组态系统 | 可视化监控大屏、拖拽组态 | 单体架构、Vue 3 + JS、Spring Boot |
核心价值:
- 让不懂代码的工程师也能搭建工业监控界面
- 让设备数据实时汇聚、存储、分析
- 让工厂运维从"人盯屏幕"变成"系统自动报警"
技术亮点:
- 前后端分离,现代前端工程化
- 微服务架构,服务独立扩展
- Docker 容器化,一次构建到处运行
- 多协议驱动,适配各种工业设备
文档信息
- 作者:张煜
- 日期:2026-05-26
- 版本:v1.0
- 适用对象:有 HTML/CSS/JavaScript + Flask 基础的初学者
- 项目地址:IoT Platform