☰
基于SpringBoot的阿尔茨海默病健康管理APP毕设全解
2026/9/28 1:10:28 网站建设 项目流程

做毕设最怕的从来不是代码写不出来,而是选题一眼看过去就知道是"老古董":又是学生管理系统,又是图书借阅系统,评委老师看了都想睡觉。阿尔茨海默病健康管理APP这个方向,我前后带过好几个学生落地,每次讲答辩效果都很好——它既有医疗健康的社会价值,又有真实的业务场景可以拆,技术上还能把SpringBoot后端、移动端、数据库设计、权限管理、定时任务这些毕设核心考点全部串起来。这篇文章就把整个项目从选题思路到表结构设计、从核心功能实现到答辩话术完整拆一遍,给准备做SpringBoot方向计算机毕设的同学一个可以直接参考的底稿。

我先把话说在前头:这个题目真正讨巧的地方在于"健康管理"而不是"医疗诊断"。一旦涉及诊断、治疗建议,就需要严格的医疗资质和专业背书,学生根本讲不清楚,评委也不会在这个方向深挖。把定位放在"认知训练、用药提醒、健康档案、异常预警"这些偏日常照护的功能上,既安全又功能充实,工作量还好控制。

1. 选题评估:这个题目为什么适合做毕设,又难在哪里

1.1 先从家属视角看真实痛点

阿尔茨海默病最折磨人的不是患者本人,而是照护他的家人。我身边就有这样的例子:老人出门遛弯找不到回家的路,家人接到电话时人已经在几公里外的陌生小区里;每天要吃三四次药,子女上班一走就没人盯着,漏服一顿可能连着好几天状态都不对;老人自己在家无聊,情绪越来越低落,认知能力肉眼可见地往下滑。

这个APP要解决的就是这三件事:防止走失、按时服药、保持认知训练。再延伸一点,每一次用药记录、每一次训练结果、每一次家人观察到的异常行为,都应该沉淀成健康档案,方便复诊时直接拿给医生看。这就是整个系统业务逻辑的原点,所有功能模块都可以从这三件事推导出来。

1.2 工作量的边界控制:什么叫"够得着的复杂度"

毕设最忌讳的就是需求膨胀。有的同学上来就要做视频通话、IoT手环联动、AI人脸识别,最后每个功能都只写了个壳子,答辩一问核心逻辑就露馅。这个选题我建议把工作量卡在以下几点:

  • 患者端APP核心功能:认知训练、用药提醒、每日打卡、SOS一键求助。
  • 家属端APP核心功能:查看患者位置、接收SOS和离园预警、设置用药任务、查看健康档案。
  • 后端管理平台(Web):用户管理、患者档案、题库管理、训练记录统计、系统公告。
  • 公共能力:登录鉴权、消息推送、数据可视化看板、定时任务调度。

这套功能组合下来,去掉水分实打实的代码量在8000到12000行左右,一个人从零开始写,三到四周能完成核心部分,再留两周做联调和修Bug,时间上是完全可控的。

1.3 技术难度评级:中等偏上,具备高分潜力

SpringBoot本身不算难,难的是整体方案的完整度。这个项目里真正的技术难点集中在三块:一是患者端和家属端两套APP共用同一个后端,权限和数据隔离怎么设计;二是用药提醒的定时任务,患者端收不到推送怎么办;三是安全防盗,老年患者误操作把数据清了怎么办。这三块你在答辩时能讲清楚,就已经超过九成的同级项目。

2. 技术选型:SpringBoot为主干,移动端不要一上来就写原生

2.1 后端为什么锁死SpringBoot

不少同学纠结用SpringBoot还是用更老的SSH或者更重的Spring Cloud。我的建议很直接:毕设就用SpringBoot 2.7.x,别碰Spring Boot 3.x,也别碰微服务。原因有三点。

第一,SpringBoot 2.7.x的中文资料、博客、踩坑帖是最全的,遇到问题一搜就有答案,这对毕设周期来说太重要了。第二,2.7.x和大多数毕设常用的MyBatis-Plus版本完美兼容,不需要处理Spring Boot 3里Jakarta命名空间迁移那一堆破事。第三,SpringCloud微服务那套东西拿到毕设里纯属给自己添堵,一个单体应用拆出五六个服务,部署都要多花一倍时间,评委也不会因为你用了Nacos就给你加分,他们更关心你的业务逻辑能不能跑通。

