
简介这是一套面向计算机专业学生与项目实战学习者的微信小程序智慧医疗系统毕设源码围绕医院预约挂号与信息管理场景提供从用户端到后台管理的完整实现方案。资源包共4个文件以3个zip源码压缩包和1个sql数据库脚本为主分别对应小程序客户端、服务器端、项目说明及hospital_order_db数据库整体约31.45MB解压后可直接导入运行。系统采用SSM框架搭配JSP、HTML、CSS、JavaScript与jQuery数据库为MySQL基于MVC与B/S架构开发环境涉及微信开发者工具、Eclipse或IDEA、Tomcat。功能上区分用户、医生、管理员三种角色小程序端支持登录注册、科室与医生信息查看、新闻与留言浏览、在线预约及个人信息修改后台端涵盖科室、医生、病人、用户、预约、新闻、留言与系统管理等模块。已有126人学习适合作为毕设参考或课程设计练手帮助读者快速理解医疗类小程序的业务闭环与前后端协作方式。1. 智慧医疗毕设选型SSMJSP微信小程序这套组合到底能不能打去年帮两个学弟看毕设一个做的是智慧医疗系统前端微信小程序、后端 SSMSpringSpringMVCMyBatis、管理端 JSP数据库 MySQL交付物是源码包加数据库脚本加说明文档。他跑起来第一句话是这玩意儿能过答辩吗。我的回答是能而且这套组合恰恰是当前高校毕设里最稳的一档因为它把能演示、能讲清、能改三件事同时满足了。智慧医疗这个题目本身不新但它的业务闭环特别适合毕设患者端挂号、问诊、查报告医生端接诊、开方管理端管科室、管医生、管药品。微信小程序负责患者侧天然贴合手机挂号的真实场景SSM 负责后端接口和事务JSP 负责管理后台虽然老但页面直出、调试直观答辩时老师一眼能看懂数据流。这套组合不追求技术时髦追求的是你两周内能跑通、一个月内能改出自己的东西。下面按环境怎么搭、库怎么建、接口怎么写、坑在哪一路讲透。2. 环境搭建与工程结构把 SSMJSP小程序三端跑起来2.1 三端分离的目录长什么样拿到源码包第一件事不是急着导入 IDE而是先看清目录结构。典型的智慧医疗毕设工程会分成三块后端 Java Web 工程含 SSM 配置和 JSP 页面、微信小程序工程、数据库脚本。后端一般是 Maven 结构src/main/java放 Controller/Service/Mappersrc/main/resources放spring-*.xml、mybatis-config.xml、jdbc.propertiessrc/main/webapp放 JSP、静态资源和WEB-INF/web.xml。小程序工程则是pages、utils、app.js、app.json那一套。我一般会先画一张数据流图贴在脑子里小程序用wx.request打后端/api/xxx接口后端 Controller 调 Service 调 Mapper 查 MySQL返回 JSONJSP 管理端则是浏览器直接请求.jsp或后端接口服务端渲染后返回 HTML。两条链路共用同一套 Service 和 Mapper这是这套架构最省事的地方——业务逻辑写一遍两端都能用。提示如果源码里后端是传统非 Maven 的 Web 工程WebContent目录 lib手动放 jar别慌导入方式换成 Eclipse 的 Dynamic Web Project 即可逻辑完全一样。2.2 后端环境JDK、Tomcat、MySQL 的版本对齐版本不对齐是新手翻车第一现场。SSM 老工程对 JDK 很敏感常见做法是 JDK 8 Tomcat 8.5 MySQL 5.7这套组合兼容性最好。如果你机器上装了 JDK 17Spring 老版本反射会报InaccessibleObjectException别硬刚装个 JDK 8 切换过去。# 查看当前 JDK 版本确认是 1.8 java -version # 配置 JAVA_HOMELinux/macOS 示例Windows 在系统环境变量里改 export JAVA_HOME/usr/lib/jvm/jdk1.8.0_xxx export PATH$JAVA_HOME/bin:$PATH # 验证 javac -version逻辑说明java -version输出里出现1.8.0才算对。参数上JAVA_HOME必须指向 JDK 根目录而不是binTomcat 启动脚本靠它找编译器。如果输出是17或21去 Oracle 或 Adoptium 下个 8u 版本装上用update-alternativesLinux或环境变量Windows切过去。MySQL 这边导入脚本前先建库。数据库脚本通常在sql/或db/目录下文件名类似hospital.sql。# 登录 MySQL mysql -u root -p # 建库并指定字符集避免中文乱码 CREATE DATABASE hospital_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 退出后用脚本导入 mysql -u root -p hospital_db hospital.sql逻辑说明字符集必须用utf8mb4因为患者姓名、病历描述里可能有生僻字甚至 emoji。参数上utf8mb4_general_ci排序规则够用别用utf8三字节否则四字节字符会插入失败。导入后执行SHOW TABLES;确认表都进来了常见表有user、doctor、department、appointment、medical_record。2.3 小程序端开发者工具导入与请求域名配置小程序工程用微信开发者工具导入选到含app.json的那层目录。导入后第一件事是改app.js或utils/request.js里的后端地址。// utils/request.js 典型封装 const BASE_URL http://localhost:8080/hospital; // 改成你的后端地址 function request(url, method, data) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL url, method: method || GET, data: data || {}, header: { content-type: application/json }, success: (res) { if (res.data.code 200) { resolve(res.data.data); } else { wx.showToast({ title: res.data.msg || 请求失败, icon: none }); reject(res.data); } }, fail: reject }); }); } module.exports { request };逻辑说明BASE_URL是后端根路径/hospital是 Tomcat 里的 context path要和web.xml或 Tomcat 配置一致。参数上header用application/json对应后端RequestBody如果后端用RequestParam接收表单改成application/x-www-form-urlencoded。开发阶段在开发者工具里勾选不校验合法域名否则localhost会被拦。真机调试时localhost换成电脑局域网 IP手机和电脑连同一个 WiFi。注意小程序请求必须走 HTTPS 才能上线但毕设演示阶段用开发者工具的不校验域名开关就够了别在这上面耗时间。3. 数据库设计与 SSM 分层智慧医疗的业务表怎么落地3.1 核心表结构与字段设计智慧医疗的业务表不多但关系要理清。下面这张表是我从多个同类工程里总结出的最小可用集合字段名可按源码微调但结构逻辑一致。表名作用关键字段user患者/用户id, openid, name, phone, passworddoctor医生id, name, department_id, title, introdepartment科室id, name, descriptionappointment挂号预约id, user_id, doctor_id, appoint_time, statusmedical_record病历id, user_id, doctor_id, diagnosis, create_timemedicine药品id, name, price, stockappointment.status是关键一般用 0 待就诊、1 已就诊、2 已取消。user.openid存微信登录返回的唯一标识这是小程序登录的核心字段。设计时注意外键关系appointment.user_id关联user.iddoctor.department_id关联department.id查询时用 JOIN 一次拿全别在 Java 里循环查库。3.2 MyBatis 映射与 Mapper 写法SSM 里 MyBatis 负责 SQL 映射。典型 Mapper 接口加 XML 的组合如下。// DoctorMapper.java public interface DoctorMapper { ListDoctor selectByDepartment(Param(departmentId) Integer departmentId); Doctor selectById(Param(id) Integer id); }!-- DoctorMapper.xml -- mapper namespacecom.hospital.mapper.DoctorMapper select idselectByDepartment resultTypecom.hospital.entity.Doctor SELECT d.*, dep.name AS departmentName FROM doctor d LEFT JOIN department dep ON d.department_id dep.id WHERE d.department_id #{departmentId} /select /mapper逻辑说明namespace必须和 Mapper 接口全限定名一致否则启动报BindingException。resultType指向实体类字段名和列名不一致时靠AS别名或resultMap对齐。参数上#{}是预编译占位符防 SQL 注入${}是字符串拼接只在动态排序字段这种场景用且必须白名单校验。查询科室下医生时用LEFT JOIN而不是INNER JOIN避免科室没医生时整个列表为空。3.3 Service 事务与挂号并发处理挂号是智慧医疗里唯一有并发风险的点同一个号源被两个人同时抢。毕设层面不用上分布式锁但Transactional加乐观锁足够讲清楚。Service public class AppointmentServiceImpl implements AppointmentService { Autowired private AppointmentMapper appointmentMapper; Autowired private DoctorMapper doctorMapper; Override Transactional(rollbackFor Exception.class) public Result book(Integer userId, Integer doctorId, Date appointTime) { // 查询该医生该时段是否已被预约 int count appointmentMapper.countByDoctorAndTime(doctorId, appointTime); if (count 0) { return Result.fail(该时段已被预约); } Appointment app new Appointment(); app.setUserId(userId); app.setDoctorId(doctorId); app.setAppointTime(appointTime); app.setStatus(0); appointmentMapper.insert(app); return Result.success(预约成功); } }逻辑说明Transactional(rollbackFor Exception.class)保证插入失败时回滚默认只回滚RuntimeException加上Exception更保险。参数上countByDoctorAndTime是自定义查询SQL 里对doctor_id appoint_time建联合索引否则并发下全表扫描会拖慢。严格说这种先查后插仍有竞态窗口毕设答辩时你可以主动提生产环境会用唯一索引或分布式锁反而是加分项。提示给appointment表的(doctor_id, appoint_time)加唯一索引插入冲突时捕获DuplicateKeyException返回友好提示这是最省事的防重方案。4. 微信小程序端对接登录、挂号、报告查询三条主链路4.1 微信登录换 openid 的完整流程小程序登录不是拿手机号而是wx.login拿 code后端拿 code 换 openid。这是热词里微信小程序登录获取手机号的前置步骤手机号需要额外授权毕设里用 openid 标识用户就够了。// pages/login/login.js wx.login({ success: (res) { if (res.code) { wx.request({ url: BASE_URL /api/user/login, method: POST, data: { code: res.code }, success: (r) { wx.setStorageSync(token, r.data.data.token); wx.setStorageSync(userId, r.data.data.userId); } }); } } });逻辑说明res.code只能用一次五分钟过期。后端拿到 code 后调用微信接口换openid和session_key再生成自己的 token 返回。参数上wx.setStorageSync把 token 存本地后续请求在 header 里带上。注意session_key绝不能下发到小程序端它只在后端用。4.2 挂号页面与科室医生联动挂号页面的交互是选科室 → 拉医生列表 → 选时段 → 提交。科室和医生用两级联动避免一次拉全量数据。// 选科室后加载医生 onDepartmentChange(e) { const deptId e.detail.value; request(/api/doctor/list?departmentId deptId, GET).then(list { this.setData({ doctors: list, selectedDept: deptId }); }); }逻辑说明e.detail.value是 picker 选中的索引或值取决于range-key配置。参数上接口用 GET 带 query 参数后端RequestParam接收。列表渲染用wx:for每个医生卡片绑定>// 统一返回给前端的日期格式 JsonFormat(pattern yyyy-MM-dd HH:mm, timezone GMT8) private Date createTime;逻辑说明JsonFormat注解控制 Jackson 序列化格式不加的话前端拿到的是时间戳。参数上timezone GMT8必须写否则服务器时区不对会差 8 小时。JSP 端展示用 JSTL 的fmt:formatDate格式保持一致避免患者和医生看到的时间对不上。注意JSP 页面里如果用了% page contentTypetext/html;charsetUTF-8 %数据库连接串也要带useUnicodetruecharacterEncodingutf8两头都设才不会乱码。5. 避坑与排查这套毕设工程最容易翻车的 5 个点5.1 启动报 404接口一个都访问不到现象Tomcat 起来了访问http://localhost:8080/hospital/api/doctor/list返回 404。原因通常是web.xml里 DispatcherServlet 的url-pattern配成了/但 Spring 配置没扫到 Controller 包或者 context path 不对。解决先看 Tomcat 启动日志有没有Root WebApplicationContext initialized再确认spring-mvc.xml里context:component-scan base-packagecom.hospital.controller/的包名和实际一致最后核对访问路径里的/hospital是不是web.xml里配的display-name或 Tomcat 部署名。5.2 中文乱码患者姓名变成问号现象小程序提交的中文姓名存进数据库变成???。原因有三层请求编码、数据库连接编码、表字段编码。解决web.xml加CharacterEncodingFilter设UTF-8JDBC URL 加useUnicodetruecharacterEncodingutf8建库建表用utf8mb4。三层缺一层都会乱按顺序排查。5.3 小程序真机请求失败开发者工具却正常现象模拟器里接口通真机预览报request:fail。原因是真机不认localhost且默认校验域名。解决把BASE_URL换成电脑局域网 IP如http://192.168.1.100:8080/hospital手机和电脑同一 WiFi开发者工具里勾选不校验合法域名。如果还不行检查电脑防火墙有没有拦 8080 端口。5.4 MyBatis 报 Invalid bound statement现象启动或调用时报Invalid bound statement (not found)。原因是 Mapper XML 没被扫描到或namespace和接口对不上。解决确认mybatis-config.xml或 Spring 配置里mapperLocations指向classpath:mapper/*.xml且 XML 文件确实编译进了target/classes。IDEA 里有时 XML 放在java目录下不会被打包挪到resources下最稳。5.5 挂号重复提交同一时段出现两条记录现象用户手快点了两次提交数据库出现两条同时段预约。原因是前端没防抖后端没防重。解决前端按钮点击后置disabled后端在appointment表加(doctor_id, appoint_time)唯一索引插入时捕获DuplicateKeyException返回请勿重复预约。这是最省事也最可靠的双保险。6. 从能跑到能答辩二次开发与验证的几个实用技巧把工程跑通只是起点答辩老师最爱问的是你改了什么。我的习惯是拿到源码后先做三件事换掉默认的登录账号密码、给核心表加两三个自己的字段、把某个页面的交互重写一遍。这三步做完你对整套代码的掌控就从能跑变成能讲。具体技巧上验证后端接口别只靠小程序用 Postman 或 curl 直接打接口最快。# 测试挂号接口 curl -X POST http://localhost:8080/hospital/api/appointment/book \ -H Content-Type: application/json \ -d {userId:1,doctorId:2,appointTime:2025-06-01 09:00}逻辑说明直接打接口能排除小程序端的干扰快速定位是后端问题还是前端问题。参数上-H指定 JSON 头-d是请求体返回的 JSON 里看code和msg判断成败。如果返回 500去看 Tomcat 日志的堆栈比在小程序里猜快十倍。二次开发时我一般会挑科室管理这个模块练手因为它增删改查齐全、逻辑简单、改完立刻能在 JSP 后台看到效果。加一个科室简介字段从数据库到实体到 Mapper 到 Controller 到 JSP 页面走一遍整套 SSM 的链路就彻底通了。改完记得同步更新数据库脚本答辩时老师要看你的 SQL 文件字段和代码对不上会扣分。最后一个血泪经验源码包里的说明文档一定要自己读一遍再改代码很多工程在README里写了默认端口、默认账号、依赖的特殊 jar跳过这步直接改后面报错会怀疑人生。我见过太多人卡在数据库连不上最后发现是文档里写了密码不是root。这套智慧医疗毕设的技术栈不新但胜在完整、可讲、可改把上面这些跑一遍你手里就有一个能撑起答辩的项目了。希望帮到你。本文还有配套的精品资源点击获取