ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于Python与微信小程序的疫苗预约系统开发实践

基于Python与微信小程序的疫苗预约系统开发实践 1. 疫苗预约微信小程序的设计与实现作为一名长期从事医疗信息化开发的工程师我最近完成了一个基于Python和微信小程序的疫苗预约系统。这个项目让我深刻体会到在公共卫生领域一个稳定、易用的预约平台能极大提升接种效率。下面我将从架构设计到代码实现完整分享这个项目的开发经验。1.1 系统架构设计我们采用前后端分离架构这是目前互联网应用的标准做法。前端使用微信小程序原生框架后端选择Python的Flask框架数据库采用MySQL 8.0。这种组合在开发效率和性能之间取得了很好的平衡。选择Flask而非Django的主要考虑是疫苗预约系统的业务逻辑相对简单直接Flask更轻量级适合快速迭代开发项目需要频繁与微信API交互Flask的灵活性更适合这种场景数据库设计上我们建立了5个核心表用户表(user)存储微信openid和基本信息疫苗表(vaccine)记录疫苗种类、库存和适用人群接种点表(site)包含地理位置、工作时间等预约记录表(appointment)核心业务表消息记录表(notification)用于消息推送1.2 核心功能实现1.2.1 用户认证模块微信登录是整套系统的入口我们使用官方提供的login接口获取code然后通过后端交换openidapp.route(/api/wxlogin, methods[POST]) def wx_login(): code request.json.get(code) if not code: return jsonify({error: 缺少code参数}), 400 # 调用微信接口获取openid wx_url fhttps://api.weixin.qq.com/sns/jscode2session?appid{APPID}secret{SECRET}js_code{code}grant_typeauthorization_code response requests.get(wx_url) data response.json() if openid not in data: return jsonify({error: 微信登录失败}), 401 # 生成JWT token access_token create_access_token(identitydata[openid]) return jsonify({token: access_token}), 200注意在实际部署时一定要将APPID和SECRET放在环境变量中不要直接写在代码里。同时要做好错误处理比如网络超时等情况。1.2.2 疫苗信息展示疫苗数据来自两个渠道本地数据库存储的基础信息实时调用疾控中心API获取库存我们使用Redis缓存热点数据显著降低了数据库压力def get_vaccine_list(): cache_key vaccine_list # 先尝试从Redis获取 cached_data redis_client.get(cache_key) if cached_data: return json.loads(cached_data) # 缓存未命中则查询数据库 vaccines db.session.query(Vaccine).filter_by(is_activeTrue).all() result [v.to_dict() for v in vaccines] # 写入Redis设置5分钟过期 redis_client.setex(cache_key, 300, json.dumps(result)) return result1.2.3 智能预约引擎预约算法是系统的核心我们实现了以下功能基于用户位置推荐3公里内的接种点时段冲突检测防止同一用户重复预约库存实时扣减app.route(/api/appointment, methods[POST]) jwt_required() def create_appointment(): current_user get_jwt_identity() data request.get_json() # 验证库存 vaccine Vaccine.query.get(data[vaccine_id]) if not vaccine or vaccine.stock 0: return jsonify({error: 该疫苗库存不足}), 400 # 检查是否已有预约 existing Appointment.query.filter_by( user_idcurrent_user, vaccine_iddata[vaccine_id] ).first() if existing: return jsonify({error: 您已预约过该疫苗}), 400 # 创建预约记录 new_appoint Appointment( user_idcurrent_user, vaccine_iddata[vaccine_id], site_iddata[site_id], appoint_timedata[appoint_time] ) db.session.add(new_appoint) # 扣减库存 vaccine.stock - 1 try: db.session.commit() # 发送微信通知 send_wx_notification(current_user, 预约成功) return jsonify({status: success}), 201 except Exception as e: db.session.rollback() return jsonify({error: str(e)}), 5001.3 性能优化实践在压力测试阶段我们发现当并发量超过5000时系统响应时间明显变长。通过以下优化措施最终将性能提升了3倍数据库连接池配置from sqlalchemy.pool import QueuePool engine create_engine( SQLALCHEMY_DATABASE_URI, poolclassQueuePool, pool_size20, max_overflow10, pool_timeout30 )异步任务处理 对于非实时性要求的操作如消息推送我们使用Celery实现异步队列celery.task def async_send_wx_notification(openid, content): # 实现消息推送逻辑 pass查询优化为所有外键添加索引避免N1查询问题使用select_related预加载关联数据2. 开发技术路线详解2.1 技术选型考量前端选择微信小程序的原因无需安装即用即走开发成本低一套代码适配iOS和Android天然的用户信任感在微信生态内后端选择PythonFlask的优势开发效率高原型可以快速落地丰富的第三方库支持易于与数据科学工具链集成如后续可能需要的数据分析2.2 开发环境搭建推荐使用PyCharm Professional版它提供了完善的Python和数据库支持。关键配置步骤创建虚拟环境python -m venv venv source venv/bin/activate # Linux/Mac venv\Scripts\activate # Windows安装依赖pip install flask flask-jwt-extended flask-sqlalchemy pymysql redis celery数据库初始化from flask_migrate import Migrate migrate Migrate(app, db) # 然后运行 flask db init flask db migrate flask db upgrade2.3 测试策略我们采用分层测试方案单元测试使用pytest测试每个独立函数接口测试使用Postman测试API端点压力测试使用Locust模拟高并发场景示例测试用例def test_appointment_api(client, auth_headers): # 测试预约接口 data { vaccine_id: 1, site_id: 1, appoint_time: 2023-08-15 10:00 } response client.post( /api/appointment, jsondata, headersauth_headers ) assert response.status_code 201 assert success in response.json[status]3. 部署与运维实践3.1 生产环境部署我们使用Docker容器化部署docker-compose.yml关键配置version: 3 services: web: build: . ports: - 5000:5000 environment: - FLASK_ENVproduction depends_on: - redis - mysql redis: image: redis:6 ports: - 6379:6379 volumes: - redis_data:/data mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} MYSQL_DATABASE: vaccine ports: - 3306:3306 volumes: - mysql_data:/var/lib/mysql volumes: redis_data: mysql_data:3.2 监控与日志我们使用PrometheusGrafana监控系统健康状态关键指标包括API响应时间数据库查询性能Redis缓存命中率队列积压情况日志收集采用ELK栈便于问题排查。配置Flask日志import logging from logging.handlers import RotatingFileHandler handler RotatingFileHandler( app.log, maxBytes10000, backupCount3 ) handler.setLevel(logging.INFO) app.logger.addHandler(handler)4. 踩坑经验与解决方案4.1 微信登录的坑问题在获取用户手机号时前端传过来的encryptedData解密失败。原因微信的会话密钥(session_key)过期或前后端不一致。解决方案每次调用wx.login获取新code后端缓存session_key时设置合理过期时间解密失败时引导用户重新登录4.2 并发预约问题问题当多个用户同时预约最后一份疫苗时会出现超卖。解决方案使用数据库事务乐观锁from sqlalchemy import select, update def reserve_vaccine(vaccine_id): stmt select(Vaccine).where(Vaccine.id vaccine_id) vaccine db.session.scalar(stmt) if vaccine.stock 0: return False # 乐观锁更新 upd update(Vaccine).where( Vaccine.id vaccine_id, Vaccine.stock vaccine.stock # 检查库存是否变化 ).values(stockVaccine.stock - 1) result db.session.execute(upd) db.session.commit() return result.rowcount 04.3 性能调优经验N1查询问题 错误做法appointments Appointment.query.all() for a in appointments: user User.query.get(a.user_id) # 每次循环都查询数据库正确做法appointments db.session.query(Appointment).options( joinedload(Appointment.user) ).all()缓存策略优化热点数据缓存时间不宜过长5-10分钟使用不同的缓存失效策略# 高实时性数据 redis_client.setex(key1, 60, value) # 低变化频率数据 redis_client.set(key2, value)5. 项目扩展方向这个基础系统还可以进一步扩展智能推荐功能基于用户历史接种记录推荐疫苗根据人群密度预测接种点排队时间数据分析看板使用Pandas分析接种率可视化各区域接种进度预约规则引擎支持不同疫苗的特殊预约规则实现分年龄段、分时段的精准预约# 示例规则引擎实现 class RuleEngine: def __init__(self): self.rules [] def add_rule(self, condition, action): self.rules.append((condition, action)) def apply(self, context): for condition, action in self.rules: if condition(context): action(context)在实际开发中我发现医疗类系统对稳定性和数据准确性的要求极高。一个小数点错误可能就会导致严重后果。因此我们在代码中加入了大量的数据校验和审计日志确保每一步操作都可追溯。这也是我建议所有开发医疗系统的同行特别注意的地方。
返回列表