简介:这份资源是面向计算机相关专业学生与Java初学者的一套微信小程序养老院管理系统完整源码,可直接用于毕业设计、课程设计或自学练手。项目采用Java后端搭配微信小程序前端,后端基于JDK1.8、MySQL5.7与Maven3.3构建,部署于Tomcat7,数据库设计借助Navicat11完成,小程序端支持HBuilderX与微信开发者工具,技术栈贴近企业级开发主流方案。压缩包共1359个文件,约32MB,包含121个Java源文件、244个Vue组件、164个JS脚本、49个wxss与48个wxml页面文件,以及SQL数据库脚本、说明文档和表结构文档,覆盖前后端与数据库全链路。目前已有86人学习下载。读者可从中获得完整可运行的项目代码、清晰的目录结构、数据库表设计参考与功能模块说明,便于快速理解养老院信息管理与服务请求的业务流程,并在此基础上二次开发或撰写论文。
1. 养老院系统源码拆解:一套 Java + 小程序 + MySQL 的毕设能跑多远
很多同学拿到「养老院系统源码(java+小程序+mysql+LW).zip」这类压缩包时,第一反应是解压、找 README、双击启动类,然后被一堆报错劝退。它本质上是一套典型的计算机毕业设计项目:后端用 Java(多数是 SpringBoot 或 SSM)提供接口,前端是微信小程序负责老人、家属、护工三类角色的交互,数据落在 MySQL,外加一份 LW(论文)文档。它解决的不是什么高精尖问题,而是把「入住登记、健康档案、用药提醒、家属探视预约、护工排班」这些养老院日常事务搬到线上。适合谁?适合正在做软件工程、计算机毕业设计、需要一套能讲清楚架构又能现场演示的同学,也适合想借一个完整项目练手 Java 后端 + 微信小程序全栈的初学者。别指望它直接商用,但把它跑通、讲透、改出两三个自己的功能,答辩和简历都够用了。
2. 环境准备:把 Java、MySQL、小程序三端先对齐
这套项目能不能跑起来,八成取决于环境版本对不对。血泪经验是:别一上来就装最新版,先看源码里的pom.xml和application.yml,让工具去迁就代码,而不是反过来。
2.1 JDK 与 Maven 的版本选择
Java 后端项目最常见的是 JDK 8,少数新一点的用 JDK 11 或 17。判断方法很简单,打开pom.xml看<java.version>或<maven.compiler.source>。如果写的是 1.8,就老老实实装 JDK 8,别用 JDK 21 去硬跑,否则javax包找不到、Lombok 编译报错会让你怀疑人生。
# 查看当前 JDK 版本,确认是不是项目需要的版本 java -version # 查看 Maven 版本,3.6 以上基本都能用 mvn -v # 在项目根目录执行,先把依赖拉下来,看有没有拉取失败 mvn clean install -DskipTestsmvn clean install里的-DskipTests很关键,毕设项目自带的测试类经常因为数据库没连上而失败,先跳过测试把包打出来。如果依赖下载慢,检查 Maven 的settings.xml有没有配国内镜像,这一步不解决,后面全是超时。
2.2 MySQL 建库与导入 SQL
MySQL 建议用 5.7 或 8.0,两者在语法上差异不大,但 8.0 默认的caching_sha2_password认证方式可能让老版本 JDBC 驱动连不上。导入流程如下:
# 登录 MySQL,创建数据库,字符集用 utf8mb4 避免中文乱码 mysql -u root -p CREATE DATABASE nursing_home DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 退出后用命令行导入项目自带的 sql 文件 mysql -u root -p nursing_home < nursing_home.sql导入后一定要use nursing_home; show tables;确认表都进去了。常见坑是 SQL 文件里带了CREATE DATABASE和USE语句,直接导入会覆盖你刚建的库,先打开 SQL 文件看一眼头部。
2.3 微信小程序的开发者工具配置
小程序端用微信开发者工具打开,重点改两个地方:一是app.js或config.js里的后端接口地址,把localhost换成你电脑的局域网 IP,否则真机预览时请求发不出去;二是project.config.json里的appid,没有正式 appid 就选「测试号」。开发者工具的「不校验合法域名」选项在本地调试阶段必须勾上,不然所有http请求都会被拦。
提示:后端接口地址不要写
127.0.0.1,真机调试时手机访问的是自己,不是你的电脑,用ipconfig查到的局域网 IP 才有效。
3. 后端启动与接口联调:让 Java 服务真正跑起来
环境对齐后,核心工作就是让 SpringBoot 启动类不报错,并且小程序能拿到数据。这一章把配置、启动、联调三件事讲透。
3.1 application.yml 里必须改的四个参数
打开src/main/resources/application.yml,不管项目怎么命名,数据库相关配置跑不出这几项:
spring: datasource: url: jdbc:mysql://localhost:3306/nursing_home?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver # 如果项目用了 Redis 做缓存或验证码,这里也要改 redis: host: localhost port: 6379四个必改点:url里的数据库名要和实际建库一致;username和password换成自己的;serverTimezone必须加,否则 MySQL 8.0 会报时区错误;driver-class-name在 MySQL 8.0 下用com.mysql.cj.jdbc.Driver,老驱动com.mysql.jdbc.Driver会警告。改完保存,别急着启动,先确认 MySQL 服务是运行状态。
3.2 启动类与端口冲突排查
找到带@SpringBootApplication注解的类,右键运行main方法。控制台出现Started XxxApplication in x seconds才算成功。如果报Port 8080 was already in use,说明端口被占:
# Windows 下查占用 8080 端口的进程 netstat -ano | findstr :8080 # 根据最后一列的 PID 结束进程,或者直接改 application.yml 里的 server.port taskkill /PID 进程号 /F更省事的做法是直接在application.yml里把server.port改成 8081 或 9090,避免和别的项目打架。启动成功后,浏览器访问http://localhost:8080,如果返回 Whitelabel 页面或一段 JSON,说明服务活着。
3.3 用 Postman 验证登录接口再对接小程序
小程序联调前,先用 Postman 把关键接口跑一遍,能省掉大量「到底是谁的错」的扯皮。以登录接口为例:
# POST 请求,Content-Type 选 application/json # 请求体 { "username": "admin", "password": "123456" }如果返回code: 200和 token,说明后端没问题,问题只可能在小程序端。常见返回code: 500的原因是数据库里没有对应账号,去user或admin表里手动插一条,密码字段注意是明文还是 MD5,很多毕设项目直接存明文,也有存 MD5 的,看代码里的加密逻辑。
3.4 小程序 request 封装与跨域处理
小程序端一般会封装一个request.js,统一处理 baseURL 和 token。核心逻辑如下:
// utils/request.js const BASE_URL = 'http://192.168.1.100:8080'; // 换成你的局域网 IP function request(options) { return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + options.url, method: options.method || 'GET', data: options.data || {}, header: { 'content-type': 'application/json', 'token': wx.getStorageSync('token') || '' // 登录后存的 token }, success: (res) => { if (res.data.code === 200) { resolve(res.data); } else { wx.showToast({ title: res.data.msg || '请求失败', icon: 'none' }); reject(res.data); } }, fail: reject }); }); } module.exports = request;BASE_URL必须是局域网 IP,header里的 token 从本地缓存取,登录成功后用wx.setStorageSync('token', res.data.token)存进去。小程序没有传统浏览器的跨域概念,但后端如果配了 Spring Security 或拦截器,未登录请求会被拦,这时候要么放行登录接口,要么在请求头带上 token。
4. 数据库表结构与核心业务逻辑:看懂养老院系统的骨架
跑通之后,能不能改功能、能不能答辩讲清楚,取决于你是否读懂了表结构和业务流转。这一章挑最核心的几张表和一条完整业务链来讲。
4.1 老人、家属、护工三张主表的关系
典型养老院系统至少有这么几张表:elder(老人)、family(家属)、nurse(护工)、health_record(健康档案)、medication(用药记录)、visit(探视预约)。关系上,一个老人可以关联多个家属,一个护工负责多个老人,健康档案和用药记录都挂在老人 ID 下。
| 表名 | 关键字段 | 作用 |
|---|---|---|
| elder | id, name, age, room_no, nurse_id | 老人基本信息,nurse_id 指向负责护工 |
| family | id, name, phone, elder_id | 家属信息,elder_id 关联老人 |
| health_record | id, elder_id, temperature, blood_pressure, record_time | 健康数据,按时间追加 |
| medication | id, elder_id, drug_name, dosage, take_time | 用药提醒,take_time 用于定时推送 |
看懂这张表,你就知道为什么「家属查看老人健康档案」这个功能要跨family和health_record两张表查——先通过家属 ID 找到 elder_id,再用 elder_id 查健康记录。
4.2 一条完整的「用药提醒」业务链
以用药提醒为例,从护工录入到家属收到通知,链路是这样的:
// 伪代码,展示业务层逻辑 public void addMedication(MedicationDTO dto) { // 1. 校验老人是否存在 Elder elder = elderMapper.selectById(dto.getElderId()); if (elder == null) throw new BizException("老人不存在"); // 2. 插入用药记录 Medication med = new Medication(); med.setElderId(dto.getElderId()); med.setDrugName(dto.getDrugName()); med.setTakeTime(dto.getTakeTime()); medicationMapper.insert(med); // 3. 查询该老人的家属,推送提醒(毕设里常简化为写一条 message 表) List<Family> families = familyMapper.selectByElderId(dto.getElderId()); for (Family f : families) { messageService.send(f.getId(), "用药提醒:" + dto.getDrugName()); } }这段逻辑里,selectByElderId是自定义的 Mapper 方法,需要在 XML 或注解里写 SQL。很多同学改功能时只改了 Controller 没改 Mapper,结果数据查不出来,排查半天。记住:Controller 负责收参,Service 负责逻辑,Mapper 负责 SQL,三层缺一不可。
4.3 分页查询与条件筛选的 SQL 写法
后台管理页面几乎每个列表都要分页,MySQL 用LIMIT实现:
-- 查询第 2 页,每页 10 条,按入住时间倒序 SELECT e.*, n.name AS nurse_name FROM elder e LEFT JOIN nurse n ON e.nurse_id = n.id WHERE e.name LIKE CONCAT('%', #{keyword}, '%') ORDER BY e.check_in_time DESC LIMIT #{offset}, #{pageSize};offset的计算公式是(pageNum - 1) * pageSize,这个计算放在 Java 层做,别在 SQL 里算。LEFT JOIN保证即使老人没分配护工也能查出来,用INNER JOIN会漏数据。LIKE CONCAT是防止 SQL 注入的写法,别直接字符串拼接。
5. 避坑与常见问题:那些让毕设翻车的细节
这一章全是踩过的坑,按「现象 → 原因 → 解决」写,遇到问题对号入座。
5.1 小程序请求返回 404 或 500
现象:Postman 能通,小程序里全是 404 或 500。原因:baseURL 写成了localhost,或者接口路径少了前缀(比如后端配了server.servlet.context-path: /api,小程序里没加)。解决:把 baseURL 换成局域网 IP,对照后端application.yml里的context-path补全路径前缀,再用开发者工具的 Network 面板看实际请求地址。
5.2 中文乱码从数据库一路乱到页面
现象:老人姓名在数据库里是问号,页面上也是乱码。原因:建库时字符集用了latin1,或者 JDBC url 没加characterEncoding=utf8。解决:重建库用utf8mb4,JDBC url 补上useUnicode=true&characterEncoding=utf8,已经乱码的数据只能重新录入。
5.3 时间字段差 8 小时
现象:数据库存的create_time和实际时间差 8 小时。原因:MySQL 8.0 时区配置和 JVM 时区不一致。解决:JDBC url 加serverTimezone=Asia/Shanghai,或者在application.yml里配spring.jackson.time-zone: GMT+8,两个都加上最稳。
5.4 真机预览白屏但模拟器正常
现象:开发者工具里一切正常,手机扫码预览白屏。原因:没勾「不校验合法域名」,或者手机和电脑不在同一局域网。解决:详情 → 本地设置 → 勾选「不校验合法域名、web-view、TLS 版本以及 HTTPS 证书」,确认手机连的是同一个 WiFi。
5.5 Maven 依赖下载失败导致启动类找不到符号
现象:mvn clean install报一堆Cannot resolve symbol。原因:依赖没下全,或者本地仓库有损坏的 jar。解决:删掉本地仓库里对应目录重新下,或者执行mvn clean install -U强制更新快照。国内网络环境建议配阿里云镜像,能省一半时间。
6. 二次开发与答辩加分:把毕设改成自己的东西
跑通只是及格线,想让这套养老院系统在答辩时不被问倒,得动手改出点自己的东西。我一般会从三个方向切入:加一个「健康数据可视化」页面、把用药提醒接上微信订阅消息、给后台加一个数据导出功能。
先说健康数据可视化。小程序端用ec-canvas引入 ECharts,后端加一个接口按时间范围返回老人的体温和血压数据:
// 小程序页面里初始化图表 import * as echarts from '../../components/ec-canvas/echarts'; function initChart(canvas, width, height) { const chart = echarts.init(canvas, null, { width, height }); canvas.setChart(chart); // 数据从后端接口拿,x 轴是日期,y 轴是体温 chart.setOption({ xAxis: { type: 'category', data: dateList }, yAxis: { type: 'value', min: 35, max: 42 }, series: [{ type: 'line', data: temperatureList, smooth: true }] }); return chart; }这个改动涉及后端新接口、小程序新页面、图表库引入三处,答辩时能讲清楚数据怎么从 MySQL 流到图表上,比单纯说「我做了个 CRUD」有说服力得多。
再说用药提醒接微信订阅消息。小程序端在用户授权后拿到templateId,后端在takeTime到达时调用微信的订阅消息接口推送。这一步的坑在于:订阅消息需要用户主动点击授权,且一次授权只能推一条,毕设演示时提前授权好,别现场翻车。
最后是数据导出。后台管理加一个「导出 Excel」按钮,后端用 EasyExcel 或 POI 把老人列表写成 xlsx。核心代码就几行:
// 用 EasyExcel 导出,实体类上加 @ExcelProperty 注解 EasyExcel.write(response.getOutputStream(), Elder.class) .sheet("老人信息") .doWrite(elderMapper.selectList(null));导出功能看着简单,但答辩老师很吃这一套,因为它体现了你懂「数据落地」而不只是「数据展示」。
我自己的习惯是:拿到任何一套毕设源码,先跑通,再挑一个模块从数据库到页面完整重写一遍,改的过程中自然会暴露你没理解的地方。这套养老院系统源码的价值不在于它本身多完善,而在于它给了你一个能拆、能改、能讲的骨架。把它当成起点而不是终点,你的毕业设计就不会只是「别人的项目换了个名字」。希望帮到你。
本文还有配套的精品资源,点击获取