news 2026/10/10 3:45:29

微信小程序预约挂号系统:SSM后台与数据库设计全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信小程序预约挂号系统:SSM后台与数据库设计全解析

简介:一套面向高校毕业设计/课程设计的微信小程序预约挂号系统完整项目包,覆盖管理员、医生、用户三类角色,并附有本地运行辅助配置。后台基于 Java 的 SSM 框架开发,结合 MySQL 数据库实现数据管理,小程序端通过微信开发者工具完成预约交互;核心业务涵盖科室信息维护、医生排班、在线预约、取消预约、调班申请与通知公告等模块,角色分工清晰、流程完整。压缩包共1210个文件,约18.92MB,文件类型覆盖png界面图片、js/wxml/wxss小程序前端文件、vue后台管理页面、java后端代码、json配置、sql数据库脚本与xml配置等,可对照目录按模块查阅,也方便二次开发。目前已有77人浏览学习。资源包内还包含安装、运行、构建等批处理脚本与工程配置文件,有助于快速跑通本地前后端环境;使用者可获取完整源码、数据库脚本及启动辅助工具,从而节省搭建时间,直接聚焦微信小程序与 SSM 整合开发的业务逻辑学习。

1. 为什么毕设题库里总有一款微信小程序预约挂号:三个角色一次讲清

翻一遍课程设计和毕业设计题目库,几乎每年都能看到基于微信小程序的预约挂号系统——这不是巧合。预约挂号同时覆盖了小程序端展示、后端管理、数据库关联查询三块硬功夫,一个题目正好把Java后端框架和移动端开发都练到位。这套资源解压后就是完整工程:小程序端负责用户注册登录、查看医生信息、发起预约操作,SSM后台管医生、科室、排班、审批,MySQL存全部业务数据。这类项目见得多了就能发现,它的优点是角色划分清楚——管理员、医生、用户三套权限边界明确,科室、排班、预约、调班申请这几张表之间的关联逻辑也完整。适合两类人:拿它交课程设计的在校生,以及想快速搭一套预约管理Demo的从业者。别急着双击1-install.bat,后面的坑值得先知道。

2. SSM后台与微信小程序的沟通方式:先搞清这套系统的骨架

2.1 三种角色的权限边界:管理员、医生、用户在数据库里怎么区分

这个系统一上来最值得看的就是角色设计。管理员、医生、用户不是简单的一个user表加role字段糊弄过去,而是拆成了独立的用户表、医生表,管理员直接作为后台账号维护。为什么这么拆?医生身上挂着一堆业务属性:所属科室、职称、擅长方向、排班记录,这些塞进用户表会让表结构又肿又乱;而小程序端的用户只需要openid、手机号、姓名几个字段。把两类差异很大的对象塞到同一张表里,后面写查询和权限控制都会被迫反复判断角色类型,徒增代码量。

我在本地看这套工程时,第一件事就是看数据库脚本里的字段注释。常见的设计是用户表长这样:

CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, openid VARCHAR(64) NOT NULL COMMENT '微信登录唯一标识', username VARCHAR(50) COMMENT '用户昵称', phone VARCHAR(20) COMMENT '手机号,用于接收预约提醒', create_time DATETIME COMMENT '注册时间', status TINYINT DEFAULT 1 COMMENT '1正常 0禁用' ); CREATE TABLE t_doctor ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL, password VARCHAR(100) NOT NULL, real_name VARCHAR(50), dept_id INT COMMENT '关联科室表', title VARCHAR(30) COMMENT '职称:主任医师/副主任医师', intro TEXT COMMENT '医生简介', status TINYINT DEFAULT 0 COMMENT '0待审核 1通过 2驳回' );

注意医生表的status默认是0,说明医生注册后要管理员审核才能开始接诊。这是预约挂号系统里比较容易忽略的一环:医生不是注册完就能上岗,后台管理员有一个「医生管理」入口专门做审核。用户表不存密码,因为小程序端走微信登录,密码逻辑交给后台的管理员账号去管。

