医疗类App近年成为互联网医疗服务的核心载体,无论是医院官方应用还是第三方健康平台,预约挂号、在线问诊和电子病历几乎都是必备功能。这三个模块看似独立,实际上数据流转紧密关联:挂号记录为问诊会话提供入口,问诊过程产生的诊断建议又沉淀为电子病历。本文将围绕这三大模块,从架构设计、数据库建模到关键代码实现,完整梳理医疗App的开发思路。

一、系统整体架构与核心模块划分
一个典型的医疗App后台可以划分为四个层次:客户端层(iOS、Android、小程序)、接入网关层(负责鉴权、限流、路由)、业务服务层(挂号服务、问诊服务、病历服务、支付服务)以及数据层(MySQL、Redis、对象存储)。这种分层结构的好处是各业务服务可以独立部署、独立扩容,比如挂号高峰期出现在早上八点放号时,可以单独对挂号服务做水平扩展,不影响问诊业务的稳定性。
在服务间通信上,问诊服务依赖挂号服务的数据。以图文问诊为例,患者必须先完成挂号(哪怕是免费问诊号),系统才能为其分配医生并创建会话。这里推荐通过消息队列解耦:挂号成功后发送一条消息,问诊服务消费该消息并初始化会话记录,即使问诊服务短暂不可用,消息也会被持久化,不会造成数据丢失。
医疗场景对数据安全要求极高,建议在网关层统一做用户身份校验和设备指纹识别,防止账号被冒用。同时所有涉及患者隐私的接口都要记录审计日志,这是后续等保测评和卫健委监管检查的硬性要求。
二、预约挂号模块的设计与实现
挂号的核心难点在于号源管理,尤其是防止超卖。一个热门专家号可能在放号瞬间被数千人同时抢购,如果处理不当,就会出现同一个号被多个患者预约成功的严重事故。解决思路与电商秒杀类似:利用Redis预减库存,将数据库压力挡在缓存层。
先看号源表的设计。号源按医生加日期加时段维度生成,每天凌晨由定时任务批量插入,表中记录总号数和剩余号数:
CREATE TABLE `schedule_slot` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `doctor_id` BIGINT NOT NULL COMMENT '医生ID', `visit_date` DATE NOT NULL COMMENT '就诊日期', `time_period` TINYINT NOT NULL COMMENT '时段:1上午 2下午', `total_count` INT NOT NULL DEFAULT 0 COMMENT '总号数', `remain_count` INT NOT NULL DEFAULT 0 COMMENT '剩余号数', `status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1可约 2停诊', UNIQUE KEY `uk_doc_date_period` (`doctor_id`, `visit_date`, `time_period`) ) COMMENT='号源表';
抢号的核心逻辑可以抽象为三个步骤:Redis原子扣减、落库生成订单、超时未支付释放号源。用Lua脚本保证扣减的原子性是最稳妥的做法:
public BookingResult grabSlot(Long slotId, Long userId) {
String stockKey = "slot:stock:" + slotId;
// 1. Redis原子预减,脚本保证不存在超卖
Long remain = redisTemplate.execute(DECR_LUA, List.of(stockKey));
if (remain == null || remain < 0) {
return BookingResult.fail("号源已约满");
}
try {
// 2. 创建挂号订单,状态为待支付
Long orderId = orderService.createPendingOrder(slotId, userId);
// 3. 15分钟未支付自动取消并回补库存
delayQueue.push(orderId, 15 * 60 * 1000L);
return BookingResult.ok(orderId);
} catch (Exception e) {
redisTemplate.opsForValue().increment(stockKey); // 失败回补
throw e;
}
}除了技术防超卖,业务规则同样重要。比如同一患者同一医院同一天最多预约几个号、取消预约的截止时间、爽约三次进入黑名单等,这些规则建议做成可配置项,放在配置表中由运营人员调整,避免每次改规则都要发版。
三、在线问诊模块的技术选型
在线问诊主要有三种形态:图文咨询、语音通话和视频问诊。图文咨询本质上是一个即时通讯场景,技术上可以选择自研长连接(基于Netty加WebSocket)或者接入第三方IM SDK。自研的优点是数据完全掌握在自己手里,符合医疗数据不出院的原则,但开发成本高;接入云厂商IM服务上线快,不过需要确认对方是否支持私有化部署。对于大多数中小团队,建议初期接入成熟的IM SDK,等业务量上来后再考虑迁移。
图文问诊的消息类型比普通聊天复杂得多,除了文字和图片,还包括处方消息、检验报告卡片、系统提示消息等。设计消息表时要预留消息类型字段和扩展字段:
CREATE TABLE `consult_message` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `session_id` BIGINT NOT NULL COMMENT '问诊会话ID', `sender_type` TINYINT NOT NULL COMMENT '1患者 2医生 3系统', `sender_id` BIGINT NOT NULL, `msg_type` VARCHAR(32) NOT NULL COMMENT 'text/image/prescription/report', `content` TEXT COMMENT '消息内容或多媒体URL', `extra` JSON COMMENT '扩展信息,如处方ID', `created_at` DATETIME NOT NULL, KEY `idx_session` (`session_id`, `created_at`) ) COMMENT='问诊消息表';
会话状态机也是问诊模块的关键。一次图文问诊的生命周期包括:待接诊、进行中、待评价、已结束、已退款。医生接单有时效要求,超时未接诊要自动提醒甚至转接其他医生,这个状态流转逻辑要写得非常严谨,任何非法状态跳转都必须被拦截,否则容易出现患者已退款但会话仍在进行中的脏数据。
视频问诊对实时性要求更高,一般直接采用WebRTC方案,医生端和患者端点对点通信,信令服务器负责房间创建和握手。需要注意的是视频问诊必须全程录制留存,监管要求诊疗过程可追溯,录制文件加密后存入对象存储,保存期限通常不少于十五年。
四、电子病历的建模与隐私合规
电子病历(EMR)是医疗App中数据最敏感的部分。设计上建议遵循结构化与描述性并存的原则:既能存医生自由书写的文本主诉,也要把诊断、处方等关键信息结构化存储,方便后续的统计分析与处方流转。病历与问诊记录、挂号记录通过唯一关联串联:
CREATE TABLE `medical_record` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `record_no` VARCHAR(32) NOT NULL UNIQUE COMMENT '病历号', `patient_id` BIGINT NOT NULL, `visit_id` BIGINT COMMENT '关联挂号记录', `session_id` BIGINT COMMENT '关联问诊会话', `chief_complaint` VARCHAR(500) COMMENT '主诉', `diagnosis` JSON COMMENT '结构化诊断,ICD-10编码', `prescription_id` BIGINT COMMENT '关联处方', `doctor_id` BIGINT NOT NULL, `created_at` DATETIME NOT NULL, KEY `idx_patient` (`patient_id`, `created_at`) ) COMMENT='电子病历表';
隐私合规是医疗App的生命线。根据个人信息保护法和卫生健康行业的规定,患者的诊疗数据属于敏感个人信息,存储时必须加密,传输全程走HTTPS,敏感字段如身份证号、手机号建议采用AES加密后落库,密钥由专门的KMS服务管理。患者查看病历时还要做二次身份验证,比如人脸识别或短信验证码,防止手机被他人拿走后病历泄露。
此外,电子病历的修改必须留痕。医生修正诊断时不能直接覆盖原记录,而是插入一条新版本,通过版本号关联历史版本。这样既能满足监管审计要求,也能在医疗纠纷时提供完整的修改链条。删号功能在合规上风险极大,一般只提供注销申请通道,数据脱敏后归档,而不是物理删除。
五、开发中的常见坑与建议
第一,不要低估放号瞬间的并发压力。很多团队在测试环境一切正常,上线后专家号放号当天系统直接被打挂。建议上线前做真实的压测,把抢号接口单独部署并配置排队机制,宁可让用户等几秒也不能让系统崩溃。第二,处方相关的功能要谨慎。线上处方必须由具备互联网诊疗资质的医生开具,且处方必须经过药师审核才能流转到药房,这个流程不能为了体验而简化。第三,iOS审核对医疗类App审核非常严格,上架前要准备好《互联网医院许可证》或与实体医院的合作协议证明,否则大概率被拒。
总体而言,医疗App开发的技术难度并不是最高的,真正难的是业务规则的严谨性和合规要求的落地。建议开发团队在动手写代码之前,先花时间梳理清楚当地的互联网诊疗监管政策,再进行架构设计,这样能避免后期大规模返工。挂号、问诊、病历三大模块的数据打通做好了,后续扩展健康档案、慢病管理、药品配送等功能就有了坚实的基础。