
1. 这个毕设题目为什么值得做社区养老背后的真实痛点如果你正在准备计算机毕设又在选题列表里看到了“安康市社区老人管理系统”“基于SpringBoot的社区长者健康照护平台”这类题目先别急着把它当成一个普通的增删改查项目来写。这个题目我去年完整做过一版从 SpringBoot 后端到 Vue 前端再到数据库设计和部署答辩全部走了一遍。今天把设计思路、技术选型理由、核心功能拆解和踩坑记录都整理出来给准备做“银发人群智慧社区服务系统”或类似题目的同学一个真实参考。这类题目看起来简单但真正做起来会发现它不是一个“老人信息登记表”的电子化而是一套需要支撑社区日常照护服务的业务系统。社区里老年人数量逐年增加纸质档案容易丢、信息更新不及时社工上门服务得靠微信电话来回沟通老人健康指标分散在体检单、家庭医生记录和子女的只言片语里。社区工作人员最需要的不是“录入信息”而是知道哪些老人需要重点关注、今天的服务工单有没有人处理、上个月健康异常的老人有没有被跟进。把这些需求转换成系统功能才是这个题目的核心价值。1.1 社区场景下到底谁在用这个系统很多人做毕设时容易陷入“我是管理员我能全都能看”的思维但真实社区里角色是分层的社区网格员和社工日常走访记录、健康指标采集、接收工单、填写服务回执家属查看老人的健康动态、接收预警提醒、对服务进行评价老年人本人能用最简单的界面发起求助或查看基本信息系统管理员维护人员权限、配置数据字典、查看统计报表我在设计时一开始只做了管理员和普通用户两个角色后来被指导老师问了一句“社工和家属看到的东西能一样吗”才意识到角色权限才是这类系统的题眼。不同角色看到的数据范围、能执行的操作完全不同这也是答辩时最容易被追问的地方。1.2 题目里三个关键词安康市、社区、老人“安康市”是地名可以直接替换成任何一个城市本质是“属地化管理”“社区”决定了系统的边界不是大型医院也不是全市级平台而是以社区网格为单位“老人”决定了交互方式和数据维度相比年轻人老人数据更需要亲属参与和线下服务配合。我最后把系统名称定为“社区长者健康照护平台”因为“照护”比“管理”更贴合业务。系统里不只有老人档案的增删改查还有健康指标记录、照护计划、服务工单和预警推送这才是题目里“银发人群智慧社区服务”的真实含义。1.3 和普通“老人信息管理系统”的本质区别普通系统维护的是静态属性姓名、身份证号、地址、电话。但这个题目里藏着动态业务老人今天的血压是否异常上周安排的定期回访有没有完成家属是否在系统上看到了预警这些问题需要工单流转、健康记录和通知机制来回答。所以我在功能设计时定了一条主线一切功能都围绕“发现需求 - 创建工单 - 执行服务 - 反馈结果 - 家属确认”这条闭环展开。健康记录和走访记录是输入工单是流转载体统计报表是输出。只要这条闭环成立系统就算立住了。2. 为什么选SpringBoot Vue前后端分离选型背后的真实理由技术选型不能只写“因为流行”答辩老师会追问原因。我当时的方案是后端 SpringBoot MyBatis Plus MySQL前端 Vue Element UI再用 JWT 做认证。整个组合跑下来非常稳下面把每个选择背后的思考说清楚。2.1 SpringBoot在毕设场景下的优势对比传统 SSM 结构SpringBoot 最大的价值是“去配置化”。以前搭 SSM 需要写一堆 XML 配置文件很多同学在配置数据源和事务的时候就已经崩溃了。SpringBoot 通过自动配置和内嵌 Tomcat让项目能快速启动代码结构也清晰。对社区老人管理系统这类业务没有高并发没有复杂分布式需求核心是快速把业务逻辑做好。SpringBoot 自带starter机制想加什么依赖直接加非常适合毕设这种需要在有限时间内交东西的场景。我建议使用 SpringBoot 2.7.x 版本配合 Java 1.8而不是一上来就追 SpringBoot 3 和 Java 17。很多教程和依赖包对旧版本更友好毕设追求的是稳定不是踩新版本的坑。这个建议在热词里也出现过“springboot版本太高”相关问题足以说明版本选不好会卡一整天。2.2 前后端分离到底“分离”了什么很多同学的毕设题目里自带“前后端分离”这几个字但答辩时需要回答清楚分离的不是“前端代码和后端代码放不同文件夹”而是“前端不再依赖后端生成页面后端只提供数据接口”。传统 JSP 模式是后端用模板引擎渲染 HTML前后端代码耦合在同一个工程里。前后端分离后Vue 负责页面路由、数据绑定和交互SpringBoot 只返回 JSON 数据。这样有几个实际好处前端开发和后端开发可以并行接口定好后各做各的换一套前端界面不用动后端逻辑部署时可以分别使用Nginx和Java服务扩展性好我在项目里做到了“后端接口返回数据前端页面上渲染”没有直接返回过带 HTML 的页面答辩时老师一眼就能看懂这是真正的前后端分离。2.3 为什么我没有直接套若依框架做 Java 毕设的人很难绕开若依这类脚手架它自带了用户管理、权限管理、代码生成器确实省时间。但我最后选择从零搭建有两个原因第一若依整合了大量代码很多逻辑不是自己写的答辩时若追问某个权限拦截器或数据权限是怎么实现的很难答清楚。第二这个题目并不复杂自己搭建一套轻量级的权限方案反而更容易掌控。用 SpringBoot JWT HandlerInterceptor 做一套简单的登录拦截代码量不大但能讲清楚每个环节。当然如果时间真的来不及用若依二次开发也能过关只是你需要额外花时间理解它的权限体系否则项目成了“框架作品”而不是“你的作品”。2.4 整体技术栈清单层次选型版本说明后端框架SpringBoot2.7.6稳定版本ORM框架MyBatis Plus3.5.3简化单表CRUD数据库MySQL8.0关系型数据存储前端框架Vue 22.6.14组件化开发UI组件库Element UI2.15.14后台管理界面状态管理Vuex3.6.2用户状态/token管理认证方式JWTjjwt 0.9.1无状态认证接口文档knife4j4.0.0接口自测与展示这里特别注意Vue 2 和 Element UI 的老搭档非常成熟对毕设来说不容易出错。如果你熟悉 Vue 3 Element Plus 也可以但我当时为了少踩坑选了 Vue 2后期证明这是个明智决定。3. 核心功能拆解从老人档案到健康照护闭环这个系统的功能点很多但真正决定系统价值的只有几个核心模块。我按业务优先级把它们串起来你会发现每个功能都不是孤立的。3.1 老人档案管理里的“不见于论文”的细节老人基本档案谁都写难的是字段设计。我最初的表只有姓名、性别、年龄、住址、电话做完发现根本不够用。后来根据社区实际业务补充了这些关键字段身份证号保存时做脱敏处理只展示前3位和后4位中间用星号代替出生日期由身份证自动提取年龄用当前日期计算而不是手工填年龄字段紧急联系人至少一位用于健康预警时短信通知健康标签高血压、糖尿病、独居、失能、轻度认知障碍等多个标签在列表页用不同颜色Tag展示网格区域编码这个字段非常关键后面做按片区的统计报表全靠它列表页做了等级色块高风险老人显示红色中风险橙色普通绿色。这样社工一打开页面就知道今天优先回访谁。这些设计虽然不复杂但体现了对业务场景的理解。3.2 健康照护计划与工单流转让服务“闭环”照护计划是“预定的服务”比如每周给独居老人上门量血压一次、每月电话慰问两次。工单是“实际执行的服务”由计划生成也可以是临时发起的求助。我设计了这样的工单状态流转待受理管理员/家属创建等待社工接单执行中社工接单并上门已完成社工填写回执已评价老人或家属对服务打分关键点在于工单一旦创建它就应该出现在接单人列表里并且状态变化要记录时间线方便查看每个环节耗时。我还给工单增加了优先级字段普通、紧急、特急。特急工单自动向管理员发送站内通知保证不会被遗漏。3.3 三端一屏家属端、社工端、管理端怎么设计系统不是单一人群使用我按角色拆了三个前端入口角色界面形式核心功能家属H5页面移动端适配查看老人健康记录、接收预警、评价工单社工管理后台中的独立模块处理工单、录入健康指标、填写走访记录管理员管理后台主页人员维护、整体监控、数据统计、数据字典配置三端共用同一个后端通过角色权限控制接口访问范围。家属端我特意放大了字号按钮做得很大因为实际使用的可能是老人的子女甚至是老人本人。这个细节很加分答辩时老师会觉得你考虑到了用户体验。3.4 健康数据预警与提醒模块的设计思路健康资料不能只存不看。我在 health_record 表里记录了血压、血糖、心率、血氧等指标并设置了预警规则血压高压超过160或低于90触发预警血糖空腹高于7.0mmol/L触发预警心率高于100或低于60触发预警同一指标连续两次异常时自动生成一条提醒记录预警消息推送给家属和网格员。实现方式不复杂后端定时任务每小时扫描一次当天数据命中规则后插入 alert_record 表并通过 WebSocket 主动推送到在线前端。这样家属端可以看到“今天血压偏高”的提醒社工端会自动生成回访任务。3.5 一个完整的用户故事从“老人求助”到“工单闭环”我拿一个场景来说明系统怎么串起来一位老人早上感到头晕家属在外地先在家属端点击“求助”按钮填写“老人摔倒需要帮助”。管理员收到特急工单立刻分配给离老人最近的社工。社工接单上门测了血压填写了回执“血压190/110已陪同至社区医院。”老人子女登录家属端看到回执和血压记录点了确认并对服务进行了评价。整个过程在系统里留下了完整轨迹。这个用户故事我没有写到论文里但在答辩时讲出来非常有效。它证明系统不是摆样子的而是能真实承载业务流程的。4. 数据库表设计这些表和字段是踩坑后确定的数据库设计决定了系统的上限。我一开始只建了老人表和用户表后来随着业务扩展表结构改了三次。下面是最终用起来很顺的核心表结构。4.1 核心表关系我用文字梳理一下核心表的关系用户表 sys_user统一保存管理员、社工、家属的登录账号通过 role 字段区分老人表 elder保存老人基本信息、健康标签、网格区域家属关系表 elder_family老人与家属的多对多关系照护计划表 care_plan记录服务类型、周期、下次执行时间服务工单表 service_order记录工单类型、状态、优先级、指派人和回执内容健康记录表 health_record记录老人每次健康指标数据走访记录表 visit_record社工走访时填写的现场情况预警记录表 alert_record触发预警规则后生成的提醒老人和家属之间通过关系表关联而不是在老人表里直接放“家属姓名”字段因为一个老人可能有多个家属一个家属也可能关联多个老人。逻辑外键关联不使用数据库物理外键这是主流实践也方便后续分表和迁移。4.2 软删除和状态字段的取舍老人、工单这类关键业务数据我全部使用 delete_flag 做逻辑删除。原因是健康记录和工单都有审计需求不应该被物理删除。比如一个社工误删了老人的健康档案如果没有软删除历史记录就全丢了。工单状态我用 status 字段配合枚举类管理而不是让每个状态变成单独的布尔字段。比如工单不只是 status 已完成还需要记录完成时间、完成人、回执内容。状态流转由后端统一控制前端只展示状态标签。4.3 健康指标的动态存储方案健康指标是系统里最值得研究的数据结构。老人可能测血压、血糖、心率、血氧、体温如果为每个指标建一个字段表会越来越宽扩展新指标还得改表。我采用了一种更灵活的方式CREATE TABLE health_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, elder_id BIGINT NOT NULL, metric_type VARCHAR(32) NOT NULL COMMENT 指标类型血压/血糖/心率等, metric_value VARCHAR(64) NOT NULL COMMENT 指标值如130/85, unit VARCHAR(16) DEFAULT NULL COMMENT 单位mmHg/mmol/L/次每分, measure_time DATETIME NOT NULL COMMENT 测量时间, operator_id BIGINT COMMENT 记录人社工或家属, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, delete_flag TINYINT DEFAULT 0 );这样做的好处是新增一个指标只需要在数据字典里加一个 metric_type不用改表结构。缺点是查询一个老人的多个指标时需要行转列或者在前端分组展示。我在 Service 层拼接返回结构把最近一次血压、血糖等数据组装成 Map前端展示起来就很方便。4.4 索引与字段设计经验有几个实际经验值得记下来年龄字段永远不要存用出生日期计算身份证号需要加密或脱敏存储别明文展示时间字段都存 datetime不要存字符串排序和统计都更可靠金额如果出现用 decimal 而不是 float高频查询字段加索引elder_id、status、create_time、metric_type、notification_time我吃过一个亏刚开始把“网格区域”忘了结果做“各片区老人数量统计”时发现没有字段可查只能返工补建 region_code。如果题目里带有城市、社区等关键词这个字段一定在最初就要设计进去。5. 前后端分离联调实战接口约定、JWT认证与分页那些坑写代码只是第一步前后端联调才是真正耗时的地方。下面这些内容是真实项目里反复遇到的问题记录下来比任何教程都有用。5.1 统一返回结构让前端不再“一处一换”刚开始后端接口返回格式不统一有的返回 List有的返回 Map前端 axios 拦截器没法做统一处理。后来我定了一个通用响应类public class ResultT { private Integer code; private String msg; private T data; } public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMsg(success); result.setData(data); return result; }前端 axios 封装里统一判断 code 是否为 200不是则弹出错误消息。这样后端只要保证接口返回 Result 结构前端代码就非常干净。这个约定在联调第一周就确定下来后边省了几十次扯皮。5.2 跨域问题开发环境最常见的一堵墙前端跑在 8050 端口后端跑在 8080 端口浏览器会拦截跨域请求。解决方式有两种要么在后端写全局 CORS 配置要么用 Nginx 反向代理。Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOriginPattern(*); config.addAllowedHeader(*); config.addAllowedMethod(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }注意生产环境如果用 Nginx 把前端静态资源和后端接口放在同一个域名下就不需要这个配置了。我的做法是开发环境用 CORS部署时靠 Nginx 反向代理两边都顺利。5.3 JWT认证轻量而有效的权限方案前后端分离项目没有 Session 依赖我用 JWT 做登录令牌。登录接口校验用户密码后生成 token前端存到 localStorage请求时放到 Authorization 请求头。后端写一个 HandlerInterceptor 校验 token。public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(Authorization); if (token ! null token.startsWith(Bearer )) { try { Claims claims JwtUtil.parse(token.substring(7)); request.setAttribute(userId, claims.get(userId)); return true; } catch (Exception e) { response.setStatus(401); return false; } } response.setStatus(401); return false; } }这个方案比起引入 Spring Security 轻量很多但能讲清楚认证流程。对于毕设项目中低并发的管理场景完全足够。我在前端路由守卫里做了判断没有 token 只能访问登录页token 过期后自动跳回登录页。5.4 分页查询PageHelper 和 el-pagination 的配合分页是管理系统的标配。后端用 MyBatis Plus 的 Page 或者 PageHelper前端用 Element UI 的表格加分页。这里有一个经典坑PageHelper 只对紧跟着的下一句 SQL 生效。如果你在 startPage 之后又执行了其他查询分页就会失效。正确写法是把查询条件全部准备好再调用分页查询GetMapping(/list) public ResultPageElder list(RequestParam Integer pageNum, RequestParam Integer pageSize, RequestParam String keyword) { PageElder page new Page(pageNum, pageSize); LambdaQueryWrapperElder wrapper new LambdaQueryWrapper(); if (StringUtils.hasText(keyword)) { wrapper.like(Elder::getName, keyword) .or().like(Elder::getPhone, keyword); } wrapper.eq(Elder::getDeleteFlag, 0) .orderByDesc(Elder::getCreateTime); return Result.success(elderService.page(page, wrapper)); }前端传 pageNum 和 pageSize 即可。搜索条件尽量放在请求参数里不要塞到 URL 路径中这样前端维护逻辑更清晰。5.5 联调中踩过的几个真实bug第一个是日期格式问题。前端传到后端的时间字符串和后端返回到前端的日期格式对不上最后靠 JsonFormat 统一解决了JsonFormat(timezone GMT8, pattern yyyy-MM-dd HH:mm:ss) private LocalDateTime createTime;第二个是 Long 类型 ID 精度丢失。当主键使用雪花 ID 时Long 传到 JavaScript 会丢精度需要转成字符串。我这里主键用了自增 ID所以没遇到但如果你用了 MyBatis Plus 默认雪花 ID就要特别注意。第三个是 Vue Router 的 history 模式部署后刷新 404。这个问题在本地开发没问题部署到 Nginx 后刷新页面就报 404原因是路由没有匹配到后端资源。解决办法是在 Nginx 配置里加一行location / { try_files $uri $uri/ /index.html; }这三个问题都是实际开发中高频出现的提前处理掉能让项目整体顺滑很多。6. 部署与答辩从本地跑通到演示不出丑项目做完只是第一步如何部署和演示决定了最终效果。这一部分分享我自己的实操流程。6.1 前后端打包与部署细节后端打包非常简单mvn clean package java -jar target/health-care-system.jar前端打包npm run build打包后生成 dist 文件夹我更喜欢用 Nginx 部署而不是把 dist 硬放到 SpringBoot 的 static 目录。因为前后端分离的意义就是要分开部署。我用一个嵌套的 Nginx 配置server { listen 80; server_name localhost; location / { root /home/www/health-front/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://localhost:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }这样浏览器访问 80 端口就是前端页面接口请求 /api/ 自动转发到后端 8080。部署完后刷新页面不会 404跨域问题也消失了。6.2 演示数据和演示脚本的准备很多同学系统开发完了一打开数据库是空的答辩演示时现场添加数据效果非常差。我强烈建议提前造一批演示数据老人档案不少于 10 条覆盖独居、高血压、失能等标签健康记录至少包含一组正常数据和一组异常数据工单覆盖待受理、执行中、已完成、已评价四种状态家属端账号已经关联好老人打开就能看到提醒答辩演示脚本可以按照业务故事线走登录管理员 → 查看今日工单 → 切换到社工处理工单 → 录入一条血压异常记录 → 系统触发预警 → 家属端收到提醒并评价。整个过程大概 5 分钟却完整展示了闭环。6.3 答辩中我遇到的几个高频问题把这些问题准备好现场心里不慌“为什么用 JWT 而不是 Session” 答前后端分离架构下Session 依赖 Cookie 和服务器状态JWT 无状态、可跨域、方便移动端和前端共用。“SpringBoot 相比 SSM 的优势” 答自动配置、内置容器、简化依赖管理降低项目搭建成本同时保留 Spring 生态的能力。“如果用户并发量大了怎么办” 答当前是低并发管理场景后续可以通过集群部署、Redis 缓存、数据库读写分离来扩展。“健康数据如何保证准确” 答数据录入做必填校验和范围校验测量数值超过合理范围给出提示关键指标支持二次确认。6.4 后续扩展从毕设到实际可落地的智慧养老平台如果你想让这个项目更出彩可以加一些扩展点对接蓝牙手环或血压计通过定时任务把设备数据写入 health_record引入腾讯云短信预警时给家属发短信把系统部署到小程序老人子女使用更方便。我在做这套系统时最大的体会是不要把它当成“交差”的工具而是当成一次完整的产品设计训练。每张表、每个状态、每次接口联调背后都有一个真实的业务场景。只要顺着“社区里老人到底需要什么帮助”这个问题去设计这个毕设就不会差。最后分享一个小技巧答辩前把所有代码 Git 提交好写清 commit message展示的时候可以说一句“项目全程采用 Git 进行版本管理”这个细节往往比框架本身更能给答辩老师留下好印象。希望这篇内容能让你的安康市社区老人管理系统做得更稳、更顺。