权限边界对应的功能菜单也分得很清楚:管理员后台有个人中心、用户管理、医生管理、科室信息管理、医生信息管理、排班信息管理、预约信息管理、取消预约管理、调班申请管理、系统管理;医生登录后只有医生信息管理、预约信息管理、取消预约管理、调班申请管理;用户就只能在微信小程序端看医生、看公告、发起预约。菜单越少,权限控制越不容易出漏洞,这个设计对课程设计答辩很友好。

2.2 SSM框架各司其职:Spring、SpringMVC、MyBatis分别扛什么活

后台采用Java生态里经典的SSM组合,也就是Spring + SpringMVC + MyBatis。有些同学上来就问「现在不都用Spring Boot吗,为什么还拿SSM做毕设」,这个问题在答辩时几乎必被问。背后原因一般是课程大纲还没更新到Spring Boot,或者导师明确要求用SSM来考察你对框架原理的理解。Spring Boot虽然把配置简化了,但SSM的手动装配反而能把「容器、路由、持久层」这三个概念讲得更透。

一次请求怎么穿过这三个框架?小程序端发一个请求到后台,SpringMVC的DispatcherServlet先接住,根据URL映射找到对应的Controller;Controller调Service,Service调Mapper接口;MyBatis把Mapper接口和XML里的SQL绑定起来,执行数据库操作,把结果一层层返回。Spring在这个过程里管的是对象创建和依赖注入——Controller、Service、Mapper这些Bean不需要手动new,全由Spring容器管理。

本地跑起来之前,先改jdbc.properties,这是整个系统能不能连上数据库的关键:

jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/hospital_booking?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=root

三个参数最容易出错。第一是characterEncoding=utf8,如果漏掉,小程序端写入的中文会变成问号,用户姓名、科室名全乱码;第二是serverTimezone=Asia/Shanghai,MySQL 8.0默认时区是UTC,不加这个参数,预约时间会差8小时;第三是useSSL=false,本地调试没有SSL证书,MySQL 5.7以上版本默认会尝试SSL握手,报一堆warning,虽然不影响运行,但看着烦。

2.3 小程序端与后台的接口约定:URL怎么配、token怎么带

小程序和后台是两个独立的端,之间只靠HTTP接口通信。接口地址不会写死在每个页面里,一般在项目里抽一个config.js统一维护:

const baseUrl = 'http://localhost:8080/hospital_booking' function request(path, method, data) { return new Promise((resolve, reject) => { wx.request({ url: baseUrl + path, method: method, data: data, header: { 'Content-Type': 'application/json', 'Authorization': wx.getStorageSync('token') }, success: (res) => { if (res.data.code === 200) resolve(res.data.data) else reject(res.data.message) }, fail: reject }) }) } module.exports = { request }

这个封装的思路是所有接口共用一套请求头,后端返回的数据也统一包一层结构,前端只判断code就够了。现在比较流行的是code为200表示成功,其他code分别对应用户不存在、登录过期、参数错误等业务异常。这样小程序端每个接口不需要单独处理异常场景,统一弹一个Toast提示message字段即可。

另一个值得注意的点是header里那个Authorization。小程序没有浏览器那种自动携带的Cookie,后端如果用session记录登录状态,小程序端是存不住的。常见做法是登录成功后后端返回一个token,小程序把它存进本地缓存,之后每个接口请求都带上这个token,后端统一拦截校验。如果这套系统里用的是SSM拦截器,可以看看HandlerInterceptor的实现,拦截器里白名单一般只有登录接口和静态资源。

提示:localhost只适合本地调试。真机预览时手机访问不到电脑上的localhost,要么在同一个局域网用电脑IP访问,要么后续部署到云服务器。答辩演示用开发者工具就够了。

3. 本地跑起来的关键三步:从1-install.bat到微信开发者工具

3.1 解压后的文件结构:.bak文件、.bat脚本和Eclipse工程标识

