简介这份资源是面向医疗信息化开发者与计算机专业学生的微信小程序医院体检管理系统完整项目源码聚焦体检流程数字化与健康数据管理场景。系统覆盖在线预约体检套餐、实时排队进度查看、电子报告查询、健康档案管理、医生在线咨询、体检注意事项提醒及健康数据分析追踪等模块适合作为毕业设计、课程实训或二次开发的学习范本。压缩包共1201个文件约15.31MB包含163个js与128个vue业务代码、111个java后端源码、80个wxss与78个wxml小程序页面以及232个png、162个svg等界面素材另有json配置、sql脚本与bat启动脚本前后端结构完整。已有189人学习下载。读者可据此梳理小程序与Java服务端的接口设计、页面组织与数据流转方式理解预约、排队、报告查询等核心链路的实现思路并借助现有目录结构快速定位模块为医疗类项目开发与功能扩展提供可复用的参考。1. 体检流程数字化的真实痛点为什么小程序成了最优解做过医院体检系统的人都知道体检业务最折磨人的不是技术难度而是流程碎片化。预约靠电话、排队靠喊号、报告靠打印、档案靠纸质文件夹患者跑上跑下护士站电话不断医生翻不到历史数据。基于微信小程序的智能化医院体检全流程管理系统核心就是用一套轻量前端把预约、排队、报告、档案、咨询、提醒、数据分析串成闭环。它适合中小型体检中心、独立健康管理机构以及想给现有 HIS 做体检模块外挂的团队。选小程序而不是 App理由很实际患者不用装、扫码即用、微信支付和消息模板天然打通开发成本低迭代快。这一章先把业务边界和系统骨架讲清楚后面再落到具体实现。2. 系统架构与数据模型把七个模块拆成可落地的表结构2.1 为什么选微信小程序 云开发/自建后端体检系统的用户分三类患者端、医生端、管理端。患者端用小程序是共识医生端可以复用同一套小程序加角色权限管理端建议单独做 Web 后台。后端有两种常见路线微信云开发适合快速验证省去服务器运维但复杂查询和事务能力弱自建后端Node.js 或 Java适合数据量大、要和院内系统对接的场景。我一般会推荐混合方案核心业务走自建 API消息推送和文件存储用云能力。数据库设计上体检业务的关键实体有用户、体检套餐、套餐项目、预约单、排队记录、体检报告、报告指标、健康档案、咨询会话、提醒任务。下面给出核心表的建表 SQL字段命名和索引都按实际查询场景设计。-- 用户表患者与医生共用用 role 区分 CREATE TABLE t_user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, openid VARCHAR(64) UNIQUE COMMENT 微信openid, name VARCHAR(32), phone VARCHAR(20), role TINYINT DEFAULT 0 COMMENT 0患者 1医生 2管理员, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 体检套餐表 CREATE TABLE t_package ( id BIGINT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(128) NOT NULL, price DECIMAL(10,2), gender_limit TINYINT DEFAULT 0 COMMENT 0不限 1男 2女, status TINYINT DEFAULT 1 COMMENT 1上架 0下架 ); -- 预约单核心业务表queue_no 用于排队 CREATE TABLE t_appointment ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, package_id BIGINT NOT NULL, appoint_date DATE NOT NULL, time_slot VARCHAR(16) COMMENT 如 08:00-09:00, queue_no INT COMMENT 当日排队号, status TINYINT DEFAULT 0 COMMENT 0待检 1检中 2完成 3取消, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_date_status (appoint_date, status) ); -- 报告指标一条报告对应多条指标 CREATE TABLE t_report_item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, report_id BIGINT NOT NULL, item_name VARCHAR(64), item_value VARCHAR(32), ref_range VARCHAR(64), abnormal TINYINT DEFAULT 0, INDEX idx_report (report_id) );逻辑说明t_appointment上的联合索引idx_date_status是排队进度查询的关键实时排队本质就是按日期和状态统计前面还有多少人。queue_no在用户支付成功后生成用当天该套餐已预约数加一注意并发下要用数据库行锁或 Redis 原子自增否则会出现重号。参数方面time_slot建议按 30 分钟或 1 小时分片太细会导致排班复杂太粗会让患者集中。2.2 排队进度的实时计算逻辑排队进度不需要 WebSocket 长连接体检场景对实时性要求是秒级用轮询加缓存就够。核心公式我的前面人数 当前叫号之前、状态为待检、且排队号小于我的记录数。实现时把当日队列放 Redis List 或 Sorted Set叫号时弹出查询时用 rank。// 查询我的排队进度Node.js Redis async function getQueueProgress(appointmentId) { const appt await db.query( SELECT queue_no, appoint_date, status FROM t_appointment WHERE id?, [appointmentId] ); if (!appt || appt.status ! 0) return { status: appt.status, ahead: 0 }; const key queue:${appt.appoint_date}; // 当前已叫到的号 const currentNo await redis.get(${key}:current) || 0; // 我的号减去当前号就是前面等待人数 const ahead Math.max(0, appt.queue_no - currentNo - 1); // 按平均每人 8 分钟估算等待时间 return { ahead, estimateMin: ahead * 8 }; }逻辑说明current由护士端叫号接口写入每次叫号INCR或直接SET。估算时间用固定均值是妥协方案更准的做法是记录每个项目的平均耗时按套餐项目数加权。参数上8 分钟是综合抽血、内外科、B 超的常见均值如果套餐含 CT 或核磁要单独拉长。注意 Redis 的 key 要设过期时间比如 48 小时避免历史数据堆积。3. 核心功能实现预约、报告、档案、咨询四件套3.1 在线预约体检套餐的完整链路预约链路是选套餐 → 选日期时段 → 填就诊人 → 支付 → 生成排队号 → 发订阅消息。小程序端用wx.request调后端支付用wx.requestPayment。关键点是支付回调里做幂等防止重复生成预约单。// 小程序端发起预约 wx.request({ url: https://api.example.com/appointment/create, method: POST, data: { packageId: 101, date: 2025-06-01, slot: 08:00-09:00 }, success(res) { if (res.data.needPay) { wx.requestPayment({ timeStamp: res.data.timeStamp, nonceStr: res.data.nonceStr, package: res.data.package, paySign: res.data.paySign, success: () wx.showToast({ title: 预约成功 }) }); } } });逻辑说明后端create接口先落一条状态为「待支付」的预约单并锁定号源支付回调里把状态改为「待检」并分配queue_no。参数上号源要按appoint_date time_slot做容量控制比如每时段限 20 人用 Redis 计数器防超卖。订阅消息用「体检预约成功通知」模板在支付回调里调用subscribeMessage.send注意模板字段要和后台申请的一致否则会报 47003。3.2 电子报告查询与健康档案管理报告查询的难点是报告生成和权限。报告通常由检验科系统导出 PDF 或结构化数据后端解析后写入t_report和t_report_item。患者端只允许查自己的报告用 openid 关联校验。健康档案则是把历次报告按时间轴聚合做趋势展示。# 报告解析入库Python 示例 import pdfplumber def parse_report(pdf_path, report_id): items [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: table page.extract_table() if not table: continue for row in table[1:]: # 跳过表头 name, value, ref row[0], row[1], row[2] abnormal 1 if is_abnormal(value, ref) else 0 items.append((report_id, name, value, ref, abnormal)) bulk_insert(t_report_item, items) def is_abnormal(value, ref): # ref 形如 3.5-9.5解析上下限比较 try: low, high map(float, ref.split(-)) return 0 if low float(value) high else 1 except Exception: return 0逻辑说明pdfplumber适合表格规整的 PDF如果报告是图片扫描件要上 OCR成本高且准确率不稳建议推动检验科直接给结构化数据。is_abnormal只处理数值型参考范围定性指标阴性/阳性要单独映射。健康档案的趋势图用 ECharts 按指标名分组取最近 5 次数据画折线异常点标红。注意报告数据涉及隐私接口必须做鉴权日志里不要打印完整指标值。3.3 医生在线咨询与体检注意事项提醒在线咨询建议做异步消息而非实时 IM体检场景的咨询多是「这个指标什么意思」「要不要空腹」异步足够且省成本。用一张t_consult表存会话患者提问、医生回复配合订阅消息通知对方。注意事项提醒分两类预约前的准备提醒空腹、憋尿、避开经期和检后提醒取报告、复查。// 定时任务体检前一天推送注意事项 const schedule require(node-schedule); schedule.scheduleJob(0 18 * * *, async () { const tomorrow dayjs().add(1, day).format(YYYY-MM-DD); const list await db.query( SELECT user_id, package_id FROM t_appointment WHERE appoint_date? AND status0, [tomorrow] ); for (const item of list) { const tips await getPackageTips(item.package_id); await sendSubscribeMsg(item.user_id, 体检提醒, tips); } });逻辑说明定时任务每天 18 点跑查次日预约按套餐取注意事项模板。getPackageTips根据套餐是否含抽血、B 超返回不同提示比如含抽血必须空腹 8 小时。参数上订阅消息有次数限制用户授权一次只能发一条所以要在预约成功时就引导用户勾选「允许提醒」。注意时区问题服务器用 UTC 时要转成东八区再算日期。4. 避坑与排查体检系统上线后最容易翻车的五件事4.1 排队号重复与并发超卖现象同一时段出现两个相同的排队号或者预约人数超过号源上限。原因生成queue_no时用了「查最大值加一」的写法并发下两个请求读到同一个值。解决用 RedisINCR生成号或数据库唯一索引UNIQUE(appoint_date, queue_no)兜底捕获冲突后重试。号源控制用 Redis 计数器扣减用DECR后判断是否小于零小于零再INCR回滚。4.2 支付回调丢失导致状态不一致现象用户付了钱预约单还是「待支付」。原因微信支付回调可能延迟或失败只依赖回调改状态不可靠。解决加主动查单补偿定时任务扫描超过 5 分钟仍待支付的单调微信查单接口确认已支付则补状态。同时回调接口要做幂等用订单号做唯一键重复回调直接返回成功。4.3 报告 PDF 解析错位现象指标值和参考范围对不上或者漏掉某些项目。原因不同检验科的 PDF 表格结构不一致extract_table按坐标切分合并单元格会错位。解决先做模板适配按报告来源配置解析规则解析后做校验比如指标数量少于预期就告警人工介入。不要指望一套正则打天下这是血泪经验。4.4 订阅消息发送失败现象提醒没发出去日志报 47003 或 43101。原因模板字段不匹配或用户没授权、授权次数用完。解决模板 ID 和字段在后台核对thing类型限 20 字符以内超长会失败。用户授权要在关键节点引导比如支付成功页弹窗不要等要发的时候才发现没授权。4.5 健康档案数据越权访问现象A 用户能查到 B 用户的报告。原因接口只校验了登录态没校验数据归属。解决所有查询强制带user_id条件报告详情用report_id user_id双条件查查不到就返回 404。管理端和医生端走单独的权限体系不要和患者端混用同一个接口。5. 健康数据分析追踪的进阶玩法把报告变成可行动的建议基础版健康档案只是把报告堆在一起进阶版要做趋势分析和风险提示。我的做法是给每个指标配一套规则连续异常或超阈值就生成健康建议推送给用户。比如血压连续三次偏高提示复查并建议低盐饮食血糖异常提示内分泌科就诊。规则用配置表管理不要写死在代码里。// 指标趋势分析取最近 N 次同指标数据 async function analyzeTrend(userId, itemName, limit 5) { const rows await db.query( SELECT ri.item_value, r.created_at FROM t_report_item ri JOIN t_report r ON ri.report_id r.id WHERE r.user_id? AND ri.item_name? ORDER BY r.created_at DESC LIMIT ?, [userId, itemName, limit] ); if (rows.length 3) return null; const values rows.map(r parseFloat(r.item_value)).filter(v !isNaN(v)); const abnormalCount rows.filter(r r.abnormal).length; // 连续异常或持续上升触发提醒 const rising values[0] values[values.length - 1]; if (abnormalCount 2 || rising) { return { itemName, suggestion: buildSuggestion(itemName, values) }; } return null; }逻辑说明analyzeTrend按指标名取最近 5 次少于 3 次不分析避免误报。abnormalCount 2是连续异常阈值rising判断趋势两者满足其一就生成建议。buildSuggestion按指标名查建议库比如「总胆固醇」对应「减少动物内脏摄入三个月后复查」。参数上limit不要太大5 次足够看趋势太多会稀释近期变化。这套逻辑跑在定时任务里每周一次结果写进t_health_advice表用户端在档案页展示。验证方法拿一批历史报告跑离线分析人工核对建议是否合理重点看假阳性。我一般会先跑一个月数据把误报的规则调松再上线。注意建议不能替代诊断文案要写「仅供参考请遵医嘱」这是合规底线。最后说个习惯体检系统的数据敏感度比普通业务高一个量级我每次上线前都会用测试账号把「越权查报告」「重复预约」「并发抢号」这三条路径手动走一遍比写多少单测都管用。希望帮到你。本文还有配套的精品资源点击获取