我在GitHub上见过大量打着"SpringBoot"标题的实际是SpringBoot+Bootstrap混在一起的老项目,代码里还留着SpringMVC时代的XML配置。这种项目照抄下来答辩必翻车。老老实实用SpringBoot+MyBatis-Plus+MySQL这套组合,安全性、稳定性、易用性都是最均衡的。

2.2 移动端方案:原生Android还是跨平台

这个项目标题写的是"APP",很多学生会默认选Android原生或iOS原生。我的建议是优先考虑跨平台方案,比如Uni-app或者Flutter。理由很实在:

  • 原生Android开发需要配置Android Studio环境,不同系统版本适配问题多,写起来也慢。
  • Uni-app用Vue语法,前端同学几乎没有学习成本,一套代码能同时打包Android和iOS,演示的时候直接用HBuilder运行到手机模拟器,效果很直观。
  • 后端接口只要返回标准JSON,前端什么框架都能接,不会影响你后端SpringBoot的知识点展示。

如果你已经学过Android原生开发,用原生也没问题,但要注意包体积和内存优化这些细节,别让APP一打开就卡死。我个人实测下来,毕设场景用Uni-app的性价比最高——它不是一个"玩具框架",H5、小程序、App三端复用,毕业之后简历上也拿得出手。

2.3 完整技术栈清单

下面这份清单是我实际用过的组合,照着准备不会出大问题:

层级选型用途说明
后端框架SpringBoot 2.7.18核心Web框架
ORMMyBatis-Plus 3.5.x数据持久层,内置CRUD好用
数据库MySQL 8.0主数据库
缓存Redis 6.x验证码、Token、热点数据缓存
鉴权JWT + Spring Security登录态管理,双端权限控制
定时任务Quartz 或 Spring Schedule用药提醒、健康数据定时汇总
API文档Swagger / Knife4j接口调试与文档展示
移动端Uni-app(Vue3语法)患者端/家属端APP
管理后台Vue + Element-Plus管理员Web端
部署Docker + Nginx前后端分离部署

注意:JWT+Spring Security这个组合在毕设里是很大的加分项,因为传统的"Session+Cookie"方式在前后端分离和APP场景下不好使,你能主动用无状态Token方案,本身就说明你理解了HTTP接口的本质。

3. 数据库设计:先把三张核心表想明白,后面写代码顺一半

3.1 用户体系:一个APP两种身份的权限模型

整个系统最需要动脑子的表结构就是用户这块。阿尔茨海默病APP的患者端和家属端,本质上是"一个患者可以绑定多个家属,一个家属可以管理多个患者"的熟人照护关系。这里一定不要做成普通的单用户表加一个角色字段,而是要把"账号"和"患者档案"分开。

我的设计是四张表:

  • sys_user:存登录账号、密码、手机号、用户类型,用户类型区分管理员、家属、患者三种角色。
  • patient_info:存患者档案,包括姓名、年龄、ADL评分、MMSE评分、紧急联系人等。
  • family_bind:存家属和患者的绑定关系,一个家属可以绑多个患者,一个患者也可以有多个家属,用状态字段标记是否主绑负责人。
  • sys_role:存角色权限数据,配合Spring Security做功能级权限控制。

这样设计的直接好处是:家属登录后能切换查看不同患者的档案,患者登录后只能看到自己的内容,管理员在后台能看到所有数据。权限判断的SQL写起来也特别干净,一条关联查询就能拿到"当前操作者身份+管理范围"。

3.2 认知训练模块:题目与测试结果怎么存

认知训练是整个APP里功能量最大的模块。训练类型可以设计为:记忆类(图片记忆)、计算类(简单算术)、命名类(看图猜物)、语言类(词语复述)。每道题目需要支持单选、多选、判断三种题型,题库要能由管理员在后台动态维护。

我建议拆成三张表:

  • training_question_type:题型类型表,存题型名称和说明。
  • training_question:题目表,存题目内容、选项JSON、正确答案、所属题型、难度等级、逻辑删除字段。
  • training_record:训练记录表,存患者ID、题目ID、用户答案、是否答对、答题耗时、得分、训练时间。

这里有一个容易踩坑的细节:题目选项不要拆成一张选项表,直接在题目表里用一个JSON字段存选项列表。原因很简单——毕设项目没有多租户高并发需求,一张选项表只会让SQL多十几个JOIN,而JSON字段用MyBatis-Plus的JacksonTypeHandler就能优雅映射成一个List对象,查询和插入都方便。