解压后的目录里能看到几个有点怪的文件。main.css.bak、update-password.vue.bak、IndexAsideStatic.vue.bak、BreadCrumbs.vue.bak、IndexHeader.vue.bak——这些不是垃圾文件,而是后台管理页面修改时的旧版本备份。以.vue.bak结尾的说明后台管理界面用了Vue组件方式开发,IndexHeader、BreadCrumbs这些组件名也印证了后台是一个典型的CMS式布局:顶部Header、侧边栏Aside、面包屑导航。.bak文件对运行没有影响,但能看出原开发者的工作节奏——改一个组件之前先把旧文件复制一份,改崩了还能退回去,这个习惯值得学着用。

另一个看点是.classpath和org.eclipse.wst.common.component。这两个文件是Eclipse的工程配置,说明原工程是用Eclipse开发并提交的。拿到工程后最稳的导入方式不是新建项目再拷贝源码,而是直接用Eclipse的Import -> Existing Projects into Workspace,让Eclipse按配置文件还原工程结构。如果强行用IDEA打开,SpringMVC的部署配置可能需要重新补一遍。

还可以顺手列一张文件清单,防止漏看:

文件名作用是否需要改动
1-install.bat初始化环境、导入依赖和数据库按本机密码改
2-run.bat启动后台服务一般不用改
3-build.bat重新打包构建改代码后用
*.vue.bakVue组件旧版备份不需要动
.classpathEclipse工程识别文件不需要动

3.2 1-install.bat、2-run.bat、3-build.bat:一键脚本背后做了什么

这套脚本的设计思路是让运行者不用记maven命令。1-install.bat负责初始化环境,常见内容是清理并安装依赖:

@echo off echo [1/3] 安装项目依赖... call mvn clean install -DskipTests echo [2/3] 初始化数据库... mysql -uroot -proot < sql/init.sql echo [3/3] 安装完成 pause

注意上面的脚本是按「最典型做法」补出来的,实际包里的脚本内容不一定完全一样,但要做的事八九不离十:先编译打包,再把SQL脚本导入MySQL。如果项目里带的是war包而不是jar包,2-run.bat一般会调用Tomcat或者直接启动嵌入式的Tomcat。运行完看到Tomcat started on port(s): 8080,说明后台起来了。

3-build.bat一般是给改动代码之后重新构建用的,日常调试基本用不上。真正操作时,很多人卡在1-install.bat不是因为代码问题,而是mysql命令行没进PATH,或者root密码和脚本里写的不一致。遇到这种情况,手动执行SQL脚本比改脚本更快:

mysql -uroot -p < sql/init.sql

手动执行的好处是先确认自己能连上数据库,再谈导入SQL。密码错了会直接提示Access denied,而不是等脚本跑到一半才暴露问题。

3.3 小程序端导入与后台地址配置

后台跑起来之后轮到小程序端。打开微信开发者工具,选择「导入项目」,目录指向工程里的小程序文件夹。注意小程序项目的AppID可以用测试号,不需要自己注册,课程设计阶段完全够用。

导入后先改接口地址。开发者工具有个容易忽略的机制:默认会校验request合法域名,否则本地请求直接被拦。课程设计都是本地联调,不需要真的去配置服务器域名,直接关掉校验更省事:详情 -> 本地设置 -> 勾选「不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书」。这一步不做,小程序打开必白屏,而且是纯前端报错,后端日志里什么都看不到,排查起来很容易误判成后端问题。

注意:关闭域名校验仅限本地开发。如果你的项目要发布体验版,仍然必须在后台配置HTTPS域名。

4. 三张核心表的联动逻辑:科室、排班与预约的数据流转

4.1 科室信息管理:排班表为什么冗余科室名字段

管理员后台第一个业务模块是科室信息管理,这个表看着简单,但它是整个系统的起点。科室表的典型结构:

CREATE TABLE t_department ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL COMMENT '科室名称', desc TEXT COMMENT '科室简介', sort INT DEFAULT 0 COMMENT '排序字段' );

