ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Spring Boot的智慧门诊预约与排队叫号系统的设计与实现

基于Spring Boot的智慧门诊预约与排队叫号系统的设计与实现 1. 项目背景与意义随着医疗信息化建设的不断深入传统门诊就医流程中挂号排队时间长、候诊秩序混乱、医生接诊效率低等问题日益突出。患者往往需要提前到院排队挂号候诊区人员聚集既增加了交叉感染风险也降低了患者就医体验。与此同时医院门诊管理缺乏统一的信息化调度手段号源分配不透明、过号处理困难、叫号依赖人工广播难以满足现代化医院精细化运营的需求。基于Spring Boot的智慧门诊预约与排队叫号系统旨在通过信息化手段重构门诊就医流程实现预约挂号、号源管理、智能排队、叫号提醒、过号处理等环节的一体化管理。系统以患者为中心以号源为主线将预约、签到、排队、叫号、就诊、复诊等环节串联起来帮助医院合理调配医疗资源缩短患者无效等待时间提升门诊整体运行效率和服务质量。从实际意义来看本系统的建设具有以下价值改善就医体验患者可在线预约、实时查看排队进度减少盲目等待和来回奔波。提升管理效率号源统一管理、队列自动调度减轻分诊台和护士站人工压力。优化资源配置通过分时段预约和动态叫号均衡医生接诊负荷减少资源闲置。支撑数据决策沉淀门诊流量、候诊时长、过号率等数据为医院运营管理提供依据。2. 系统技术栈本系统采用前后端分离架构后端基于Spring Boot构建前端使用Vue.js配合Element UI组件库数据库选用MySQL缓存层使用Redis整体技术选型兼顾开发效率、运行稳定性和后期可维护性。层次技术选型说明后端框架Spring Boot 2.7.x提供自动配置、内嵌容器、快速构建RESTful服务持久层MyBatis-Plus简化单表CRUD操作内置分页插件数据库MySQL 8.0存储用户、号源、预约、排队等业务数据缓存Redis缓存号源余量、排队状态、验证码等热点数据安全认证Spring Security JWT实现登录认证与接口权限控制前端框架Vue.js 3 Element Plus构建管理端和患者端页面实时通信WebSocket实现叫号通知和排队进度实时推送接口文档Swagger / Knife4j自动生成在线接口文档便于前后端联调3. 系统功能模块设计系统按用户角色划分为患者端、医生端和管理员端三个主要入口核心功能围绕预约、排队、叫号三条业务主线展开。3.1 患者端功能用户注册登录支持手机号注册、密码登录和JWT身份认证。科室与医生查询按科室、医生、日期查询可预约号源。在线预约挂号选择就诊时段提交预约锁定号源。排队进度查询实时查看当前排队位置和预计等待时间。签到与过号处理到院签到进入候诊队列过号可申请重新排队。3.2 医生端功能当日患者列表查看已签到和待就诊患者信息。叫号操作呼叫下一位患者支持重呼、过号标记。就诊状态管理将患者状态更新为就诊中、已完成或转诊。3.3 管理员端功能科室与医生管理维护科室信息、医生排班和出诊时间。号源规则配置设置每日号源总量、分时段号源数量。队列监控实时查看各科室候诊人数和平均等待时长。数据统计统计预约量、就诊量、过号率、平均候诊时间等指标。4. 数据库设计系统核心数据表包括用户表、医生表、科室表、号源表、预约记录表和排队记录表。以下列出主要表结构。4.1 用户表 t_user字段名类型说明idbigint主键自增phonevarchar(20)手机号唯一passwordvarchar(100)加密后的密码real_namevarchar(50)真实姓名roletinyint角色1患者2医生3管理员create_timedatetime创建时间4.2 号源表 t_slot字段名类型说明idbigint主键自增doctor_idbigint医生IDslot_datedate出诊日期start_timevarchar(10)时段开始时间如08:00end_timevarchar(10)时段结束时间total_countint该时段号源总量remain_countint剩余号源数量4.3 预约记录表 t_appointment字段名类型说明idbigint主键自增user_idbigint患者用户IDslot_idbigint号源IDappointment_novarchar(30)预约流水号statustinyint状态0待签到1已签到2已完成3已取消4过号create_timedatetime预约创建时间4.4 排队记录表 t_queue字段名类型说明idbigint主键自增appointment_idbigint预约记录IDdoctor_idbigint医生IDqueue_noint排队序号statustinyint状态0等待中1叫号中2已完成3过号call_countint叫号次数create_timedatetime进入队列时间5. 核心功能实现5.1 预约挂号接口预约挂号是系统的核心业务之一。患者选择医生和时段后提交预约请求后端需要完成号源校验、余量扣减和预约记录创建三个步骤。为保证并发场景下号源不超卖这里使用Redis分布式锁对号源扣减进行保护。Service public class AppointmentServiceImpl implements AppointmentService { Autowired private SlotMapper slotMapper; Autowired private AppointmentMapper appointmentMapper; Autowired private StringRedisTemplate redisTemplate; Override Transactional(rollbackFor Exception.class) public Appointment createAppointment(Long userId, Long slotId) { String lockKey lock:slot: slotId; String lockValue UUID.randomUUID().toString(); Boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, lockValue, Duration.ofSeconds(10)); if (Boolean.FALSE.equals(locked)) { throw new BusinessException(系统繁忙请稍后重试); } try { Slot slot slotMapper.selectById(slotId); if (slot null || slot.getRemainCount() lt; 0) { throw new BusinessException(该时段号源已约满); } // 扣减号源余量 int updated slotMapper.decreaseRemainCount(slotId); if (updated 0) { throw new BusinessException(该时段号源已约满); } // 创建预约记录 Appointment appointment new Appointment(); appointment.setUserId(userId); appointment.setSlotId(slotId); appointment.setAppointmentNo(generateAppointmentNo()); appointment.setStatus(0); appointment.setCreateTime(LocalDateTime.now()); appointmentMapper.insert(appointment); return appointment; } finally { // 释放分布式锁 String currentValue redisTemplate.opsForValue().get(lockKey); if (lockValue.equals(currentValue)) { redisTemplate.delete(lockKey); } } } private String generateAppointmentNo() { return AP System.currentTimeMillis() String.format(%04d, new Random().nextInt(10000)); } }5.2 排队叫号实现患者到院签到后进入候诊队列系统按签到顺序生成排队序号。医生点击叫号时后端从队列中取出当前等待的患者将其状态更新为叫号中并通过WebSocket向前端推送叫号通知。Service public class QueueServiceImpl implements QueueService { Autowired private QueueMapper queueMapper; Autowired private AppointmentMapper appointmentMapper; Autowired private WebSocketServer webSocketServer; Override public QueueRecord signIn(Long appointmentId) { Appointment appointment appointmentMapper.selectById(appointmentId); if (appointment null || appointment.getStatus() ! 0) { throw new BusinessException(当前预约状态不可签到); } // 更新预约状态为已签到 appointment.setStatus(1); appointmentMapper.updateById(appointment); // 生成排队记录 int maxQueueNo queueMapper.selectMaxQueueNo(appointment.getDoctorId()); QueueRecord queueRecord new QueueRecord(); queueRecord.setAppointmentId(appointmentId); queueRecord.setDoctorId(appointment.getDoctorId()); queueRecord.setQueueNo(maxQueueNo 1); queueRecord.setStatus(0); queueRecord.setCallCount(0); queueRecord.setCreateTime(LocalDateTime.now()); queueMapper.insert(queueRecord); return queueRecord; } Override public QueueRecord callNext(Long doctorId) { // 查询当前等待中的最小排队序号 QueueRecord next queueMapper.selectNextWaiting(doctorId); if (next null) { throw new BusinessException(当前没有等待中的患者); } next.setStatus(1); next.setCallCount(next.getCallCount() 1); queueMapper.updateById(next); // 通过WebSocket推送叫号消息 webSocketServer.sendMessageToDoctor(doctorId, 请 next.getQueueNo() 号患者到 诊室就诊); return next; } }5.3 号源初始化定时任务管理员配置好医生排班后系统通过定时任务为每个出诊日自动生成号源记录。这里使用Spring Boot自带的Scheduled注解实现每日凌晨执行。Component public class SlotGenerateTask { Autowired private DoctorScheduleMapper scheduleMapper; Autowired private SlotMapper slotMapper; Scheduled(cron 0 0 1 * * ?) public void generateDailySlots() { LocalDate targetDate LocalDate.now().plusDays(7); Listlt;DoctorSchedulegt; schedules scheduleMapper .selectByDate(targetDate); for (DoctorSchedule schedule : schedules) { // 按每30分钟一个时段生成号源 LocalTime start schedule.getStartTime(); LocalTime end schedule.getEndTime(); while (start.isBefore(end)) { LocalTime slotEnd start.plusMinutes(30); Slot slot new Slot(); slot.setDoctorId(schedule.getDoctorId()); slot.setSlotDate(targetDate); slot.setStartTime(start.toString()); slot.setEndTime(slotEnd.toString()); slot.setTotalCount(schedule.getSlotCount()); slot.setRemainCount(schedule.getSlotCount()); slotMapper.insert(slot); start slotEnd; } } } }5.4 WebSocket实时推送配置排队叫号系统对实时性要求较高前端需要及时感知叫号状态变化。系统使用Spring Boot内置的WebSocket能力实现服务端主动推送。Component public class WebSocketServer { private static final Maplt;Long, Sessiongt; DOCTOR_SESSIONS new ConcurrentHashMaplt;gt;(); OnOpen public void onOpen(Session session, PathParam(doctorId) Long doctorId) { DOCTOR_SESSIONS.put(doctorId, session); } OnClose public void onClose(PathParam(doctorId) Long doctorId) { DOCTOR_SESSIONS.remove(doctorId); } public void sendMessageToDoctor(Long doctorId, String message) { Session session DOCTOR_SESSIONS.get(doctorId); if (session ! null amp;amp; session.isOpen()) { try { session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } } }6. 系统界面设计系统前端采用Vue.js 3和Element Plus组件库构建主要页面包括患者端的预约挂号页、排队进度页医生端的叫号工作台以及管理端的号源配置和数据统计页。患者端预约页面以科室、医生、日期三个维度提供筛选条件号源余量实时展示患者选择时段后确认预约即可完成挂号。排队进度页面通过进度条和数字展示当前排队位置配合WebSocket推送实现叫号提醒。医生端叫号工作台以卡片形式展示当日患者队列支持一键叫号、重呼、过号标记等操作界面简洁直观减少医生操作负担。7. 总结与展望本文设计并实现了一个基于Spring Boot的智慧门诊预约与排队叫号系统覆盖预约挂号、号源管理、签到排队、叫号通知等核心业务流程。系统采用前后端分离架构通过Redis分布式锁解决号源并发扣减问题借助WebSocket实现叫号实时推送整体方案在功能完整性和技术可行性上均达到了预期目标。后续可以从以下几个方向继续优化一是引入消息队列削峰填谷应对就诊高峰期的并发压力二是结合大数据分析预测各科室就诊流量辅助医院动态调整号源配置三是对接医院HIS系统实现患者信息、费用结算等更深层次的数据互通。
返回列表