3.3 用药提醒与健康档案

用药提醒需要一张medication_task表:服药时间点(时分秒)、药品名称、剂量、频次类型(每天/每周几次)、停药时间、所属患者ID、状态(启用/停用)。注意不要存成"早上8点"这种字符串,要存成08:00格式的Time类型,方便定时任务做时间比对。

健康档案我做了两类:一类是主观反馈,家属在APP里记录患者的情绪、睡眠、饮食、异常行为;另一类是客观记录,来自认知训练得分、用药完成率、打卡率等系统自动生成的指标。两类数据汇总到health_report表,前端用ECharts做折线图和雷达图展示趋势。表结构大致是:主键、患者ID、记录日期、指标类型、指标名称、指标数值、单位、记录来源、备注。

3.4 表数量控制在12到15张为最佳

经历过几个项目后我的感受是:表太少说明功能单薄,表太多说明你在给自己挖坑。12到15张表是最舒服的区间。这里面除了上面说的核心表,再补上:系统公告表、意见反馈表、消息通知表、操作日志表,整个系统的完整性一下就上来了。操作日志表用AOP切面注解的方式记录关键操作,这又是答辩时一个不错的技术亮点。

4. 核心功能实现:从登录鉴权到定时任务,一条链路打通

4.1 JWT双端登录与权限拦截

APP端的登录不能像网页那样依赖Cookie保持会话,所以我这里用的是JWT。用户登录成功后,后端用jwt生成一个包含用户ID、角色、过期时间的Token串返回给前端。前端每次请求在Header里带上Authorization: Bearer token,后端用一个拦截器统一校验。

具体代码逻辑大致是:

@Component public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行登录接口和注册接口 if (request.getRequestURI().contains("/auth/login") || request.getRequestURI().contains("/auth/register")) { return true; } String token = request.getHeader("Authorization"); if (token != null && token.startsWith("Bearer ")) { token = token.substring(7); try { Claims claims = JwtUtil.parseToken(token); request.setAttribute("userId", claims.get("userId")); request.setAttribute("userType", claims.get("userType")); return true; } catch (Exception e) { response.setStatus(401); return false; } } response.setStatus(401); return false; } }

这段代码是整个系统最基础也最关键的部分。写完之后记得把userId和userType存到request.setAttribute里,这样后续的业务代码里直接取,省得每个接口再解析一次Token。

Spring Security在毕设里我一般只用来做密码加密(BCrypt)和部分URL级别的拦截,不做太重的框架整合,因为自己写的拦截器反而更好向答辩老师解释。你要想展示对Spring Security的理解,可以加上"未登录访问受保护接口返回401而不是200"这样的细节描述。

4.2 家属端与患者端的数据隔离

两套APP共用一个后端,最容易出问题的就是数据越权:患者A登录后查到了患者B的档案。解决办法是在Service层增加一个"数据屏风"逻辑——所有涉及患者数据的查询,都必须先校验当前登录用户与目标患者的绑定关系。

MyBatis-Plus的QueryWrapper在这里非常好用:

