资讯详情

SpringBoot+Vue养老公寓管理系统:前后端分离实战与部署详解

📅 2026/10/24 4:41:23 | 华诺云谱 👁 阅读
SpringBoot+Vue养老公寓管理系统:前后端分离实战与部署详解
SpringBootVue的大健康养老公寓管理系统这两年我在好几个技术交流群里都看到有人问属于典型的“需求明确、技术栈主流、功能点丰富”的毕设/课设选题。养老行业数字化本身就是一个持续升温的方向加上题目自带“大健康”三个字直接帮你把系统功能范围框定了老人档案、健康数据、服务流程、费用管理这几块做完论文的“研究意义”部分基本不用发愁。这个项目源码最核心的价值在于它覆盖了一套前后端分离管理系统该有的完整链路。后端有SpringBoot的接口分层、MySQL的数据持久化、MyBatis或JPA的数据库操作前端有Vue2/Vue3的组件化页面、Axios接口调用、Element-UI或Element Plus的表格表单连登录认证、角色权限、图表统计这类加分项也都包含在内。对毕设、课设或者纯学习的人来说这套东西拆开来每一样都不算难但合在一起能让你把大学四年学的东西真正串起来。下面我按自己的实操经验把这套系统的设计思路、代码细节、部署流程、避坑清单全部拆开讲一遍。1. 项目概览与场景定位1.1 这个系统到底解决了什么问题先想清楚一个事养老公寓的管理员每天在忙什么安排老人入住退房、记录紧急联系人、跟踪老人每天的血压血糖、分配护工上门服务、登记家属探访、月底对账收钱。这些事如果靠Excel和微信通知效率低是一方面更麻烦的是数据容易丢、容易错尤其是健康数据这种东西一旦出现记录断层真出了健康问题谁都说不清楚责任。这套管理系统就是把上面这些线下流程搬到线上做成一个具有“业务闭环”的管理平台。所谓闭环就是每一次操作都有来龙去脉护工给老人测了血压血压值会进健康档案健康档案出现异常系统会提醒护士跟进护士做的服务记录会自动关联到工单和费用模块。数据不再是一个个孤立的信息孤岛而是串成一条业务链这对养老公寓的实际管理是有真实价值的。1.2 为什么说它是毕设/课设的上上之选我见过太多学生选了一个“超市管理系统”或者“图书馆管理系统”答辩的时候被老师问一句“你这个系统和现成的相比有什么优势”直接就卡住了。养老公寓管理系统的选题优势在于它的业务场景足够真实、有社会意义而且功能模块天然丰富不会出现“做了三个CRUD页面就无事可做”的情况。从技术角度讲这个题目能自然地把以下考核点全带上权限管理管理员、护士、护工不同角色能看到和操作的菜单不同健康数据管理涉及大数据量的定时记录、趋势图表展示关系型数据库设计老人表、床位表、健康数据表、工单表、账单表至少五六张表关联前后端交互JSON格式传输、分页查询、条件筛选、文件上传老人头像、体检报告这些点正好是答辩时老师最爱问的。你随便挑一个展开都能讲两三分钟不会出现冷场。2. 技术选型与整体架构2.1 前后端分离为什么成了标配现在做管理系统基本默认SpringBoot Vue这套组合。SpringBoot负责后端接口内置Tomcat打成一个Jar包就能跑Vue负责页面渲染通过Nginx或者直接本地Node环境访问后端API。前后端分离最大的好处是职责清晰后端只提供纯JSON数据接口前端只负责页面展示和交互找工作面试的时候被问到“你们项目怎么联调的”你也能讲出一套实际经验。我自己拿到这套源码之后第一件事是看它的前后端目录结构。一个标准的这套技术栈项目前端应该长这样vue-project ├── public ├── src │ ├── api # 封装Axios请求 │ ├── assets # 静态资源 │ ├── components # 公共组件 │ ├── router # 路由配置 │ ├── store # 全局状态Vuex或Pinia │ ├── views # 页面组件 │ ├── utils # 工具函数 │ ├── App.vue │ └── main.js ├── package.json └── vite.config.js后端一般是Maven标准结构springboot-project ├── src │ └── main │ ├── java │ │ └── com/xxx │ │ ├── controller # 控制层 │ │ ├── service # 服务层 │ │ ├── mapper # 数据访问层 │ │ ├── entity # 实体类 │ │ ├── config # 配置类 │ │ └── common # 通用返回结果、异常处理 │ └── resources │ ├── mapper # MyBatis XML文件 │ └── application.yml └── pom.xml这个结构本身就是一套加分模板。写论文或者写说明文档的时候直接把架构图配文字描述写清楚老师就知道你不是拿来就抄而是真看懂了工程组织方式。2.2 数据库表结构怎么设计才够用又不复杂很多同学拿到一个毕设项目第一反应就是往数据库里疯狂加表加到最后一两张表根本用不上。我的建议是养老公寓管理系统把核心表控制在一张底图加一张业务主链的规模就够。我拆这套源码时发现它的表结构设计比较克制核心大概有这几张sys_user系统用户表包含用户名、密码、角色类型elder_info老人信息表包含姓名、身份证号、家属电话、入住时间、健康状态bed_info床位表包含楼栋、楼层、房间号、床位号、状态health_record健康数据表包含老人ID、血压、血糖、心率、体温、测量时间service_order服务工单表包含服务类型、护工ID、老人ID、完成状态、时间fee_record费用记录表包含费用类型、金额、缴清状态这几张表的设计逻辑是用户表管登录老人表管基础档案床位表管公寓资源健康表和工作表管日常业务费用表管财务。前后关联通过外键和逻辑ID串起来例如health_record里存elder_idservice_order里存elder_id和handler_id。具体建表语句里约束要体现出来老人身份证号要设唯一约束健康数据表的测量时间要设置默认当前时间费用表的金额字段推荐用decimal(10,2)。这些细节答辩的时候随口说出来会让老师觉得你基础扎实。3. 核心功能模块拆解3.1 老人档案与床位管理最基础也最见功夫养老公寓管理系统最核心的信息资产就是老人档案。这不仅仅是“姓名年龄电话”那么简单完整档案应该包含基本信息姓名、性别、出生日期、身份证号、民族联系信息家属/紧急联系人姓名、关系、电话入住信息入住日期、入住类型自理/半自理/全护理、所属楼栋房间健康概况过敏史、慢性病标签、医嘱摘要附加材料身份证照片、体检报告上传在这个模块的实现上我比较推荐前端做一个带“Tab页”的详情弹窗。点列表里的“详情”按钮能切换基本信息、健康记录、费用记录等分页签。因为老人档案字段太多了全部摊在一个表单里会让用户崩溃。床位管理可以做得相对简单一点毕竟是辅助模块。维护一张床位的状态字段0表示空闲、1表示已入住、2表示维修中前端用一个用颜色区分的表格展示楼层分布图就能实现“可视化空床查询”。这个思路虽然简单但展示效果很好答辩演示的时候老师扫一眼就能看懂。3.2 健康档案与预警闭环大健康系统的灵魂这个模块是整个系统能不能叫“大健康”的关键。如果只是存几条血压记录然后列表展示那就和普通台账没有区别。要想体现“智能感”至少要加一层健康预警逻辑。我建议的实现方式是这样在health_record表设计时增加一个status字段然后在后端保存健康数据的Service层里做一次判断。比如老年人的血压正常范围可以大致定在收缩压90-139mmHg、舒张压60-89mmHg如果录入的收缩压超过140系统自动把这条记录标记为“异常”同时生成一条待办提醒。前后端的联动效果是健康数据列表里异常记录会高亮标红首页提醒面板出现“王某某今日血压偏高请关注”。源码里的健康趋势图用到了ECharts近30天血压折线图是个很稳的加分功能。前端用ECharts直接读接口返回的健康记录列表在computed函数里把血糖血压数据拆成两个数组绘制双Y轴折线图。这个图展示在老人详情页里答辩时演示老人历史血压走势比任何文字描述都有说服力。3.3 服务工单与费用结算把系统从查询工具升级为业务流程工具如果只有档案和健康记录这个系统顶多算个电子台账。加上服务工单才是真正上了业务流程。工单模块的核心链路是护士给老人登记一个需求比如“张阿姨需要测餐后血糖”生成一条待处理工单护工登录系统后在“待办工单”列表里看到任务完成后更新状态。页面状态流转用tag标签展示待接单是蓝色、进行中是橙色、已完成是绿色、已取消是灰色。费用模块相对独立但非常加分。养老公寓的费用按月度产生包含床位费、护理费、餐饮费三类基础费用可能还有医疗耗材等额外费用。后端可以写一个定时任务每月1号给所有在住老人生成当月的应收账单。定时任务用Spring的Scheduled注解实现一个月跑一次。答辩的时候讲这个设计直接体现你理解“自动化任务”的应用场景。前端账单页还能引出一个实用功能费用可视化。用饼图展示当月总费用构成用柱状图展示近6个月公寓营收趋势。这些数据都从fee_record表按月份聚合查询出来SQL里写GROUP BY语句就能实现。3.4 统一登录与角色路由前后端权限控制的落地实现很多人忽略登录模块觉得不就是查一下用户名密码吗这是大错特错。权限设计和登录安全是答辩老师最爱深挖的点因为这部分能判断你是真的理解系统设计还是只会复制粘贴。这套系统的登录实现采用的是JWTJSON Web Token方案。前端输入账号密码后端校验通过后返回一个token前端把token存到localStorage或sessionStorage后续每次请求都带上这个token后端用拦截器校验。密码存储要加密老项目常用MD5或SHA-256散列存储。考虑安全更有说服力可以展示一下BCrypt加盐加密方案Spring Security的BCryptPasswordEncoder可以直接用。角色权限的核心实现思路不同角色登录成功后后端返回不同的菜单列表和操作权限标识前端根据这些数据动态生成侧边菜单。管理员看到的是“系统管理”“全部报表”护工看到的只有“我的工单”“健康录入”。这样实现以后前端路由有动态权限后端接口也有拦截校验两条线并行这在毕设问答的时候就是核心武器。4. 关键代码与实操实现4.1 后端一个完整接口的“一生”以一个老人的健康数据分页查询为例完整链路是这样的。Controller层只负责接收参数和返回结果RestController RequestMapping(/api/health) public class HealthRecordController { Autowired private HealthRecordService healthRecordService; GetMapping(/list) public Result getHealthList(RequestParam Integer elderId, RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 10) Integer pageSize) { PageInfoHealthRecordVO pageInfo healthRecordService.queryByElder(elderId, pageNum, pageSize); return Result.success(pageInfo); } }Service层做业务判断比如插入健康数据时自动判定是否异常Service public class HealthRecordServiceImpl implements HealthRecordService { Autowired private HealthRecordMapper healthRecordMapper; Override public int addHealthRecord(HealthRecordDTO dto) { HealthRecord record new HealthRecord(); BeanUtils.copyProperties(dto, record); // 核心业务逻辑健康预警判定 record.setStatus(0); if (dto.getSystolicPressure() 140 || dto.getDiastolicPressure() 90) { record.setStatus(1); // 异常 } if (dto.getBloodSugar() 7.0) { record.setStatus(1); } return healthRecordMapper.insert(record); } }Mapper层用MyBatis的注解和XML都行注解写法适合简单SQLXML写法适合动态条件拼接select idselectByElderId resultTypecom.example.entity.HealthRecord SELECT * FROM health_record WHERE elder_id #{elderId} ORDER BY measure_time DESC /select这套逻辑分层告诉了我们一个非常关键的原则Controller不要写业务Service不要堆SQLMapper只认SQL不认业务。很多毕设代码被导师批为“不规范”毛病往往就是Controller里写了半天业务逻辑Service层空空的看起来非常尴尬。4.2 前端列表页表单页的落地写法Vue前端核心页面写法我以“健康数据列表页”为例拆解。Element UI的表格带上分页组件这是整个管理系统里出现频率最高的布局template div el-card el-form inline el-form-item label老人姓名 el-input v-modelqueryParams.elderName placeholder请输入姓名 clearable / /el-form-item el-form-item label状态 el-select v-modelqueryParams.status el-option label全部 value / el-option label正常 value0 / el-option label异常 value1 / /el-select /el-form-item el-form-item el-button typeprimary clickfetchList查询/el-button /el-form-item /el-form /el-card el-table :datatableData border stripe el-table-column propelderName label老人姓名 width120 / el-table-column propsystolicPressure label收缩压 width100 / el-table-column propdiastolicPressure label舒张压 width100 / el-table-column propbloodSugar label血糖 width100 / el-table-column propmeasureTime label测量时间 width180 / el-table-column label状态 template #default{ row } el-tag :typerow.status 1 ? danger : success {{ row.status 1 ? 异常 : 正常 }} /el-tag /template /el-table-column /el-table el-pagination background layouttotal, prev, pager, next :totaltotal v-model:current-pagequeryParams.pageNum current-changefetchList / /div /template这个页面包含的技术点条件查询表单、表格绑定、分页组件、状态标签动态渲染。写类似页面完全可以直接抄这个模板改一改字段就行。如果觉得这种具体写法是“比较老的Element UI版本”换成Element Plus基本形态也差不多只是组件命名和导入方式略有差异。4.3 数据库初始化脚本要点这套源码一般会附带一个SQL文件拿到手先不要急着整个导入打开看一眼再导。我建议重点检查这几项表名前缀是否统一sys_、elder_、health_这种字符集是否utf8mb4不然后端存emoji或特殊字符会报错主键策略是否自增配置了ASSIGN_ID反而可能在普通MySQL库上出问题初始数据有没有管理员账号和测试数据没有的话你自己得先造一批手动造测试数据也别嫌麻烦这是非常值得的十分钟。造数据的核心原则要体现“业务真实性”比如给王阿姨造连续一个月的血压记录每天早晚各一条中间穿插几条偏高的异常记录。这样列表有翻页、图表有曲线、预警有数据演示效果和答辩说服力瞬间提升。5. 从源码到本地运行的完整部署流程5.1 后端启动三步走拿到源码第一步要在本地把环境准备好。我建议使用统一的开发环境配置清单环境要求推荐版本说明JDK1.8或11SpringBoot 2.x最稳定搭配MySQL5.7或8.08.0注意驱动和时区问题Maven3.6推荐用IDEA自带MavenNode.js14以上Vue项目构建IDEIDEA/VS Code后端用IDEA前端随习惯后端启动具体步骤用IDEA打开后端项目文件夹等待Maven自动下载依赖。如果下载慢去Maven仓库配置阿里云镜像。新建数据库schema导入SQL脚本。注意默认字符集和排序规则设置。修改application.yml里数据库连接配置核心是url、username、password三件套。spring: datasource: url: jdbc:mysql://localhost:3306/elderly_health?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver然后直接运行启动类的main方法。看到控制台输出“Started”加上Tomcat started的日志后端就启动成功了。测试接口可以用浏览器直接访问登录接口通常支持GET后期调试用POST。5.2 前端启动常见坑位前端项目需要先装依赖再启动npm install npm run serve这里最大的坑是npm install非常慢或者抛出一堆错误。遇到这个问题先别慌大概率是网络源的问题切换到国内镜像源基本能解决npm config set registry https://registry.npmmirror.com如果node-sass之类的包报错错得很离谱多半是Node版本和依赖不匹配。框架版本如果在package.json里写固定版本你就按固定版本装对应Node版本写的是^范围符号可以把Node切到14或16版本试一次。前端启动成功后控制台会显示Local地址一般是http://localhost:8080。这时你会发现页面能开但数据都是空的或者报跨域错误。跨域问题是因为前端地址是8080后端接口地址是8081或9090端口不同浏览器默认拒绝跨域访问。解决办法优先在后端写一个全局跨域配置类这样开发联调和后续打包部署都能顺畅配合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); } }如果前端封装了Axios还被跨域拦大概率是请求头带了自定义token字段导致的预检请求失败配合上面的allowedHeaders配置就能解决。5.3 打包知识后端Jar 前端Dist本地开发环境跑通了还不算完答辩前如果能把项目包成可交付的产品形态会显得专业很多。后端打包特别简单mvn clean package -DskipTests打完包会在target目录下生成一个jar文件直接java -jar target/xxx.jar前端打包npm run build打包完会生成dist目录里面是纯静态文件。正式部署时推荐用Nginx托管静态文件同时配置反向代理把/api请求转发到后端Jar的地址server { listen 80; server_name localhost; location / { root /usr/share/nginx/html/dist; 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; } }这一套如果自己能独立讲明白面试官问你“上线部署了解吗”你就有了真实的故事可以讲。6. 常见问题与排查技巧实录6.1 数据库连接时区错误与驱动找不到项目一启动就报“Public Key Retrieval is not allowed”或者“Server returns invalid timezone”这类错误基本就是MySQL 8.0配置问题。URL连接串上显式指定serverTimezoneAsia/Shanghai驱动用com.mysql.cj.jdbc.Driver。注意URL中也要加上allowPublicKeyRetrievaltrue参数尤其是数据库用户用了caching_sha2_password插件时。有的源码配套的是MySQL 5.7的驱动配置用的旧驱动类com.mysql.jdbc.Driver在MySQL 8.0数据库上会直接报ClassNotFoundException或者连接失败。统一换成新的驱动即可。6.2 前端页面能打开但接口404这种问题大多是后端接口路径和前端调用路径对不上。前端axios封装的baseURL如果是/api后端Controller的RequestMapping也写了/api那就重复了。排查方法直接看浏览器F12里的Network面板看具体请求的URL然后跟后端的Controller做对比。我处理这种问题一般是先去掉一层的/api前缀保持前后端只保留一层统一的访问标识。还有一种是SpringBoot内置Tomcat端口被占用启动时直接报Web server failed to start。Windows下用netstat -ano | findstr 8081查出占用PID任务管理器结束进程。更省事的办法是直接修改application.yml中的server.port换一个端口但是前端代理配置和目标端口也要同步改。6.3 表格数据能查出但中文乱码中文乱码一般发生在三个环节一是MySQL表字符集不是utf8mb4二是IDEA控制台显示乱码其实是显示问题不是数据问题三是数据库连接URL没有指定characterEncoding。如果数据库已经建好了直接修改表字符集ALTER TABLE elder_info CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;如果IDEA控制台启动日志乱码加上-Dfile.encodingUTF-8到VM options里。这个操作建议做不然每次启动看中文乱码特别烦。6.4 前端npm install总失败绝招除非是文件路径或权限问题npm install失败90%是慢或者依赖冲突。慢换镜像源依赖冲突删掉package-lock.json和node_modules重新装。老项目还会遇到node-sass这种“毒瘤”直接卸载换成sassdart-sassnpm uninstall node-sass npm install sass -D源码里如果大量使用了/deep/或::v-deep这种样式穿透写法换成:deep()写法兼容新版本。7. 进阶玩法从毕设到实战的差距在哪这一节写给做完源码、准备答辩的人同时也写给想把这个项目写进简历的人。毕设源码跑通只能让你拿60分想拿90分必须做出下面这些增量。7.1 补上演示数据和真实场景我见过很多学生演示的时候数据库里只有两条测试记录老师还没开始提问他自己先尴尬了。一套完整的演示数据至少要有10个以上老人档案、覆盖不同健康状态的记录、至少两个月的费用流水、网格状的工单状态分布。数据不要随便乱造越真实越好。比如老人年龄和健康数据要匹配90岁的老人血压正常范围按年轻人标准算显然不合理。这虽然只是演示细节却直接反映你对业务的理解是否到位。7.2 给项目加一个突出亮点保持原有功能不变挑一个点做好做深就已经足够加分。我比较推荐这三个方向健康数据大屏让首页把最有冲击感的健康统计今日异常人数、各楼层健康评分、本月服务完成率平铺展示视觉效果好且实现不复杂。消息通知功能健康数据异常时自动生成系统通知页面右上角红点提示管理员点开能看到预警列表。Excel导出报表月度健康统计报表的Excel导出功能后端用EasyExcel或POI实现这几乎是实际工作中的刚需功能答辩时也非常能打。这三个点里面Excel导出和消息通知的代码网上现成教程非常多工作量集中在一个后端接口和一个前端按钮。而且它们不会破坏原有主流程风险很低属于“花小钱办大事”的精准投资。7.3 答辩演示顺序与讲解要点答辩演示顺序比大多数人想象中更重要。千万别一上来就讲登录注册那是整套系统最无聊的部分。我建议按这个顺序先用30秒讲项目背景与大健康管理痛点带出你要完成的目标切换到首页大屏展示今日核心指标让老师第一眼看到“数据智能看板”演示老人档案录入与健康数据录入展示表单校验和标签状态演示一条完整的健康异常预警流程输入异常数据列表标红首页提醒更新演示服务工单从生成到完成的流程闭环最后切到系统管理展示不同角色登录后看到的菜单差异以及JWT拦截效果这个顺序有一条完整的主线讲完老师基本上对你的项目已经有了“这学生确实是自己做的”的印象。结束后如果老师问“哪里是你觉得最有挑战的”不要讲登录讲健康预警的业务判定逻辑或跨域解决方案都可以这些细节才体现思考深度。8. 一些个人经验和心态建议这套项目源码我前前后后帮不同的人看过不下十遍每一次都能发现新的可优化点也每一次都能感觉到毕设类项目和真实企业项目之间的差距。这种差距不在技术栈而在对业务的理解深度上。比如健康预警阈值文档里定的是140/90实际很多大型医院对老人的血压控制线会更宽分为普通老年人和糖尿病老年人两套标准。如果你在代码里写成可配置的阈值字典表并且答辩时说出“不同老人健康基线不同”这个理由这一句话就能把项目的业务分析能力拔高一个档次。我个人的操作习惯是拿到源码先不改代码先把数据库跑起来把数据造一批然后完整走一遍系统流程把每个功能点的截图存好。这个动作至少有三个好处一是能迅速找出源码里有哪些功能是没做完整的“半成品”二是能发现哪些页面之间的跳转逻辑有问题三是写论文的时候素材直接就有。真的不要一上来就闷头改代码、换框架那是糟蹋时间和源码。最后再分享一个小技巧如果你打算把这个项目写进简历一定要在本机跑起来之后录一段3分钟左右的演示视频包括登录、数据录入、异常预警、图表展示这几个关键动作。面试官基本没有时间现场登你系统看但短视频他一定会扫一眼。这是完全属于你自己的“项目说明书”比简历上写的熟练程度和项目经验都有说服力。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