医生表通过dept_id关联科室表。到这里都还是常规设计,真正有意思的是排班表和预约表。做排班查询时,小程序端要展示的列表是「科室名 + 医生名 + 号源余量」,如果把科室名和医生名都靠联表查,每加载一页都要做两次JOIN,演示时数据量小看不出来,但代码写起来很烦。常见做法是在排班表里直接冗余科室名和医生名:

CREATE TABLE t_schedule ( id INT PRIMARY KEY AUTO_INCREMENT, dept_id INT NOT NULL, dept_name VARCHAR(50) COMMENT '冗余科室名', doctor_id INT NOT NULL, doctor_name VARCHAR(50) COMMENT '冗余医生名', schedule_date DATE NOT NULL COMMENT '排班日期', time_slot VARCHAR(20) COMMENT '上午/下午/晚间', total_num INT DEFAULT 30, booked_num INT DEFAULT 0, status TINYINT DEFAULT 1 COMMENT '1可预约 0停诊' );

冗余字段违背了数据库第三范式,但在这种读多写少的业务场景里收益很高。排班列表一次查询直接出全部展示字段,不需要反复联表。答辩时如果有人问「为什么冗余」,回答「用空间换查询性能」就是标准答案。

科室信息管理页面通常提供增删改查,但删除科室前要检查该科室下有没有医生,不然会出现「科室已删除,医生还挂在空科室」的数据孤儿。常见实现是先查询医生表里dept_id是否还有引用,有引用就提示「该科室下存在医生,请先处理医生信息」。

4.2 预约信息表的状态流转:从已预约到已完成再到已取消

预约信息表是整套系统里数据变化最频繁的表。用户在小程序端选一个排班,发起预约,生成一条预约记录。后续动作有三种:医生在后台把预约标记成已完成;用户或管理员取消预约;预约时间到了没来,默认是爽约。状态字段的值一般是数字枚举:

CREATE TABLE t_appointment ( id INT PRIMARY KEY AUTO_INCREMENT, schedule_id INT NOT NULL, user_id INT NOT NULL, appoint_no VARCHAR(32) COMMENT '预约号', status TINYINT DEFAULT 0 COMMENT '0已预约 1已完成 2已取消 3爽约', create_time DATETIME, cancel_time DATETIME );

预约成功之后,排班表的booked_num要加1;取消预约后要减1。这一步如果放在前端代码里做,会出现并发问题——两个用户同时取消,booked_num被减两次。正确做法是在同一个事务里更新预约状态和排班号源:

UPDATE t_appointment SET status = 2, cancel_time = NOW() WHERE id = ? AND status = 0; UPDATE t_schedule SET booked_num = booked_num - 1 WHERE id = ? AND booked_num > 0;

两条UPDATE放一个事务里,后者通过受影响行数判断是否成功。这个细节做好了,答辩时能讲的东西就多了一个:你考虑过并发场景。很多同学写预约功能只做了INSERT,没有同步维护号源余量,虽然单机演示看不出来,但逻辑上是不完整的。

4.3 调班申请的实现思路:医生提交、管理员审批

调班申请是这套系统里比较少见的功能模块,也是和普通预约挂号Demo拉开差距的地方。医生如果某天临时有事,不能直接在排班表里改数据,而是先提交一条调班申请,注明原排班、目标时间、调班原因,管理员审核通过后才生效。

调班申请表的核心字段设计:

CREATE TABLE t_adjust_apply ( id INT PRIMARY KEY AUTO_INCREMENT, doctor_id INT NOT NULL, schedule_id INT NOT NULL COMMENT '原排班id', target_date DATE COMMENT '目标日期', target_slot VARCHAR(20), reason VARCHAR(255), status TINYINT DEFAULT 0 COMMENT '0待审核 1通过 2驳回', apply_time DATETIME, audit_time DATETIME );

管理员在后台的「调班申请管理」里看到待审核列表,点通过时系统做两件事:把原排班状态改成停诊,把医生插入目标日期的排班。如果原排班已经有用户预约,常见做法是先电话通知用户,系统层面则不提供自动迁移,这一点在答辩时可以如实说明,反而显得考虑过真实业务。