@Override public List<HealthRecordVO> getPatientRecords(Long patientId) { // 校验当前用户是否有权限查看该患者 checkPatientAccess(patientId); QueryWrapper<HealthRecord> wrapper = new QueryWrapper<>(); wrapper.eq("patient_id", patientId); wrapper.orderByDesc("record_date"); List<HealthRecord> records = healthRecordMapper.selectList(wrapper); return records.stream().map(record -> ...).collect(Collectors.toList()); }

核心方法checkPatientAccess的逻辑是:先从Token里拿到当前用户ID和角色,如果是管理员直接放行;如果是家属角色,查family_bind表确认绑定关系;如果是患者角色,确认这个patientId就是自己。这段代码写成一个公共方法放在BaseService里,未来所有涉及患者数据的接口都能复用。

4.3 用药提醒的定时任务方案

用药提醒最考验可靠性。SpringBoot自带的@Scheduled注解可以定时扫描数据库里的medication_task表,找到当前时间点需要提醒的任务,然后通过消息推送服务把提醒发到前端。整体流程这样设计:

@Component public class MedicationRemindTask { @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次 public void scanMedicationTasks() { List<MedicationTask> tasks = medicationTaskMapper.selectList( new QueryWrapper<MedicationTask>() .eq("status", 1) .eq("remind_flag", 0) // 还没有被提醒过 ); for (MedicationTask task : tasks) { // 判断当前时间是否与计划的服药时间匹配 String now = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm")); if (task.getMedTime().equals(now)) { pushMessage(task); task.setRemindFlag(1); medicationTaskMapper.updateById(task); } } } }

这里有一个毕设中常见的问题:定时任务在服务器跑起来了,但是前端的APP收不到推送。原生的WebSocket能解决,但对毕设来说实现WebSocket客户端在Uni-app里还是有些麻烦。我的建议是把消息落库到message_record表,APP进入前台时主动拉取未读消息。这样既不需要复杂的推送通道,又能在答辩时讲清楚"消息推送的可靠性设计"。

更好的做法是结合Redis的过期键监听,把提醒时间精确到秒级别,不过考虑到阿尔茨海默病用药提醒分钟级精度已经足够,这个方案在核心实现上完全能自圆其说。

4.4 认知训练的前后端完整链路

训练模块前端是用户在APP上点选答案,提交后前端把答案传给后端,后端校验对错、算分、存档。需要注意两个业务点:

第一,题目顺序要随机。同一患者多次训练如果题目顺序固定,第二次训练时答案都能背下来,测得就不准了。后端提供一个"随机抽取十题"的接口:

public List<TrainingQuestion> getRandomQuestions(Long typeId, Integer limit) { QueryWrapper<TrainingQuestion> wrapper = new QueryWrapper<>(); wrapper.eq("type_id", typeId) .eq("deleted", 0) .last("ORDER BY RAND() LIMIT " + limit); return questionMapper.selectList(wrapper); }

ORDER BY RAND()针对十道题这种规模完全没有性能问题,不用过度优化。第二,训练结果要生成一个"当前得分环比"的趋势数据,方便家属看到患者近一个月的认知变化曲线,这块数据分析在管理后台用ECharts可视化展示。

4.5 防走失SOS与电子围栏

这个功能听着高大上,实现起来其实就是两个接口加一个定时任务。患者端APP上有"一键求助"按钮,点击后把GPS定位信息通过接口上报后端,后端立即往所有绑定的家属账号推送消息通知。电子围栏则是给患者设定家庭范围,定时任务检查患者最新的坐标是否超出范围范围,如果超出就触发预警。

GPS的获取用Uni-app自带的uni.getLocationAPI就行,拿到经纬度之后直接POST到后端。后端判断是否越界,我一般用简单粗暴的"经纬度矩形判断":设定中心点经纬度和半径,用Haversine公式计算距离,超过阈值就判越界。

这个功能在演示时特别容易出效果:模拟器上改一下经纬度坐标,立刻触发预警短信模板,评委一般都会眼前一亮。

5. 联调部署与翻车点:SpringBoot版本、跨域、打包一个都别跑

5.1 SpringBoot 3.x的坑,提前绕开

为什么一直强调用2.7.18而不是3.x?因为3.x里javax.*都迁移成了jakarta.*,很多教程和网上的老代码根本跑不起来,网上搜"SpringBoot 3 上传文件 报错"基本都是这些兼容问题。你若非要用3.x,JWT解析的依赖版本也要跟着换,工作量白白多出来一大截。另外SpringBoot 3最低要求JDK 17,不少教学机房还是JDK 8,直接卡死。

我的建议是:本地环境统一装JDK 8 + Maven 3.8 + SpringBoot 2.7.18。这套组合经过大量项目验证,稳定得让人心安。

5.2 跨域问题:APP开发最常见的报错

前后端分离项目在联调阶段,前端报"Access-Control-Allow-Origin"错误是最常见的。跨域的本质是浏览器的同源策略,你在HBuilder的浏览器里调试APP页面,端口是localhost:8080,接口地址却是localhost:9090/api,就触发了跨域。

后端全局解决跨域,SpringBoot里重写一个配置类即可:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600); } }

注意:如果用了allowCredentials(true),则allowedOriginPatterns不能用*,要写具体的域名来源。这个细节问我的人特别多,我特意强调一下。

5.3 文件上传与静态资源路径

毕设系统里会有患者头像上传、题目图片上传这些需求。上传的文件不能存到数据库里,而是存到服务器的某个目录,数据库只存文件路径。

SpringBoot默认静态资源映射在classpath:/static/下,但上传的图片不能打进jar包里,否则以后没法替换。正确做法是配置一个本地磁盘路径的映射:

spring: servlet: multipart: max-file-size: 10MB max-request-size: 50MB upload: dir: /usr/local/upload/

再写一个静态资源映射:

@Configuration public class UploadFileConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceLocations("file:" + uploadDir); } }

