ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SpringBoot+Vue居家养老健康管理系统:全栈开发与答辩避坑指南

2026/10/7 15:06:04 拓冰建站 浏览量
SpringBoot+Vue居家养老健康管理系统:全栈开发与答辩避坑指南 简介这是一套基于Java、SpringBoot、Vue与MySQL的居家养老健康管理系统完整毕业设计资源面向需要完成高分毕设、课程设计或期末大作业的计算机专业学生。系统围绕老年人健康档案管理、医疗信息记录、健康状况跟踪、用药提醒、健康监测与紧急呼叫等场景设计界面简洁、操作简便兼顾实用性与可维护性。压缩包共876个文件约39.09MB包含128个Java后端源码、69个Vue组件、158个JavaScript脚本、56个HTML页面与52个CSS样式另有SQL数据库脚本、论文文档及bat启动脚本等前后端代码与数据库一应俱全。项目经严格调试下载后无需修改即可在IDEA与Maven环境下部署运行MySQL 5.7以上配合Navicat即可完成数据管理。目前已有67人学习下载适合希望快速获得可运行项目、参考完整目录结构与排错思路的开发者。1. 居家养老健康管理系统一套能跑通、能答辩、能写进简历的 SpringBootVue 全栈方案居家养老健康管理系统这个题目每年毕业季都会被大量计算机专业学生选中原因很直接业务场景清晰、角色划分明确、技术栈主流而且答辩老师一听就懂。但真正动手时很多人卡在第一步——不知道从哪开始搭或者搭到一半发现表结构设计混乱、前后端联调报 401、论文里的架构图和代码对不上。这套基于 JavaSpringBootVueMySQL 的方案核心解决的就是「从零到能演示」这条链路后端用 SpringBoot 提供 REST 接口前端用 Vue 做管理端和老人/家属端页面MySQL 存健康档案、体检记录、用药提醒、紧急呼叫等数据。适合正在做毕业设计、课程设计或者想用一个完整项目补齐 SpringBootVue 全栈经验的人。下面按「先跑起来、再改明白、最后能讲清楚」的顺序拆开讲。2. 环境搭建与项目骨架把 SpringBootVueMySQL 三件套跑通2.1 后端骨架SpringBoot 项目结构与依赖选型拿到源码后第一件事不是急着改业务而是先确认后端能不能独立启动。常见的 SpringBoot 项目结构是controller / service / mapper / entity / config五层分包配合application.yml做多环境配置。依赖方面除了spring-boot-starter-web还需要mybatis-plus-boot-starter做 ORMmysql-connector-java连数据库lombok省 getter/setter如果要做登录鉴权再加jjwt。这里有个血泪经验SpringBoot 版本不要盲目追新2.7.x 和 3.x 在javax与jakarta包名上不兼容很多老教程的代码直接抄会报ClassNotFoundException。我一般会先看pom.xml里的 parent 版本再决定用哪套写法。!-- pom.xml 关键依赖片段 -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version !-- 稳定版兼容性最好 -- /parent dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies逻辑说明parent 锁定 SpringBoot 版本避免子依赖版本冲突MyBatis-Plus 在 MyBatis 基础上封装了 CRUD单表操作不用写 XMLMySQL 驱动 8.x 对应 MySQL 8.0 数据库如果本机装的是 5.7驱动版本可以降到 5.1.49但连接 URL 要加useSSLfalseserverTimezoneAsia/Shanghai。参数方面server.port默认 8080如果前端也跑在 8080 会冲突建议后端改 9090前端 devServer 代理到 9090。2.2 数据库初始化建库、建表与初始数据数据库是这套系统的地基。居家养老健康管理系统的核心表一般包括user用户表含老人、家属、管理员角色、health_record健康档案、checkup_report体检报告、medication_reminder用药提醒、emergency_call紧急呼叫记录。建库时字符集用utf8mb4排序规则utf8mb4_general_ci否则老人姓名里的生僻字会乱码。CREATE DATABASE elderly_care DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE elderly_care; CREATE TABLE user ( id bigint NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL COMMENT 登录名, password varchar(100) NOT NULL COMMENT BCrypt加密, real_name varchar(50) DEFAULT NULL, role varchar(20) NOT NULL COMMENT elder/family/admin, phone varchar(20) DEFAULT NULL, age int DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE health_record ( id bigint NOT NULL AUTO_INCREMENT, user_id bigint NOT NULL, blood_pressure varchar(20) DEFAULT NULL, blood_sugar decimal(5,2) DEFAULT NULL, heart_rate int DEFAULT NULL, record_date date NOT NULL, PRIMARY KEY (id), KEY idx_user_date (user_id, record_date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;逻辑说明user表用role字段区分三种角色避免建三张用户表导致登录逻辑分叉health_record用user_id record_date联合索引因为按老人查最近一周数据是最高频查询。参数上blood_sugar用decimal(5,2)而不是float血糖值 5.67 这种精度不会丢。初始数据至少插一个管理员账号密码存 BCrypt 哈希不要存明文答辩时老师一问「密码怎么存的」就能答上。2.3 前端 Vue 工程安装依赖与代理配置前端用 Vue 2 还是 Vue 3 取决于源码但 2024 年之后的项目建议 Vue 3 Vite。安装依赖时npm install卡住是高频问题先换淘宝镜像npm config set registry https://registry.npmmirror.com。启动前检查vite.config.js或vue.config.js里的代理把/api转发到后端 9090 端口否则前端请求会 404。// vite.config.js 代理配置 export default defineConfig({ server: { port: 5173, proxy: { /api: { target: http://localhost:9090, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) } } } })逻辑说明changeOrigin: true让后端收到的 Host 头是 localhost:9090避免某些鉴权逻辑判断域名失败rewrite把/api前缀去掉这样后端 Controller 不用每个都写/api。参数上如果后端已经配了server.servlet.context-path/api那 rewrite 就要去掉两者只留一个否则路径会变成/api/api/xxx。这一步跑通后前端能拿到后端返回的 JSON才算真正联调成功。3. 核心业务模块落地健康档案、用药提醒与紧急呼叫3.1 健康档案 CRUDMyBatis-Plus 分页与条件查询健康档案模块是使用频率最高的功能。老人或家属登录后能看到历史血压、血糖、心率记录管理员可以按姓名、日期范围筛选。用 MyBatis-Plus 的Page对象做分页配合LambdaQueryWrapper拼条件代码量比手写 XML 少一半。// HealthRecordServiceImpl.java Service public class HealthRecordServiceImpl extends ServiceImplHealthRecordMapper, HealthRecord implements HealthRecordService { Override public PageHealthRecord pageQuery(int pageNum, int pageSize, Long userId, String startDate, String endDate) { LambdaQueryWrapperHealthRecord wrapper new LambdaQueryWrapper(); wrapper.eq(userId ! null, HealthRecord::getUserId, userId) .ge(StringUtils.hasText(startDate), HealthRecord::getRecordDate, startDate) .le(StringUtils.hasText(endDate), HealthRecord::getRecordDate, endDate) .orderByDesc(HealthRecord::getRecordDate); return this.page(new Page(pageNum, pageSize), wrapper); } }逻辑说明eq的第一个参数是布尔条件只有 userId 不为 null 时才拼 SQL避免WHERE user_id null查不到数据orderByDesc保证最新记录在前。参数上pageNum从 1 开始pageSize建议默认 10前端传参时注意别传 0 或负数否则 MyBatis-Plus 会返回空列表但不报错排查起来很费时间。Controller 层用GetMapping(/page)接收参数返回Result.success(page)统一包装。3.2 用药提醒定时任务与消息推送的简化实现用药提醒的完整方案会涉及 WebSocket 或短信网关但毕业设计里用 Spring 的Scheduled定时任务 前端轮询就够演示。核心逻辑是每天固定时间扫描medication_reminder表把当天需要提醒的记录查出来写入notification表前端每 30 秒请求一次未读通知。Component public class MedicationScheduler { Autowired private MedicationReminderMapper reminderMapper; Autowired private NotificationMapper notificationMapper; // 每天早上7点、中午12点、晚上6点触发 Scheduled(cron 0 0 7,12,18 * * ?) public void scanAndNotify() { ListMedicationReminder list reminderMapper.selectList( new LambdaQueryWrapperMedicationReminder() .eq(MedicationReminder::getStatus, 1) .le(MedicationReminder::getStartDate, LocalDate.now()) .ge(MedicationReminder::getEndDate, LocalDate.now()) ); for (MedicationReminder r : list) { Notification n new Notification(); n.setUserId(r.getUserId()); n.setContent(请按时服用 r.getMedicineName()); n.setCreateTime(LocalDateTime.now()); n.setReadFlag(0); notificationMapper.insert(n); } } }逻辑说明cron表达式0 0 7,12,18 * * ?表示每天 7 点、12 点、18 点整执行status1表示提醒启用中startDate和endDate限定用药周期避免过期提醒还在推。参数上如果测试时不想等定时触发可以把 cron 改成0/30 * * * * ?每 30 秒跑一次验证逻辑后再改回去。注意Scheduled需要在启动类加EnableScheduling否则任务不生效这个坑我踩过不止一次。3.3 紧急呼叫WebSocket 实时通知的最小闭环紧急呼叫是居家养老场景的差异化功能。老人点一下按钮家属端和管理员端要立刻收到弹窗。用 SpringBoot 的ServerEndpoint做 WebSocket 端点前端用原生WebSocket对象连接比引入 STOMP 更轻量。Component ServerEndpoint(/ws/emergency/{userId}) public class EmergencyWebSocket { private static final MapLong, Session SESSIONS new ConcurrentHashMap(); OnOpen public void onOpen(Session session, PathParam(userId) Long userId) { SESSIONS.put(userId, session); } OnMessage public void onMessage(String message, PathParam(userId) Long userId) { // 老人端发送呼叫转发给所有家属和管理员 SESSIONS.forEach((id, s) - { if (!id.equals(userId) s.isOpen()) { try { s.getBasicRemote().sendText(紧急呼叫来自用户 userId); } catch (IOException e) { e.printStackTrace(); } } }); } OnClose public void onClose(PathParam(userId) Long userId) { SESSIONS.remove(userId); } }逻辑说明SESSIONS用ConcurrentHashMap存在线用户onMessage收到呼叫后遍历转发。参数上ServerEndpoint的路径里{userId}是路径参数前端连接时拼上自己的 ID例如ws://localhost:9090/ws/emergency/1001。注意 WebSocket 和 HTTP 共用一个端口时SpringBoot 需要额外配置ServerEndpointExporterBean否则端点注册不上前端会一直报连接失败。4. 避坑与排查前后端联调中最容易翻车的 5 个点4.1 跨域问题CORS 配置了还是报错现象前端请求后端接口浏览器控制台报Access-Control-Allow-Origin缺失但后端明明加了CrossOrigin。原因通常是拦截器或 Spring Security 在 CORS 之前执行导致预检请求被拦截。解决把 CORS 配置提到过滤器链最前面或者用WebMvcConfigurer全局配置不要只在 Controller 上加注解。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); } }注意allowedOriginPatterns和allowedOrigins的区别前者支持通配符且允许携带凭证后者在allowCredentials(true)时不能写*否则启动报错。4.2 登录 401Token 存了但后端解析不到现象登录成功前端把 token 存进 localStorage后续请求带上Authorization头但后端返回 401。原因多半是拦截器里取 header 的 key 写错了比如前端发Authorization后端取token。解决统一约定 header key并在拦截器里打印日志确认取到的值。String token request.getHeader(Authorization); if (StringUtils.hasText(token) token.startsWith(Bearer )) { token token.substring(7); }参数上Bearer后面有一个空格substring(7)正好截掉少截或多截都会导致 JWT 解析失败。4.3 数据库时区插入时间和显示时间差 8 小时现象Java 代码里new Date()是当前时间存进 MySQL 后查出来少了 8 小时。原因MySQL 的serverTimezone没配或者 JDBC URL 里写了serverTimezoneUTC。解决URL 改成serverTimezoneAsia/Shanghai同时 MySQL 全局时区设为08:00。mysql -uroot -p -e SET GLOBAL time_zone 08:00;如果用的是 MySQL 8.0还要确认my.cnf或my.ini里default-time-zone配置生效改完重启 MySQL 服务。4.4 MyBatis-Plus 字段映射驼峰转下划线失效现象实体类属性realName对应数据库字段real_name但查询结果里realName是 null。原因MyBatis-Plus 默认开启驼峰映射但如果手写了resultMap或者用了TableField没指定映射会断。解决检查application.yml里mybatis-plus.configuration.map-underscore-to-camel-case是否为 true默认就是 true不用改如果用了自定义 SQL在 XML 里加resultType而不是resultMap。4.5 前端打包后刷新 404Vue Router 模式选错现象npm run build后把dist放进 SpringBoot 的static目录首页能打开但刷新/health/list就 404。原因Vue Router 用了 history 模式服务器没配 fallback。解决要么改成 hash 模式URL 带#要么在 SpringBoot 里加一个转发配置把所有非 API 请求转发到index.html。Controller public class ForwardController { RequestMapping(value /{path:[^\\.]*}) public String forward() { return forward:/index.html; } }注意这个配置要放在 API 拦截器之后否则会把/api/xxx也转发掉。5. 论文与答辩把代码讲成故事把架构图讲出取舍5.1 论文里的架构图怎么画才不被挑刺很多人的架构图是「三层架构」模板表现层、业务层、数据层画完老师问「为什么用 MyBatis-Plus 不用 JPA」就答不上来。我的习惯是画两张图一张部署图标清楚浏览器、Nginx可选、SpringBoot 应用、MySQL 的物理关系一张模块图按「用户管理、健康档案、用药提醒、紧急呼叫、数据统计」五个模块画每个模块下面标注关键类名。这样老师顺着图问你顺着图答不会跑偏。图纸类型必须标注的内容常见扣分点部署图端口号、协议、数据库版本不写端口老师问「前端怎么访问后端」模块图模块名、核心类、依赖关系模块之间没有箭头看不出调用关系ER 图主键、外键、索引字段只画实体不画关系一对多没体现时序图登录、查询健康档案两条即可画太多导致重点不突出5.2 答辩现场最容易被追问的 3 个技术点第一个是「密码怎么存的」答 BCrypt 加盐哈希不要答 MD5MD5 已经被认为不安全。第二个是「紧急呼叫怎么保证实时性」答 WebSocket 长连接比轮询延迟低如果老师追问并发就说当前是单机内存存 Session生产环境可以换 Redis 发布订阅。第三个是「健康数据多了怎么优化查询」答联合索引user_id record_date并说明为什么不用单独索引user_id——因为查询总是带日期范围联合索引能覆盖。5.3 从毕业设计到简历项目的包装技巧如果想把这段经历写进简历不要写「实现了增删改查」要写「基于 SpringBoot Vue 实现居家养老健康管理系统设计 5 张核心表用 MyBatis-Plus 分页插件支撑健康档案查询通过 WebSocket 实现紧急呼叫实时通知前端用 Vue Router 守卫做角色权限控制」。面试官如果问「遇到什么困难」就讲跨域和时区这两个坑真实且能体现排查能力。最后说一句我自己的习惯代码写完先别急着写论文把项目跑一遍把每个报错截图存下来这些截图就是论文「测试章节」的素材也是答辩时证明「确实自己做过」的证据。希望帮到你。本文还有配套的精品资源点击获取