恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

医院挂号小程序开发指南:SSM+微信小程序,从表设计到并发防超卖

  • 首页
  • 资讯中心
  • /
  • 医院挂号小程序开发指南:SSM+微信小程序,从表设计到并发防超卖

相关资讯

大模型考试应试策略:四级能力金字塔与阅卷采分点精讲 2026/10/22 10:00:37
日志少打一个参数,为何引发Agent服务大面积500? 2026/10/22 10:00:37
OpenClaw实战:从零搭建个人智能管家与自动化工作流 2026/10/22 10:00:37

最新资讯

从两千到五十万:个人版AI与企业级数字员工平台的真实差距
机器人控制米家智能家居:从语音指令到设备联动实战指南
2026小红书流量分配逻辑:从内容赛马到生意闭环
AI写作多轮失忆怎么破?Goink结构化记忆层架构拆解
从零构建信息安全知识图谱:告别碎片化学习的系统路径
DDoS与CC攻击的识别与防御:从带宽层到应用层的分层对抗实战

今日推荐

电商智能运营体系从0到1:架构设计、落地步骤与避坑指南
压缩空气储能与热网热惯性联合优化调度:热电联产系统建模与求解
若依框架AI代码生成不稳定?用Agent Skill三层结构+五步法搞定

本周热门

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

医院挂号小程序开发指南:SSM+微信小程序,从表设计到并发防超卖