这个小问题不处理好的后果是:部署到Linux服务器后,图片全部404,答辩现场非常尴尬。

5.4 打包部署的完整过程

我用的是Maven打成jar包配合Docker部署的方式。核心步骤是:

  • 在项目根目录用mvn clean package -DskipTests打包。
  • 编写Dockerfile,基础镜像用openjdk:8-jdk-alpine,把jar包拷贝进去。
  • 用docker run -d -p 9090:9090映射端口。
  • 前端打包成dist目录,交给Nginx做静态托管,再用Nginx把/api开头的请求反向代理到后端容器。
FROM openjdk:8-jdk-alpine COPY target/dementia-health.jar app.jar EXPOSE 9090 ENTRYPOINT ["java", "-jar", "/app.jar"]

这么一套下来,答辩时你还能顺手补一句"项目使用Docker容器化部署,实现了环境一致性",又是一句加分话术。

6. 答辩演示:从数据准备到追问预案,帮你把项目讲到最大值

6.1 提前准备一套的"演示剧本"

很多同学项目做完了,答辩现场才开始演示,边点边想下一步点哪里,结果手忙脚乱,还容易暴露Bug。正确的做法是写一个演示脚本,把"先展示什么、后展示什么、每一步对应什么功能点"列得清清楚楚。

我建议的顺序是:

  • 先展示管理后台,添加一个患者的档案信息,上传头像。
  • 再展示患者端APP登录,做一次认知训练,提交后看后台统计图表是否更新。
  • 接着展示家属端APP,查看刚才那位患者的训练记录、用药计划、SOS预警。
  • 最后打开数据库,用一条SQL证明"患者端的数据是物理隔离的"。

整个流程控制在3到4分钟内,时间越短越好,重点是每一步都能对应到"我用到了什么技术"。

6.2 评委老师最喜欢追着问的几个问题

根据我带学生的经验,评委最常问的问题集中在以下几条,每一条我都给你一个可以背下来的回答思路:

  1. "你用的JWT和传统Cookie有什么区别?"——答:JWT是无状态的认证机制,服务器不需要保存会话信息,Token自包含用户身份和过期时间,更适合APP端调接口,也方便横向扩展。
  2. "训练题目打乱顺序用的是什么方法?如果题目有几万道,会不会慢?"——答:目前是ORDER BY RAND(),因为题库规模在百道量级,实测响应时间在10毫秒以内;如果规模大到万级,可以改用预置乱序编号字段或Redis里维护乱序列表,避免全表随机排序。
  3. "如果有100万用户同时访问,你的系统哪里会先扛不住?"——答:先瓶颈在MySQL的连接数和单表查询,我会引入Redis做热点缓存,对用户Token和常用档案使用缓存,同时通过分库分表或读写分离减轻数据库压力。
  4. "APP收不到推送的时候怎么办?"——答:目前的方案是消息落库+主动拉取,客户端进入前台和下拉刷新都会拉取未读消息,弥补了推送通道不稳定的问题。

这些问题问完,你还活生生的答案是,评委老师基本就满足了。

6.3 尾巴:几个能拉开差距的小细节

最后再分享几个我在实际操作中摸索出来的小技巧,都是不用花太多力气但很出效果的细节。

第一,项目里的README一定要写清楚环境版本、启动步骤、测试账号。有的评委不会现场看代码,但会打开README看你的工程化素养。第二,在APP启动页加一个版本号显示,并在管理后台做一个系统公告发布功能,这会让你的系统显得"活"而不"死"。第三,数据库字典表别省,把"药品频次类型""用户类型""训练题型""指标类型"都做成字典,写代码时不用到处硬编码,答辩时也能主动展示"数据字典设计是我系统设计阶段考虑过的模块"。

我从这些项目里最大的体会是:毕设拿高分的关键不是用了多高深的技术,而是你对自己项目的理解有多透。阿尔茨海默病健康APP这个题目,业务真实、技术合理、工作量适中,任何一个把上面内容真正走通的人,答辩都不会心虚。如果你正卡在选题或者中期阶段,这个方向值得认真考虑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询