ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于SpringBoot和微信小程序的宠物定位与电子围栏监控系统

基于SpringBoot和微信小程序的宠物定位与电子围栏监控系统 1. 选题思路与技术栈这个宠物定位系统到底在做什么1.1 从一个真实痛点说起我这两年帮不少学弟学妹看过课程设计和毕业设计的代码发现大部分人都卡在同一个问题上题目不是太普通就是太飘。太普通的比如学生管理系统、图书管理系统答辩时老师闭着眼睛都能猜到流程太飘的又容易做到一半发现硬件买不起、算法推不动。宠物定位与监控系统恰好卡在中间既有物联网硬件接入的完整链路又能用SpringBoot把业务逻辑做扎实最后再用小程序把用户体验串起来是一个技术覆盖面很广、但每个环节都在课程设计能力范围内的题目。这个系统解决的需求很直接养宠物的人没法24小时盯着猫狗宠物跑丢之后只能靠朋友圈寻宠信息。宠物项圈上装一个带GPS和通信模块的硬件定时把经纬度上报到后端主人打开小程序就能看到宠物当前的位置、历史轨迹还能在地图上画一个电子围栏宠物一旦跑出围栏就立刻收到告警推送。整个闭环涉及到设备端、服务端、小程序端三个层面这也是物联网项目最有魅力的地方。1.2 为什么选SpringBoot做后端主力很多同学会问做物联网项目是不是一定要用Python或者Node.js不是不可以但从课程设计的角度SpringBoot有三个实打实的优势。第一是生态和资料足够多。SpringBoot整合MyBatis Plus、整合MQTT客户端、整合WebSocket都有大量现成的案例遇到问题搜索引擎基本都能解决。相比Python的FastAPI虽然轻量但在校园环境里传统Java技术栈的资料密度明显更高答辩时评委也更熟悉。第二是结构清晰适合展示。SpringBoot天然分层Controller接收请求Service处理业务Mapper操作数据库。这种分层结构和软件工程课程里讲的设计思想完全对得上。演示项目时你可以很自然地说这里是设备上报接口这里是告警服务评委一听就知道你理解架构。第三是部署相对省心。一个内置Tomcat的Jar包就能跑起来配合MySQL和EMQX两个中间件在一台4G内存的云服务器上就能完整运行。对毕设来说稳定压倒一切SpringBoot的稳定性没得说。小程序端选微信小程序而不是App也是从课程设计角度考虑。小程序不需要签名打包、不需要上架审核开发版真机预览就能演示而且微信生态里地图组件、定位授权、订阅消息都有现成API可以省掉大量底层适配工作。2. 整体架构与软硬件链路从GPS坐标到小程序图标的完整流程2.1 系统里有哪些角色和设备一个完整的宠物定位监控系统从物理角度看有四个角色宠物佩戴的定位终端、云端服务端、微信小程序、以及整个系统的数据库和消息中间件。定位终端不是我们课程设计需要从零设计的硬件市面上有很多现成的开发板方案比如ESP32配合GPS模块和4G/2G通信模块。终端端的主要工作是按照固定周期获取GPS坐标把经纬度、设备编号、电量、时间戳打包成一条消息通过MQTT协议发送到云端的Broker。服务端运行着SpringBoot应用它要做的事情比较多接收设备上报的定位数据、解析和校验、写入数据库、判断是否触发电子围栏、如果有越界情况就产生告警记录、再通过WebSocket或订阅消息把位置实时推送到小程序。服务端还要处理用户注册登录、绑定宠物和设备、查询历史轨迹、管理围栏规则等HTTP接口。小程序是用户直接接触的界面负责调用微信地图组件渲染宠物位置、显示历史轨迹线、展示围栏范围、接收告警通知。小程序本身不直接连接数据库所有数据都通过HTTP接口或者WebSocket从服务端获取。2.2 设备侧一条数据是怎么一步步变成地图上的点的我建议在做后端设计之前先把一条数据从设备端到地图图标的完整路径画清楚。理解了这个链条后面写代码才不会乱。第一步设备上的GPS模块通过串口把NMEA格式的定位数据传给主控芯片主控解析出原始的经纬度、时间和定位状态。第二步主控把数据封装成JSON里面至少包含deviceId、longitude、latitude、timestamp、battery、satelliteCount等字段。第三步主控通过MQTT发布到topic比如pet/location/{deviceId}这个动作是实时的一般按3到10秒一个周期上报。第四步SpringBoot里的MQTT订阅回调收到消息经过解析校验后写入定位表同时调用围栏判断服务检查是否越界。第五步如果在线用户存在就通过WebSocket把这个位置点推送给对应的小程序端。第六步小程序收到新的经纬度后把地图上的Marker移动到新位置。这里最关键的设计决策是小程序不要主动轮询后端获取位置而是让后端通过WebSocket主动推送。原因很简单轮询会产生大量无效HTTP请求10个用户每人每秒请求一次服务端压力不小而且位置刷新有延迟。WebSocket是长连接后端有数据就推没有数据就保持连接空载开销很小。2.3 小程序端的功能模块划分小程序端我建议按底部TabBar分三个页面首页地图、宠物列表、个人中心。首页地图是最核心的页面一打开就默认显示当前选中宠物的实时位置地图上有一个宠物头像Marker下方可以切换显示轨迹模式和围栏模式。轨迹模式会调用接口拉取某个时间段内的定位点用Polyline画出一条带箭头的路径围栏模式会把用户设置的地理围栏用圆圈或多边形画出来宠物在圈内显示正常状态在圈外则把Marker和围栏区域标红。宠物列表页面用来管理多只宠物展示每只宠物的头像、昵称、最近在线时间、电量、设备在线状态。用户可以在这里添加新宠物、绑定设备、编辑宠物资料、查看设备信息。个人中心存放用户的登录状态、账号管理、消息通知设置、关于页面。这三个页面看起来简单但每个页面背后都有对应的一组后端接口。比如首页地图要调用获取宠物最新位置和获取围栏配置的接口列表页要调用我的宠物列表的接口个人中心要调用绑定设备的接口。接口设计得规范前端开发就会很顺畅。3. SpringBoot后端核心实现数据上报、轨迹存储与电子围栏3.1 设备上报接口与消息处理逻辑设备上报数据有两种实现方式一种是设备直接通过HTTP POST请求发送JSON到SpringBoot接口另一种是走MQTT。我在系统里用MQTT作为设备上报的主通道但同时也保留了一个HTTP上报接口作为备用方便没有MQTT环境时做功能演示。HTTP上报接口的设计很直白用一个DeviceLocationController来接收POST请求路径设为/api/device/location请求体是定位数据JSON。这里有一个很多新手会忽略的点接口不能直接信任设备上报的数据必须先根据deviceId查询设备是否存在、是否已绑定用户否则任何知道接口地址的人都可以往里灌垃圾数据。MQTT方式的话需要引入spring-integration-mqtt或者用Eclipse Paho的客户端在SpringBoot启动时建立连接并订阅主题。收到消息后先解析JSON再走和HTTP上报相同的Service逻辑。为了避免代码重复我会把核心处理逻辑写在一个DeviceLocationService里HTTP和MQTT两个入口都调这个方法。这里有一段典型的消息处理伪代码逻辑public void handleLocationReport(DeviceLocationReport report) { // 1. 校验设备是否存在且在线 Device device deviceMapper.selectByDeviceId(report.getDeviceId()); if (device null) { log.warn(unknown device: {}, report.getDeviceId()); return; } // 2. 写入定位记录表 LocationPoint point new LocationPoint(); point.setDeviceId(device.getId()); point.setPetId(device.getPetId()); point.setLongitude(report.getLongitude()); point.setLatitude(report.getLatitude()); point.setBattery(report.getBattery()); point.setReportTime(new Date(report.getTimestamp())); locationPointMapper.insert(point); // 3. 更新缓存里的最新位置 redisTemplate.opsForValue().set( pet:latest: device.getPetId(), JsonUtils.toJson(point), 60 * 60 * 24); // 4. 判断电子围栏 checkGeofence(device.getPetId(), point); // 5. 通过WebSocket推送实时位置给在线用户 wsSessionManager.sendToUser(device.getOwnerId(), location: JsonUtils.toJson(point)); }3.2 电子围栏的简单判断算法电子围栏不多说原理太复杂这里直接用球面距离公式判断宠物当前位置和围栏中心点之间的距离。围栏存储时以petId、centerLongitude、centerLatitude、radiusMeters四个字段存在于geofence表。当新位置点进来就调用距离计算方法如果距离大于半径说明出了围栏。距离计算建议用Haversine公式它能比较准确地计算地球球面上两点之间的距离。如果只是简单用平面坐标算距离纬度越高误差越大答辩时很容易被老师抓到数学问题。public static double distance(double lat1, double lon1, double lat2, double lon2) { double r 6371000; double radLat1 Math.toRadians(lat1); double radLat2 Math.toRadians(lat2); double deltaLat Math.toRadians(lat2 - lat1); double deltaLon Math.toRadians(lon2 - lon1); double a Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) Math.cos(radLat1) * Math.cos(radLat2) * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2); double c 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return r * c; }如果围栏不是圆形而是不规则多边形那就要用射线法判断点是否在多边形内这个可以作为扩展点写进课程设计文档里但实际项目用圆形围栏就够用了。3.3 告警服务的去重与通知策略电子围栏判断出宠物越界后不能每次上报都生成一条告警因为设备每隔几秒就会上报一次宠物在外面待十分钟就可能产生上百条告警。服务端需要做一次去重同一只宠物同一个越界事件只生成一条告警记录直到宠物回到围栏内下一次越界再生成新告警。实现方式可以选择用Redis加一个简单的状态标记。当判断越界时检查pet:geofence:alert:{petId}这个key是否存在不存在则说明是首次越界生成告警并把这个key设置成10分钟过期如果key已经存在说明还在同一个越界事件中只更新告警记录的最后位置不再新建。当宠物回到围栏内删除这个key状态归零。通知层面课程设计环境里最实用的是微信小程序订阅消息。用户在页面上点击开启越界提醒按钮后小程序会调用wx.requestSubscribeMessage向用户申请一次订阅授权拿到授权后可以给用户发一条订阅消息。但要注意微信的订阅消息是一次性的用户每次点授权只能让服务端发一条不是永久的。所以服务端设计时不能假设一定能推送成功还需要在小程序页面上用站内信或红点的方式来补充提醒。4. 物联网通信选型MQTT接入为什么比HTTP更合适4.1 MQTT的三个核心特性很多课程设计在物联网通信上会偷懒直接用HTTP接口把设备数据POST到后端。这样能跑通但仔细一想设备每隔5秒上报一次HTTP请求头本身就有一大堆冗余数据而且没有长连接的概念每次都要重新建立TCP连接。对于宠物定位这种高频、低功耗、可能网络不稳定的场景MQTT是明显更合适的协议。MQTT有三个特性刚好切中这个场景。第一个是发布订阅模型设备端发布消息到主题服务端订阅主题就能收到消息双方不用知道彼此的IP地址中间通过Broker解耦。第二个是QoS质量等级设备上报可以选择QoS 0最多一次、QoS 1至少一次、QoS 2只有一次。课程设计里建议用QoS 1能防止消息在网络抖动时丢失又不会像QoS 2那样多一次握手增加开销。第三个是遗嘱消息机制设备掉线时Broker会帮它发一条遗嘱消息服务端收到后能立刻判断设备离线。用生活化的比喻来说MQTT就像是一个小区快递站设备把包裹放到驿站服务端随时去驿站取不需要打电话约时间一直接头。HTTP则像快递员必须亲手送到你手上双方都必须同时在线还要反复确认。4.2 本地开发如何搭一个MQTT Broker如果不想花钱买云服务商的物联网套件本地搭一个EMQX Broker是完全够用的。EMQX是开源项目支持Docker一键启动资源占用也很低。课程设计时在本地Windows或者Linux服务器上跑一个EMQX然后SpringBoot通过tcp://localhost:1883连接小程序端通过ws://localhost:8083/mqtt连接就能打通端到端链路。我把本地开发环境的Broker配置整理成一张表方便对照配置项值说明端口1883MQTT TCP端口设备和服务端使用WebSocket端口8083小程序或浏览器通过WebSocket连接Dashboard端口18083管理后台可以查看连接数、订阅主题用户名admin / public开发环境默认账号主题前缀pet/location/{deviceId}设备上报位置主题前缀pet/status/{deviceId}设备上下线状态SpringBoot集成EMQX其实只需要在pom.xml里加一个Paho客户端依赖然后写一个配置类在启动时建立长连接。这里最容易踩的坑是Jackson和Paho的回调线程模型Paho的回调是单线程阻塞的如果处理消息时直接操作数据库导致耗时太长会阻塞后续消息。正确做法是把消息先丢进一个线程池异步处理或者用消息队列削峰。4.3 离线补传与心跳保活的工程细节宠物定位设备在户外难免会进入信号盲区比如地下车库、郊区树林。设备在连不上Broker期间不能把定位数据扔掉而应该先把记录缓存在设备本地等网络恢复后按时间顺序补传。数据库表里需要有一个isSupplement字段标注这条记录是实时上报还是离线补传这样小程序端展示轨迹时可以把补传数据标记成虚线避免用户误以为宠物实时在线。心跳保活也很重要。MQTT本身有一个Keep Alive机制客户端在连接时指定心跳间隔比如60秒。如果Broker在1.5倍心跳周期内没收到客户端的任何包就会断开连接并触发遗嘱消息。服务端维护一张设备在线状态表每次收到心跳或位置数据就更新lastSeenAt字段小程序宠物列表页展示的在线状态就是从这张表查出来的。5. 微信小程序端开发要点地图实时刷新与用户交互5.1 地图组件与定位权限的坑微信小程序的map组件是官方提供的原生组件使用起来很简单但有几个细节需要特别注意。第一个是cover-view的问题在map组件上覆盖的自定义按钮必须用cover-view而不是普通view否则在真机上会被map组件遮挡。第二个是marker的图标动态加载宠物头像时要先上传到小程序后台或云存储拿到临时URL再绑定到iconPath。第三个是地图高度不能直接用100%必须给一个固定px值或者通过wx.getSystemInfo拿到屏幕高度再计算不然地图区域会塌成一条线。获取用户当前位置需要调用wx.getLocation接口但这个接口从2022年起要求必须在app.json里声明requiredPrivateInfos字段并且需要在小程序管理后台申请用户隐私保护指引。课程设计用的个人开发账号也能申请但要提前几天操作不然开发时真机预览会直接报错。下面是小程序地图页面的核心片段const mapContext wx.createMapContext(petMap); moveToPetLocation(pet) { mapContext.moveToLocation({ latitude: pet.latitude, longitude: pet.longitude, success: () { this.setData({ latitude: pet.latitude, longitude: pet.longitude, markers: [{ id: 1, latitude: pet.latitude, longitude: pet.longitude, iconPath: pet.avatarUrl, width: 40, height: 40 }] }); } }); }5.2 实时位置刷新方案WebSocket还是MQTT over WebSocket小程序端要实时刷新宠物位置有两种主流方案。第一种是接入MQTT over WebSocket直接订阅和手机绑定的设备主题好处是实时性最强、链路最短设备上报后Broker直接推给小程序不经过自己的后端。第二种是用WebSocket连接SpringBoot由后端把位置转发给小程序好处是方便在服务端做权限控制、数据持久化、围栏判断。我的建议是课程设计优先用第二种也就是SpringBoot WebSocket的方案。原因有三个第一后端已经积累了所有业务数据WebSocket推送时可以把处理过的位置、电量、围栏状态一起推给前端小程序端的逻辑更简单第二WebSocket的鉴权可以在握手阶段用Token完成避免小程序直接连接Mqtt Broker时暴露账号密码第三答辩演示时更容易解释数据流方向设备 - 后端 - 小程序一条清晰的链路。实现WebSocket推送时要处理好连接和用户绑定的映射关系。用户登录后小程序通过uni.connectSocket或者wx.connectSocket建立连接在URL后面拼上Token参数后端HandshakeInterceptor解析Token并缓存Session。推送时根据PetId查询所属的用户再找到对应的WebSocketSession发送消息。要注意的是一个用户可能同时登录两个设备比如手机和Pad所以userId - SetSession才能避免只推给其中一个。5.3 轨迹展示与交互细节轨迹展示最直观的方式是把一段时间内的定位点连接成线。小程序端的map组件有polyline属性按顺序传入经纬度数组就行。展示轨迹前需要先调用后端接口拉数据接口参数是petId、startTime、endTime返回的定位点要按时间升序排列这样轨迹线才连贯。这里有个体验细节如果定位点非常多比如2小时每隔5秒一个点就有1440个点全部画上去会很卡。可以做一个简单的降采样每隔N个点取一个或者在SQL查询时用MOD(ROW_NUMBER(), N)0做抽样。课程设计里我觉得每10秒一个点就够了如果上报频率是5秒降采样到每2个点保留1个地图渲染完全流畅。画电子围栏时圆形围栏可以转换成circles属性在map组件上直接绘制多边形围栏则需要转换成polygons属性。如果后端返回的是中心点和半径前端可以现场计算多边形的顶点坐标然后把圆形拟合成多边形再绘制这样更灵活一些。6. 数据库设计细节从表结构到轨迹查询优化6.1 核心表设计与关系宠物定位监控系统的数据量不大但表关系比普通管理系统复杂。核心表有六张用户表、宠物表、设备表、定位记录表、围栏配置表、告警记录表。用户表和宠物表是一对多关系一个用户可以养多只宠物。宠物表和围栏表是一对一关系每个宠物最多一条有效围栏配置。宠物表和设备表可以是一对一也可以是一对多有些宠物可能换过多个设备但为了课程设计简单我建议做成一宠物一设备设备表中带一个currentPetId字段。定位记录表只负责存位置点表结构如下CREATE TABLE location_record ( id BIGINT NOT NULL AUTO_INCREMENT, pet_id BIGINT NOT NULL COMMENT 宠物ID, device_id VARCHAR(64) NOT NULL COMMENT 设备编号, longitude DECIMAL(10, 6) NOT NULL COMMENT 经度, latitude DECIMAL(10, 6) NOT NULL COMMENT 纬度, speed DECIMAL(5, 2) DEFAULT 0.00 COMMENT 速度 km/h, battery TINYINT DEFAULT 100 COMMENT 电量百分比, is_supplement TINYINT DEFAULT 0 COMMENT 是否离线补传, report_time DATETIME NOT NULL COMMENT 设备上报时间, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 入库时间, PRIMARY KEY (id), KEY idx_pet_time (pet_id, report_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT宠物定位记录表;这里我特别强调idx_pet_time这个联合索引。查询轨迹的核心SQL是WHERE pet_id ? AND report_time BETWEEN ? AND ?如果没有这个联合索引数据量一上来查询就会走全表扫描速度会非常慢。别以为课程设计的数据量几万条没事演示时如果反复查询大范围时间段的轨迹延迟是能明显感知到的。6.2 轨迹查询的分页与降采样轨迹查询接口不能一把梭把所有点返回给前端。我的做法是接口默认限制最多返回500个点如果这段时间内的定位点超过500个就按时间间隔均匀抽样。这样既控制了响应体大小又保证了轨迹形状完整。SQL层面可以这样实现均匀抽样SELECT longitude, latitude, report_time FROM ( SELECT a.*, ROW_NUMBER() OVER (PARTITION BY pet_id ORDER BY report_time) AS rn FROM location_record a WHERE pet_id #{petId} AND report_time BETWEEN #{startTime} AND #{endTime} ) t WHERE MOD(t.rn, #{sampleRate}) 0 ORDER BY report_time;ROW_NUMBER窗口函数在MySQL 8.0里很好用。如果学校机房还在用MySQL 5.7就需要换成用户变量的写法或者直接把数据拉到Java里再降采样。数据库版本这个问题课程设计文档里最好写清楚开发之前先查一下本机MySQL版本。6.3 最新位置的存储策略定位记录表是追加式的每次查询最新位置如果都去这张大表里找效率不高。更合理的做法是用Redis缓存每只宠物的最新位置或者在一张单独的pet_latest_location表里只存一条记录每次新数据进来就更新。Redis的好处是快而且可以设置过期时间自动清理长时间不在线的宠物缓存。如果不想引入Redis可以设计一张小表CREATE TABLE pet_latest_location ( pet_id BIGINT NOT NULL, longitude DECIMAL(10, 6) NOT NULL, latitude DECIMAL(10, 6) NOT NULL, battery TINYINT DEFAULT 100, last_seen_at DATETIME NOT NULL, PRIMARY KEY (pet_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;每次收到设备上报时先更新location_record再INSERT ... ON DUPLICATE KEY UPDATE更新这张小表。查询宠物首页地图时直接查这张小表速度极快。这个设计在答辩时也可以作为一个小亮点提出来说明你考虑了读写分离和热点数据的缓存。7. 联调阶段最常踩的坑环境配置、消息乱序与权限问题7.1 本地启动整套系统的环境准备清单我在帮别人调试这个项目时发现大多数问题出现在环境准备阶段。整理一份按顺序执行的清单照着做可以少踩很多坑。首先安装JDK 8或JDK 11不建议用JDK 17以上的版本因为Spring Boot 2.x系列在高版本JDK下有时会出现反射告警虽然不影响运行但课程设计答辩时弹出一堆红色告警会显得不专业。其次安装MySQL 8.0导入项目提供的pet_monitor.sql脚本。第三安装RedisWindows下的Redis可以直接下载zip解压运行redis-server.exe。第四安装EMQX同样可以下载Windows安装包。最后用IDEA打开后端项目修改application.yml里的数据库账号密码、Redis地址、EMQX地址然后启动。常见问题就是服务启动时报Unable to connect to Redis。很多同学根本没有启动Redis服务就急着启动SpringBoot这个错误很典型解决方式就是先把Redis打开。7.2 MQTT消息顺序与消息重复设备上报数据时如果走MQTT并且设置了QoS 1网络抖动时Broker可能重发消息服务端就会收到重复的定位点。虽然位置数据重复一两条不影响大局但定位表里会有时间戳完全相同的两条记录轨迹线看起来会有小毛刺。解决方案有两层。第一层是在数据库表设计时给device_id report_time加上唯一索引重复的消息插入时会报错直接忽略。第二层是在业务代码里做幂等判断更简单的方法是先查一下相同report_time的记录是否存在但这种方案在高并发下不太可靠所以优先推荐用唯一索引。消息乱序的问题也很隐蔽。设备上报时间戳是设备端生成的但网络传输过程中可能前后两条消息到达服务端的顺序不一致也就是时间戳早的消息后到。如果直接以数据库create_time排序轨迹线会产生回退跳变。正确的做法是轨迹查询时一律按report_time排序不能按create_time排序。这一点在写SQL时一定注意。7.3 小程序真机调试的权限与域名问题小程序开发工具里很多功能在模拟器上正常一到真机就白屏。最典型的有三个问题。第一个是wx.getLocation在真机上需要手动点右上角胶囊按钮的定位图标授权位置权限。调试的时候要先把手机微信的位置权限打开。第二个是请求域名必须是HTTPS而且要在小程序后台配置request合法域名。如果是本地联调可以在开发工具里勾选不校验合法域名但真机预览时这个选项不生效。所以我一般建议联调时用内网穿透工具把本地SpringBoot服务映射成HTTPS临时域名或者直接把后端部署到云服务器用Nginx转发HTTPS。第三个是WebSocket连接地址也必须用wss不能用ws。如果后端是SpringBoot原生WebSocket需要在Nginx里配置WebSocket代理升级头。这块有好多坑建议把Nginx配置写在项目文档里方便复查。8. 课程设计答辩前需要梳理的问题清单8.1 老师最可能问的几个问题答辩时间一般只有十分钟老师主要想看你是不是真的理解自己写的代码。据我观察宠物定位与监控这种题目老师基本会围绕以下四个方向问问题。第一个问题设备是怎么上报数据的你只需要讲清楚从设备GPS模块到MQTT Broker再到SpringBoot消费的链路中间可以提一下QoS和主题设计。第二个问题电子围栏是怎么判断宠物越界的这里要说出Haversine公式和去重策略最好能现场在白板上画一下圆心和半径。第三个问题如果设备断网了数据怎么处理这个问题考察的是离线补传和心跳保活答得好会加分。第四个问题系统能不能支撑大量设备同时在线这个问题比较尖锐如果你只做了单机版要诚实说明当前的瓶颈在哪里同时提出可以用消息队列削峰、设备分片、集群化Broker这些优化方案表明你有思考过扩展性。8.2 文档和交付物怎么整理才让老师觉得完整毕业设计和课程设计除了代码能跑文档也是评分的重要部分。我自己的习惯是除了一篇通用的开发文档还会额外整理三份小文档。第一份是数据库设计说明里面包含ER图、每个表的字段说明、索引设计思路。这份文档不一定要长但一定要清楚。第二份是接口文档用Swagger自动生成也行手写一个Markdown表格也行把每个接口的请求参数和响应示例列出来老师检查代码时直接对照接口会很容易阅读。第三份是部署手册从零开始如何搭建环境、导入数据库、启动后端、运行小程序每一步都要截图。这份文档的意义在于如果老师想自己复现你的项目就能快速跑起来。项目目录里建议放一个docs文件夹把这些文档和SQL脚本、源码放在一起再写一个清晰明了的README。这样整个工程看起来很规范答辩时也会给老师留下好印象。8.3 还能往哪些方向扩展如果你的课程设计想冲高分或者后续还想把这个项目做成毕设可以考虑在现有基础上加几个扩展点。第一个是接入第三方地图API实现地理围栏的逆地理编码让用户在地图上画任意多边形围栏而不是只能画圆形。第二个是加入宠物健康监测比如通过加速度传感器数据判断宠物的活动量生成每日活动报告。第三个是把设备端换成低功耗模式通过NB-IoT或者Cat.1模块降低功耗并结合太阳能充电延长待机时间。第四个是把告警通道从订阅消息升级到短信或电话告警不过这个需要买服务课程设计阶段演示WebSocket通知就够了。我在实际调试过程中还有一个体会不管题目看起来是难是易真正决定项目质量的是你把细节做到什么程度。比如设备离线状态有没有在小程序上准确展示定位点的漂移有没有做过滤围栏误报率是不是太高这些问题在答辩时都会被放大。做宠物定位与监控系统最好的做法是先跑通最小闭环再一步步把容错和体验补上去。项目源码和数据库脚本整理好以后建议多在几台机器上用不同版本的环境跑一遍提前把环境差异带来的问题解决掉别等到答辩当天才发现数据库连接不上或者地图组件一片空白。
返回列表