ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring Boot智能药箱系统:服药提醒定时任务与毕设部署全解析

Spring Boot智能药箱系统:服药提醒定时任务与毕设部署全解析 给计算机专业的学生做毕设指导这几年我见得太多次凌晨三点在群里问“为什么我的服务器起不来”的场面了。如果你正在为基于Spring Boot的智能药箱系统头疼别急——这篇文章就是为你准备的。从一个完整的毕设交付包出发我会把服药时间提醒这个核心功能从需求分析一路讲到代码实现、本地部署和服务器上线。这套思路适合谁计算机专业准备毕设的学生、想拿Spring Boot练手做实战项目的初学者甚至是想快速搭建物联网健康类Demo的开发者都能在里面找到能直接抄的作业。需要先说明一点我拆解的不是一个“只给你一堆文件”的空壳项目。完整源码、论文文档毕设圈里常说的LW、部署说明、演示视频这四个部分是一个能通过答辩的毕设缺一不可的。下面我会从需求侧和代码侧两条线把整个项目拆透尤其会重点讲大家最容易出问题的定时提醒和部署环节。1. 项目整体拆解智能药箱系统到底在做什么1.1 从标题看需求这个系统解决了什么问题智能药箱系统字面理解就是给“吃药”这件事加一个管理工具。对年轻人来说按时吃药可能不是问题但对慢性病患者、独居老人、需要长期服药的群体来说记错时间、漏服、重复服用是常态。这个系统的核心价值就是让“几点该吃什么药”这件事从人脑记忆变成系统自动触发。标题里特意强调“服药时间提醒”说明这个功能是整个项目的灵魂其他模块都是围绕它做支撑的。放到毕业设计的语境里这个选题之所以热门是因为它踩中了三个点第一需求清晰评委一看就懂不需要花五分钟解释业务概念第二技术栈成熟Spring Boot MyBatis MySQL这套组合在毕设里几乎是标准答案资料多、踩坑少第三可扩展性强后续无论是加硬件联动、加小程序前端还是引入统计分析都能在论文里写出彩。从实际应用来看这个系统也不算悬空。很多智能药箱产品已经在市面上卖了核心逻辑就是“药箱带显示和提醒功能后台能设置服药计划”。毕设版本不需要做出实体硬件用软件模拟数据流把提醒链路打通就足够证明你掌握了一个完整系统的设计能力。1.2 完整交付包里都需要哪些东西标题最后那串“源码LW部署说明演示视频”其实已经说明了合格毕设的组成结构。先说源码它不是一个文档而是一个可以直接启动的工程包含后端Java代码、数据库脚本、配置文件。很多学生拿到源码后第一件事是运行这是对的但我的建议是一定要按自己的思路重新走一遍关键代码尤其是提醒逻辑不然答辩的时候一句“用了Spring自带的Scheduled”就解释不清楚了。然后说LW也就是论文文档。论文不是把源码复制粘贴进去而是要讲清楚“为什么要设计这些表”“为什么选Spring Boot而不是SSM”“提醒模块的可扩展性体现在哪”。部署说明则是让你能在自己的电脑或服务器上复现整个环境的操作手册从JDK安装到MySQL配置每一步都要能照着做。演示视频则是答辩前录制的系统操作录屏时长控制在五到八分钟把核心流程走一遍。这四个部分合在一起才叫完整的交付。这里我也要提醒一句市面上确实有人宣称“全bao一条龙”但如果你只是拿到文件却不知道项目怎么跑、核心逻辑在哪答辩时被问到“为什么这里要加事务”这种问题很容易当场冷场。所以我更倾向于把这份交付包理解成“参考实现”而不是“免检答案”。1.3 功能模块设计与业务流程闭环我把这套系统的功能模块拆给大家看照着这个清单去核对你的源码是不是齐全。用户模块注册、登录、个人信息维护。这里要注意角色区分比如患者和家属或管理员最好用不同角色对应不同的操作权限。药品模块药品信息的增删改查包括药品名称、规格、库存数量、生产日期、有效期。服药计划模块这是核心中的核心。用户为某个药品创建一条计划设置开始日期、结束日期、服用时间点、每次剂量。提醒记录模块每次定时任务触发后都生成一条提醒记录记录“应提醒时间”和“实际发送时间”方便追溯。服药确认模块用户收到提醒后在页面点击“我已服药”系统记录确认时间如果超时未确认可以做二次提醒或者标记为漏服。业务流程闭环是这样走的管理员添加用户 → 用户登录后添加药品 → 为药品创建服药计划 → 系统定时器扫描当天计划 → 到达时间点推送提醒 → 用户确认服药 → 系统记录反馈 → 超时未确认生成漏服记录。这个闭环讲清楚论文的需求分析部分就完成了一大半。为了让你在核对源码时更快上手我把模块与后端接口、数据库表对应起来做成了一张速查表功能模块核心接口数据库表关键状态用户管理/api/user/register、/api/user/loginsys_user角色字段 role药品管理/api/drug/add、/api/drug/listdrug_info库存 stock服药计划/api/plan/add、/api/plan/listmed_plan计划状态 status提醒记录/api/remind/listremind_log待提醒/已发送服药确认/api/remind/confirmremind_log已确认/已超时小结一下这一章最想强调的是一个逻辑链条有清晰的需求和模块边界后面的代码才不会写成一团乱麻。很多毕设翻车不是代码跑不起来而是自己在答辩时根本讲不清系统到底有哪些功能、这些功能之间怎么协作。所以动手写代码前先把这个模块清单和闭环流程在脑子里过一遍比什么都重要。2. 核心技术解析服药时间提醒是怎么实现的2.1 定时任务的三种常用方案选型实现服药提醒本质上就是一个定时任务业务。Spring Boot生态里常见的有三种做法。方案一Scheduled注解。这是最简单的方式在方法上标注Scheduled(cron 0 0 8 * * ?)配合Spring Boot启动类上的EnableScheduling就能让服务在每小时、每天、每月的固定时间点执行任务。优点是零依赖不需要额外配置文件缺点是任务逻辑全部写死在代码里不方便动态调整。比如用户新增一条服药计划你得想办法重建调度器或者用一个全局扫描任务来代替。方案二Quartz调度框架。Quartz提供了Job、Trigger、Scheduler这套完整模型支持数据库持久化可以把调度状态存到表里。相比Scheduled它最大的好处是“动态创建任务”用户新增一个服药计划时我们可以直接在运行时创建一条Trigger到点触发Job。缺点是学习曲线陡一些表和配置也更多。方案三xxl-job等分布式调度平台。这类工具适合微服务、多节点场景提供可视化管理界面、失败重试、日志面板。对于毕设来说属于杀鸡用牛刀但可以在论文的“系统扩展”章节提一笔表明你了解分布式场景下的任务调度方案。我的建议是毕设首选用Scheduled加数据库存储待执行计划的方式用一个每分钟触发一次的定时器去数据库里查接下来几分钟内有没有该提醒的记录。这样做的好处是只有一个扫描任务逻辑简单而且新增服药计划不需要动态操作调度器只需要往表里插一条数据就行。等你有富余时间再去研究Quartz的动态Trigger作为加分点。2.2 提醒消息的推送通道怎么选定时任务只是一个触发器真正“触达用户”的是消息推送通道。这里有几个层次。第一层是站内消息。系统里建立一张提醒表定时任务往表里插入待提醒记录前端页面通过WebSocket或者短轮询接受到期消息。这种方案成本最低演示效果直观因为用户可以在系统里直接看到“该吃药了”的弹窗。如果你的前端用了Vue或React可以配合WebSocket做一个实时通知角标。第二层是邮件通知。用Spring Boot自带的JavaMailSender配置好邮箱SMTP参数就能发送HTML邮件。它适合演示“离线通知”场景但国内环境对邮件敏感度一般容易被丢进垃圾箱而且演示时如果邮件延时会影响答辩节奏。第三层是短信或IM通知。接阿里云短信、腾讯云短信或者钉钉、企业微信机器人都行。这类渠道需要申请模板、配置AccessKey配置过程本身就是一个很好的论文素材能体现你接触了真实第三方接口。但要注意短信通常要充值如果只是为了演示很多服务商有免费测试额度记得提前准备。如果这个项目想和硬件结合还可以让定时任务触发树莓派上的继电器或者通过语音模块播放“请按时服药”的提示音。这部分可以放进扩展设计里核心实现阶段不必依赖它。我的建议是把站内消息作为核心提醒通道用WebSocket做实时推送邮件作为一个备选通道演示时两种效果都能展示。短信和IM在论文里写“预留接口”避免演示时因为网络或平台审核出问题。2.3 数据库设计思路与核心表结构服药提醒的核心数据模型我倾向于这几张表。sys_user用户表id、username、password加密存储、role、phone。drug_info药品表id、user_id、name、specification、stock、validity_date。med_plan服药计划表id、user_id、drug_id、start_date、end_date、dosage、status、remind_times例如“08:00,12:00,18:00”。remind_log提醒记录表id、plan_id、remind_time、actual_send_time、status区分未提醒、已提醒、已确认、漏服以及confirm_time。这里特别提醒几个设计细节。第一remind_times用字符串存多个时间点代码里split一下就能处理。但如果你需要精确到“每个时间点独立启停”那就拆分成med_plan_detail子表一条计划对应多条时间点记录。我见过很多同学在这个取舍上纠结我的建议是表结构尽量往“能应对动态变化”的方向走也就是一张计划主表加一张时间点子表这样将来被问到“同一个药品一天吃两次但今天只吃一次怎么办”你能给出状态调整方案而不是支支吾吾。第二时间字段用LocalDateTime或LocalTime别用字符串比较大小。第三remind_log里加一个window_minutes字段表示提醒后多少分钟内需要确认超过就标记漏服。这个字段很关键能体现你考虑了真实用药场景中的缓冲需求。2.4 为什么提醒不能只靠一条定时任务我见过很多初版代码是这么写的在配置里写死一个cron表达式到点触发一次任务然后就不管了。这在演示Demo里没问题但放在毕业设计里就很容易被答辩老师追问。真实场景下会出现这些情况一个用户早上8点的药但是系统在7点50才创建这条计划怎么办用户前一条记录还没确认后一条时间又到了要不要发重复提醒用户出差去了另一个时区提醒时间要不要跟着变周末是否跳过所以“提醒”应该是一个有状态、有判断的服务而不是一个简单的定时器。在实际项目里我会这样做用一个每分钟或每30秒扫描的任务查询所有状态为“进行中”的计划。把每条计划的提醒时间点解析出来和当前时间做差值计算落在未来5分钟内就生成提醒记录。对已生成提醒但用户在窗口期内未确认的记录生成二次提醒或漏服记录。用MySQL的updated_at和乐观锁版本号避免多个实例同时扫描同一批数据导致重复提醒。核心逻辑是定时任务只做“扫描”真正“发送提醒”的动作由状态机驱动。这样做的好处是即使某个时间点服务器刚好重启重启后扫描任务也能把遗漏的提醒补上。这个思路我强烈建议写进论文它是整个系统的技术亮点也是区分“背代码”和“懂设计”的分水岭。3. 实操过程从零到一搭建Spring Boot项目3.1 环境准备与项目初始化说再多理论不如直接把工程搭起来走一遍。先列一下环境清单JDK 8或11Spring Boot 2.x推荐82.7以上推荐11如果你本机是17直接上Spring Boot 2.7.x或3.x都行Maven 3.6以上IDEA社区版或旗舰版都够用MySQL 5.7或8.0Postman或Apifox做接口测试。项目初始化有两种路径。第一种打开IDEA选择Spring Initializrgroup填com.exampleartifact填smart-medicine-box依赖勾选Spring Web、MyBatis Framework或MyBatis-Plus、MySQL Driver、Lombok。第二种直接去start.spring.io下载一个压缩包解压后用IDEA打开。注意生成时Spring Boot版本别选太新的有些和MyBatis的兼容性还没磨合好稳妥点选2.7.x。初始化后把默认的application.properties改成application.yml并配置好数据源server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/smart_medicine?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true这里我要特意提一句serverTimezoneAsia/Shanghai和useSSLfalse这两个参数是解决“本地连接MySQL报错”的常青选项。很多同学一打开项目就报Communications link failure八成是时区或SSL配置不对。这个坑我在后面排查表里还会再列一次因为它太常出现了。3.2 核心代码实战实体、Mapper、Service、Controller我们用最常见的代码风格演示一遍核心链路。先用Lombok建实体类Data TableName(med_plan) public class MedPlan { TableId(type IdType.AUTO) private Long id; private Long userId; private Long drugId; private LocalDate startDate; private LocalDate endDate; private String dosage; private String remindTimes; private Integer status; // 0-未启用 1-进行中 2-已结束 }然后是Service层的核心方法我建议命名为checkAndSendReminders()。这里用一个每分钟触发的Scheduled方法扫描未来5分钟内需要提醒的记录Service public class ReminderService { Resource private MedPlanMapper medPlanMapper; Resource private RemindLogMapper remindLogMapper; Scheduled(cron 0 * * * * ?) public void scanUpcomingReminders() { // 1. 查询所有进行中的计划 ListMedPlan activePlans medPlanMapper.selectActivePlans(); LocalDateTime now LocalDateTime.now(); for (MedPlan plan : activePlans) { // 2. 只处理当天仍在计划期内的计划 if (!isWithinPlanPeriod(plan, now.toLocalDate())) { continue; } // 3. 解析时间点判断是否落在未来5分钟窗口内 for (LocalTime remindTime : parseRemindTimes(plan.getRemindTimes())) { LocalDateTime scheduledDateTime LocalDateTime.of(now.toLocalDate(), remindTime); long diffMinutes ChronoUnit.MINUTES.between(now, scheduledDateTime); if (diffMinutes 0 diffMinutes 5 !isAlreadyGenerated(plan.getId(), scheduledDateTime)) { sendReminder(plan, scheduledDateTime); } } } } }这段代码代表了整套系统的核心调度思路。isAlreadyGenerated方法需要去remind_log表里查一下防止同一分钟重复插入记录sendReminder内部负责把提醒记录落库同时通过WebSocket或第三方通道推送消息。实际项目里还要加分布式锁这里为了看起来直观我用的是单机场景。如果论文想写“多实例部署”就给这个Service加一层Lock或基于数据库的乐观锁控制并把这部分放在“系统可靠性设计”一节里展示。Controller层通常设计成RESTful接口比方说/api/plan/add、/api/plan/list、/api/remind/confirm。前端Vue项目里的按钮本质上就是调用这些接口。这里不再贴完整的Controller代码但必须提醒大家接口里要做参数校验比如结束日期不能早于开始日期药品ID必须存在这些同样是评审老师容易追问的点。3.3 数据库脚本与初始化数据建表时我建议在doc/sql/目录下放一个init.sql。创建数据库和核心表的脚本如下CREATE DATABASE IF NOT EXISTS smart_medicine DEFAULT CHARSET utf8mb4; USE smart_medicine; CREATE TABLE med_plan ( id bigint(20) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL COMMENT 用户ID, drug_id bigint(20) NOT NULL COMMENT 药品ID, start_date date NOT NULL, end_date date DEFAULT NULL, dosage varchar(50) DEFAULT NULL COMMENT 每次剂量, remind_times varchar(100) NOT NULL COMMENT 提醒时间点逗号分隔, status tinyint(4) DEFAULT 1 COMMENT 0-未启用 1-进行中 2-已结束, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT服药计划表;这里我特意加上时间字段和索引。索引在数据量上来之后非常重要虽然毕设数据量小看不出来但答辩时老师可能会问“为什么给user_id加索引”你就可以回答“该字段是高频查询条件”并且可以在explain里展示一下执行计划非常加分。remind_log表的核心字段这里不再用SQL贴一遍但有一个关键点要强调status的取值范围建议定为0-待提醒、1-已发送、2-已确认、3-已超时并且加一个confirm_time。这组状态在论文的时序图里对应得很清晰配合2.4节的状态机逻辑整个系统的动态行为就能完整呈现。3.4 接口联调与功能验证项目启动后用Postman先测几个核心接口。第一注册用户注意密码要用BCrypt加密存储不要明文入库。第二添加药品返回药品ID。第三创建服药计划设置remindTimes为“08:00,12:00,18:00”。第四等定时任务到点观察控制台或数据库里是否生成了提醒记录。第五调用确认接口模拟用户点击“我已服药”。整个联调过程里最需要耐心的部分是WebSocket连接验证。前端页面打开后后端的提醒一旦发送浏览器要能收到实时消息。如果发现前端连不上先检查后端的WebSocket端点和前端配置的地址是否一致再检查是否被网关或跨域拦截。跨域问题在前后端分离项目里非常常见解决方案就是在配置类里加一个CorsRegistryConfiguration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true); } }联动验证通过后建议把测试截图放进论文的“系统功能展示”章节这是很多导师最喜欢看的素材。截图要带着接口返回JSON和控制台日志一起截比单纯截个页面显得更有说服力。4. 部署说明与常见问题排查实录4.1 本地打包与运行部署的第一步是打包。在项目根目录执行mvn clean package -DskipTests结束后在target/目录下会出现一个smart-medicine-box-0.0.1-SNAPSHOT.jar。本地运行可以直接java -jar target/smart-medicine-box-0.0.1-SNAPSHOT.jar前提是本机的MySQL服务已经启动并且数据库脚本已经执行过。这里我遇到过很多次的问题打包时测试类报错或者测试类启动Spring上下文连不上数据库。所以打包命令里-DskipTests是必需品但注意这只会跳过测试执行不会跳过编译。如果连编译都过不了就得检查依赖里是否缺了Lombok注解处理器或者JDK版本不一致。打包出来后用java -jar启动时如果报“端口被占用”可以用lsof -i:8080在Linux或Mac下查看在Windows下用netstat -ano | findstr 8080找到占用进程kill掉再重新启动。对于演示环境也可以改server.port换一个端口比如8081。这个操作非常简单但在答辩现场用得非常频繁建议提前练一遍。4.2 Linux服务器部署实战如果你的演示环境是一台云服务器或者本地虚拟机部署步骤大概是这样的。先把JDK和MySQL装好然后上传jar包到/opt/app/目录。创建一个启动脚本start.sh#!/bin/bash APP_NAMEsmart-medicine-box-0.0.1-SNAPSHOT.jar nohup java -Xms256m -Xmx512m -jar /opt/app/$APP_NAME /opt/app/logs/app.log 21 echo PID: $!用nohup启动的好处是即使关闭SSH会话服务也不会停。查看日志用tail -f /opt/app/logs/app.log。如果要停止服务用ps -ef | grep smart-medicine找到PID执行kill -9 PID。MySQL远程连接这一节是很多同学的痛。如果你在本地用Navicat连不上服务器数据库先检查云服务器安全组或防火墙是否放行了3306端口再检查MySQL用户是否允许远程主机访问。一个比较稳妥的配置是不开放3306端口而是在服务器上直接执行SQL脚本让Spring Boot连接本地的localhost:3306这样更安全演示也不受影响。如果你还要部署前端静态页面可以利用Nginx做反向代理把/api路径代理到后端的8080端口server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }这个配置解决了一个最常见的部署问题前端页面和后端接口不在同一个域名端口下导致跨域或路径错乱。用Nginx统一入口后前后端就变成了同源访问省掉很多麻烦。4.3 高频问题与排查方法速查表我整理了一张毕设调试中最常遇到的排查表希望能帮你省下几个小时的搜索引擎时间。现象可能原因解决方案启动报Failed to configure a DataSource未配置数据源或依赖冲突检查application.yml的url、username、password确认mysql驱动存在连接数据库超时时区、SSL或网络问题URL加serverTimezoneAsia/Shanghai和useSSLfalse定时任务到点不执行启动类没加EnableScheduling在启动类上补注解检查cron表达式写的是否正确前端跨域报错未配置CORS添加CorsConfig或加Spring的跨域注解WebSocket连接闪断端口被代理占用或鉴权失败检查前端连接地址、是否有网关拦截项目启动慢且启动后CPU高依赖了太多不需要的Starter去掉无用依赖避免启动时加载不必要的自动配置中文乱码数据库字符集不对建库用utf8mb4URL加characterEncodingutf8数据库表字段与实体映射不上MyBatis驼峰转换没开配置map-underscore-to-camel-case: true这张表里的每一个坑都是我实际跑项目时遇到过不止一次的。尤其第二行和第三行出现频率最高很多人熬夜排查到凌晨最后发现只是少了一个注解或者一个URL参数。其实只要养成一个习惯启动报错先看完整堆栈别只看第一行和最后一行很多答案就在中间那几行Caused by里面。5. 论文LW写作与演示视频录制要点5.1 与源码对应的论文结构安排一套合格的毕设论文目录基本是固定的摘要、绪论、相关技术、需求分析、系统设计、系统实现、系统测试、总结与展望。但很多同学拿到源码后不知道论文怎么写我分享一个实操技巧把源码当成论文的“素材库”。每写到一章就去源码里找对应的设计证据。例如写“相关技术”时把Spring Boot、MyBatis-Plus、WebSocket的用途说清楚写“数据库设计”时直接引用init.sql里的DDL语句作为附录写“系统核心实现”时贴上ReminderService核心方法并配上状态流转说明。论文里最容易暴露的问题是“章节之间断层”。前文说设计了WebSocket实时提醒后面实现里却没有对应代码前面说支持用户角色权限实现里却只有一张user表。这个问题的根源是论文和代码没有对齐。这里我建议做一张“需求跟踪表”每条需求对应一个接口、一个页面和一个测试结果写论文的时候照着这张表逐项描述逻辑就缜密了。我还可以分享一个小技巧在论文的“系统测试”章节里不要只贴全绿的测试通过截图最好加一张边界场景的测试表格。比如“计划结束日期当天的提醒是否正常生成”“同一时间多条药品计划是否同时提醒”“漏服后二次提醒与用户确认是否会冲突”。这些表格一放上去论文的完成度立刻就不一样了。5.2 演示视频怎么录才不会翻车演示视频是答辩前最后一道防线时长控制在5到8分钟画质720p以上分辨率1920x1080。录制前先把系统数据清空从干净状态开始演示不要让评委看到一堆测试垃圾数据。演示顺序建议是这样首页 → 注册或登录 → 添加药品 → 创建服药计划 → 演示定时提醒触发 → 确认服药 → 查看提醒记录 → 展示后台统计数据。这里有个现场问题等待定时提醒触发可能要等好几分钟视频里不能干等。我的办法是把系统时间调整到计划时间前几分钟或者预留一个测试接口直接触发sendReminder然后用剪辑软件把等待过程剪掉只保留页面弹出提醒的那一瞬间。录制时麦克风声音要清楚语速不要太快每演示完一个步骤停顿两秒给答辩老师看清楚操作位置。录制工具方面我习惯用OBS Studio录屏再用剪映做简单剪辑和加字幕。字幕不是必须的但如果讲解有口音还是建议加上。视频里不要出现真实密码或敏感信息造一些测试数据即可比如“用户张三、药品阿莫西林、每天08:00/12:00/18:00”。最后导出时把文件命名成“系统演示.mp4”放到论文的附录或者压缩包里方便老师直接查看。6. 实战避坑经验与扩展建议6.1 我踩过的一些坑第一个坑是“重复提醒”。最开始我用固定cron表达式比如Scheduled(cron 0 0 8 * * ?)结果用户改了计划时间后旧任务还在跑新任务没建出来导致8点发出两条完全一样的通知。后来改成扫描方案后这个问题就消失了因为扫描方案只认数据库当前状态数据库里改了什么扫描任务就按什么执行。第二个坑是“时区错位”。数据库里存的时间是CSTJava里读出来变成UTC导致提醒差8小时用户明明8点的药系统11点才提醒。排查后我在JDBC连接串里固定了时区同时在代码里统一用Asia/Shanghai作为系统默认时区这才消停。这个坑特别隐蔽因为本地测试时可能一切正常部署到服务器后时间就对不上了。第三个坑是“论文查重”。很多同学把网上的模板和相似系统的文字直接粘到论文里查重率飙到80%以上非常危险。我的建议是论文里所有的技术原理描述用自己的话重写代码部分尽量用短代码块展示避免大段粘贴。因为查重系统对“核心功能描述”查得很严多写点自己项目的界面交互细节反而容易过。6.2 给这个项目做加分的扩展方向如果时间和精力允许我推荐从这几个方向给系统加分。第一加一个小程序或APP前端让提醒真正跟手第二给后端接入一个简单的Redis缓存存用户的最近服药记录在接口性能上做对比数据第三引入硬件模拟比如通过串口控制一个微型舵机或LED灯体现“智能药箱”的“智能”属性第四在论文里加一章“系统可靠性设计”讲一下定时任务幂等、数据库事务和日志埋点。我特别推荐第二种和第四种因为它们不依赖额外硬件而且论文里能写的东西非常丰富。比如Redis缓存章节你可以测一下从MySQL查和从Redis查的耗时差异把折线图放进论文这就是一个非常扎实的实验数据。这种细节往往就是答辩老师认可你的关键。扩展方向不要贪多选一个做深比列十个没做的好得多。最后再分享一个我常年跟学生强调的心得毕设最重要的是“讲得出逻辑”而不是“代码多华丽”。哪怕你只是用Spring Boot的Scheduled加一个扫描任务实现了提醒只要你能把为什么要扫描、为什么用这个时间窗口、漏服怎么处理讲清楚就已经超过很多人了。拿到别人的源码或者参考项目第一件事不是改文档而是自己在本地把项目跑起来再对照代码走一遍提醒链路。当你亲手把一条提醒记录从数据库补出来这个项目才算真正是你的答辩的时候也就自然有底气了。
返回列表