医生端为什么没有直接改排班的权限,这也是权限设计的一个亮点。如果医生能直接改排班,用户已经预约的时段就会悄悄被改掉,产生纠纷。强制走调班审核流程等于给排班变更留了审计记录,谁申请的、什么时候批的、原排班改成什么,全部查得到。

5. 避坑:微信小程序预约挂号最常见的5个翻车现场

5.1 现象:小程序打开白屏,控制台报「不在以下合法域名列表中」

原因:微信开发者工具默认开启合法域名校验,本地调试用的http://localhost:8080不在列表里,请求被前端直接拦掉,后端没有收到任何请求。

解决:详情 -> 本地设置 -> 勾选「不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书」,改完重新编译。如果关闭校验后还是白屏,再看Network面板里有没有请求发出,确认是不是baseURL配错了。

5.2 现象:后台管理页面能打开,小程序登录却报500

原因:登录接口的URL配错了。最常见的是小程序端config.js里的baseURL写成https://或者是其他端口。另一个很隐蔽的原因:openid获取失败。微信登录需要调用微信接口换取openid,如果小程序AppID使用的是测试号,某些接口权限受限,后端拿不到openid,返回500。

解决:先打开浏览器直接访问「后台地址/api/user/login」,用POST工具测一下接口本身通不通。通,再抓小程序端的请求URL,把baseURL改成浏览器访问的那个地址。后端日志一般在Tomcat窗口或者logs目录下,500错误看堆栈最直接。

5.3 现象:1-install.bat执行到一半中断,提示Access denied for user

原因:脚本里写的MySQL账号密码与本机不一致。很多毕设包默认用户名root,密码是123456或root,而你自己机器上的root密码是另一个。

解决:先用mysql -uroot -p手动登录确认,登录成功后执行:

mysql -uroot -p < sql/init.sql

如果不想手动敲命令,直接改jdbc.properties里对应的密码,然后重新执行install脚本。这时候还要同步检查applicationContext.xml里有没有写死的数据源,有些SSM项目会把数据库配置写在XML里,只改properties不生效。

5.4 现象:预约时间显示差8小时

原因:MySQL服务器的时区是UTC,JDBC连接串没有指定时区,后端查出来的时间比北京时间少8小时。这个坑在本地开发时最容易出现,因为Windows时区其实已经是东八区,但MySQL系统变量还是默认的UTC。

解决:jdbc.url里加上serverTimezone=Asia/Shanghai,改完重启应用。如果已经插入的测试数据时间错了,用SQL批量修正:

UPDATE t_appointment SET create_time = DATE_ADD(create_time, INTERVAL 8 HOUR);

顺手记一个查时区的方法:执行SELECT NOW();看输出时间和当前时间对不对得上,对不上再改连接串,别盲目改MySQL全局时区,那个影响面太大。

5.5 现象:.bak文件在编辑器里打开是一堆乱码

原因:.bak后缀被系统当成未知文件,用文本编辑器打开时按系统默认编码解析,文件里的中文字符全花了。

解决:不要直接改后缀,先在IDE里确认编码是UTF-8,再把扩展名从.bak改成.vue打开。改后缀之前先复制一份,防止IDE识别出错把原文件搞坏。另外Maven构建时默认只编译特定目录下的文件,.bak不会被当成源码编译,所以它们躺在工程里不影响打包。

6. 从毕设到能演示的进阶技巧:把预约流程走通并录成演示视频

6.1 演示前必做的数据准备

演示最常见的翻车不是代码跑不起来,而是打开小程序看不到数据。预约流程必须有医生、有排班、有号源,不然演示时只能对着空页面解释。

按这个顺序准备数据:先在后台建两个科室(内科、外科),再注册两位医生并通过审核,给每个医生生成未来两天的排班,排班的号源不用改默认值,保持30个。最后用小程序端注册一个用户,真实走一遍预约。关键检查项是:科室下拉框有数据、医生列表能显示、点进排班后号源余量是30。这三点都正常,演示就不会卡壳。

