ARTICLE DETAIL

资讯详情

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

SpringBoot医疗挂号管理系统实战:从零搭建设计到稳定上线

SpringBoot医疗挂号管理系统实战:从零搭建设计到稳定上线 1. 从医院窗口排队说起为什么需要一个挂号管理系统我估摸着凡是做过医疗信息化项目的老哥对医院窗口挂号的长队都不会陌生。早高峰的三甲医院挂号窗口前人挤人专家号几秒抢光普通号也是寸步难行。前几年我参与过一个社区卫生服务中心的信息化改造当时院长提的第一个需求不是电子病历不是智能导诊而是先把挂号这件事理顺。他说得实在别的都可以缓挂号排队这个问题患者骂得最多。医疗挂号管理系统11680就是在这样的背景下做的。它不是一个花哨的Demo而是一套能真实落地到门诊场景中使用的核心业务系统。我做的这套系统基于SpringBoot搭建后端服务前端配合Vue数据库用的是MySQL整体走的是当前Java技术栈里最主流的那套组合。先把这个系统到底解决什么问题说清楚。从患者侧看系统解决的是挂号难、排队久的问题。患者通过登录系统可以查看科室信息、医生排班情况然后在线完成挂号操作不必在窗口苦等。从医院侧看系统解决的是号源管理混乱的问题。以前窗口挂号哪个医生还剩多少个号全靠人工数数错了就是医患纠纷。系统上线后号源库存由数据库统一管理挂了几个还剩几个精确到个位数。适合谁来参考这篇内容如果你是正在做医疗类毕业设计的应届生或者公司刚接了中小型诊所/社区医院的信息化项目再或者你只是想把SpringBoot的全链路开发能力完整走一遍这篇都能给你提供一条能直接抄作业的路径。我写这篇东西不打算讲概念因为SpringBoot自动装配原理、JVM内存模型这些东西八股文一抓一大把。我要写的是真实项目中我是怎么一步步把挂号系统从零搭起来、又是怎么在联调和上线阶段被各种稀奇古怪的问题锤了一顿的。2. 技术选型背后的取舍不只是SpringBoot很多新手拿到SpringBoot医疗挂号管理系统这类题目第一反应就是把SpringBoot框架搭起来然后开始写Controller。但真正决定这个项目是能跑通Demo还是能上线被用的是选型阶段的一系列取舍。我把我最终的方案列出来然后逐个说为什么这么选。技术组件选型选型理由核心框架SpringBoot 2.7.x稳定版资料多规避部分新版本适配问题持久层ORMMyBatis-Plus单表CRUD免写SQL提升开发效率复杂查询仍可手写SQL前端框架Vue 2 Element UI后台管理系统最佳拍档组件成熟学习曲线平缓数据库MySQL 8.0业务量级在中小型医院完全够用运维成本低缓存Redis做号源预扣减和热门医生排班缓存鉴权方案JWT Spring Security轻量改造无状态鉴权适合前后端分离架构接口文档Knife4jSwagger增强版前后端联调必备生成接口文档效率高为什么SpringBoot版本我特意选了2.7.x而不是最新的3.x这是个很实在的问题。SpringBoot 3.0之后强制要求JDK 17及以上而很多学校机房的JDK还停留在8公司的老服务器上跑的也是JDK 8。如果你选SpringBoot 3.x相当于把你的部署环境也一起换了那成本就大了去了。另外MyBatis-Plus对SpringBoot 3.x的支持曾经有一段时间适配不完善遇到启动报错排查起来很浪费时间。没必要因为这个去挑战生态兼容性。选2.7.xJDK 8就能跑稳定社区踩坑记录多出了任何问题基本都能搜到解决方案。再来说说为什么用MyBatis-Plus而不是原生的MyBatis。我的理由很简单这个系统的核心业务是挂号挂号的本质是数据库的增删改查大量操作是单表操作。如果用原生MyBatis你会发现你花了大量的时间在写insert into t_doctor(...) values(...)这种机械SQL。MyBatis-Plus的BaseMapper把BaseMapper接口里常用的insert、deleteById、selectById、updateById全都封装好了你只需要让你的Mapper接口继承它就已经具备了基础的CRUD能力代码量肉眼可见地减少。当然涉及多表关联查询、报表统计这种复杂SQL时我仍然会用Select注解手写SQL。框架该用的用手写SQL该写的写这才是正确的姿势。Redis在这里的作用容易被低估。挂号系统最核心的资源是号源号源在某些医生的热门时段是极其紧俏的。如果所有请求都直接打到MySQL上数据库压力大不说并发一高还可能带来超卖问题——同一个号被两个患者同时挂走了。Redis做预扣减就是为了解决这个问题先操作缓存再异步写库配合事务和锁机制把并发风险摁在可控范围内。这个我后面展开讲。前端选Vue 2 Element UI不选Vue 3说实话Vue 3 Element Plus现在生态也很成熟了如果你是从零开始的新项目选Vue 3没毛病。但我自己这次选了Vue 2原因是这套系统需要给非专业用户医院分诊台护士使用Element UI的表单组件、弹窗组件、日期选择器都很成熟稳定Vue 2在这类业务系统里被验证的次数太多Bug少。后来我深刻体会到医疗系统这种对稳定性要求极高的场景你要的不是最新潮的技术而是最不会出问题的组合。3. 数据库设计挂号的本质是资源与状态的流转我常说看一个业务系统懂不懂行不用看代码直接看数据库表设计就知道了。挂号系统的核心表设计如果做对了整个系统的逻辑就通了一半做错了后面每一个功能都写得很拧巴。3.1 核心表结构设计我先建了十张基础表这里挑最关键的六张来聊用户表t_user存放患者和系统管理员两类角色通过role字段区分。字段包含user_id、username、passwordBCrypt加密存储、real_name、id_card、phone、role、create_time。科室表t_departmentdept_id、dept_name、dept_intro、sort_order。注意这里有个容易被忽视的设计sort_order用于控制科室在前端展示的排序。因为不同医院科室的展示优先级完全不一样内科可能在前面外科可能也在前面不按一个可配置的字段排后续调整时要改代码那就不科学了。医生表t_doctordoctor_id、dept_id、doctor_name、title职称、intro、consultation_fee挂号费、schedule_type、status。这里有一个关键点医生的挂号费为什么要单独放一张表而不是写死在排班表里因为同一个医生在不同时间段的挂号费可能不同比如专家门诊和工作日普通门诊的价格不同。挂号费如果只存医生表那排班的时候就改不了价格了如果只存排班表那医生基本信息里又要冗余一份默认值。我的处理方案是两个地方都存医生表存默认挂号费排班表存实际执行价。展示时优先取排班表的实际执行价。排班表t_scheduleschedule_id、doctor_id、dept_id、schedule_date、start_time、end_time、total_number总号源数、remain_number剩余号源数、consultation_fee、version乐观锁版本号。这张表是整个系统的核心承载了号源库存和排班信息。total_number和remain_number是该时段的总量限额和当前剩余额度。挂号订单表t_registrationreg_id、user_id、patient_id、doctor_id、schedule_id、reg_number取号序号、reg_time、status0待就诊/1已就诊/2已取消、cancel_time、pay_status、pay_time。这张表记录的是每一次挂号行为。就诊人表t_patientpatient_id、user_id、patient_name、id_card、phone、relation自建/亲属。很多初次做这个系统的新手会把患者和用户当成同一个概念实际上不是。一个用户账号下可以绑定多个就诊人最常见的场景是子女帮父母挂号。患者档案是真实去医院看病的人用户账号只是登录用的凭证。这个区分在业务层面非常重要直接影响后续挂号时选就诊人的交互流程。3.2 状态字段的设计沉淀这些表里我大量使用了status字段。有一个设计惯例我在项目里反复强调状态字段的每一个取值都要在注释里写清楚含义然后在Java代码的枚举类里维护常量。以挂号订单状态为例0 - 待就诊已支付排号成功 1 - 已就诊医生叫号并完成接诊 2 - 已取消患者主动取消或超时未支付 3 - 已退号就诊前申请退号费用原路退回为什么要做到这个粒度因为挂号订单的状态流转是一套完整闭环。你想想如果不做上面的拆分用户取消了挂号但状态还是已挂号那医生端在接诊时就会看到一大堆虚假的患者数据分诊和叫号都会被干扰。状态字段设计得细业务流程才能走得通。另一个关键是排班表和挂号订单表之间是通过schedule_id关联的绝对不能依赖医生ID和时间的组合去反推排班。我见过有的同学为了图省事挂号订单只存doctor_id和reg_time查询的时候再用时间和医生反查排班——这种设计在数据量小的时候看不出来问题一旦同一个医生在一天内有两个排班时段系统就直接错乱了。血泪教训提前写在前面。4. 排班与号源设计先把数据结构想透再动手写代码排班模块是挂号系统的心脏。挂号系统里最难的部分不是挂号本身而是排班。为什么因为排班涉及的数据关系太多了。一个医生一周内可能有多个排班时段每个时段是一个独立的号源池。如果某天上午出诊半天那上午时段挂的号全归这半天管下午不开放号源。同时排班又有周期性——比如每周一的上午某医生固定出诊需要能一键生成下周的排班。4.1 排班数据的两种生成策略我在实际项目里遇到了一个数据设计问题是存一条一条的排班记录比如周一上午一条、周三下午一条还是存排班规则然后按规则自动生成方案一每次排班都要人工录入很繁琐但灵活。方案二可以做到一键生成下周排班但排班规则的抽象会很复杂比如医生A固定每周一三五出诊但下周五恰好停诊怎么处理规则系统就很难表达因为会议冲突周五停诊这种一次性的例外。我最终的方案是妥协折中数据库存明细排班数据后台管理端提供引用模板生成的功能。医院管理员在后台可以选中某一周的排班数据一键复制到下一周然后在新生成的排班里手动修改有变动的时段。这样既保证了灵活性又减少了大量重复录入的工作量。这个设计思路在真实业务中是大厂也普遍采用的方案我建议做同类项目的同学直接抄。4.2 号源总量的分配逻辑再来说号源总量。total_number是怎么定的按我的经验排班数据在创建时有一个半自动规则普通门诊接诊速度按8分钟/人次计算半天出诊按4小时算理论上限约30个号。专家门诊接诊速度按15~20分钟/人次计算上限约12~15个号。如果是复诊患者同一患者在同一医生处复诊可以直接在医生工作台加号不属于线上号源池。这个数据是需要跟医院运营人员反复确认的不是拍脑袋定。因为放号多了医生看不过来患者等待时间暴增投诉率升高放号少了号源秒光患者挂不到号还是投诉。平衡最大接诊负荷和患者就医体验是运营层面的事系统只是提供配置能力。号源扣减的时序问题排班表里的remain_number是剩余号源。患者发起挂号请求时流程是先校验还有没有余号有则扣减然后创建挂号订单。如果校验和扣减是先查再更新两步操作在高并发下就会出现经典的超卖问题两个请求同时查到了remain_number1都执行了扣减结果号被挂了两次。我自己第一版代码就犯过这个错用Postman循环压了100个并发请求一查MySQL同一个人挂到了同一个号段当场表演脸上出汗。这个问题的解决方案在后面单独开一节讲因为涉及的细节不值得被淹没在零散篇幅里。5. 挂号核心链路从选科室到锁号每一步都别有洞天5.1 挂号流程的全链路梳理患者端发起挂号的完整流程是这样的登录系统在首页看到科室列表。点击某个科室进入该科室的医生列表页看到医生简介、职称、挂号费和当前可预约状态。点击医生进入排班详情页通过日期控件选择出诊日期看到该日期下的空闲时段上午/下午和余号数。选择时段进入确认页选择就诊人可以给自己挂也可以给绑定的家人挂。提交挂号请求系统校验号源、校验就诊人绑定关系、校验是否重复挂号同一个医生同一个排班时段一个就诊人只能挂一次然后创建订单。跳转支付页面本系统内做了模拟支付真实对接银联/微信支付时只需要替换支付接口。支付成功后系统返回挂号序号比如上午第07号同时短信/站内信推送挂号成功通知。这里面每一步都有业务规则要处理。我挑几个最容易出问题的细节重点说。重复挂号的拦截患者早上挂了某个医生上午的号觉得时间不合适又挂了一次下午的这个系统要允许吗业务上允许。那如果同一患者在同一排班时段内重复提交呢绝对不允许。所以数据库设计里我加了一个唯一索引uk_user_schedule (patient_id, schedule_id)。在数据库层面就确保同一就诊人同一个排班时段只能有一条有效的挂号记录。注意这里的有效指的是status ! 2已取消。当一个患者取消挂号后重新挂号时唯一索引会被清理重建。5.2 数据一致性的核心难题锁与事务这一步是整个挂号系统技术含量最高的一环。为了不让这一节变成教科书我直接还原我当时写第一版代码踩坑的过程。第一版代码是这样的// 伪代码第一版错误示范 public Result createRegistration(RegistrationVO vo) { Schedule schedule scheduleMapper.selectById(vo.getScheduleId()); if (schedule.getRemainNumber() 0) { schedule.setRemainNumber(schedule.getRemainNumber() - 1); scheduleMapper.updateById(schedule); // 创建挂号单 registrationMapper.insert(buildRegistration(vo)); return success(); } return error(号源已满); }你觉得这段代码逻辑有毛病吗初看完全没问题。但你用JMeter开50个线程同时打这个接口每个线程都用不同的就诊人挂同一个schedule_id你会发现最终订单表里出现的挂号记录数量大于实际扣减的号源数。这就是典型的超卖。问题出在哪在于selectById查出来的remainNumber是旧数据第一个线程把它从10改成9第二个线程在第一个线程还没提交时也读到了10也改成了9。两个业务的判断都认为当前还有号结果扣错了。这就是并发环境下的读-改-写不是一个原子操作。解决方案我给了三种按推荐程度排序方案一乐观锁改SQL成本最低给排班表加version字段更新语句带条件和版本号判断UPDATE t_schedule SET remain_number remain_number - 1, version version 1 WHERE schedule_id #{scheduleId} AND version #{version} AND remain_number 0这条SQL由MyBatis执行返回的影响行数作为判断依据。如果影响行数为0说明version被其他线程改了或者remain_number已经为0这次挂号失败。应用层不需要加锁数据库层面就保证了原子性。这是成本最低、适用性最广的方案中小型医院系统用它就非常够了。方案二Redis预扣减适合高并发场景在Redis里用decr命令扣减号源缓存值decr本身是原子的。扣减成功后把创建订单的请求丢到一个队列由消费者线程异步落库。落库成功后再把订单状态置为已确认。这个方案的好处是把数据库的压力扛在了Redis上结合业务来看效果很理想但工程复杂度上升了一个档次需要处理缓存与数据库的一致性、队列消费失败的重试与补偿等问题。我这套系统最终选了这个方案因为我对多线程并发比较有把握而且上线后确实挺稳的。方案三悲观锁SELECT ... FOR UPDATE在事务里先执行SELECT ... FOR UPDATE锁住这一行再判断余号、修改余号、插入订单最后提交事务。逻辑上绝对安全但并发性能不如乐观锁因为一个线程持有锁期间其他线程全部阻塞等待。这种方案适合并发量不大但绝不能出错的场景比如这个系统里如果只有几十个并发效果也可以接受但我不推荐为这个方案加戏。我在项目里给团队定的策略是热门的专家号接口走Redis预扣减异步落库普通号接口走乐观锁。不同的业务负载配合不同的技术方案这是做真实项目的正常姿势不是一道方案打天下。6. 后台管理端与前端联调从能跑到好用的那段路很多做这类系统的人容易把精力全放在患者端挂号的流程上后台管理端草草做了几个页面就交差。大错特错。医院真正天天用的、最考察系统可用性的是后台管理端。护士、分诊台工作人员、科室主任、信息科的人每天打开电脑操作的全是它。6.1 后台管理的功能地图我的后台管理端包含这些功能模块科室管理增删改查设置展示排序停用/启用科室。医生管理维护医生档案绑定科室设置职称、简介、默认挂号费、出诊状态。排班管理选择医生、日期、时段设置号源总量和挂号费支持一键复制上周排班。挂号订单管理按科室、医生、日期、状态多维度筛选支持手动取消异常订单。患者管理查看注册用户及其绑定就诊人信息。数据统计按科室统计每日挂号量、按医生统计接诊量、挂号费用汇总等前端用ECharts渲染趋势图。这里我想重点提醒的是排班管理的交互设计。用Element UI的日期选择器选择日期然后遍历当前医生的七个排班时段用一个表单展示每个时段是否出诊、出诊的号源量是多少、挂号费是多少。如果本周停诊直接在对应的行里把状态置为停诊。这个交互做对了护士姐姐录入排班数据时不会骂人做错了她们会天天给信息科打电话报修。我用了一周的随访时间就为了观察护士录入排班的操作路径然后按她们的习惯调交互细节。做业务系统用户的习惯永远是最重要的需求文档。6.2 前后端接口对齐的那点事前后端联调阶段我吃过的亏主要在接口设计上。我第一版把挂号接口设计成POST /api/registration/submit参数一次性传了scheduleId、patientId、userId、remark等七个字段。前端同学接接口的时候在页面里要来回切换确认参数名常常出错。后来我把接口设计调整成了两层第一层校验层POST /api/registration/verify传scheduleId和patientId只做资格校验是否重复挂号、是否号源充足、就诊人是否已实名。第二层提交层POST /api/registration/submit传verifyToken和patientId基于校验通过的token直接创建订单。这样前端交互自然分成了检查信息和确认提交两步体验跟真实挂号平台的流程高度一致。前端同学也不用一次性处理完所有参数。如果你的项目时间紧迫一层接口也能用只是交互体验会差一些。6.3 接口文档的维护前后端分离开发接口文档绝不能省。我用Knife4j生成Swagger文档每次修改接口后自动同步。这玩意儿帮我们省掉了大量我问你接口改了没你自己看下文档的扯皮时间。你如果做这个类型的毕业设计或项目我强烈建议从一开始就接上Knife4j后面对着你自己的代码调试也能省很多事。7. 部署、压测与上线前的一次事故7.1 部署方案的确定系统部署我用了最经典的三层结构Nginx做前端静态资源服务和反向代理后端SpringBoot打成Jar包跑在独立服务器上MySQL和Redis分别放在数据库服务器和缓存服务器。如果没有独立的数据库服务器那MySQL和Redis可以放同一台机器只要内存管够就行。操作步骤简化如下这部分基本是通用流程前端项目执行npm run build生成dist目录。把dist目录里的静态文件拷贝到Nginx配置的root目录。修改Nginx的conf文件把/api开头的请求反向代理到后端服务的端口我后端用的是8080。后端项目执行mvn clean package -DskipTests打出Jar包。用nohup java -jar medical-registration.jar --spring.profiles.activeprod 启动服务。验证Nginx转发的CORS配置确认前后端跨域问题已处理。7.2 压测暴露出来的严重问题上线前我做了一轮JMeter压测模拟100个并发用户同时挂号。结果让我愣住了接口平均响应时间从平时的80ms飙升到了2300ms而且还出现了大量的超时请求。更糟心的是Redis连接数直接被打满了报错信息是RedisConnectionFailureException。排查的过程是这样的先看后端日志发现大量的Redis连接池获取连接超时。检查Redis配置发现我初始配置的连接池最大连接数就20个activeCount一超过20新请求就被挂起等待。这个配置对于一个高并发接口来说就是瓶颈所在。然后我看了数据库慢查询日志发现几条针对schedule表的SELECT语句执行时间接近1秒。查看执行计划发现这条SQL没有命中任何索引走的是全表扫描。我当时建表的时候忘了在schedule_id上建索引导致每次都全表扫。解决方案Redis连接池最大连接数调到100初始化连接数为10等待最大毫秒数调到2000。给排班表、订单表补上关键的数据库索引ALTER TABLE t_registration ADD INDEX idx_doctor_datetime (doctor_id, reg_time); ALTER TABLE t_registration ADD INDEX idx_schedule_id (schedule_id); ALTER TABLE t_schedule ADD INDEX idx_dept_date (dept_id, schedule_date);针对管理员后台的列表查询把SQL加上了分页防止一次性查全表数据。给前端列表页的查询加了防抖阻止用户连续点击查询按钮时产生重复请求。改完再压一轮接口平均响应时间降到180ms左右100个并发下没有出现超时和丢单。数据说话这个结果就让我踏实了。7.3 上线当天遇到的特别客户上线当天我还在门诊大楼的信息科蹲着结果分诊台的护士长跑过来说小伙子医生名单里老专家的照片是歪的你看看怎么弄。我当时第一反应是是不是前端样式问题查了查原来是我在录入老专家医生档案时有张照片的像素比其他的大了一倍前端设定的是固定尺寸显示大图被拉伸变形了。后来在医生管理里给照片上传功能统一做了裁剪压缩处理。一件不起眼但真实存在的问题让我明白了一个道理你做的系统最终是给普通用户用的任何细节没考虑到用户就会立刻用真实情绪反馈给你。做技术的惯性思维考虑的是功能实现了没真正做好系统要考虑的是用户用着顺不顺。8. 踩坑实录那些不翻文档永远不知道的坑讲真一个项目做完代码写得多好是其次踩过多少坑才决定了你的经验值涨了多少。我把这轮开发中印象最深的几个坑整理出来也是一份可以当排查手册用的清单。8.1 日期时间差8小时问题这是中国开发者常年踩的老坑了。MySQL连接串里没有配置serverTimezone参数时默认使用UTC时间结果数据库中存的时间比北京时间慢8小时。比如前端选择的就诊时间是2024-12-20 09:00后端存进去变成了2024-12-20 01:00第二天患者拿着挂号单来医院发现医生排班表上根本找不到这单子。解决方案JDBC连接串里显式加上jdbc:mysql://localhost:3306/medical_his?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse并在Jackson序列化配置里统一设置时区spring.jackson.time-zoneGMT8 spring.jackson.date-formatyyyy-MM-dd HH:mm:ss8.2 分页插件和自定义SQL的热更新冲突用的MyBatis-Plus分页插件在写自定义多表联查SQL时如果是从PageHelper项目迁移过来的老代码容易把PageHelper.startPage的用法混进来导致分页不生效、或数据变成全表。说实话这两个分页方案我实际都用过MyBatis-Plus的Page对象配合selectPage就够了不要在同一个项目里混合两种分页写法。我最后统一用MyBatis-Plus的IPage处理删掉了所有PageHelper.startPage问题自然消失。8.3 JWT过期后前端跳转死循环登录鉴权这块后端在JWT过期后会返回401状态码。前端Axios拦截器捕获401后触发跳转到login页面。但login页面本身也有一个请求获取图形验证码这个请求也会被拦截器捕获又触发一次跳转。页面就陷入跳转到loginlogin又发起请求401又被跳转的死循环。解决方案是Axios拦截器里增加白名单判断// 伪代码 if (error.response.status 401) { const isLoginPage window.location.pathname /login; if (!isLoginPage) { // 跳转到登录页并清除本地登录态 } }8.4 超时未支付订单的释放患者发起了挂号但没支付这个号应该多久释放出来如果一直占着号源就白白浪费了。业务上我设定的规则是订单创建后10分钟内未支付系统自动取消订单号源重新释放。实现方式是在后端起一个轻量定时任务每5分钟扫描一次超时未支付的挂号订单。注意这里不能用Redis的过期监听来精确控制因为业务上有很多边界情况比如用户正在支付流程中做定时扫描再校验状态更稳妥。// 定时任务核心逻辑简化版 for (Registration order : expiredOrders) { // 校验订单状态仍是待支付 if (order.getStatus() 0) { // 更新订单状态为已取消 // 同步释放排班表号源remain_number 1 } }这里有一个关键的并发问题用户刚好在系统执行定时任务的前一秒完成了支付订单状态已变成已支付那定时任务扫描时看到了status为0就会误取消。我的处理是增加一个修改条件UPDATE t_registration SET status2 WHERE reg_id? AND status0受影响行数为0说明订单已被其他流程支付成功修改当前流程不再操作保证数据一致性。9. 用真实医疗场景检验过的核心清单项目上线到我写这篇总结的时候系统已经正常运行了差不多四个半月。我根据实际使用情况整理了一份核心清单你可以把它当成一个自查表检查你的挂号系统是否已经可以扛住真实环境的考验。检查项判断标准我的实测结论号源并发扣减100并发下无超卖、无重号通过挂号订单数据一致性对账挂号订单数号源扣减数通过超时订单释放10分钟未支付自动取消且号源回补通过重复挂号拦截同一就诊人同一排班时段不能重复挂号通过已退号号源回补用户退号后号源实时1通过数据统计报表当日挂号量每小时滚动更新通过前端白屏异常并发访问下页面前端无明显卡顿通过其中已退号号源回补这个点我第一次做的时候漏掉了用户取消挂号之后排班的remain_number没有变化导致号被白白留在那后面想挂的人挂不了。后来在联调之前补上了这个逻辑。现在每次想起来都庆幸自己提前发现了如果上线后再被患者当场发现你们系统取消挂号后号就没了那真是很被动的。你设计和开发的时候建议把这个环节当重点测。除了以上功能层面还有两个非功能性的事项我想多说两句。第一是操作日志系统的关键操作挂号、取消挂号、退号、排班修改必须有日志记录出了问题能够追溯是谁在什么时间做了什么事。我用的思路是AOP切面注解给关键方法打上OperationLog注解自动记录操作人、操作时间、操作参数、操作结果。这件事工作量不大但上线后被问谁动了这个排班的时候它是唯一的证据。第二是数据备份MySQL数据库每天凌晨2点自动备份一次保留最近7天这个用crontab写个备份脚本即可不复杂但别嫌麻烦跳过医疗数据的丢失风险是不能承受的。10. 写在最后关于这类系统还能怎么延伸做医疗挂号管理系统这件事对我来说最有价值的不是把SpringBoot、MyBatis-Plus、Vue这些技术又过了一遍而是理解了业务流程上的严谨性和代码上的严谨性是同一种严谨。挂号系统的难点从来不是某个接口的某个SQL怎么写而是在多并发、多状态、多角色的复杂场景里每个业务动作都能准确落库每笔数据都能经得起对账。回头来看这套系统有几个方向仍然值得继续扩展。第一个是接入真实的支付通道把模拟支付替换为微信/支付宝SDK涉及签名、回调验签、退款等功能第二个是引入消息队列比如RabbitMQ把挂号成功后通知患者、通知医生端的异步消息处理得更优雅第三个是做一个简单的医生工作台让医生可以直接在系统里查看当天待就诊患者队列并完成叫号这会把整个就诊闭环彻底打通。如果你打算在这个课题上做毕业设计延伸第二条和第三条都是不错的加分项。最后分享一个我个人的操作习惯每次交付这类系统前我会把核心流程完整地走三遍第一遍用正常数据走第二遍用异常数据走第三遍用并发数据走。三遍走完心里还没底的功能就说明它还不够熟继续打磨。这是我做了多年项目留下的习惯也建议你试一下。系统在这几个月里的表现还算稳定当然也会有些零零碎碎的小优化需求冒出来比如分诊台希望增加按医生职称筛选排班、患者希望能在手机上查看排队进度。这些都是做真实业务系统的日常。有了这套地基后面的迭代不过是往墙上添砖加瓦罢了。
返回列表