ARTICLE DETAIL

资讯详情

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

微信小程序在线诊疗系统开发实战:架构、源码与调试全记录

微信小程序在线诊疗系统开发实战:架构、源码与调试全记录 小程序做在线诊疗系统这几年我在好几个项目里都碰过类似需求。和纯网页版本不同小程序天然具备轻量、免安装、微信授权登录这些优势特别适合挂号、问诊、查报告这类低频但又刚需的医疗场景。最近刚交付完一个完整的工程源码、文档、调试一条龙都配齐了趁热把从架构设计到实际排错的整个链路梳理一遍既是复盘也希望能给正在做同类型项目的同学一条可以直接参考的路线。1. 项目整体设计与模块拆解1.1 为什么选微信小程序承载在线诊疗先说结论在线诊疗这类业务最合适的轻量载体就是微信小程序而不是原生App或者网页H5。理由很直接。医疗服务的用户群体跨度很大从二十几岁的年轻人到五六岁十岁的中老年人都有让用户为了挂个号专门下载一个App这个门槛太高了。小程序呢微信里直接搜、直接扫用完即走不用安装对不熟悉智能手机操作的用户特别友好。另外一个关键点是微信授权登录用户点一下就能完成身份认证省掉了手机号验证码、注册账号这一大串流程。在医疗场景里用户往往是带着焦虑情绪来的多一步操作就多一分流失。从开发者的角度说小程序的技术栈是前端通用的WXML、WXSS、JavaScript后端接口只要按微信的规范来对接就行前后端分离调试和迭代都方便。再加上微信生态本身提供了支付、订阅消息、定位这些能力预约挂号后的提醒、线上支付费用这些功能都能直接用现成的组件不需要自己从头造轮子。1.2 系统核心功能模块划分我交付的这一版功能上分了三个端患者小程序端、医生工作台端、管理员后台端。这里说明一下医生端和管理员端考虑到实际使用场景做成了后台管理系统页面但底层数据和服务是完全打通的。患者小程序端是核心包含这么几个模块用户登录与授权微信一键登录绑定手机号维护基础健康档案。科室导航与医生列表按科室分类浏览支持按医生姓名、职称、擅长领域搜索。预约挂号选日期、选时段、选医生生成挂号单支持取消。在线问诊图文咨询和简单的语音留言医生端回复后患者能收到消息提醒。电子处方与报告医生开具处方后患者端能看到用药说明和注意事项。健康档案历次问诊记录、处方记录、体检报告上传。医生工作台端查看排班、处理问诊请求、开具处方、查看患者历史病历。管理员后台端医生信息管理、科室管理、挂号订单管理、数据统计。从业务闭环看患者从找医生、挂号、问诊、拿到处方整个流程在小程序里就能走完不需要跳出去。这也是当初设计时最看重的一点流程闭环越完整用户体验越顺。1.3 技术栈选型逻辑技术选型这件事很多新手容易上来就追新非要用最时髦的框架结果把自己绕进去。我这次选的是最稳妥、也最适合教学和二次开发的组合小程序端原生微信小程序框架。有人问为什么不用uni-app或者Taro实话讲如果项目只针对微信一个平台原生框架的调试体验是最好的微信开发者工具对原生项目的支持最完整出问题也最容易查资料。考虑到作业、毕业设计或者初创团队的技术储备原生框架门槛最低。后端Java Spring Boot MyBatis Plus。理由就一个词生态成熟。无论是个人学习还是企业项目Spring Boot的社区资料最多遇到问题基本都能搜到答案MyBatis Plus让单表操作和分页查询都变得非常省事。数据库MySQL 8.0配合Navicat或者DBeaver做可视化管理。存储过程、触发器这些在这个项目里用得不多但索引、事务、外键约束这些基本功是够用的。接口风格RESTful APIJSON格式传输。这套组合的最大好处是源码结构清晰文档好写调试链路短。我后面所有的实战经验都是基于这套组合跑出来的。2. 源码组织的核心细节与实现要点2.1 小程序端源码结构规划很多人拿到源码第一件事就是跑起来但真正要看懂项目得先看目录结构。我交付的小程序端源码目录是严格按照职责拆分的。miniprogram/ ├── pages/ │ ├── index/ // 首页科室导航轮播banner │ ├── login/ // 登录页微信授权手机号绑定 │ ├── department/ // 科室列表页 │ ├── doctor/ // 医生列表页 │ ├── booking/ // 预约挂号页 │ ├── consultation/ // 在线问诊页 │ ├── prescription/ // 电子处方页 │ ├── profile/ // 个人中心页 │ └── records/ // 健康档案页面 ├── components/ // 自定义组件医生卡片、日期选择器、空状态 ├── utils/ │ ├── request.js // 封装wx.request统一处理鉴权和错误码 │ ├── auth.js // 登录态管理 │ └── config.js // 环境配置接口基地址 ├── static/ // 静态资源图标、图片 └── app.js / app.json / app.wxss这个结构看着简单但里面有个容易踩坑的地方utils/request.js这个封装很重要。如果不做统一封装每个页面各自写wx.request一旦后端接口地址变了或者要统一加token鉴权就得把几十个文件全改一遍那酸爽我试过一次再也不想试第二次。request.js的封装思路是把wx.request包一层 Promise统一处理baseURL、请求头token注入、HTTP状态码和业务状态码的区分、错误提示。这样页面里调用接口就非常干净比如登录后拉取医生列表页面里只需要写const result await request({ url: /api/doctor/list, method: POST, data: { departmentId } });后面真机调试的时候你会发现这个封装的威力所有接口的报错信息格式统一了排查问题快很多。2.2 后端接口设计的约定后端源码我按Controller、Service、Mapper三层组织这是Spring Boot最标准的写法。三个角色各管各的Controller只做参数接收和数据返回Service层写业务逻辑Mapper层负责数据库交互。接口设计的几个约定我是这么定的统一返回体{ code: 0, message: success, data: {} }code为0代表成功非0代表业务错误比如1001表示token过期1002表示参数校验失败。分页统一格式page、pageSize两个参数返回{ list, total, page, pageSize }。鉴权方式使用微信登录后返回的openid作为用户唯一标识后端生成token存到Redis里小程序每次请求在header里带上token。这里有个细节预约挂号的时间段设计。数据库里booking_slot表存的是医生某天的排班时段比如上午8:00-9:00、9:00-10:00每个时段绑定可挂号人数。用户提交挂号时后端要做一个事务操作先查该时段剩余名额大于0才能插入挂号单同时扣减名额。两个操作必须放在一个事务里不然并发抢号的时候会出现超卖。这个在文档里我专门用一节写了说明因为它是整个系统最容易出bug的地方之一。2.3 三个关键业务场景的源码实现预约挂号这个场景除了事务还要处理一个状态机问题。挂号单的状态我定了四种待就诊、已完成、已取消、已过期。用户取消是主动操作医生标记完成是后端逻辑而已过期需要用一个定时任务扫描把就诊时间已过但状态还是待就诊的改成已过期。这几种状态流转如果不理清楚后续统计报表的数据全是乱的。在线问诊我用的方案是异步留言式不追求实时视频。原因是视频通话对服务器带宽和信令服务器要求高一个小型项目没必要上。用consultation表和consultation_message表记录问诊会话和消息患者发一条消息医生回复一条通过微信订阅消息通知对方。这个方案实现成本低而且完全能覆盖常见病咨询的使用场景。电子处方这块医生端填写药品名称、用量、用法、疗程后端生成处方记录并关联到问诊会话。前端小程序端用wx:for渲染药品列表每一条都带用药提醒。处方状态分待审核、已生效、已过期因为要模拟合规流程处方需要管理员做一次审核才生效这个逻辑虽然简单但能撑起业务完整性。3. 文档编写不是凑字数而是交付的一部分3.1 需求文档和技术文档的分工这个项目标题里带了个【文档】实战中我见过太多人把文档当应付检查的东西写一堆套话拿去交差。但实际上一份好的文档在后续调试和二次开发里帮助极大。我这次交付的文档分两层需求文档面向业务方或者答辩老师说明系统是干什么的、给谁用、有哪些功能、业务流程怎么走。重点在用例图、业务流程图和功能清单。技术文档面向接手源码的开发者说明系统怎么搭的、代码结构什么样、数据库怎么设计、接口怎么调用、环境怎么部署。这两份文档如果混在一起写要么业务方觉得太技术要么开发同学觉得太啰嗦。分开写各取所需。3.2 数据库设计文档的打磨数据库设计文档我一般不会只贴一张表结构图而是每张表都配上字段含义、类型、约束和关联关系说明。挑几张核心表说说user表微信用户信息openid唯一索引绑定手机号字段以及姓名、身份证号等实名信息。doctor表医生基础信息关联department表科室表包含职称、擅长领域、排班状态。booking表挂号记录外键关联user_id和doctor_id包含挂号日期、时间段、状态字段。consultation表问诊会话关联user_id和doctor_id状态字段区分进行中、已结束。prescription表处方记录关联consultation_id状态字段控制审核流程。prescription_item表处方明细药品名称、规格、用法用量。文档里我会对每个字段标注是否为索引因为后面调试慢查询时需要知道哪些字段走索引。比如booking表里查某个医生某天的号源(doctor_id, booking_date)就应该建联合索引不然后期数据量上来一条SQL能拖垮整个接口。3.3 接口文档与调试的关系接口文档我推荐用Markdown直接写轻量、能进git格式也清晰。每个接口的文档包含接口地址、请求方式、请求参数、返回值举例、错误码列表。举个例子预约挂号接口的文档段落POST /api/booking/create Headers: Authorization: Bearer token Body: { doctorId: 2, bookingDate: 2025-06-20, slotId: 5, patientName: 张三 } Response: { code: 0, message: success, data: { bookingId: 1024, status: 待就诊, doctorName: 李医生 } }为什么接口文档这么重要因为前后端分离开发的模式下前端同学拿到这份文档不用等后端写完就能先mock数据开发页面。后端同学调接口时也能按文档里的请求示例去堆参数。注意我见过很多人把接口文档写成交代作文一大段描述性文字但连个请求示例都没有。这是大忌。同样的信息表格和代码示例永远是最高效的载体。文档不是写给自己感动的是写给使用者看的。拿这个原则去衡量文档的质量会高很多。4. 调试实战那些年踩过的坑4.1 微信开发者工具的核心技巧微信开发者工具是调试小程序的第一战场但是很多人只把它当模拟器用没有好好榨干它的价值。最重要的一个技巧是Source面板的断点调试。在开发者工具里点击代码行号就能打断点然后在Console面板里查看变量值。很多同学喜欢用console.log到处打点这当然可以但排查复杂问题时断点调试的效率高得多。特别是定位一个接口数据处理的问题断点停在数据处理那一行逐步往下走数据是在哪一步变歪的立刻就能看到。另一个容易被忽略的是Network面板。小程序的网络请求都能在这里看到包括请求URL、请求头、响应体、耗时。我调试接口联调问题时基本就是靠Network面板判断是前端没发请求、发了请求参数不对、还是后端返回了错误数据。三个环节一目了然。4.2 真机调试与抓包验证模拟器跑得好好的一上真机就白屏、接口报错这是小程序开发的经典问题。原因通常是模拟器的环境和小程序基础库版本差异或者某些接口在真机上有限制。解决思路分几步走先做真机预览把项目传上去扫码用手机跑一次。如果接口请求失败优先检查域名配置小程序要求所有请求域名必须在微信公众平台配置服务器域名白名单并且必须是HTTPS协议。这个检查项我几乎每次都会踩因为本地开发用的时候可以勾选开发者工具的普通模式跳过域名校验但一上真机这个勾选就不生效了所有请求都会被拦截。排查的标准配置是在Build时去掉勾选域名校验然后再跑一遍。如果涉及更底层的网络问题就需要抓包工具了。我用Charles比较多配置https抓包的时候需要下载证书并安装到手机。抓包能确认后端接口真正返回的数据结构排查是不是后端返回了HTML错误页或者网关超时。真机调试还有一个很实用的场景查看微信订阅消息下发。开发者工具可以模拟订阅消息但真机上能验证用户是否真的会收到通知这种体验是模拟器给不了的。4.3 常见报错排查速查表这一节我直接整理成表格都是实际项目里反复出现的问题。每个问题都附上排查思路和解决办法大家真遇到了可以直接对照着处理。报错现象大概率原因排查与解决登录后接口返回401token未注入请求头检查request.js封装的header确认token从storage取出后手动添加真机请求失败模拟器正常域名未白名单化或未用HTTPS在微信公众平台配置合法域名服务器启用HTTPS页面白屏Console报undefined数据请求回来前页面渲染了空数据用wx:if控制页面渲染时机或者提供loading状态。预约挂号并发时额度超卖下单逻辑未加事务锁把查余额和扣减名额放进同一事务或者使用乐观锁字段version小程序包体积过大图片、静态资源太多图片走CDN代码分包加载组件按需引入后台管理登录后Session丢失session有效时间过短或存储方式不稳定用Redis存储后台登录态并设置合理的过期时间这些问题每一个我都实际遇到过。特别是并发超卖那个第一次出现时我用两个微信账号同时挂号同一秒钟抢同一个医生的号结果系统生成了两张挂号单可号源只剩下一个名额。后来查代码发现问题在于我先查了剩余名额然后再执行插入操作两次数据库操作之间没有事务隔离于是并发时产生了竞态条件。改用事务行级锁后这个问题就彻底解决了。代码里加了个版本字段更新时判断版本号是否变化变化则重试。4.4 后端调试从日志到接口自测后端调试这块我觉得最有用的习惯是分级打印日志而不是项目上线了才发现没法定位问题。Controller层要打请求参数和返回值Service层要打关键业务逻辑的分支Mapper层要打SQL执行情况。这样一旦线上出了问题顺着日志就能一步步还原当时的场景。Spring Boot自带Logback我习惯把日志按天滚动保留最近15天并且把错误日志单独用一个文件存。排查问题时先看错误日志文件能省很多时间。接口自测方面推荐Swagger或者Postman。在项目里集成Swagger依赖后启动服务就能自动生成接口调试页面方便又直观。Postman则适合做接口的批量回归测试把每个接口的请求脚本保存下来改完代码跑一遍就知道有没有破坏之前的接口。有一点要提醒自测时要把鉴权流程理清楚。很多接口需要登录后带上token才能访问所以我在Postman里会做一个登录脚本自动获取token并添加到后续请求的header里。这个设置好在一次后面所有接口都能直接调。5. 交付部署与二次开发扩展5.1 环境准备与部署步骤交付一套系统光给源码是不够的还得把部署文档写清楚不然接手的人第一步就卡住。我这次整理的环境要求是JDK 1.8以上Spring Boot 2.x版本对应JDK8即可。MySQL 5.7或8.0。Maven 3.6用于后端项目构建。微信小程序开发者工具用于前端预览。Redis非必须但推荐用来存token和缓存科室列表。部署流程上后端先建库、建表把SQL脚本执行一遍再修改application.yml里的数据库连接信息启动mvn spring-boot:run就算OK了。前端在开发者工具里导入项目修改utils/config.js里的接口基地址为本地或服务器的后端地址就完成了联调。这里有一个新手很容易忽略的点小程序端config.js里的域名如果要用正式环境必须用HTTPS而且需要在微信公众平台的后台把域名加到request合法域名里。如果只是本地开发调试可以在开发者工具里勾选“不校验合法域名”但真机调试时记得关掉这个勾选。5.2 二次开发与功能扩展方向这个系统交付后找我问得最多的一个问题是我想加XX功能从哪里入手比较合适我的建议是别上来就去改代码先想清楚新功能落在哪个模块里会不会影响现有数据表的结构。比如加一个“在线支付”功能那要改动的地方就清楚了预约挂号成功后引导用户进入支付流程支付成功后回调更新挂号单状态。这涉及booking表加一个支付状态字段小程序端加一个支付页面后端加一个支付回调接口。想清楚了改动范围就锁定了。再比如加一个“报告解读”功能可以复用consultation表上传检查报告图片后把报告内容和医生解读都关联到会话中患者在问诊记录里就能看到报告和解读。这个过程不需要改表结构只需要新增上传接口和前端页面。5.3 源码交付的注意事项源码交付这件事我踩过不少坑最后总结出几条必须注意的规范敏感信息脱敏数据库密码、接口密钥、微信小程序AppSecret这些不能明文写在源码里。我的做法是用环境变量或者配置文件模板来代替交付时提供一个application.yml.example真实的配置文件自己创建。数据库脚本单独抽出来MySQL脚本里要包含建库语句、建表语句、初始数据并且按顺序编号01_schema.sql、02_init_data.sql。这样接手的人执行脚本时不会有依赖混乱的困扰。引入说明文档README这个文档只讲三件事项目是什么、怎么跑起来、目录结构说明。跑起来这部分要写得像菜谱一样清晰保证一个没有接触过这个项目的人照着走一遍就能成功启动。版本标签明确git仓库里建议打上tag比如v1.0.0表示第一版完整交付。这样如果后面做了修改接手的人可以很方便地对比差异。6. 写在最后的一些心得说实话在线诊疗这类系统业务逻辑本身不算特别复杂真正拉开差距的地方在于细节处理并发挂号不超卖、状态流转不混乱、接口文档清晰、部署步骤完善。这些点单独拿出来都不难但合在一起就能看出一个项目工程化水平的高低了。我个人在实际操作中体会最深的是文档和调试其实是同一件事的两面。文档写清楚了调试的时候你才知道期望值是什么调试做透了你写文档的时候才会发现哪些地方自己还没想明白。所以如果精力有限我建议先把接口请求和数据处理的主链路写清楚再谈那些花里胡哨的功能。还有一个建议送给准备拿这类项目做演示或者交作业的同学不要只演示正常流程一定要演示边界情况比如重复挂号、号源不足、用户取消挂号、医生端拒绝问诊。这些边界情况能覆盖说明你真的把系统想透了。面试时吹项目经历的时候讲一个自己处理过的并发问题比罗列十个功能点都更有说服力。这个系统后续要继续扩展的话我强烈建议先做数据统计模块把挂号量、问诊量、处方量的趋势图做出来。有了数据看板整个系统的价值感会提升一大截而且这些数据也足够支撑你做下一步的运营决策。哪怕是模拟数据对理解业务也很有帮助。
返回列表