6.2 一条让答辩稳住的演示路线

演示顺序就是业务流程顺序,不要跳着点菜单。第一次进系统先以用户身份登录小程序,去科室页找一个医生,发起预约,预约成功后截图;然后切到医生端登录,看到刚才的用户预约记录,把状态改成已完成;再切到管理员后台,从预约信息管理里看到这条记录。最后补一个调班申请:医生提交申请,管理员审批通过,回到排班信息管理里看到原排班已停诊。

这套流程把三个角色串成了一条完整链路,一共不到五分钟,但每个功能模块都覆盖到了。录屏记得把微信开发者工具的Network面板和后台控制台的日志同时录进去,评阅人看到真实请求比看口述更有说服力。这套资源本身已经打包好了运行脚本和数据库初始化SQL,下载后按这条主流程走一遍,基本不用再到处搜教程。

从那以后我每次拿到别人的毕设包,都强制自己先把主流程完整跑通再动代码,连数据库密码这种最不起眼的字段也会先核对一遍——很多看似神秘的问题,最后都落在基础配置上。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 3:45:17

VNX Unified存储实验指南:从双控初始化到ALUA路径验证

简介&#xff1a;本资源是EMC中国教育服务官方发布的《VNX统一存储实施实验室指南》中文版PDF文档&#xff0c;面向企业存储工程师、系统集成人员及数据中心运维技术人员&#xff0c;聚焦VNX统一存储平台的现场部署、配置管理与故障处理实战能力提升。文档涵盖VNX系统架构解析、…

作者头像 李华
网站建设 2026/10/10 3:45:06

C++项目用ADO接数据库:从AdoDB.rar到regtlibv12注册与避坑指南

简介&#xff1a;这是一份面向C程序员的ADODB数据库操作源码包&#xff0c;适合在Windows环境中通过COM/OLE DB访问SQL Server、Oracle、MySQL等数据库的开发者&#xff0c;用于解决C项目中的数据库读写、查询与事务管理等核心需求。压缩包共79个文件&#xff0c;大小约38.43MB…

作者头像 李华
网站建设 2026/10/10 3:44:52

Windows权限提升实战指南:从令牌到服务的提权命令详解

搞Windows安全这几年&#xff0c;我有一个特别深的感受&#xff1a;大部分“拿到一台机器却拿不到管理员权限”的窘境&#xff0c;不是卡在漏洞利用上&#xff0c;而是卡在基础权限模型没吃透。很多朋友上来就想用提权工具一把梭&#xff0c;结果不是被杀毒软件拦掉&#xff0c…

作者头像 李华
网站建设 2026/10/10 3:43:51

DBeaver连接MySQL建库建表实操指南

很多学MySQL的同学&#xff0c;第一关不是SQL语法&#xff0c;而是不知道用什么工具干活。命令行当然能建库建表&#xff0c;但那条路对新手太劝退。我用DBeaver连接本地MySQL、创建数据库表这套流程&#xff0c;已经重复过上百次&#xff0c;也带过不少零基础的人上手&#xf…

作者头像 李华
网站建设 2026/10/10 3:42:40

2003-2023地级市工业三废面板数据整理与清洗指南

做了几年环境数据分析&#xff0c;手里的城市面板数据少说也整理过几十套。要说哪类数据最让人又爱又恨&#xff0c;工业三废绝对排得上号——想研究污染排放和经济增长的关系&#xff0c;它是核心变量&#xff1b;想评估环境规制的影响&#xff0c;它是因变量&#xff1b;可真…

作者头像 李华
网站建设 2026/10/10 3:42:40

微电网调度中的风光场景生成与削减:蒙特卡洛+概率距离法实战

做微电网调度优化的时候,我大部分时间其实不是在写约束,而是在想办法对付不确定性。前段时间接了一个模拟项目,给定一片风电和一片光伏作为可调度的分布式电源,目标是最小化运行成本。第一步很常规:用蒙特卡洛法把未来24小时的风光出力抽成5000个随机场景。第二步就出问题了——…

作者头像 李华