基于 Spring Boot + Vue3 的水产养殖监测管理平台设计与实现
温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系名片!
一、项目背景与意义
水产养殖是农业生产的重要组成部分,但传统养殖方式高度依赖人工经验:养殖户需要定时巡塘、凭肉眼判断水质、手动开启增氧机。这种方式存在数据滞后、响应不及时、人力成本高等问题。一旦遇到高温闷热天气导致溶氧骤降,往往在发现鱼虾浮头时已经造成大面积损失。
随着物联网与 Web 技术的发展,构建一套集实时数据采集、可视化监控、异常告警、养殖档案管理于一体的水产养殖监测管理平台,能够有效降低养殖风险、提升管理效率。本文基于 Spring Boot + Vue3 前后端分离架构,完整介绍该平台的设计思路与核心实现。
二、系统总体架构
平台采用前后端分离架构,整体分为感知层、传输层、服务层与应用层四部分。
flowchart TD A[传感器设备 溶氧/温度/pH/氨氮] --> B[MQTT 网关] B --> C[Spring Boot 服务端] C --> D[(MySQL 业务库)] C --> E[(InfluxDB 时序库)] C --> F[Redis 缓存] C --> G[WebSocket 推送] G --> H[Vue3 前端大屏] H --> I[养殖户 / 管理员] C --> J[告警服务 短信/站内信]- 感知层:各类水质传感器与增氧机、投饵机等执行设备。
- 传输层:设备通过 MQTT 协议上报数据,网关统一接入。
- 服务层:Spring Boot 提供 RESTful 接口、设备接入、告警计算与数据聚合。
- 应用层:Vue3 构建的管理后台与数据大屏,支持 PC 与移动端访问。
三、技术选型
| 层次 | 技术栈 | 说明 |
|---|---|---|
| 后端框架 | Spring Boot 3.x | 快速构建、自动装配、内嵌 Tomcat |
| 安全认证 | Spring Security + JWT | 无状态登录鉴权,支持角色权限 |
| 持久层 | MyBatis-Plus | 简化 CRUD,支持分页与逻辑删除 |
| 数据库 | MySQL 8 + InfluxDB | 业务数据与时序监测数据分离存储 |
| 缓存 | Redis | 缓存字典、设备状态与告警去重 |
| 消息通信 | EMQX + MQTT | 设备数据上报与指令下发 |
| 实时推送 | WebSocket | 监测数据实时刷新 |
| 前端框架 | Vue3 + Vite | 组合式 API,构建速度快 |
| UI 组件 | Element Plus | 后台管理常用组件库 |
| 图表可视化 | ECharts | 趋势曲线、仪表盘、大屏展示 |
四、数据库设计
核心业务表围绕「养殖户—池塘—设备—监测数据—告警」展开,主要表结构如下:
-- 池塘信息表 CREATE TABLE pond ( id BIGINT PRIMARY KEY AUTO_INCREMENT, pond_name VARCHAR(64) NOT NULL COMMENT '池塘名称', farmer_id BIGINT NOT NULL COMMENT '所属养殖户', area DECIMAL(10,2) COMMENT '面积(亩)', fish_type VARCHAR(64) COMMENT '养殖品种', create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 设备信息表 CREATE TABLE device ( id BIGINT PRIMARY KEY AUTO_INCREMENT, device_sn VARCHAR(64) NOT NULL UNIQUE COMMENT '设备编号', pond_id BIGINT NOT NULL COMMENT '所属池塘', device_type VARCHAR(32) COMMENT 'DO/TEMP/PH/NH3', status TINYINT DEFAULT 1 COMMENT '1在线 0离线', last_online DATETIME ); -- 告警记录表 CREATE TABLE alarm_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, pond_id BIGINT NOT NULL, metric VARCHAR(32) COMMENT '告警指标', value DECIMAL(10,2) COMMENT '触发值', level TINYINT COMMENT '1提示 2警告 3严重', alarm_time DATETIME DEFAULT CURRENT_TIMESTAMP, handled TINYINT DEFAULT 0 );监测数据量大且写入频繁,因此单独存入 InfluxDB,按measurement=device_sn、tag=metric组织,便于按时间范围快速聚合查询。
五、后端核心实现
5.1 设备数据接入
使用 Spring Integration MQTT 订阅设备主题,收到报文后解析并写入时序库,同时触发阈值判断。
@Component @RequiredArgsConstructor public class MqttDataListener { private final InfluxDataService influxDataService; private final AlarmService alarmService; @MqttListener(topics = "pond/device/+/data") public void onMessage(String topic, String payload) { DeviceData data = JsonUtils.parse(payload, DeviceData.class); // 1. 写入时序库 influxDataService.write(data); // 2. 阈值校验,触发告警 alarmService.check(data); // 3. WebSocket 推送前端 WebSocketServer.sendToAll(JsonUtils.toJson(data)); } }5.2 告警规则引擎
告警阈值按养殖品种与季节可配置,避免硬编码。核心判断逻辑如下:
public void check(DeviceData data) { AlarmRule rule = ruleCache.get(data.getPondId(), data.getMetric()); if (rule == null) { return; } if (data.getValue().compareTo(rule.getMinValue()) < 0 || data.getValue().compareTo(rule.getMaxValue()) > 0) { // Redis 去重,5 分钟内同一指标只告警一次 String key = "alarm:" + data.getPondId() + ":" + data.getMetric(); Boolean first = redisTemplate.opsForValue() .setIfAbsent(key, "1", Duration.ofMinutes(5)); if (Boolean.TRUE.equals(first)) { alarmRecordService.save(data, rule); notifyService.push(data, rule); } } }5.3 统一响应与异常处理
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(BusinessException.class) public Result<Void> handleBusiness(BusinessException e) { return Result.fail(e.getCode(), e.getMessage()); } @ExceptionHandler(Exception.class) public Result<Void> handleException(Exception e) { log.error("系统异常", e); return Result.fail(500, "系统繁忙,请稍后重试"); } }六、前端核心实现
6.1 实时监测大屏
通过 WebSocket 接收推送数据,结合 ECharts 动态刷新溶氧趋势曲线与仪表盘。
<script setup> import { onMounted, onUnmounted, ref } from 'vue' import * as echarts from 'echarts' const chartRef = ref(null) let chart = null let ws = null onMounted(() => { chart = echarts.init(chartRef.value) chart.setOption({ title: { text: '溶解氧实时趋势' }, xAxis: { type: 'category', data: [] }, yAxis: { type: 'value', name: 'mg/L' }, series: [{ type: 'line', smooth: true, data: [] }] }) ws = new WebSocket('ws://localhost:8080/ws/monitor') ws.onmessage = (event) => { const data = JSON.parse(event.data) if (data.metric !== 'DO') return const option = chart.getOption() option.xAxis[0].data.push(data.time) option.series[0].data.push(data.value) if (option.xAxis[0].data.length > 30) { option.xAxis[0].data.shift() option.series[0].data.shift() } chart.setOption(option) } }) onUnmounted(() => { ws?.close() chart?.dispose() }) </script> <template> <div ref="chartRef" style="width: 100%; height: 360px;"></div> </template>6.2 请求封装与权限控制
import axios from 'axios' import { ElMessage } from 'element-plus' const request = axios.create({ baseURL: '/api', timeout: 10000 }) request.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) config.headers.Authorization = Bearer ${token} return config }) request.interceptors.response.use( res => { const { code, data, message } = res.data if (code === 200) return data ElMessage.error(message || '请求失败') return Promise.reject(new Error(message)) }, err => { if (err.response?.status === 401) { localStorage.removeItem('token') location.href = '/login' } return Promise.reject(err) } ) export default request七、功能模块划分
- 基础管理:养殖户、池塘、设备档案的增删改查与批量导入。
- 实时监测:多指标实时曲线、设备在线状态、历史数据回溯。
- 告警中心:告警列表、分级展示、处理记录与阈值配置。
- 养殖档案:投饵、用药、捕捞等生产记录,形成可追溯台账。
- 统计分析:按池塘、时间维度统计水质达标率与告警频次。
- 系统管理:用户、角色、菜单权限与操作日志。
八、部署与优化建议
推荐使用 Docker Compose 一键编排 MySQL、Redis、EMQX 与应用服务,前端打包后由 Nginx 托管并反向代理接口。
services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: aquaculture ports: - "3306:3306" redis: image: redis:7-alpine ports: - "6379:6379" emqx: image: emqx/emqx:5.3 ports: - "1883:1883" - "18083:18083" app: build: . depends_on: - mysql - redis - emqx ports: - "8080:8080"性能优化方面,可从以下几点入手:
- 监测数据批量写入 InfluxDB,减少网络往返。
- 历史曲线查询增加时间范围限制与降采样,避免全量扫描。
- 设备状态与字典数据放入 Redis,降低数据库压力。
- WebSocket 推送按池塘分组订阅,避免全量广播。
九、总结
本文基于 Spring Boot + Vue3 设计并实现了水产养殖监测管理平台,通过 MQTT 完成设备接入、InfluxDB 存储时序数据、WebSocket 实现实时推送,配合可配置的告警规则,帮助养殖户从「凭经验」转向「看数据」。后续可进一步引入视频监控与智能投喂算法,提升平台的智能化水平。