SpringBoot+微信小程序医院预约挂号系统开发实践

发布时间:2026/9/17 9:24:18

SpringBoot+微信小程序医院预约挂号系统开发实践 1. 项目概述作为一名有10年开发经验的Java全栈工程师我最近完成了一个基于SpringBoot微信小程序的医院预约挂号系统。这个项目不仅适合作为计算机相关专业的毕业设计选题也完全可以作为实际医院门诊系统的原型进行二次开发。这个系统采用了当前主流的B/S架构前端使用微信小程序Vue.js实现移动端应用后端基于SpringBoot框架开发数据库选用MySQL。系统实现了完整的预约挂号流程包括用户注册登录、医生排班管理、号源管理、预约挂号、订单支付、就诊记录查询等功能模块。在实际开发过程中我遇到了不少技术难点比如微信小程序与后端API的对接、高并发场景下的号源锁定机制、分布式事务处理等。通过这个项目我积累了很多宝贵的实战经验下面就来详细分享这个系统的设计与实现过程。2. 系统架构设计2.1 技术栈选型在项目启动阶段我经过多方比较最终确定了以下技术栈后端技术栈Spring Boot 2.7.x简化配置快速构建微服务Spring Security认证与授权管理MyBatis-Plus简化数据库操作Redis缓存热点数据提高系统响应速度RabbitMQ异步处理预约消息削峰填谷前端技术栈微信小程序原生开发适配移动端Vue.js 3.x管理后台前端框架Element PlusUI组件库数据库MySQL 8.0关系型数据库Redis 6.x缓存数据库选择这些技术主要基于以下几点考虑Spring Boot生态成熟社区支持好遇到问题容易找到解决方案微信小程序用户基数大无需安装使用方便Vue.jsElement Plus组合开发管理后台效率高MySQLRedis的组合可以满足大部分医院场景的数据存储需求2.2 系统架构设计系统采用典型的分层架构设计┌───────────────────────────────────────┐ │ 微信小程序客户端 │ └───────────────────────────────────────┘ ▲ │ HTTP/HTTPS ▼ ┌───────────────────────────────────────┐ │ API Gateway │ │ (路由、限流、认证、日志、监控等) │ └───────────────────────────────────────┘ ▲ │ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 用户服务 │ │ 预约服务 │ │ 支付服务 │ └─────────────┘ └─────────────┘ └─────────────┘ ▲ ▲ ▲ │ │ │ ▼ ▼ ▼ ┌───────────────────────────────────────┐ │ MySQL集群 │ └───────────────────────────────────────┘ ▲ ▲ ▲ │ │ │ ▼ ▼ ▼ ┌───────────────────────────────────────┐ │ Redis集群 │ └───────────────────────────────────────┘这种架构设计具有以下优势前后端完全分离便于独立开发和部署微服务架构各服务职责单一便于扩展引入API网关统一处理跨域、认证、限流等问题数据库读写分离提高系统吞吐量3. 核心功能模块实现3.1 用户认证模块用户认证是系统的第一个门槛我采用了JWT(JSON Web Token) 微信小程序登录的方案// 微信小程序登录接口示例 PostMapping(/wxLogin) public Result wxLogin(RequestBody WxLoginDTO dto) { // 1. 调用微信接口获取openid String openid wxService.getOpenid(dto.getCode()); // 2. 查询或创建用户 User user userService.findOrCreateByOpenid(openid); // 3. 生成JWT token String token JwtUtil.generateToken(user.getId(), user.getRole()); // 4. 返回token和用户基本信息 return Result.success(new LoginVO(token, user)); }关键点说明微信小程序前端调用wx.login()获取临时code后端用code向微信服务器换取openid根据openid查询用户不存在则自动注册使用JWT生成token返回给客户端安全考虑token设置合理过期时间(如2小时)敏感接口需要校验token和用户角色记录登录日志防范恶意请求3.2 号源管理模块号源管理是系统的核心功能需要考虑医生排班、号源生成、号源状态变更等场景// 生成未来7天的号源 Scheduled(cron 0 0 0 * * ?) // 每天凌晨执行 public void generateSchedule() { // 1. 获取所有医生 ListDoctor doctors doctorMapper.selectList(null); // 2. 为每个医生生成未来7天的排班 for (Doctor doctor : doctors) { for (int i 1; i 7; i) { LocalDate date LocalDate.now().plusDays(i); // 3. 检查是否是医生的休息日 if (!doctor.getWorkDays().contains(date.getDayOfWeek().getValue())) { continue; } // 4. 生成上午和下午的号源 generateTimeSlot(doctor, date, 08:00-12:00, 30); generateTimeSlot(doctor, date, 14:00-18:00, 30); } } } private void generateTimeSlot(Doctor doctor, LocalDate date, String period, int total) { Schedule schedule new Schedule(); schedule.setDoctorId(doctor.getId()); schedule.setWorkDate(date); schedule.setWorkPeriod(period); schedule.setTotalNumber(total); schedule.setAvailableNumber(total); scheduleMapper.insert(schedule); }关键业务逻辑使用定时任务每天自动生成未来7天的号源考虑医生的工作日设置(如每周三休息)每个时段(上午/下午)设置合理的号源数量支持手动调整号源(如临时停诊)3.3 预约挂号模块预约挂号需要考虑高并发场景下的数据一致性问题我采用了Redis分布式锁乐观锁的方案Transactional public Result makeAppointment(AppointmentDTO dto) { // 1. 获取分布式锁 String lockKey lock:schedule: dto.getScheduleId(); boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, 1, 10, TimeUnit.SECONDS); if (!locked) { return Result.fail(当前号源紧张请稍后再试); } try { // 2. 查询号源信息 Schedule schedule scheduleMapper.selectById(dto.getScheduleId()); if (schedule null || schedule.getAvailableNumber() 0) { return Result.fail(号源已约满); } // 3. 使用乐观锁更新号源 int updated scheduleMapper.decreaseAvailableNumber( dto.getScheduleId(), schedule.getVersion()); if (updated 0) { return Result.fail(号源已被其他用户预约); } // 4. 创建预约记录 Appointment appointment new Appointment(); // 设置预约信息... appointmentMapper.insert(appointment); // 5. 发送MQ消息异步处理后续流程 rabbitTemplate.convertAndSend( appointment.exchange, appointment.create, appointment.getId()); return Result.success(预约成功); } finally { // 释放锁 redisTemplate.delete(lockKey); } }并发控制策略使用Redis分布式锁防止超卖数据库乐观锁确保数据一致性异步处理非核心流程(如发送通知)合理设置锁的超时时间避免死锁4. 数据库设计4.1 主要表结构用户表(user)CREATE TABLE user ( id bigint NOT NULL AUTO_INCREMENT, openid varchar(64) DEFAULT NULL COMMENT 微信openid, username varchar(32) NOT NULL COMMENT 用户名, password varchar(64) DEFAULT NULL COMMENT 密码, phone varchar(11) DEFAULT NULL COMMENT 手机号, avatar varchar(255) DEFAULT NULL COMMENT 头像, gender tinyint DEFAULT 0 COMMENT 性别(0未知 1男 2女), birthday date DEFAULT NULL COMMENT 生日, status tinyint DEFAULT 1 COMMENT 状态(0禁用 1正常), create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY idx_openid (openid), UNIQUE KEY idx_phone (phone) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;医生表(doctor)CREATE TABLE doctor ( id bigint NOT NULL AUTO_INCREMENT, name varchar(32) NOT NULL COMMENT 医生姓名, title varchar(32) DEFAULT NULL COMMENT 职称, department_id bigint NOT NULL COMMENT 科室ID, specialty varchar(255) DEFAULT NULL COMMENT 专长, introduction text COMMENT 简介, photo varchar(255) DEFAULT NULL COMMENT 照片, work_days varchar(32) DEFAULT 1,2,3,4,5 COMMENT 工作日(1-7), status tinyint DEFAULT 1 COMMENT 状态(0停诊 1正常), create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_department (department_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT医生表;排班表(schedule)CREATE TABLE schedule ( id bigint NOT NULL AUTO_INCREMENT, doctor_id bigint NOT NULL COMMENT 医生ID, work_date date NOT NULL COMMENT 出诊日期, work_period varchar(20) NOT NULL COMMENT 时段(上午/下午), total_number int NOT NULL COMMENT 总号源数, available_number int NOT NULL COMMENT 可用号源数, version int NOT NULL DEFAULT 0 COMMENT 乐观锁版本号, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_doctor_date_period (doctor_id,work_date,work_period), KEY idx_work_date (work_date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT排班表;4.2 索引优化为了提高查询性能我在以下字段上创建了索引用户表的openid和phone字段 - 用于快速查找用户医生表的department_id字段 - 用于按科室筛选医生排班表的(doctor_id, work_date, work_period)组合唯一索引 - 防止重复排班排班表的work_date字段 - 用于按日期查询排班5. 系统部署与性能优化5.1 部署架构生产环境建议采用以下部署方案┌─────────────────┐ ┌─────────────────┐ │ Nginx LB │ │ Nginx LB │ └────────┬────────┘ └────────┬────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ API Gateway │ │ API Gateway │ └────────┬────────┘ └────────┬────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ 用户服务 │ │ 预约服务 │ └────────┬────────┘ └────────┬────────┘ │ │ ▼ ▼ ┌───────────────────────────────────────┐ │ MySQL集群 │ │ (主从复制读写分离) │ └───────────────────────────────────────┘ ▲ │ ▼ ┌───────────────────────────────────────┐ │ Redis集群 │ │ (哨兵模式自动故障转移) │ └───────────────────────────────────────┘5.2 性能优化措施缓存策略使用Redis缓存热点数据(如医生信息、科室信息)实现多级缓存本地缓存(Caffeine) 分布式缓存(Redis)合理设置缓存过期时间避免脏数据数据库优化主从分离读多写少的场景使用从库对大表进行分表(如按月份分表存储预约记录)合理使用索引避免全表扫描接口优化使用Hystrix实现服务熔断降级对耗时的操作(如生成报表)异步处理接口限流防止恶意请求前端优化小程序使用分包加载图片等静态资源使用CDN加速合理使用本地存储减少网络请求6. 常见问题与解决方案6.1 微信小程序登录失败问题现象调用wx.login获取code后后端无法换取openid排查步骤检查小程序appid和secret是否正确确认小程序后台配置的服务器域名包含当前域名检查微信接口返回的错误信息解决方案// 正确的微信接口调用示例 public String getOpenid(String code) throws WxErrorException { WxMaService wxService WxMaConfiguration.getWxMaService(); WxMaJscode2SessionResult session wxService.getUserService() .getSessionInfo(code); return session.getOpenid(); }6.2 预约超卖问题问题现象同一号源被多个用户同时预约成功原因分析高并发场景下多个请求同时通过库存检查解决方案使用分布式锁控制并发数据库使用乐观锁前端限制频繁点击// 使用Redis分布式锁数据库乐观锁 public boolean lockSchedule(Long scheduleId) { String key lock:schedule: scheduleId; return redisTemplate.opsForValue() .setIfAbsent(key, 1, 10, TimeUnit.SECONDS); } public int decreaseAvailableWithVersion(Long scheduleId, int version) { return scheduleMapper.decreaseAvailableNumber(scheduleId, version); }6.3 定时任务重复执行问题现象集群环境下定时任务在多台服务器上重复执行解决方案使用Redis分布式锁控制任务执行Scheduled(cron 0 0 0 * * ?) public void generateScheduleTask() { String lockKey task:generateSchedule; boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, 1, 5, TimeUnit.MINUTES); if (!locked) { return; } try { generateSchedule(); } finally { redisTemplate.delete(lockKey); } }7. 项目扩展方向这个基础版本完成后还可以考虑以下扩展方向智能推荐基于用户历史就诊记录推荐相关科室和医生在线问诊集成即时通讯功能支持图文问诊检查报告对接医院LIS/PACS系统查看检查结果医保对接与医保系统对接支持医保在线结算大数据分析分析就诊数据辅助医院管理决策在实际开发这个项目的过程中我深刻体会到医疗系统的严谨性和复杂性。每个功能点都需要考虑各种边界条件和异常情况比如医生临时停诊如何处理、预约超时未支付怎么回收号源等。这些细节的处理往往比核心功能的实现更耗费时间但也正是这些细节决定了一个系统的可靠性和用户体验。
延伸阅读

