SSM+微信小程序智慧医疗系统:从架构到部署的毕设实战解析

发布时间:2026/10/18 18:59:18
SSM+微信小程序智慧医疗系统:从架构到部署的毕设实战解析 简介一套基于微信小程序的智慧医疗系统毕业设计项目源码面向计算机专业学生、毕业设计者以及需要项目实战练习的开发者覆盖医疗预约、科室和医生信息浏览、新闻公告、留言互动等典型场景。资源包包含四个文件其中三个ZIP压缩包和一个SQL数据库脚本压缩包总大小三十一点四五兆字节ZIP包内分别封装小程序客户端、服务器端、项目说明与软件工具SQL脚本为医院预约数据库文件便于快速导入运行。系统后端采用SSM框架前端使用微信小程序与JSP结合MySQL数据库功能上分为小程序端和后台管理端包含用户、医生、管理员三种角色支持科室医生查询、在线预约、留言互动、个人资料修改以及后台的科室、医生、病人、预约、新闻、留言管理。目前已有126人学习浏览适合毕业设计或学习SSM与小程序开发的读者参考。资源经严格调试确保可运行源码、数据库脚本与说明文档齐全可直接作为完整项目方案使用。1. 这套 Java 毕设源码到底解决什么问题做医疗类毕设的同学大概率都被同一个问题卡过题目叫“智慧医疗系统”但打开源码发现要么是纯网页版没移动端、要么小程序只是个壳、后端代码全是 Servlet 堆出来的数据库脚本还动不动就报错。这套 SSM JSP 的微信小程序智慧医疗系统是少有的把“管理后台 医生工作端 患者小程序端”三个入口放在同一套源码里的项目。患者用微信扫码进小程序完成预约挂号、查报告、在线问诊医生在后台处理接诊、开处方、更新病例管理员管科室、管排班、管数据统计。它能直接解决两个问题一是毕设需要的“前后端分离但又不是完全分离”的完整闭环二是给想快速搭建医院系统原型的开发者一套能跑的基线代码。项目自带数据库脚本和项目说明文档不用你自己去猜表结构导入就能连。适合的人群很明确正在选毕业设计题目、对 SSM 框架熟悉但对微信小程序不熟的在校生以及想用最短时间搭一个医疗管理 Demo 去演示的开发者。我要提醒一句这套项目的价值不在于代码量有多大而在于它把医院业务里最核心的几条链路——挂号、就诊、病历、药品——都用 SSM 小程序的方式串起来了。接下来我会把架构、部署、改业务的关键点一个一个拆开讲。2. SSM JSP 小程序这种组合凭什么能跑通医疗系统2.1 SSM 框架在小程序后端里的分工逻辑很多人一听“SSM JSP”第一反应是“这都什么年代的组合了”。但把视角换到毕设和中小型医院内部系统这个组合反而最稳。Spring 管对象创建和事务SpringMVC 管请求路由MyBatis 管数据库读写三者各管一段、互不越界。小程序端发请求到后端后端返回 JSON 数据来驱动页面而后台管理页面则走 JSP 直接渲染。这套项目里SpringMVC 的 Controller 层负责接口暴露。比如患者在小程序里点“提交预约”实际请求的是/appointment/add这个路径Controller 接到 JSON 参数后调 Service 层Service 里校验号源是否充足再调 MyBatis 的 Mapper 完成数据库 INSERT。如果校验失败直接抛异常给全局异常处理器由统一 JSON 结构返回给小程序端前端再弹 toast。整条链路清晰出了问题看 Controller 的日志就能定位到是哪一层断了。SSM 里的事务配置是这套系统绝对不能省的一环。预约挂号涉及两步写库操作先往预约表插一条记录再把该时段的剩余号源数减一。两步必须在一个事务里完成否则患者看到预约成功但医生端没有记录这种事故在医疗系统里是致命的。MyBatis 的 batch 操作和 Spring 的Transactional注解配合能保证这两步要么都成功要么都回滚。2.2 JSP 在这个项目里不是老古董是后台管理的“免构建方案”JSP 的作用经常被低估。这套系统的后台管理页面是纯 JSP 实现的没有 Vue、没有 React原因很简单管理后台不需要多高的交互复杂度服务端渲染 JSP 标签库 EL 表达式十分钟就能拼出一个带数据的表格页面。而且 JSP 天然支持权限控制——管理员登录后把用户信息塞进 SessionJSP 页面里用c:if标签判断角色是管理员就显示“科室管理”菜单是医生就只显示“我的排班”和“接诊记录”比前端路由守卫还直接。在实际部署上JSP 也省了很多事。打包后在 Tomcat 的webapps目录下直接扔 war 包就能跑不用单独配 Nginx 做静态资源服务更不用搞 Node 环境编译。系统里大量页面都是这种结构后台管理页用 JSP 渲染列表点击“编辑”跳到一个带表单的 JSP 页面提交后回到 Controller 走更新逻辑。小程序的 API 接口和 JSP 页面共用一个后端、一套 Service、一套 Mapper只是返回的数据格式不同——一个返回 JSON一个返回 ModelAndView。2.3 核心目录结构拿到源码后先认路再动手拿到这套源码后不要急着点运行。先看目录结构——SSM 项目是标准的 Maven 分层搞清楚哪一层是干什么的后面改功能才不会改错文件。常规的目录结构是这样的src ├── main │ ├── java │ │ ├── com.xxx.controller # 控制层小程序API 后台页面路由 │ │ ├── com.xxx.service # 业务层预约、问诊、排班核心逻辑 │ │ ├── com.xxx.dao # MyBatis Mapper接口 │ │ ├── com.xxx.entity # 实体类与数据库表对应 │ │ ├── com.xxx.util # 工具类日期处理、MD5加密、微信登录解密 │ │ └── com.xxx.interceptor # 拦截器小程序端Token校验、后台登录拦截 │ ├── resources │ │ ├── mapper # MyBatis的XML映射文件 │ │ ├── jdbc.properties # 数据库连接信息 │ │ ├── spring-mvc.xml # SpringMVC配置 │ │ └── spring-mybatis.xml # Spring MyBatis整合配置 │ └── webapp │ ├── WEB-INF │ │ └── jsp # 后台管理的所有JSP页面 │ └── static # CSS、JS、图片资源 └── sql └── database.sql # 数据库初始化脚本建库建表初始数据重点看两个地方。第一是sql/database.sql这里决定了你导入数据库后有哪些表、哪些初始账号密码。第二是resources/jdbc.properties这决定了后端能不能连上你的 MySQL——改密码和端口是在这改不是去代码里搜。项目说明文档通常会讲每个目录的功能但实习时踩过的坑告诉我大多数同学拿到源码的第一步是双击 IDEA 运行然后报错再回头翻文档白白浪费一个小时。3. 本地跑通这套系统从 MySQL 导入到小程序端起页面3.1 环境准备清单版本必须卡死的四个组件这套系统不是新项目环境版本相对保守。我建议直接按下面的版本来不要下意识装最新版。MySQL 8.0 以上改了密码加密规则和 JDBC 驱动包名SSM 老项目容易踩驱动不兼容的坑。JDK 用 1.8Spring 老版本在更高版本的 JDK 上会出现模块访问报错。Tomcat 用 8.5Servlet 版本和依赖里的javax.servlet包刚好匹配。微信开发者工具用最新稳定版即可但小程序端的调试基础库建议选 2.x 版本太高的基础库可能不支持老语法。组件推荐版本说明JDK1.8不要用 11 以上Spring 版本对 JDK 模块化支持不好MySQL5.7 或 8.05.7 最稳8.0 需改驱动名和 SSL 配置Tomcat8.5.x对应 Servlet 3.1正好匹配项目依赖微信开发者工具最新稳定版调试基础库选择 2.30.x 左右安装顺序也有讲究:先 MySQL再 JDK然后 Tomcat最后装 IDEA 和微信开发者工具。装完 MySQL 以后记得把 root 密码设简单一点比如root或者123456本地开发用没问题后面 jdbc.properties 里可以直接匹配。3.2 导入数据库脚本三条 SQL 命令搞定全部表结构拿到database.sql后不用打开文件一条条复制执行。用命令行或者 Navicat 直接执行整个脚本更快。执行完成后你可以用SHOW TABLES;验证一下是否有核心表比如sys_user用户表、doctor医生表、patient患者表、appointment预约记录表、medical_record病历表。正常情况下脚本会自动建库如果用的是 MySQL 8.0脚本里如果带有CHARSETutf8mb4就没问题。-- 在MySQL命令行中执行整个数据库脚本 SOURCE /你的路径/sql/database.sql; -- 验证核心表是否创建成功 SHOW TABLES; -- 查看初始管理员账号 SELECT * FROM sys_user WHERE role admin;如果你的 MySQL 报Unknown database错误多半是脚本里没写CREATE DATABASE语句手动先执行一句CREATE DATABASE hospital_system DEFAULT CHARSET utf8mb4;再重新导入。导入完成后查一下初始账号项目说明文档里通常会写初始管理员和测试医生的账号密码默认密码一般是123456或admin登录后第一个动作就是去后台改掉。3.3 Tomcat 部署参数三个必改的配置文件初始化数据库只是第一步接着要修改后端连接配置。核心配置文件是jdbc.properties里面的数据库地址、用户名、密码需要改成你的本地环境。如果之前 MySQL 装的是 8.0 以上版本JDBC 驱动也要注意——老项目里往往是com.mysql.jdbc.Driver8.0 以后要改成com.mysql.cj.jdbc.Driver同时连接串后面要补上时区和 SSL 参数。jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/hospital_system?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password123456这里有个坑要提前讲用 5.7 时driver用com.mysql.jdbc.Driver用 8.0 时必须换成com.mysql.cj.jdbc.Driver同时要去pom.xml里确认mysql-connector-java的版本是 8.x。不然后端启动时直接报ClassNotFoundException或者Public Key Retrieval is not allowed错误。serverTimezoneAsia/Shanghai不加的话日期字段插入会差 8 小时预约记录时间全错位排查起来很痛苦。3.4 启动后端看到这行日志才算成功后端是标准的 SSM Web 项目用 IDEA 打开后等待 Maven 下载依赖。依赖下载顺利的话会跳到下一步:配置 Tomcat。IDEA 右上角选 Edit Configurations新增一个 Tomcat Server LocalDeployment 里点加号选 Artifact选带war exploded的那个Application context 填/不要填项目名。这样访问时就不用带多余路径小程序端请求地址也能少拼一段。# 如果你习惯命令行部署可以把项目打成war包扔进Tomcat mvn clean package -DskipTests cp target/xxx.war $CATALINA_HOME/webapps/ sh $CATALINA_HOME/bin/startup.sh tail -f $CATALINA_HOME/logs/catalina.out启动成功的标志不是 IDEA 控制台不报红而是 Tomcat 日志里出现类似[localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive ... has finished的字样。这时打开浏览器访问http://localhost:8080/能看到后台登录页就说明后端活了。如果页面 404多半是 Artifact 的 Application context 没配成根路径;如果 500打开 Tomcat 的localhost.log最常见的是数据库连不上或 Mapper XML 没扫到。3.5 微信开发者工具接入改三个文件就能看到患者端页面后端跑通后剩下是小程序端。微信开发者工具导入项目时目录选择小程序代码所在的文件夹不是选整个项目根目录。导入后先别急着点编译要改三个文件app.js里的后端接口请求地址默认可能是http://localhost:8080或局域网 IP如果你的后端就在本机localhost就能用;utils/config.js里的 API 基础路径要和小程序页面里的请求前缀保持一致;app.json里的页面注册列表确认一下有没有缺失页面项目说明里的截图如果打不开多半是这里少配了某个页面路径。// app.js 中修改全局请求地址 globalData: { baseUrl: http://localhost:8080 // 本地调试用localhost } // 小程序request请求示例 wx.request({ url: app.globalData.baseUrl /api/doctor/list, method: GET, success: (res) { // 拿到医生列表数据渲染到页面 } })改完以上内容在开发者工具里编译能看到首页轮播图和科室入口就说明前后端打通了。这里有个跨域问题小程序开发者工具默认不校验合法域名所以本地用http://localhost:8080没问题。但如果你要用真机预览同一个 WiFi 下的效果需要把baseUrl改成电脑的局域网 IP同时后端 SpringMVC 要开启跨域支持不然真机请求会被挡掉。跨域怎么配我在第 5 章的避坑记录里单独讲。4. 核心业务流程拆解预约、医生接诊、管理员排班4.1 预约挂号的完整请求链路小程序→Controller→Service→Mapper预约挂号是这套系统最核心的业务。整个链路很有代表性能看出 SSM 项目的数据流动方式。小程序端患者选择科室、医生、日期点击确认预约后数据被发送到后端的/appointment/add接口。Controller 层的主要任务不是写业务逻辑而是把 JSON 数据封装成实体类然后调 Service。这个系统的 Controller 层基本保持了“瘦Controller、胖Service”的规范代码可读性高适合学习。预约接口的代码大致是这个风格Controller RequestMapping(/appointment) public class AppointmentController { Autowired private AppointmentService appointmentService; ResponseBody RequestMapping(value /add, method RequestMethod.POST) public Result addAppointment(RequestBody Appointment appointment) { // 判断患者是否登录未登录返回401 // 调service预约成功返回ok号源不足返回error return appointmentService.createAppointment(appointment); } }真正的业务逻辑在AppointmentService.createAppointment()里。常见做法是先用synchronized或数据库乐观锁控制并发然后检查该时段剩余号源remaining 0。接着插入appointment记录再更新schedule表的剩余号源减一。两步之间加Transactional保证原子性。这套系统的精华就在这个 Service 方法它把并发控制、事务、业务异常三者都串了起来读懂了这段SSM 框架的核心用法就掌握了一大半。4.2 小程序端预约页面的实现细节日期选择和号源状态小程序端的预约页面不复杂但有几个交互细节会影响体感。日期选择用微信自带的picker modedate组件时间段从后端接口拉取。医生某天的号源如果剩余是 0按钮要置灰不可点文字改成“已约满”。用户选好时间后页面要显示“剩余号源 X 个”的提示。这些状态都来自后端返回的数据前端只做渲染和禁用不做任何计算。// 预约页面核心逻辑简化版 Page({ data: { doctorId: null, selectedDate: , timeSlots: [], today: }, onLoad(options) { this.setData({ doctorId: options.doctorId }) this.loadTimeSlots() }, loadTimeSlots() { wx.request({ url: app.globalData.baseUrl /api/schedule/query, data: { doctorId: this.data.doctorId, date: this.data.selectedDate }, success: (res) { this.setData({ timeSlots: res.data.data }) } }) }, submitAppointment(e) { // 检查用户是否已经实名认证没认证先跳注册填写身份信息 // 确认后调 /appointment/add 提交预约 } })用户点击提交后前端先做一次本地校验患者姓名、手机号是否完整再弹确认框。确认后请求后端接口。后端返回成功前端wx.showToast提示“预约成功”同时跳转到“我的预约”列表页。如果后端返回号源不足提示“该时段已被约满请选择其他时间”。这套交互不算华丽但胜在逻辑完整你拿它做二次开发时可以保留这个流程框架只去改样式和接口路径。4.3 医生接诊与病历写入后台 JSP 页面的表单提交医生的日常工作在后台 JSP 页面里完成。登录后看到的是“待接诊列表”每一条记录显示患者姓名、预约时间、主诉。点击“接诊”跳转到问诊页面页面里嵌套一个病历表单——主诉、现病史、既往史、检查结果、诊断、处方建议。表单提交到后端的/medicalRecord/save接口Controller 接收数据后Service 层会做一件事同时更新medical_record表和appointment表的就诊状态。JSP 页面里用的都是原生 form 提交或 ajax 提交。这套项目多用 jQuery 的$.ajax向 Controller 发 POST成功后刷新页面并弹提示。JSP 相比 Vue 的优势在这个场景显现了不用维护前后端两套数据模型实体类里字段名和数据库列名对得上就行。一个医生录入一份病历的时间大约 2 分钟数据的每个字段都有明确的表字段对应排查问题时看提交的参数就能定位是前台漏传还是后台漏收。4.4 管理员排班与号源管理改一次排班影响所有预约管理员的排班功能是大boss因为它决定了整个系统能不能闭环。排班表通常有三个字段医生 ID、日期、时段、剩余号源数。管理员选中医生、日期和时段填入该时段可预约总数点击保存后台就往schedule表里插入一条记录。小程序端查号源时查的就是这张表预约成功会把剩余数减一。排班管理的代码逻辑很简单但业务上有个必须考虑的边界已经有预约记录的排班不能直接删除。如果管理员强行删除了某条排班患者端已经产生的预约记录会变“孤儿数据”——患者以为自己约上了医生端却看不到。周到的做法是删除前先查appointment表里有没有关联记录有就无法删除只能改状态或者把删除改成“停诊”预约记录保留但标记为停诊状态,患者端显示“医生停诊请重新预约”。我在模拟项目X里测试过停诊流程患者端的提示比直接硬删要友好得多。4.5 数据库表设计五张核心表的字段和关系搞懂这套系统的表关系对二次开发帮助极大。核心表包括用户表管理员和医生账号、患者表患者注册信息和实名信息、科室表、排班表、预约表、病历表。它们的关联关系可以概括为一句话患者预约排班医生书写病历。下面这张表是核心业务表的关键字段表名核心字段关联关系sys_userid, username, password, role, doctor_id关联医生表扩展医生信息patientid, user_id, name, phone, id_card关联用户表登录账号scheduleid, doctor_id, date, time_slot, total_num, remaining_num关联医生表appointmentid, patient_id, schedule_id, status关联患者表和排班表medical_recordid, appointment_id, patient_id, doctor_id, diagnosis, prescription关联预约表和患者表修改业务时建议遵循这种表结构思路状态用status字段控制不删除记录主键都用自增 ID每个业务表都带create_time字段。这套设计虽然不是大数据量级的但结构清晰完全够一个门诊级别的小系统承载也方便后续加字段。5. SSM 小程序项目避坑记录数据库、跨域、Tomcat 与微信域名5.1 MySQL 版本升级导致后端连接报错现象用最新版 MySQL 8.x 导入数据库脚本后后端启动时报Access denied for user rootlocalhost或ClassNotFoundException: com.mysql.jdbc.Driver。原因MySQL 8.0 改了默认密码加密方式caching_sha2_password并且 JDBC 驱动类名从com.mysql.jdbc.Driver换成com.mysql.cj.jdbc.Driver。老 SSM 项目里pom.xml和jdbc.properties都是按 5.7 时代配置的两个不匹配就报错。解决分两步改。第一步去pom.xml把mysql-connector-java版本改成 8.0.x 并重新加载 Maven。第二步把jdbc.properties里的驱动类和 URL 参数换掉。jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/hospital_system?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrueallowPublicKeyRetrievaltrue这个参数别省不加上去 8.0 会一直报公钥检索失败。如果你实在不想改这些配置另一个办法是卸载 MySQL 8.0 改装 5.7但个人建议改配置别降版本——同一台机器上以后可能还有别的项目要用 8.0。5.2 Tomcat 端口被占用导致页面打不开现象IDEA 启动 Tomcat 时控制台直接报Port 8080 was already in use。浏览器访问localhost:8080打开的是别的页面或者是 404。原因要么有别的进程占用了 8080——常见的是别的 Java 程序或某不知名后台服务要么上一次运行没有正常停止 Tomcat进程还挂在后台。IDEA 点停止按钮有时不会真正杀掉 Java 进程,在 Mac 和 Linux 上特别容易出现僵尸进程。解决找进程、杀进程、改端口三条路。推荐先用命令找到 PID 再杀掉。如果你后续还要同时跑小程序端和后端8090 这个端口改起来也很顺手。lsof -i :8080 kill -9 PID改完端口后记得同步处理后端jdbc.properties不用动但如果你小程序端用真机调试utils/config.js里的baseUrl端口也要改否则小程序请求发不出去。如果用的是 IDEA 内嵌 Tomcat在 Edit Configurations 里改 HTTP Port 参数即可不用改server.xml。5.3 小程序请求不到后端跨域和域名校验的坑现象小程序编译后页面能打开但没有数据。点击登录后没有反应打开调试器看到request:fail或url not in domain list。用电脑浏览器访问同一个接口地址却能返回数据说明后端没挂问题出在小程序和后端的通信环节。原因本地开发时开发者工具默认校验合法域名。如果你直接请求http://localhost:8080或http://192.168.x.x:8080会被工具拦掉——除非你在开发者工具里勾选“不校验合法域名”。另外从小程序页面发请求到后端接口跨域问题在后端也要开后端不配合小程序照样收不到数据。解决本地调试最省事的做法是在开发者工具右上角“详情-本地设置”里勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”。后端需要支持跨域的话SpringMVC 里加一个 CORS 配置类或用CrossOrigin注解。推荐写一个统一的配置类避免每个 Controller 都要加注解。// 全局CORS配置允许所有本地调试来源 Configuration public class CorsConfig { Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(GET, POST, PUT, DELETE) .allowedHeaders(*); } }; } }真机调试时allowedOrigins(*)在部分微信版本里会被提示“不支持通配符”稳妥做法是改成http://localhost:8080和你的局域网 IP 两个具体来源。真机预览时手机和电脑必须在同一局域网而且baseUrl要改成电脑的 IP不能再写localhost。5.4 小程序端访问时出现“不在以下 request 合法域名列表中”现象真机预览时接口请求直接失败。微信提示“不在以下 request 合法域名列表中”页面白屏没数据。原因微信对线上小程序的 request 请求强制要求 HTTPS 且域名必须在小程序后台配置的合法域名列表里。本地开发可以用“不校验域名”绕过但你一旦在开发者工具里开启了“预览”或“真机调试”这个限制在某些场景下会被强制启用。解决如果你是正式上线只能在微信公众平台配置 HTTPS 域名。但你的毕设只是本地演示就不用管这个限制——开发者工具里保持“不校验合法域名”勾选状态预览时手机和电脑连同一个 WiFi然后把baseUrl改成电脑的局域网 IP。如果这样还不行检查电脑防火墙有没有拦 8080 端口Windows 上经常拦。临时关闭防火墙或加放行规则基本能解决。5.5 中文乱码MySQL 连接串和后端编码要一起设对现象数据库里的中文是正常的但页面上显示乱码或 ? 号。插入数据库的中文变成???管理员后台看到一片问号。原因三层编码不一致——MySQL 表字符集、JDBC 连接串字符集、JSP 页面字符集。老项目最容易出问题的点在于MySQL 默认字符集是latin1而脚本建表时没有指定utf8mb4。虽然新版的 MySQL 初始化后默认就是 utf8mb4但如果你导入的脚本里建表语句没带CHARSETutf8mb4还是会沿用库级别的默认值。解决修改三处保证一致。第一数据库导入前先看库的字符集SHOW CREATE DATABASE hospital_system;如果不是 utf8mb4就用ALTER DATABASE ... CHARACTER SET utf8mb4;修改。第二JSP 页面顶部加上编码声明。第三在 SpringMVC 配置里加一个字符编码过滤器这个最容易漏——后端接收 POST 请求时如果没做编码转换从 request 里拿到的中文就是乱码。!-- web.xml 中添加编码过滤器 -- filter filter-nameencodingFilter/filter-name filter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameencodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping这三处都设成 UTF-8中文基本不会再出问题。“号”问题大多是数据库连接串缺characterEncodingutf8“乱码但能读”大多是 JSP 页面编码和文件存储编码不一致。排查顺序建议先看数据库再看网络传输最后看 JSP 页面声明。6. 把毕设做出彩的三个小技巧如果你的题目就是这套智慧医疗系统答辩时怎么让老师觉得“这学生不只是跑通了代码”关键不在代码量而在你改了什么、为什么这么改。我给出三个可直接落地的方向第一个是给预约接口加一个简单的防重复提交机制第二个是在小程序端加一个基于缓存的科室列表第三个是给后台加一个简单的数据统计页。三个方向都基于现有代码扩展不需要重写架构。防重复提交是老师最爱问的点之一——“多个患者同时预约最后一个号源会不会超卖”现有代码里如果只是在 Service 里查一下remaining 0并发场景下确实会超卖。常见做法是给schedule表的更新语句加条件UPDATE schedule SET remaining_num remaining_num - 1 WHERE id #{scheduleId} AND remaining_num 0;受影响行数为 1 说明预约成功为 0 说明号源已被抢完。这是典型的乐观锁思路不引入 Redis、不加分布式锁在毕设答辩里既能说明你懂并发控制又能落地。配合外层事务这一行 SQL 就是把数据安全拿捏住了。第二个技巧是科室列表缓存。小程序每次进入首页都要请求科室列表数据基本不怎么变却每次都打数据库。小程序端可以用本地缓存做一层拦截第一次请求后存入wx.setStorageSync下次启动先读缓存过期时间 24 小时。代码改动不大但能在演示时展示一个“性能优化”的亮点。// 缓存科室列表24小时过期 function getDepartmentList() { const cacheKey department_list const cached wx.getStorageSync(cacheKey) if (cached Date.now() - cached.time 24 * 60 * 60 * 1000) { return Promise.resolve(cached.data) } return wx.request({ url: app.globalData.baseUrl /api/dept/list }).then(res { wx.setStorageSync(cacheKey, { time: Date.now(), data: res.data }) return res.data }) }第三个技巧是后台统计页。现有数据库里的预约记录和时间字段完全可以支撑最简单的统计——按日期统计预约量、按科室统计挂号占比。用 MyBatis 写一个带GROUP BY的查询JSP 页面用 ECharts 的 CDN 引入一个柱状图或饼图就能让后台从“管理系统”升级成“有点数据驾驶舱的感觉”。这个方向不会破坏现有业务逻辑是最安全的功能扩展。我在某图像处理Demo上做过同样的操作效果立竿见影:首页从纯表格变成图表观感提升一大截工作量约半天。如果你时间更充裕可以再做一个小程序端的“就诊提醒”——预约成功后记录就诊时间用wx.setStorageSync存一条本地提醒到时间主动弹通知。这个功能不依赖后端推送毕设答辩时作为创新点讲完全没有问题。毕业设计做到这个程度已经不是“复现源码”而是真正在源码之上做了增量开发。把我上面讲的三段代码加进去再加一页截图放在论文里整套项目就立住了。最后说一句实际开发中的习惯这个方向我做过不止一次每次接手老项目第一件事一定是改jdbc.properties和数据库密码第二件事就是用浏览器直接访问后端接口确认链路通没通再动前端。磨刀不误砍柴工把环境一次调好后面全程顺畅。这套 SSM 小程序的智慧医疗系统在毕设赛道上是一条保守但稳妥的路加上几处自己动手的小改进完全能做出让人眼前一亮的效果。希望帮到你。本文还有配套的精品资源点击获取