发布时间:2026/10/22 10:00:37
医院挂号小程序开发指南:SSM+微信小程序,从表设计到并发防超卖 简介面向计算机专业毕业设计场景这套医院挂号小程序项目采用微信小程序SSMMySQL组合适合需完成课程设计或毕业设计的在校学生也适合想快速上手前后端分离开发的入门者。资源共858个文件涵盖png/svg等界面素材、vue/js/java前后端源码、wxss/wxml小程序页面文件、json/xml配置文件以及sql数据库脚本与mp4演示视频包体约46.83MB目录结构清晰既有前端工程也有后台管理逻辑。系统依托SSM框架实现患者、医生、科室、专家信息、预约及取消预约申请等管理功能后台可在浏览器登录运维兼顾小程序端与Web端。除完整源码和数据库外压缩包还附带了毕业论文文档、视频演示和bat一键脚本能帮助理解系统分析、功能设计与数据库设计过程并辅助环境搭建与运行调试。目前已有180人浏览学习适合需要一套可运行、可讲解的毕业设计项目作为参考。1. 医院挂号小程序是什么水平一个毕设题目三种技术含量「医院挂号小程序」在网上搜一圈跳出来的几乎都是同一个配方微信小程序做前端SSM 做后端接口MySQL 存数据。这个组合能成为毕业设计里的常青树不是因为它新而是业务逻辑刚好卡在一个舒服的位置——比纯增删改查系统多了一点并发和状态的讲究又比电商秒杀少了一大截复杂度。它不要求你会分布式、消息队列、缓存集群这堆东西但能把「请求进来—查库—判断状态—写库—返回」这一条完整的数据链路讲清楚论文阶段特别好展开。如果你正站在选题路口或是想从「只会写管理系统」跨向前后端分离这个题目值得做。缺点是模板满天飞想拿高分得在并发处理和状态设计上做出差异化下面我按「表怎么建—接口怎么写—小程序怎么对—出错怎么看」的顺序拆一套能跑通、能答辩、也能写进简历的方案。2. 把挂号的数据模型先立住MySQL 里建五张核心表挂号的业务逻辑和「买菜下单」最大的区别在于你约的不是医生本人而是医生在某一天、某个半天的「号源」。这个中间层的设计直接决定了后面所有代码的复杂度用户表、科室表、医生表都好理解真正的核心是排班表和预约表之间的联动。我一般先画实体关系再写 SQL避免做到一半发现字段不够用。下面是我认为最稳妥的五张核心表结构。2.1 用户、科室、医生、排班、预约五张表各自管什么表关系一句话就能说清医生属于科室排班挂在医生名下预约把用户和排班绑在一起。最终落库的脚本在 MySQL 里执行一遍建表顺序不能乱因为有外键依赖。先看前三张基础表CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT, openid varchar(64) NOT NULL COMMENT 微信用户唯一标识, nickname varchar(50) DEFAULT NULL, phone varchar(20) DEFAULT NULL, create_time datetime DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_openid (openid) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE department ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL COMMENT 科室名称如内科、骨科, location varchar(100) DEFAULT NULL COMMENT 楼层位置方便展示在详情页, intro varchar(255) DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE doctor ( id int(11) NOT NULL AUTO_INCREMENT, department_id int(11) NOT NULL COMMENT 所属科室, name varchar(20) NOT NULL, title varchar(50) DEFAULT NULL COMMENT 职称主治/副主任/主任, avatar varchar(255) DEFAULT NULL, intro varchar(255) DEFAULT NULL, PRIMARY KEY (id), KEY idx_department (department_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;openid加唯一索引是登录不串号的底线一个微信号对应一条用户记录重复登录走更新而非新增。department_id的索引支撑「按科室查医生列表」这个最高频查询不加也行数据量小但如果后面要做科室分类统计索引能省不少事。前两张表不要放冗余字段医生的科室名称需要展示时直接连表查询不要让doctor表存一个department_name这是典型的反范式错误做法。真正决定这套系统复杂度的是排班表和预约表CREATE TABLE schedule ( id int(11) NOT NULL AUTO_INCREMENT, doctor_id int(11) NOT NULL, schedule_date date NOT NULL COMMENT 出诊日期, period tinyint(1) NOT NULL DEFAULT 1 COMMENT 1上午 2下午, total int(11) NOT NULL COMMENT 总号量, remain int(11) NOT NULL DEFAULT 0 COMMENT 剩余号量, version int(11) NOT NULL DEFAULT 0 COMMENT 乐观锁版本号, PRIMARY KEY (id), KEY idx_doctor_date (doctor_id, schedule_date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE appointment ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, schedule_id int(11) NOT NULL, patient_name varchar(20) NOT NULL COMMENT 就诊人姓名支持替家人挂号, patient_card varchar(30) DEFAULT NULL COMMENT 就诊卡号到院绑定用, status tinyint(1) NOT NULL DEFAULT 1 COMMENT 1已预约 2已取消 3已完成 4已过期, code varchar(10) NOT NULL COMMENT 取号凭证到院出示, create_time datetime DEFAULT NULL, PRIMARY KEY (id), KEY idx_user (user_id), KEY idx_schedule (schedule_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;schedule表的粒度是「医生 日期 时段」这是挂号的最小单位。用户在页面上看到的「上午还剩 3 个号」实际读的就是remain字段。很多初学者会把号量直接写在doctor表里结果遇到「周一放 20 个号、周二放 30 个号」的需求就要改表结构这就是没把实体关系理顺。appointment表刻意加了patient_name字段因为替父母、替孩子挂号是线下医院最常见的场景把这个字段设计进去论文里的功能模块图和创新点都能多写一页。2.2 预约状态机为什么取消预约不是删除记录预约表里有四个状态这是这套系统的第二个关键设计。直接删除预约记录会导致用户看不到历史订单医院也没有「取消率」可言所以取消操作本质是「把状态从已预约改成已取消」。状态值含义触发时机1已预约用户提交预约成功后写入2已取消用户主动取消或管理员手动取消3已完成就诊日结束后由定时任务批量更新4已过期就诊日已过但用户未取消系统自动判定状态机的推进方向是单向的已预约可以变成已取消或已完成但不能从已完成再变回已预约。小程序端的「我的预约」页面每一条记录都要先读状态再决定按钮显示成「取消预约」还是「去评价」还是「已过期」。常见的翻车是有人用delete from appointment where id?实现取消导致用户在订单列表里看到的记录直接消失而且后面做统计分析时数据永远对不上。保留记录的成本极低收益是论文的数据分析模块有的写比如「统计某科室一周取消率」这种表格一画答辩时老师就不容易追问出漏洞。2.3 辅助表和唯一约束管理员、密码字段不要给自己埋雷除了五张核心表还需要管理员表和公告表。管理员表负责后台登录公告表用来在小程序首页展示停诊通知这两张表结构简单但对系统完整性帮助很大:CREATE TABLE admin ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(64) NOT NULL COMMENT 存储加盐后的哈希值, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE notice ( id int(11) NOT NULL AUTO_INCREMENT, title varchar(100) NOT NULL, content text, create_time datetime DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;注意admin表的password毕业设计里大量出现明文存储或裸 MD5答辩时被老师一句「你是怎么防脱库的」就能问住。我一般建议用 MD5 加盐或 BCrypt代码量只多几行但能直接写进「系统安全性设计」章节属于性价比极高的两三行代码。另一个容易踩坑的地方是唯一约束不要对appointment(user_id, schedule_id)建简单唯一索引因为一位用户对同一个排班只能有一条「有效」预约但取消之后会有历史记录简单唯一索引会让「取消再约」直接报错。正确的姿态是把这个判断交给 service 层在事务里查有效状态的预约是否存在。提示建表统一用utf8mb4不要用utf8。虽然 MySQL 里这俩在绝大多数场景下表现一样但utf8mb4才能完整支持生僻字和部分符号一次性建成后面就不用返工。3. SSM 后端怎么写service 层决定这套代码能不能扛住并发SSM 这套组合现在仍是很多高校课程的主线Spring 管对象和事务、SpringMVC 管接口路由、MyBatis 管 SQL 映射。它的好处是每一层的职责非常明确坏处是配置文件多初学者经常被 XML 绊住。我在这一章不准备从头贴配置而是把「预约」这个核心接口从 Controller 到 Mapper 完整走一遍再把最容易写错的地方圈出来。3.1 工程结构和依赖Controller-Service-Mapper 三层要拆干净标准 Maven 工程结构如下包名我用的是com.example.hospital你按自己的小组名替换即可hospital-server/ ├── pom.xml └── src/main/ ├── java/com/example/hospital/ │ ├── controller/ # 接口层只做参数接收和结果封装 │ ├── service/ # 业务层事务、状态判断都在这里 │ ├── mapper/ # MyBatis 接口对应 XML 里的 SQL │ ├── entity/ # 实体类跟数据库表一一对应 │ └── common/ # 统一响应、常量、工具类 └── resources/ ├── spring/ ├── mybatis/ └── mapper/*.xmlpom 依赖不需要花哨核心就三个dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId version5.3.x/version /dependency dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId version2.0.x/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.x/version /dependency版本号整体用 5.3.x / 2.0.x / 8.0.x 这一代就行不用追新。三个依赖对应的分别是 SpringMVC、MyBatis 与 Spring 的桥接包、MySQL 驱动。很多同学会漏掉mybatis-spring只引入mybatis本体结果 Spring 容器里死活扫不到 Mapper 接口报错信息又长又抽象。另外连接池我建议用dbcp2或druid之一二选一即可纯 JDBC 连接在测试时「偶尔好用偶尔卡死」属于给自己找不痛快。3.2 统一响应和 Controller 层写法业务错误别返回 HTTP 500前后端联调时最容易吵架的地方是「这接口到底有没有成功」。前端要做的事情很多预约按钮要置灰、失败要弹 toast、成功要跳页面。如果后端一会儿返回 200 一会儿返回 500前端每个请求都要写两套处理逻辑。所以我第一件事就是定一个统一响应体public class R { private int code; // 200 成功500 业务失败401 登录过期 private String message; private Object data; public static R ok(Object data) { return new R(200, success, data); } public static R fail(String message) { return new R(500, message, null); } // 省略构造函数和 getter/setter }这里的code是业务状态码并不是 HTTP 状态码。预约失败、号源已满这类业务异常HTTP 层照样返回 200只是 body 里的code是 500前端通过res.data.code判断。这样做的目的是让 HTTP 层和中端代理层的日志保持干净把错误归类到业务侧。Controller 里所有方法都返回R前端拿到数据后先判断code 200再做后续操作逻辑统一不需要在每个页面写重复的容错。3.3 预约方法事务、行锁和「乐观扣减」的完整写法预约接口是整个系统最值得讲的部分也是答辩时老师最可能追问的地方。核心需求一句话在多人同时抢最后一个号时系统不能超卖。最低级的写法是「先查remainJava 里判断大于 0再执行 update」这在并发下必出问题——两个线程同时读到remain 1都认为自己能约最后remain变成负数。我的处理方式是事务 条件更新两步一起做Transactional public R book(BookRequest req) { // 1. 锁住排班行避免并发读同一份号源 Schedule schedule scheduleMapper.selectForUpdate(req.getScheduleId()); if (schedule null) { return R.fail(排班不存在); } // 2. 校验日期过期的排班不能预约 if (schedule.getScheduleDate().isBefore(LocalDate.now())) { return R.fail(该排班已过期); } // 3. 同一用户对同一排班只能有一条有效预约 int validCount appointmentMapper.countValid(req.getUserId(), req.getScheduleId()); if (validCount 0) { return R.fail(您已预约过该号源请勿重复预约); } // 4. 条件扣减remain 大于 0 才允许更新 int rows scheduleMapper.deduct(req.getScheduleId()); if (rows 0) { return R.fail(该时段号源已满); } // 5. 写入预约记录 Appointment appointment new Appointment(); appointment.setUserId(req.getUserId()); appointment.setScheduleId(req.getScheduleId()); appointment.setPatientName(req.getPatientName()); appointment.setStatus(1); appointment.setCode(generateCode(schedule)); appointmentMapper.insert(appointment); return R.ok(appointment); }selectForUpdate对应的是SELECT ... FOR UPDATE它会把这一行锁住直到事务提交才释放。第 4 步的deduct对应的 SQL 是关键update iddeduct UPDATE schedule SET remain remain - 1, version version 1 WHERE id #{scheduleId} AND remain 0 /updatewhere remain 0保证扣减本身就是一次「检查再更新」返回的rows是受影响行数为 0 说明号源已经没了。这套组合的巧妙之处在于不需要显式地在 Java 里写锁数据库的行锁和条件更新天然把并发挡在了外面。要注意的是Transactional必须加在 public 方法上并且不能是同类内部调用否则事务不会生效。排班表的version字段就是乐观锁版本号在数据一致性的讲解里可以配合画时序图这也是论文里拿得出手的细节。4. 微信小程序端怎么对接从 wx.login 到预约成功页微信小程序的开发难度其实比后端低真正坑人的是登录态维护和按钮防连点。很多照着教程做的同学后端接口写得还行一到小程序端就乱套登录要么每次都重新登录要么 token 过期了还拿着旧身份在请求。这一章我按完整链路走一遍从登录到预约成功页面的数据绑定。4.1 登录链路小程序端发 code后端换 openid微信开放能力设计得很明确小程序端拿不到用户真实的 openid只能通过wx.login拿到一个临时 code然后交给后端由后端用 code appid secret 去微信服务器换取 openid。这个 secret 是绝不能出现在小程序代码里的否则任何人都能冒充你的后端。前端代码很简单// pages/login/login.js wx.login({ success: (res) { wx.request({ url: https://yourdomain.com/api/user/login, method: POST, data: { code: res.code }, success: (resp) { if (resp.data.code 200) { wx.setStorageSync(token, resp.data.data.token); wx.navigateBack(); } else { wx.showToast({ title: 登录失败, icon: none }); } } }); } });wx.login返回的 code 有效期只有几分钟而且只能用一次所以拿到后要立刻发给后端。后端收到 code 后请求微信的jscode2session接口拿到 openid 后不要原样返回给前端而是生成一个自定义 token 存起来后续请求都带这个 token。常见做法是建一张token表或者在内存 Map 里维护 token 到 user_id 的映射毕业设计规模用表足够Redis 会引入新的依赖论文还要多写一节环境搭建没必要。4.2 请求封装和 401 兜底每个页面少写十行重复代码小程序原生的wx.request回调风格很啰嗦每个页面都写一遍success/fail会导致代码大量重复。我习惯封装一个 Promise 化的请求方法所有页面统一调用// utils/request.js function request(path, data, method POST) { return new Promise((resolve, reject) { wx.request({ url: https://yourdomain.com path, method: method, data: data, header: { Authorization: wx.getStorageSync(token) || }, success: (res) { if (res.data.code 401) { // 登录过期先清掉本地 token 再跳登录页 wx.removeStorageSync(token); wx.navigateTo({ url: /pages/login/login }); return; } resolve(res.data); }, fail: reject }); }); }这里有个细节值得注意登录过期的判定不依赖 HTTP 401而是看res.data.code 401。我在后端统一响应里定义过 401 这个业务码由拦截器在 token 校验失败时返回。前端一旦拿到 401就清空本地 token 并跳登录页这个兜底逻辑放在封装层所有页面自动生效不需要每个页面单独判断。4.3 科室列表、排班选择和预约按钮防连点科室列表页面的数据流是「页面加载 → 调后端接口 → setData → wx:for 渲染」。页面逻辑比较简单但有两个地方新手容易写丑一是wx:for忘记加wx:key控制台会一直告警二是把整个列表塞进一个view的字符串里渲染。正确做法是把数据直接绑定到数组上!-- pages/department/index.wxml -- view classdepart-item wx:for{{departList}} wx:keyid bindtapgoDoctorList >// pages/department/index.js getDepartmentList() { request(/api/department/list, {}, GET).then(res { if (res.code 200) { this.setData({ departList: res.data }); } }); }排班选择页面更需要注意预约按钮的「防连点」问题用户手快点了两下会发出两个请求后端如果没做状态判断就会出现两条预约单。前端能做的是一旦点过就立刻让按钮进入 loading 态禁止再次点击button bindtaponBook disabled{{booking}} {{booking ? 提交中... : 立即预约}} /buttononBook() { if (this.data.booking) return; this.setData({ booking: true }); request(/api/appointment/book, { scheduleId: this.data.scheduleId, patientName: this.data.patientName }).then(res { if (res.code 200) { wx.navigateTo({ url: /pages/order/detail?id res.data.id }); } else { wx.showToast({ title: res.message, icon: none }); } }).finally(() { this.setData({ booking: false }); }); }这里的disabled和booking双保险缺一不可disabled从视觉上阻止第二次点击booking在逻辑上兜底防止异步回调还没回来时用户通过其他方式触发事件。即使前端做到位了后端第 3 章里「同一用户对同一排班只能有一条有效预约」的判断仍然是最终防线前端防误触、后端防并发两边配合才不会出乱子。5. 避坑真机 404、中文乱码、号源超卖、日期错位的排查记录这套方案我自己完整做过一遍也从别人翻车的代码里排除过问题。下面五条是出现频率最高的每一条都是「现象 → 原因 → 解决」的排查思路按优先级从高到低排列。5.1 真机上请求全挂开发者工具里却一切正常现象在微信开发者工具里点预约后端接口正常返回一扫码到真机所有wx.request直接进 fail 回调页面白屏或弹「网络异常」。原因微信小程序的生产环境要求请求域名必须已备案、支持 HTTPS并且在小程序后台配置到「request 合法域名」里。开发者工具默认勾选了「不校验合法域名」所以本机开发时能通真机上这条校验是强制的。解决开发阶段在「详情 → 本地设置」勾选「不校验合法域名、TLS 版本以及 HTTPS 证书」只用于调试。上线前把后端域名配到小程序后台的 request 合法域名列表。如果你的后端是本地局域网 IP真机调试时只能让手机和电脑连同一个 Wi-Fi并且后端监听地址不能是localhost要改成0.0.0.0否则手机根本访问不到。5.2 后端返回的中文变成「???」或乱码现象登录接口返回的昵称、科室名称在数据库里正常页面显示却是乱码。有些同学会往代码里加各种编码过滤器问题依旧。原因三处编码不一致。最常见的是 JDBC 连接串没指定characterEncodingutf8MySQL 默认按 latin1 读取请求参数其次是表的字符集建成了utf8甚至默认的latin1第三是后端响应头里没有application/json;charsetutf-8。解决连接串一次性配好别拖jdbc:mysql://localhost:3306/hospital?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai表字符集在建表脚本里已经统一用utf8mb4如果已经建好的表用一句话改掉ALTER TABLE department CONVERT TO CHARACTER SET utf8mb4;改完连接串和表字符集后重启 Tomcat乱码基本消失。如果还有问题看 MySQL 服务端my.ini里的character-set-server配置把它也改成utf8mb4。这一条属于排查顺序问题先查连接串再查表不要一上来就改代码。5.3 排班日期显示总是差一天预约接口提示「已过期」现象后端数据库里排班日期是 2025-06-01小程序页面显示「2025-05-31」或者明明还没过期预约时却提示「该排班已过期」。原因日期差一天通常有两个来源。一个是 JDBC 连接串没指定serverTimezoneMySQL 驱动会拿服务器默认时区和本地时区做换算导致DATE类型读出后偏移。另一个是前端把字符串转成Date对象时引擎把2025-06-01解析成了 UTC 时间展示时再按本地时区转就少了一天。解决后端连接串加上serverTimezoneAsia/Shanghai这在上一条的配置里已经带了。前端如果有new Date(2025-06-01)这类代码直接去掉使用纯字符串格式作为展示值// 不要写 new Date(2025-06-01).toLocaleDateString() // 直接展示后端返回的字符串 this.setData({ dateText: res.data.scheduleDate });凡是「显示层」需要展示的日期一律以后端字符串为准只在做日期比较时才转成Date。这个习惯能省掉很多时区玄学问题。如果需要做日期计算建议用dayjs之类的库原生Date对 ISO 字符串的处理太容易踩坑。5.4 号源超卖预约成功人数超过 totalremain 变成负数现象排班显示总号量 20实际库里预约记录有 25 条remain是 -5。原因典型的竞态问题。两个请求同时进入预约方法都执行了「查询 remain → 判断大于 0 → 更新」查询阶段两者都读到remain 1于是都进入更新阶段各扣一次结果变成 -1。没有事务保护和条件更新高并发下必现只是时间和请求量的问题。解决用第 3 章写的update schedule set remain remain - 1 where id ? and remain 0来扣减号源不要用「先查后改」。同时服务层加Transactional保证扣减和插入预约单要么都成功要么都失败。验证办法很简单用第 6 章的并发脚本打 30 个请求去看最终remain是否等于total - 成功预约数如果出现负数就是这里没写对。这一条是答辩时最容易被追问的点写清楚能直接拉高项目评价。5.5 接口 404 或者启动时「扫描不到 Controller」现象Tomcat 能正常启动但访问/api/department/list返回 404或者后端一直报「No mapping found for HTTP request」日志里只出现一行告警。原因Spring 容器扫不到 Controller 类。常见场景有三个context:component-scan的 base-package 写错了扫到了空的包路径Controller类编译后的 class 文件没被复制到 Tomcat 的 class 目录新版 Tomcat 下web.xml里DispatcherServlet拦截了所有请求但没有配置springmvc.xml的包扫描。解决先看启动日志里有没有RequestMappingHandlerMapping的映射记录确认哪些接口被注册了。把 spring 配置文件里的扫描路径改成和包名完全一致context:component-scan base-packagecom.example.hospital.controller/ context:component-scan base-packagecom.example.hospital.service/注意service包也必须有否则 service 层的Service没被扫描Controller 里Autowired会报错或注入 null。排查时养成「先看日志、再对包路径、最后看编译目录」的习惯这类 404 基本都是配置问题而不是代码问题。6. 答辩前这样验证用并发脚本给预约接口「上强度」后端写完成不完整别只拿 Postman 点两下就宣告收工。挂号系统的核心竞争点是并发不出错验证这一步用不了一分钟但能提前暴露最严重的问题。我一般用一个 bash 脚本模拟多人同时抢号把预约接口用 30 个并发请求同时打过去看最终库里的预约记录数是否超过 total。# 30 个并发请求抢同一个排班号源 for i in $(seq 1 30); do curl -s -X POST http://localhost:8080/api/appointment/book \ -H Content-Type: application/json \ -d {scheduleId:1,userId:$i,patientName:压力测试用户} done wait脚本跑完后执行一条查询核对数据一致性SELECT remain FROM schedule WHERE id 1; SELECT COUNT(*) FROM appointment WHERE schedule_id 1 AND status 1;如果remain是负数或者第二个查询结果大于total说明第 3 章的并发控制没写对这是答辩前最不能留的问题。演示环节的流程同样要提前定好顺序我的习惯是「后台发布排班 → 用户登录 → 预约 → 取消 → 再约」这条主流程一镜到底把状态机完整展示一遍。数据库里按 2.2 的状态定义预置几条不同状态的订单演示时切到「我的预约」页面让老师看到已预约、已取消、已过期三种状态同时存在。答辩老师最喜欢问的问题就是「你怎么保证不超卖」和「取消预约之后号源会不会释放」这两条答案在 3.3 和 2.2 里都准备好了熟练把update ... where remain 0的 SQL 背出来就够了。我自己最容易在演示时翻车的点反而是环境问题服务器 8080 端口被其他服务占掉Tomcat 起不来。现在每次验证前我的习惯是先跑一条netstat -ano | grep 8080确认端口干净再启动服务。这方法不复杂但能救很多次场。希望帮到你。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号