更多相关文章

2026/9/17 9:19:18

光模块:AI算力时代的物理层核心器件

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 9:19:18

YOLOv8模型改进实战:Backbone/Neck/Head优化与剪枝避坑指南

1. 这不是“YOLOv11”,但你必须先搞懂它才能真正改进模型先说一句大实话:目前官方并没有发布YOLOv11。Ultralytics官网最新稳定版本仍是YOLOv8,v9和v10均未正式开源(截至2024年中),所谓“YOLOv11”在主流学…

2026/9/17 9:19:18

制造业智能化转型:AI技术落地与挑战解析

1. 制造业智能化转型的时代背景过去五年间,全球制造业正经历一场由数据驱动的深刻变革。根据麦肯锡全球研究院报告,采用智能化技术的制造企业平均生产效率提升可达30%-50%,而我国东部沿海地区率先开启了这场转型浪潮。作为工业大省&#xff0…

2026/9/17 10:29:28

数据中心物理层规划:机柜选型、布线路径与预连接系统实战解析

简介:美国康普出品的《数据中心规划指南》PDF文档,面向数据中心设计师、网络工程师、IT基础设施管理者,也适用于智慧城市与人工智能背景下的技术决策者,系统讲解从选址到运维的全生命周期规划。压缩包内仅含1个PDF文件&#xff0c…

