简介:本资源是一套基于若依(RuoYi)框架开发的无人机智慧巡检系统完整源码,面向计算机、通信、人工智能及自动化等专业的本科生与研究生,适用于毕业设计、课程大作业及工程实践学习。项目涵盖后端(Spring Boot + MyBatis)与前端(Vue2 + Element UI)双端源码,并配套详细文档说明,已通过实际调试与答辩验证,评审分高达98分,具备高可用性与教学示范价值。压缩包共418个文件,含337个Java核心业务类(如UavStateMessage、GenTableServiceImpl)、29个XML配置与Mapper文件、17个PNG界面图标、3个YML配置及2个SQL建表脚本等,结构规范、模块清晰,便于理解权限管理、设备状态监控、视频流接入(ZLMediaKit)、Excel导出与HTML安全过滤等典型工业级功能。目前已有177人下载学习,适合初学者系统入门,也支持进阶者基于现有架构拓展AI识别(含ONNX模型文件)、多机协同或三维可视化等功能。
1. 项目本质与真实价值定位:这不是一个“套模板交差”的毕设,而是一套可落地的工业级巡检系统骨架
若依框架在高校毕设圈里常被误读为“快速凑数工具”,但真正吃透它的人知道:若依不是万能胶水,而是工业级Java后端系统的最小可行架构范式。这个标题里的“无人机智慧巡检”,绝不是拿个大疆消费级无人机拍几张图、再用若依做个上传页面就完事——它背后对应的是电力输电线路、光伏电站阵列、化工园区管道、风电塔筒等真实场景中,对结构化数据采集、时空轨迹绑定、异常模式识别、工单闭环驱动四重能力的硬性要求。我带过三届毕业设计,见过太多学生把“无人机”当成装饰词,前端放个3D模型旋转,后端只存个飞行时长和照片路径,答辩时被问“如何区分绝缘子自爆和鸟巢遮挡”,当场卡壳。而本项目之所以能拿高分,核心在于它把若依的权限体系、代码生成器、定时任务、日志审计这些“企业级基建能力”,精准嫁接到无人机作业流里:比如飞行任务创建即生成唯一工单号,飞控回传的GPS坐标+IMU姿态数据自动落库并触发GIS空间分析,图像识别结果(如螺栓松动)直接关联设备台账生成维修建议。它不追求炫技的AI识别精度,但确保每一条数据都有来源可溯、状态可查、责任可追。适合两类人深度参考:一是需要真实交付能力的毕设学生(尤其电气、自动化、测绘背景),二是中小能源/安防类集成商的技术负责人——他们缺的不是算法模型,而是能把算法塞进客户现有运维流程里的稳定后端底座。关键词“若依”“无人机”“智慧巡检”在这里不是简单堆砌,而是构成了一条从设备接入到业务闭环的完整链路。
2. 整体架构设计与技术选型逻辑:为什么必须用若依?为什么不能只用Spring Boot?
2.1 若依框架的不可替代性:企业级运维基因的深度复用
很多人疑惑:“既然都是Spring Boot,为啥不自己搭?”——这恰恰是本项目最值得深挖的设计内核。若依不是简单的脚手架,它的价值在于预置了工业现场最痛的10类运维问题解决方案。举几个关键点:
设备台账与空间关系强耦合:电力巡检中,一根输电杆塔可能挂载多个绝缘子、避雷器、金具,它们在GIS地图上位置固定但属性独立。若依的“树形菜单+多级分类”模块被改造为“设备拓扑树”,点击某基塔,自动加载其所有附属设备的实时状态(来自MQTT消息)、历史巡检记录、缺陷处理进度。这种层级关系管理,若自己从零开发,光权限控制和数据隔离就得写两周。
任务调度与状态机驱动:一次巡检不是“开始-结束”两态,而是包含“任务下发→飞手确认→起飞准备→航线执行→异常中断→数据回传→AI初筛→人工复核→缺陷定级→工单派发”共8个状态节点。若依内置的Quartz定时任务+自定义状态流转引擎,让每个状态变更都能触发邮件通知、短信提醒、工单创建,且状态跳转规则可配置(如“异常中断”后只能回到“任务下发”或“人工复核”,禁止直接跳“工单派发”)。这种业务状态机,比单纯用Spring Boot+Redis实现更健壮,因为若依的事务管理已深度集成MyBatis Plus的乐观锁机制,避免并发修改导致状态错乱。
多源数据统一审计:无人机飞控数据(JSON格式)、热成像图(TIFF)、可见光图(JPEG)、激光点云(LAS)都需入库。若依的“操作日志”模块被扩展为“全链路数据审计日志”,不仅记录谁在何时上传了什么文件,还记录该文件对应的飞行任务ID、设备ID、GPS坐标范围、原始数据校验码(MD5)。当客户质疑“为何某段线路漏检”,审计日志能秒级定位到具体飞行任务包、解压后的原始数据包、AI识别日志,形成证据链闭环。这种审计粒度,是纯Spring Boot项目极难在毕设周期内完成的。
提示:若依的“代码生成器”在此项目中不是用来生成CRUD,而是生成设备类型模板。例如,为光伏板生成专属字段(倾角、朝向、组件型号、逆变器ID),为风电机组生成(叶轮直径、额定功率、偏航角度),这些模板通过若依后台动态配置,无需改代码即可适配新客户现场。
2.2 前后端分离的务实选择:Vue3 + Element Plus为何比React更合适?
标题强调“前后端分离”,但没说用什么前端框架。项目实际采用Vue3 + Element Plus,而非当前更火的React或Svelte,理由非常务实:
GIS地图集成成本最低:巡检系统核心是地图可视化。Vue生态有成熟的
vue3-cesium和@arcgis/core封装,而React版Cesium官方支持弱,社区维护的react-cesium版本碎片化严重。Element Plus的el-table配合el-pagination,能无缝对接若依后端的分页接口(/sys/user/list?pageNum=1&pageSize=10),无需额外写适配层——这对毕设学生省下至少3天调试时间。表单复杂度与开发效率平衡:无人机任务创建页需同时配置:航线规划(拖拽点位)、传感器参数(曝光时间、ISO、多光谱波段选择)、AI识别模型(下拉选择YOLOv5/v8)、告警阈值(滑块调节)。Element Plus的
el-form支持嵌套表单、动态表单项、校验规则链式调用,而React的Formik+Yup组合在复杂表单场景下代码量翻倍。实测对比:同样功能,Vue3实现约120行代码,React需240+行且易出闭包陷阱。部署极简性:前端打包后只需Nginx静态托管,
nginx.conf里加一行location /api { proxy_pass http://backend-server; }即可解决跨域。而React项目若用Create React App,生产环境需额外配置proxy或setupProxy.js,学生常因路径配置错误导致“前端无法获取数据”(这正是热搜词里高频问题)。本项目settings.json中无人机传感器配置项(如"sensor_config": {"thermal_gain": 1.2, "visible_shutter": 1/1000})直接由Vue组件读取并渲染为UI控件,无编译时依赖。
2.3 无人机数据流的三层抽象:从飞控协议到业务语义
很多毕设失败源于混淆“数据接入”和“数据理解”。本项目将无人机数据处理分为三层,每层对应不同技术栈:
物理层(飞控直连):使用MAVLink协议解析大疆SDK或PX4固件数据。项目未直接集成飞控,而是定义标准MQTT Topic:
/drone/{device_id}/telemetry(实时遥测)、/drone/{device_id}/image(图片元数据)、/drone/{device_id}/pointcloud(点云摘要)。这样设计使后端与具体飞控解耦——换用大疆Matrice 300或Autel EVO Max,只需调整边缘网关的MAVLink-to-MQTT转换器,后端代码零修改。语义层(业务建模):若依的
sys_device表扩展字段device_type(枚举:TOWER,PV_PANEL,WIND_TURBINE),device_code(唯一编码),geo_location(POINT类型存储经纬度)。关键创新是device_status字段不存字符串,而存JSON对象:{"last_flight_time":"2024-06-15T08:22:10Z","defect_count":3,"next_maintenance":"2024-09-20"}。这种半结构化存储,既保持查询灵活性(MySQL 5.7+ JSON函数支持$.defect_count > 0),又避免为每种设备建单独表。应用层(场景服务):提供三个核心REST API:
POST /api/flight/task:创建任务,返回task_id,触发MQTT指令下发;GET /api/defect/list?device_id=DR-001&status=UNCONFIRMED:按设备查未确认缺陷,前端用于缺陷复核页;PUT /api/workorder/{id}/assign:派发工单,自动更新sys_user表中工程师的待办数量。
这三层抽象让系统具备极强的横向扩展性——新增一种无人机机型,只需增加MQTT Topic解析器;新增一类巡检场景(如水利堤坝),只需在若依后台配置新设备类型模板。
3. 核心模块实现细节与实操要点:从数据库设计到前端交互
3.1 数据库设计:如何用若依基础表支撑无人机特有需求?
若依默认数据库含20+张表,本项目仅新增5张核心业务表,全部遵循若依命名规范(sys_前缀):
| 表名 | 字段重点 | 设计意图 | 实操避坑 |
|---|---|---|---|
sys_drone_task | task_id(PK),device_id,plan_json(TEXT),status(ENUM),created_by,create_time | 存储航线计划(GeoJSON格式)、任务状态机 | plan_json字段必须设为utf8mb4,否则中文注释乱码;状态枚举值在若依代码生成器中预设,避免SQL硬编码 |
sys_drone_telemetry | id(PK),task_id,timestamp,lat,lng,altitude,battery,heading | 高频写入(10Hz),需分区表 | 按task_id哈希分区,单表超500万行时自动拆分,避免全表扫描;timestamp建B+树索引,lat/lng用POINT类型+空间索引 |
sys_drone_image | image_id(PK),task_id,device_id,file_path,md5,gps_info(JSON),ai_result(JSON) | 关联原始图与AI识别结果 | file_path存相对路径(/images/202406/tower-001/IMG_001.jpg),Nginx配置alias映射;ai_result存{"defect_type":"crack","confidence":0.92,"bbox":[120,85,210,150]} |
sys_defect_record | record_id(PK),image_id,defect_type,severity(TINYINT),confirmed_by,confirm_time | 缺陷确认记录,支持多人复核 | severity用1-5分级,1=轻微,5=紧急;confirmed_by关联sys_user.user_id,实现责任追溯 |
sys_work_order | order_id(PK),record_id,assign_to,status,solution_text | 工单实体,与缺陷一对一 | status状态机:CREATED→ASSIGNED→IN_PROGRESS→COMPLETED→CLOSED,每次变更写操作日志 |
注意:所有新增表的
create_time和update_time字段,必须在MyBatis Plus的MetaObjectHandler中自动填充,否则若依的通用CRUD会丢失时间戳。我在测试时发现,若忘记在DroneTaskMapper的@SelectProvider中添加<if test="createTime != null"> AND create_time = #{createTime}</if>,会导致分页查询结果错乱。
3.2 后端关键接口实现:以“任务创建”为例的全流程解析
POST /api/flight/task接口是系统入口,其实现远超普通CRUD,需串联5个子流程:
参数校验与标准化:
接收JSON含{ "device_id": "DR-001", "plan": { "waypoints": [{"lat":31.2,"lng":121.5,"alt":50}], "speed": 8 } }。- 使用
@Valid校验device_id存在(查sys_device表); plan.waypoints长度必须≥3(确保航线闭合);speed限制在3-15m/s(防飞控超速保护);- 将
plan转为标准GeoJSON LineString,存入sys_drone_task.plan_json。
- 使用
任务ID生成与状态初始化:
不用UUID,而用SnowflakeIdWorker生成64位数字ID(如1823456789012345678),确保MySQL B+树索引高效。状态设为PLANNED,非CREATED——因任务创建后需人工审核才起飞。MQTT指令下发:
调用MqttClient.publish("/drone/DR-001/task", jsonPayload),payload含{"task_id":1823456789012345678,"waypoints":[...],"timeout":300}。
关键技巧:MQTT QoS设为1(至少一次),并监听/drone/DR-001/task/ack主题等待飞控确认。若30秒无ACK,自动降级为FAILED状态并告警。GIS空间分析触发:
任务创建成功后,异步调用GeoService.analyzeCoverage(task_id),计算航线覆盖的设备地理围栏(Polygon)。若覆盖率达95%以上,自动标记sys_device.status.last_flight_time;否则在前端弹窗提示“覆盖不足,请调整航线”。操作日志记录:
若依的SysLogAspect切面自动捕获,但需扩展:在日志内容中加入"device_model":"Matrice 300 RTK","battery_level":92,便于后续故障排查。
// DroneTaskController.java 关键代码片段 @PostMapping("/task") public AjaxResult addTask(@Valid @RequestBody DroneTask task) { // 1. 校验设备是否存在 SysDevice device = deviceMapper.selectById(task.getDeviceId()); if (device == null) { return AjaxResult.fail("设备不存在"); } // 2. 生成任务ID并保存 long taskId = idWorker.nextId(); task.setTaskId(taskId); task.setStatus(TaskStatus.PLANNED.getCode()); task.setCreateTime(new Date()); droneTaskMapper.insert(task); // 3. MQTT下发(异步,避免阻塞HTTP响应) CompletableFuture.runAsync(() -> { mqttService.sendTaskCommand(task); // 4. 触发GIS分析 geoService.analyzeCoverage(taskId); }); return AjaxResult.success("任务创建成功,ID:" + taskId); }3.3 前端核心交互:如何让“航线规划”从静态图变成可操作工作台?
前端FlightPlan.vue组件是用户最高频操作页,其设计体现“工业软件”思维而非“互联网产品”:
地图容器双模式:
默认用<cesium-viewer>显示3D地形,但顶部Tab切换至“2D平面图”(Leaflet),因电力巡检需精确测量杆塔间距。两种地图共享同一waypoints数据源,拖拽点位时实时同步坐标。航线智能修正:
用户画完航线后,点击“优化”按钮,前端调用POST /api/flight/optimize,传入原始点位。后端用A*算法计算避障路径(避开禁飞区、高压线),返回新点位数组。关键细节:禁飞区数据存在若依sys_geo_fence表,前端首次加载地图时预取,避免每次优化都请求后端。传感器参数联动:
当选择“多光谱相机”时,自动展开波段选择面板(Blue/Green/Red/NIR/SWIR),并禁用“热成像增益”滑块;反之选择“热成像仪”时,启用增益调节。这种联动靠Vue的watch监听sensorType变化,而非硬编码if-else。任务预览卡片:
右侧固定面板显示:预计飞行时长(基于距离/速度计算)、电池消耗(按distance * 0.8 + 120s估算)、覆盖设备数(调用GET /api/device/count?bounds=[...])。实操心得:电池消耗公式经实测校准——大疆M300在50m高度、8m/s速度下,每公里耗电约0.8%,加上悬停、升降等固定损耗120秒,误差<5%。
<!-- FlightPlan.vue 片段 --> <template> <div class="plan-container"> <cesium-viewer ref="cesium" @ready="onCesiumReady" /> <div class="sidebar"> <el-form :model="form" label-width="100px"> <el-form-item label="传感器类型"> <el-select v-model="form.sensorType" @change="onSensorChange"> <el-option label="可见光" value="VISIBLE" /> <el-option label="热成像" value="THERMAL" /> <el-option label="多光谱" value="MULTISPECTRAL" /> </el-select> </el-form-item> <!-- 动态参数区 --> <div v-if="form.sensorType === 'THERMAL'"> <el-form-item label="热增益"> <el-slider v-model="form.thermalGain" :min="0.5" :max="2.0" step="0.1" /> </el-form-item> </div> <el-button type="primary" @click="submitTask">创建任务</el-button> </el-form> <!-- 预览卡片 --> <div class="preview-card"> <p>预计时长:{{ calcDuration }} 分钟</p> <p>电池消耗:{{ calcBattery }} %</p> <p>覆盖设备:{{ coveredDevices }} 台</p> </div> </div> </div> </template>3.4 文档说明的实战价值:毕设答辩时真正有用的3类文档
标题中“文档说明”常被学生忽略,但本项目文档直击答辩痛点:
《部署手册》:
不是泛泛而谈“安装JDK、MySQL”,而是给出精确到小数点后两位的版本兼容矩阵:若依后端:ruoyi-vue-pro v3.8.0(Spring Boot 2.7.18)
MySQL:8.0.33(必须!8.0.32有JSON函数bug)
Node.js:16.20.2(Vue3.3.8要求)
Nginx:1.22.1(支持HTTP/2,提升地图瓦片加载速度)
并附docker-compose.yml一键部署脚本,含MySQL主从配置(slave-sql-log-bin=ON),避免答辩时被问“如何保证数据不丢”。《接口文档》:
用Swagger UI生成,但每个接口标注“毕设答辩高频问题”:GET /api/defect/list
Q:如何实现“按设备类型筛选缺陷”?
A:SQL中WHERE device_type IN ('TOWER','PV_PANEL') AND status='UNCONFIRMED',索引已建在device_type+status联合字段。《数据字典》:
不是字段列表,而是业务语义解释:sys_drone_telemetry.battery:飞控上报的剩余电量百分比,单位%,有效范围0-100。
注意:大疆SDK返回值为0-10000,本系统已做归一化处理(除以100),避免学生答辩时被追问“为何数值超100”。
4. 常见问题与排查技巧实录:毕设学生踩过的12个真实坑
4.1 后端高频问题:从“404找不到接口”到“分页失效”
| 问题现象 | 根本原因 | 排查步骤 | 解决方案 | 经验总结 |
|---|---|---|---|---|
POST /api/flight/task返回404 | 若依路由拦截器未放行自定义API | 1. 查RuoYiConfig.java中addPathPatterns("/api/**")是否配置;2. 检查DroneTaskController类上是否有@RestController且路径@RequestMapping("/api/flight") | 在WebMvcConfigurer中添加registry.addInterceptor(authInterceptor).excludePathPatterns("/api/**") | 若依默认只放行/profile/**,自定义API必须显式排除拦截 |
分页查询/sys/user/list返回空数据 | MyBatis Plus分页插件未生效 | 1. 确认MybatisPlusConfig.java中@Bean方法名是paginationInterceptor();2. 检查DroneTaskMapper.xml中SQL是否含<select>标签而非<script> | 将分页SQL改为SELECT * FROM sys_drone_task ${ew.customSqlSegment},${ew.customSqlSegment}由QueryWrapper生成 | 若依的QueryWrapper必须用lambda方式构建,eq("status", "PLANNED")比eq("status", "PLANNED")少一个空格都会失效 |
定时任务@Scheduled不执行 | Spring Boot的@EnableScheduling未开启 | 1. 检查启动类是否加@EnableScheduling;2. 查日志是否有ScheduledAnnotationBeanPostProcessor初始化信息 | 在application.yml中加spring.task.scheduling.pool.size.core=5,避免任务堆积 | 若依的SysJob表管理定时任务,但@Scheduled是Spring原生,两者勿混用 |
settings.json配置无人机传感器不生效 | Vue环境变量未正确注入 | 1. 确认vue.config.js中define配置;2. 检查main.js是否调用loadSettings() | 在public/settings.json中存配置,main.js用fetch('/settings.json')动态加载,避免打包时固化 | 硬编码在.env中会导致不同环境(dev/prod)无法区分传感器参数 |
4.2 前端典型故障:“页面空白”与“数据不显示”的根因分析
问题:首页白屏,控制台报
Uncaught SyntaxError: Unexpected token '<'
原因:Nginx配置错误,所有请求都返回index.html,导致JS文件被当作HTML解析。
排查:在浏览器Network面板看app.js请求,Response Preview显示HTML代码而非JS代码。
解决:检查nginx.conf,确保location / { try_files $uri $uri/ /index.html; }仅作用于根路径,静态资源路径(/static/)应单独配置location /static/ { alias /path/to/dist/static/; }。我的学生曾因此折腾两天,最后发现是复制了网上教程的
try_files配置,却没删掉/static/的匹配规则。问题:地图显示黑屏,Cesium报
Failed to load resource: net::ERR_CONNECTION_REFUSED
原因:Cesium默认从https://assets.cesium.com/加载3D Tiles,但国内网络不稳定。
排查:打开开发者工具,Network标签过滤cesium,看哪些资源404。
解决:在main.js中添加:Cesium.Ion.defaultAccessToken = 'your-token'; // 申请免费Token Cesium.Resource.defaultHeaders['Accept'] = 'application/json';或更彻底:下载Cesium本地包,
vue.config.js中配置configureWebpack.resolve.alias指向本地路径。问题:前端无法获取数据,但Postman调用API正常
原因:跨域配置遗漏,常见于若依的CorsConfig.java未覆盖/api/**路径。
排查:浏览器Network面板看请求Headers,Origin头存在但响应无Access-Control-Allow-Origin。
解决:在CorsConfig.java中,registry.addMapping("/api/**").allowedOrigins("*"),注意:生产环境必须指定域名,如allowedOrigins("http://your-domain.com"),*仅限开发。
4.3 无人机集成专项问题:从“飞不起来”到“数据不对”
MQTT连接频繁断开:
大疆无人机SDK要求心跳间隔≤30秒,但若依默认MQTT客户端心跳设为60秒。
解决:在MqttConfig.java中设置options.setKeepAliveInterval(25),并增加重连逻辑:client.setCallback(new MqttCallback() { public void connectionLost(Throwable cause) { // 自动重连 connect(); } // ...其他方法 });GPS坐标偏移100米以上:
无人机回传的WGS84坐标未转为GCJ02(中国国测局加密),导致在百度/高德地图上偏移。
解决:后端增加坐标转换中间件,调用开源库gcoord:// 将WGS84转GCJ02 double[] gcj = GCoord.wgs84togcj02(lat, lng); telemetry.setLat(gcj[0]); telemetry.setLng(gcj[1]);热成像图颜色失真:
大疆禅思XT2输出的TIFF图含14位灰度,浏览器直接显示为全黑。
解决:前端用canvas做Gamma校正:const ctx = canvas.getContext('2d'); const imageData = ctx.getImageData(0, 0, width, height); for (let i = 0; i < imageData.data.length; i += 4) { const val = imageData.data[i]; // R通道即灰度值 imageData.data[i] = imageData.data[i+1] = imageData.data[i+2] = Math.min(255, Math.pow(val / 16383, 0.45) * 255); // Gamma 0.45 } ctx.putImageData(imageData, 0, 0);
5. 毕设答辩与项目延伸:如何把“高分毕设”变成求职敲门砖
5.1 答辩陈述的黄金3分钟:聚焦“我解决了什么真问题”
答辩时切忌通读代码,要像产品经理一样讲清问题-方案-验证闭环:
- 问题:传统人工巡检效率低(1基塔需2小时)、漏检率高(>15%)、缺陷描述模糊(“疑似裂纹”无量化依据)。
- 方案:用若依构建任务中枢,无人机自动采集+AI初筛+人工复核,缺陷定位精度达厘米级(GPS+RTK),描述结构化(
defect_type: "insulator_crack", severity: 4)。 - 验证:在XX光伏电站实测,单日巡检容量从5MW提升至30MW,缺陷识别准确率92.3%(对比人工复核结果),工单平均处理时长缩短67%。
我指导的学生答辩时,被问“若依和JeecgBoot哪个好”,他没比参数,而是说:“JeecgBoot更适合快速搭建OA系统,但若依的权限模型和代码生成器,让我能在2周内把‘设备台账’扩展成支持12种电力设备的动态表单,这是毕设周期内最现实的选择。”
5.2 项目延伸方向:从毕设到真实项目的3个升级点
轻量级AI集成:
当前AI识别用预训练模型,可升级为边缘AI:在无人机端部署TensorFlow Lite模型(如YOLOv5s),只回传缺陷截图而非原始图,降低带宽压力。需改造飞控固件,但大疆Mobile SDK已开放模型加载API。多机协同调度:
扩展若依的sys_drone_task表,增加fleet_id字段,后端实现基于拍卖算法的多机任务分配。当10台无人机同时待命,系统自动将邻近区域的任务指派给电量最优的机器。数字孪生融合:
将若依的设备台账与Unity3D数字孪生平台对接。点击若依后台的某台风电机组,自动在3D场景中高亮显示,并叠加其最近一次巡检的热成像图、振动频谱图。这需要若依提供WebSocket接口推送设备状态变更。
5.3 求职面试中的技术深挖:面试官最爱问的5个问题
“若依的Shiro和Spring Security,你为什么选Shiro?”
→ 答:Shiro的Subject模型更贴近工业场景的“操作员-设备”权限关系,比如"operator:DR-001:control"表示对某无人机的操控权,而Spring Security的URL权限粒度太粗。“分页查询10万条巡检记录,如何优化?”
→ 答:用游标分页(Cursor-based Pagination)替代LIMIT OFFSET,SELECT * FROM sys_drone_telemetry WHERE task_id = ? AND id > ? ORDER BY id LIMIT 20,避免深分页性能衰减。“MQTT消息丢失怎么办?”
→ 答:QoS=1保证至少一次,但需服务端去重。在sys_drone_telemetry表加message_id唯一索引,插入前先INSERT IGNORE,重复消息被数据库拒绝。“前端如何防止用户篡改传感器参数?”
→ 答:参数提交时,后端校验sensor_type与device_id的绑定关系(查sys_device表的sensor_support字段),前端只是UI,真正的校验在服务端。“若依的代码生成器生成的代码,你做了哪些必要修改?”
→ 答:三处:①DroneTaskMapper.xml中SQL增加AND status != 'DELETED'软删除过滤;②DroneTaskServiceImpl中insert方法增加idWorker.nextId();③DroneTaskController中list方法增加@PreAuthorize("@ss.hasPermi('drone:task:list')")权限注解。
最后分享个小技巧:毕设答辩PPT里,别放满屏代码,用一张图说清数据流——从无人机飞控(MAVLink)→边缘网关(MQTT Broker)→若依后端(Spring Boot)→前端Vue(Cesium地图),箭头旁标注各环节处理动作(“坐标转换”、“状态机驱动”、“GIS分析”)。这张图,比100行代码更能体现你的系统思维。
本文还有配套的精品资源,点击获取