ARTICLE DETAIL

资讯详情

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

基于Flask的医院预约挂号系统开发实践

基于Flask的医院预约挂号系统开发实践 1. 项目概述仁康医院预约挂号系统是基于Python Flask框架开发的Web应用旨在解决传统医院挂号排队时间长、号源分配不均等问题。这个系统允许患者通过网页端完成科室选择、医生查询、时段预约等操作同时为医院管理人员提供号源管理、数据统计等功能。我在实际开发这类系统时发现医疗行业的预约系统与普通电商预约有着本质区别必须考虑号源唯一性、就诊时段冲突检测、退号规则等医疗特有的业务逻辑。这也是为什么很多通用预约框架无法直接套用在医疗场景的原因。2. 技术选型与架构设计2.1 为什么选择Flask框架Flask作为轻量级Python Web框架相比Django更适合中小型医疗机构的预约系统开发微内核设计医院业务需求变化快Flask的扩展机制便于快速迭代ORM自由度高医疗数据关系复杂可自由选择SQLAlchemy或Peewee模板灵活前端需要频繁调整展示逻辑Jinja2模板比Django模板更易定制典型的基础架构如下from flask import Flask from flask_sqlalchemy import SQLAlchemy app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] mysql://user:passlocalhost/hospital db SQLAlchemy(app)2.2 数据库设计要点医疗挂号系统的核心表结构设计需要特别注意号源表必须包含排他锁机制防止超卖CREATE TABLE schedule ( id INT PRIMARY KEY, doctor_id INT NOT NULL, date DATE NOT NULL, time_slot VARCHAR(20) NOT NULL, total INT DEFAULT 0, reserved INT DEFAULT 0, version INT DEFAULT 0 # 乐观锁版本号 );预约记录表需要记录完整的操作流水class Appointment(db.Model): id db.Column(db.Integer, primary_keyTrue) patient_id db.Column(db.Integer) schedule_id db.Column(db.Integer) status db.Column(db.String(10)) # 待支付/已预约/已取消 create_time db.Column(db.DateTime) update_time db.Column(db.DateTime)3. 核心功能实现3.1 号源库存管理医疗号源的本质是时间槽库存实现时需要注意# 使用乐观锁解决并发问题 def make_appointment(schedule_id): schedule Schedule.query.filter_by(idschedule_id).first() if schedule.reserved schedule.total: raise Exception(号源已满) schedule.reserved 1 schedule.version 1 try: db.session.commit() return True except IntegrityError: db.session.rollback() return False3.2 预约业务流完整的预约流程应包含患者身份验证医保卡/身份证绑定科室-医生-时间三级选择支付环节支持医保卡线上支付电子凭证生成含二维码关键实现代码app.route(/api/appointment, methods[POST]) def create_appointment(): data request.get_json() # 1. 验证患者信息 patient verify_patient(data[id_card], data[phone]) # 2. 检查号源状态 schedule Schedule.query.get(data[schedule_id]) if not schedule or schedule.status ! available: return jsonify({error: 无效的号源}) # 3. 创建预约记录 appointment Appointment( patient_idpatient.id, schedule_idschedule.id, statuspending_payment ) db.session.add(appointment) # 4. 生成支付订单 order create_payment_order(appointment) return jsonify(order.to_dict())4. 特殊业务场景处理4.1 退号规则实现医疗行业的退号规则比电商复杂就诊前24小时可免费退号24小时内退号收取手续费就诊当天不可退号实现示例def cancel_appointment(appointment_id): appointment Appointment.query.get(appointment_id) schedule appointment.schedule # 计算时间差 now datetime.now() delta schedule.start_time - now if delta.days 0: raise Exception(已过期的预约不能取消) elif delta.days 0: raise Exception(就诊当天不可取消) elif delta.days 1: # 24小时内收取手续费 refund_amount calculate_refund(appointment, penaltyTrue) else: refund_amount calculate_refund(appointment) # 更新状态 appointment.status cancelled schedule.reserved - 1 db.session.commit() return refund_amount4.2 黑名单机制为防止恶意占号需要实现爽约次数统计自动加入黑名单限制预约频次def check_blacklist(patient_id): # 检查最近30天的爽约记录 missed Appointment.query.filter( Appointment.patient_id patient_id, Appointment.status no_show, Appointment.create_time datetime.now() - timedelta(days30) ).count() if missed 3: add_to_blacklist(patient_id) return False return True5. 安全与合规要点5.1 医疗数据保护必须实现患者信息加密存储敏感操作日志记录访问权限控制建议配置# 敏感字段加密 from cryptography.fernet import Fernet key Fernet.generate_key() cipher_suite Fernet(key) class Patient(db.Model): id_card db.Column(db.String(128)) # 存储加密后的值 def set_id_card(self, number): self.id_card cipher_suite.encrypt(number.encode()) def get_id_card(self): return cipher_suite.decrypt(self.id_card).decode()5.2 高并发优化挂号系统必须应对早高峰的并发请求使用Redis缓存号源余量采用队列削峰数据库读写分离示例配置from redis import Redis from rq import Queue redis_conn Redis(hostredis-server) task_queue Queue(high, connectionredis_conn) # 将预约请求放入队列 app.route(/api/appointment, methods[POST]) def create_appointment(): data request.get_json() task_queue.enqueue(process_appointment, data) return jsonify({status: processing})6. 部署与监控6.1 生产环境部署推荐方案Nginx Gunicorn多workerSupervisor进程管理独立MySQL实例Gunicorn启动配置gunicorn -w 4 -b 0.0.0.0:5000 --access-logfile - --error-logfile - wsgi:app6.2 关键指标监控必须监控预约成功率接口响应时间数据库连接数支付失败率使用Prometheus的示例from prometheus_client import Counter, Gauge APPOINTMENT_REQUESTS Counter( appointment_requests_total, Total appointment requests ) app.route(/api/appointment) def appointment(): APPOINTMENT_REQUESTS.inc() # ...7. 常见问题排查7.1 号源超卖问题现象同一号源被重复预约 解决方案检查数据库隔离级别需REPEATABLE READ以上验证乐观锁机制是否生效添加Redis分布式锁7.2 支付状态不同步现象支付成功但预约状态未更新 排查步骤检查消息队列消费情况验证回调接口日志核对事务完整性8. 扩展功能建议根据实际运营需求可扩展智能推荐医生基于患者病史候补预约功能检查检验预约联动药品配送预约候补预约实现思路class WaitList(db.Model): patient_id db.Column(db.Integer) department_id db.Column(db.Integer) create_time db.Column(db.DateTime) def notify_available(self): # 当有号源释放时通知患者 pass在开发这类系统时最大的经验教训是一定要在早期与医疗业务人员充分沟通理解他们的工作流程。我曾遇到因为不了解医院现场分诊规则导致开发的预约时段与实际就诊流程不匹配的情况。建议在开发前至少花一周时间实地观察医院的挂号、分诊、就诊全流程。
返回列表