2026/9/17 10:29:28

CMMI3软件质量保证体系落地拆解:责任分配、评审与QA审计

简介:《精品(2021-2022年)资料软件质量保证体系》是一份面向精品课件开发团队、软件项目经理与QA/QC人员的质量管理文档,重点解决课件从需求、设计、编码到测试交付过程中的质量责任不清、评审与配置管理缺乏统一规范等问题。压缩…

2026/9/17 10:29:28

Boost-Buck级联电路双闭环控制Simulink仿真建模与参数整定

最近在梳理电力电子仿真相关的项目,刚好把手头一个Boost-Buck电路的双闭环控制模型完整整理了一遍。这个题目看着简单,真正做起来涉及的细节挺多——拓扑怎么选、双闭环怎么搭、PI参数怎么调、Simulink模型怎么搭才能跑得稳、波形怎么分析,每…

2026/9/17 10:29:28

Windows GPU UMD开发:stage4part5命令提交与同步实战

1. 这不是“显卡驱动安装教程”,而是一份面向GPU底层开发者的UMD内核级实践手记如果你在搜索引擎里输入“GPU UMD 学习指南 stage4part5”,大概率会撞上一堆PyTorch GPU安装失败、PaddleOCR跑不起来、GPU占用率低但程序卡死的求助帖——这恰恰说明&#…

2026/9/17 10:29:28

保险财务系统落地指南:账务逻辑、数据集成与对账实战

简介:一份面向保险财务从业者与业务系统实施人员的培训PPT,聚焦保险公司财务系统核心机制,系统梳理业务与财务双线并行、预收承保控制、收付费类型与方式、内部转帐、日结分类、异地收付费及业务财务自动接口等关键模块。资源为单个pptx文件&…

2026/9/17 10:24:28

ASM:注意力引导的状态空间建模新范式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码