先提个醒:别把“在线问诊挂号开药系统”当成一个简简单单的预约小程序来做。它表面上是挂号、聊天、下单、支付几个页面拼起来,实际跑一遍患者流程你就知道,这里面的角色关系、状态流转和数据一致性,比普通电商项目复杂得多。这篇文章不会停留在“我搭了个Spring Boot/uni-app能跑”这种层面,而是把这类系统真正要面对的业务闭环、工程骨架和踩坑点拆开讲清楚,适合正在做毕设、课设,或者打算认真做一个医疗类微信小程序全栈作品的同学参考。
1. 先拆业务闭环:这个系统到底要管多少件事
1.1 一次完整就诊流程是怎么串起来的
在线问诊挂号开药系统,名字看起来长,拆开其实是三个相对独立又有强关联的环节。患者进小程序第一眼看到的可能是医生列表、科室分类、排班时间;但背后的流程是从“选择医生”开始的:选定科室 -> 查看医生排班 -> 选择时间段 -> 提交挂号信息 -> 支付挂号费 -> 生成挂号记录 -> 进入候诊/问诊状态。问诊结束后,医生根据病情描述和检查结果判断是否需要开药;如果需要,就进入开方环节:创建处方、添加药品、填写用法用量、提交药师审核(如果业务要求的话);患者收到处方后确认并支付药品费用,系统再进入配药发货流程。
这三个环节不是孤立的数据表,而是共享同一条“用户—就诊记录”主线的连续状态机。很多新手做这类项目时最常见的失误,就是把挂号记录、问诊记录、处方记录各建一张表,彼此之间没有外键关联,也没有状态字段。结果就是患者明明已经退号了,医生还能给他开处方;或者问诊都结束了,但挂号状态还是“待就诊”。所以做项目的第一步不是写登录注册,而是先把状态流转梳理清楚。
我建议你画一张简单的状态表,至少覆盖四个核心对象:预约单、问诊单、处方单、订单。每个对象都需要有自己的生命周期。预约单可以是“待支付 -> 已支付/待就诊 -> 就诊中 -> 已完成”或“已取消”;处方单则是“草稿 -> 待审核 -> 已通过 -> 已取药/已发货”等。状态机定好了,后端接口的权限判断就顺了:某状态下允许谁调用什么接口,写在代码里绝不互相矛盾。
1.2 和普通商城系统最本质的区别在哪里
如果只说“用户下单、支付、发货”,那这跟商城确实像。但医疗类系统有两点是商城远不能比的。
第一,数据正确性直接和人身安全绑定。处方里的药品名称、规格、剂量、频次错了,不是退个货就能弥补的。商城里库存少一件,后面补货就行;处方里剂量少了单位,赔不起。所以在后台接口层面,医生创建处方时必须联动药品表的基本信息,而不是让前端手填一个药品名字。药品名称、厂家、规格、剂型、库存量、单价,这些基础数据必须落库并由后端校验。
第二,权限边界要细得多。一个普通商城系统通常就三种角色:管理员、商家、用户。问诊系统至少得有患者、医生、药师(若有)、管理员这四类。医生能查看患者提交的病历资料,但患者不能随意查看其他患者的问诊记录;医生能修改自己的排班和擅长领域,但不能动药品库存;药师能审核处方,但不应直接改药品信息。这些如果不能通过后端统一做权限判断,前端页面隐藏按钮根本没有安全保障。
所以我的建议是:先把这些“业务规则”用自然语言列一遍,再去建表写接口。比如“患者提交挂号的医生必须处于可预约状态”“医生只能给处于‘就诊中’状态的问诊单开药”“用户取消订单后库存必须回补”。每一条规则背后都对应一个后端校验逻辑,这类项目做完之后你会发现,难点从来不是某个框架的API不会调,而是业务规则有没有覆盖完整。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型推导:为什么是 uni-app、Python、微信小程序这个组合
2.1 前端用 uni-app,是为了给“多端”留后路
在做这类项目时,前端框架的选择很关键。如果目标只做微信小程序,你用原生微信小程序开发也可以,代码写起来更直接,也没有跨端编译的中间层问题。但 uni-app 的好处在于:同一套 Vue 代码,可以编译到微信小程序、App、H5 等多个端。很多门诊项目需要同时出“医生端App、患者小程序、管理后台网页”的演示效果,用 uni-app 一套代码至少能同时覆盖小程序和H5,省下大量重复开发时间。
uni-app 的组件体系、页面路由、uni.request 接口,和原生小程序习惯有差异,但它底层最终还是编译成微信小程序原生语法。只要你在 HBuilderX 里跑过“运行到小程序模拟器”,就会发现页面反应会有几十毫秒的编译延迟,这正常;真正要注意的是别在代码里写浏览器专用 API,比如 window、document,小程序端是不存在的。路由传参也要注意,uniapp 的 uni.navigateTo 里通过 url 传对象时,需要先用 encodeURIComponent(JSON.stringify(obj)) 序列化,接收时再 decodeURIComponent,否则参数会被截断,这就是“uniapp获取路由参数”最常见的坑源。
如果你想做的是一个“演示起来流畅、视觉完整、答辩或交付时有真实感”的系统,uni-app 是不错的底盘。Vue 语法本来就是很多前端同学的舒适区,生态里关于选择器、表单校验、UI 库的现成方案也比较充足。尤其医疗系统里有大量表单页,比如挂号信息、患者主诉、收货地址、用药反馈,uni-app 里你可以自己封装多个带校验的表单组件,配合选择器组件做级联,体验会比小程序的原始 picker 灵活很多。
2.2 Python 后端为什么常用 Flask 而不是 Django
Python 后端在这个项目里最常见的两个选择就是 Flask 和 Django。如果你从零开始、想尽快看到接口效果,我推荐 Flask。它是微框架,启动一个服务只需要几行代码,开发时随时可以改 py 文件并重启,目录结构也自由。医疗问答、聊天记录这类接口,用 Flask 的蓝图分一下模块,业务逻辑放在 service 层,代码量并不大,反而好控制。
Django 的优势是自带 Admin 后台、ORM、认证、Admin 可视化,适合快速生成管理界面的场景。门诊系统确实有后台管理需求——管理医生排班、维护药品库、查看订单记录——Django Admin 几乎零成本给你一套可用的后台。但是 Django 的项目结构和约定较重,很多第一次做全栈项目的同学容易迷失在 settings、app、migration 这类目录里,反而拖慢进度。如果你工期紧张或本身是前端背景,Flask + SQLAlchemy 更友好。
我个人更推荐的做法是:核心后端使用 Flask 提供 JSON API,管理后台前端用 uni-app 的 H5 模式或单独一个简单的 Vue 页面来对接接口。数据库常用的 MySQL,但如果你只是课堂展示或课设,SQLite 也能跑通;只是要注意 SQLite 对并发写和 JSON 字段的支持都比较弱,如果系统里要演示多人同时挂号,最好还是上 MySQL。
2.3 微信小程序端的定位与“只能用它完成”的原因
可能有人会问,前面说 uni-app 可以同时生成 H5 和 App,为什么标题还强调“微信小程序”?因为在线问诊这类系统的真实使用场景,大部分还是发生在微信环境里。患者不用专门下载App,打开微信搜索小程序就能用,登录时直接通过微信授权拿到手机号和用户信息,降低使用门槛。挂号通知、处方提醒、支付结果这类业务又天然依赖微信的服务通知和支付体系。
不过这里想提醒一句:产品形态虽然叫小程序,但你的后端不能只在微信的“web-view”容器里写一套网页。小程序有自己的生命周期,页面有 onLoad、onShow,有独有的登录机制 wx.login。你需要在后端写一个登录接口,接收小程序传来的 code,再调用微信的接口换取 openid 和 session_key,生成自己的 token 返回前端。这个流程如果做得不对,后面每个接口的身份验证都会出问题。
在开发阶段,你要保持 HBuilderX、微信开发者工具、后端服务三端同时在线。这里有个很容易让新手崩溃的问题:运行到微信小程序模拟器时,如果发现“小程序ID还是原来的”,多半是 HBuilderX 里的 manifest.json 没有改成你自己的 AppID,或者在微信开发者工具里没有切换成测试号。建议打开 manifest -> 小程序配置,把对方的 AppID 填进去,然后在微信开发者工具右上角详情里确认“AppID”一致。这类问题不是代码逻辑错,而是项目配置串了。
3. 工程骨架设计:目录、数据模型与一套稳定的接口约定
3.1 项目目录结构与后端模块划分
代码组织得好坏,直接决定你赶工期的效率。前端 uni-app 工程的目录结构,基本沿用 Vue 单页应用的思路:pages 下按功能分模块,比如分为 home(首页/医生列表)、appointment(挂号)、consult(问诊)、pharmacy(开方购药)、user(个人中心)。公共的 request 封装、登录态工具函数要单独放出来,别在每个页面里复制一遍 uni.request 的写法。
后端如果采用 Flask,目录可以这样划分:
text复制server/
├── app.py # 应用入口,注册蓝图
├── config.py # 配置:数据库、密钥、微信appid等
├── models/ # SQLAlchemy 数据模型
│ ├── user.py
│ ├── doctor.py
│ ├── appointment.py
│ ├── consultation.py
│ ├── prescription.py
│ └── medicine.py
├── api/ # 蓝图路由文件
│ ├── auth.py # 登录、注册、Token刷新
│ ├── doctor.py # 医生排班、问诊列表
│ ├── patient.py # 患者档案、挂号
│ ├── consult.py # 消息、问诊会话
│ ├── prescription.py # 处方接口
│ └── pay.py # 支付回调
├── services/ # 业务逻辑层
│ ├── appointment_service.py
│ ├── prescription_service.py
│ └── inventory_service.py
└── utils/
├── response.py # 统一返回
├── auth_decorator.py # 登录装饰器
└── wechat.py # 微信 code2session 等
我见过太多把所有接口都写在 app.py 里的项目,不到一个月就变成一团乱麻。Flask 的蓝图机制就是为了解决模块化问题,你不用它就是给自己添乱。业务逻辑层单独抽出来还有一个好处:当你在视图函数里要做“创建处方后同时扣减库存”这类多步操作时,可以放到 service 层统一控制事务,而不是在每个接口函数里裸写数据库操作。
3.2 核心数据表字段设计:从用户表到处方明细表
系统表结构不要一开始就塞几十个表,先抓住最关键的那几张。基础用户表可以设计成一张带角色字段的表,字段包括 id、openid、unionid(可选)、nickname、avatar、phone、role,role 可以是 patient 或 doctor;管理员账号可以独立放管理员表,也可以复用同一张表加个 role。医生和患者有很多专属信息,比如医生的擅长、科室、职称、简介,患者的年龄、身份证号、过敏史等,建议单独建 doctor_profile 和 patient_profile,和用户表一对一关联。
排班与挂号相关的表是整个系统的发动机。我建议保存三张表:
doctor_schedule:医生排班表,字段包括 doctor_id、work_date、start_time、end_time、period_type(上午/下午/晚间)、remain_count、total_count、status。这一步相当于“号源池”。appointment:挂号单表,字段包括 patient_id、schedule_id、appointment_no、visit_date、time_slot、status、cancel_reason、create_time、pay_time。consultation:问诊记录表,patient_id、doctor_id、appointment_id、start_time、end_time、status、chief_complaint、diagnosis。
开药环节有三张紧密关联的表:
medicine药品表:medicine_code、name、specification、unit、stock、price、manufacturer、usage_guidance 等prescription处方主表:consultation_id、doctor_id、patient_id、total_amount、status、audit_status、create_time、remarkprescription_item处方明细表:prescription_id、medicine_id、medicine_name(冗余快照)、quantity、dosage、frequency、days、amount
为什么要做冗余快照?因为药品信息后续可能改价、改名,而处方具有“当时有效”的法律和业务意义,患者看到的应该是医生开方那一刻的药品名称和价格,而不是现在的。如果只关联药品 id,某天药房管理员把“阿莫西林胶囊 0.25g”改成“阿莫西林胶囊 0.5g”,所有历史处方价格就全乱了。这是这类系统设计中很基础却很重要的一点。
3.3 接口返回体、鉴权方式和分页规约
全栈项目如果前后端各写各的规范,联调时就会被各种小问题拖死。建议统一返回结构,最简单的一种是:
json复制{
"code": 0,
"message": "success",
"data": {}
}
code 为 0 代表成功,非 0 为业务错误码;前端封装的 request 工具拦截非 0 的 code 并统一弹 toast,用户不用在每个页面里重复写错误处理。鉴权方面,后端使用自定义 token,比如把 user_id 和 role 加密成一个 JWT 或字符串,前端存储在 uni.setStorageSync('token', token),每次请求时放进 header 的 Authorization。后端写一个登录装饰器,从 header 取 token 解析出用户,再注入到视图函数里。
分页统一采用 page 和 page_size 参数,返回数据里附带 total、pages 字段。问诊记录、订单列表、排班列表这些高频数据都必须分页,否则数据量一上来,小程序端每页渲染几百条数据会非常卡。
我额外建议把所有时间字段在数据库存为标准 datetime,前端展示时再格式化成“2025-03-01 09:30”。最怕的是项目中混用时间戳、字符串、datetime 三种格式,到后来排序、跨端显示全都对不上。这类系统里时间不仅是展示信息,还参与医生排班冲突、号源释放等判断逻辑,格式一乱必然会出大问题。
4. 三块核心业务的细节与状态流转设计
4.1 预约挂号:号源怎么扣,退号怎么还
预约挂号不能每次请求都无脑减库存。患者选完时间段、点了“提交挂号”但一直没支付,这个号源算谁的?如果直接扣减号源库存并将预约单状态置为“待支付”,那其他人就无法再约这个时段,只有等支付超时后才释放。比较好的方案是在预约单创建时设置一个过期时间,比如15分钟;用定时任务或者惰性释放逻辑,将超过支付时限且未支付的预约单状态改成“已取消”,同时把对应排班表的 remain_count 加回去。
科室和医生排班也不是每天都手动录入,可以做个“一键排班”的接口:管理员选好科室、医生和有效日期范围后,系统自动按工作日和时段生成 schedule 记录。这比手动逐条添加高效得多,演示时也更有说服力。
具体到预约下单的事务流程:前端提交预约请求后,后端先读取该 schedule 的剩余号源,判断大于0;然后开启事务,将排班表的 remain_count 减1,创建 appointment 记录,状态设为待支付;接着触发支付;支付回调成功后再把状态改为已支付。这里必须用数据库事务或行锁,保证并发情况下不会超卖,绝对不能先查后改,否则两个人同时请求时都可能看到剩余号源为1并同时下单。
4.2 在线问诊:消息记录与状态迁移是核心
问诊模块最常见两种形态。一种是纯图文消息,聊天界面发送文字和图片;另一种是表单问诊,患者先填主诉、症状、病史,医生再根据表单回复,消息记录作为补充。对全栈项目来说,图文聊天界面在跨端适配上有不少工作量:需要自己实现输入框、消息气泡、图片预览、未读计数,还需要处理长列表的性能优化和消息滚到底部的体验。uni-app 中可以通过 scroll-view 的 scroll-into-view 实现滚动定位,但要注意不同机型上高度计算差异,否则会出现“滚不到底部”的情况。
问诊状态要贯穿整个环节。最简单合理的状态机可以是:待响应 -> 咨询中 -> 已结束。患者提交诉求后,问诊单状态是“待响应”;医生接入并回复后,进入“咨询中”;任一方主动结束或超时自动结束后,进入“已结束”。只有处于“咨询中”的会话,医生才有权限创建处方。这个判断要在后端做,不要依赖前端是否显示按钮。
如果你想让项目更有质感,可以在问诊结束后加入评价功能,让患者给医生的回复质量、服务态度打分。虽然这是锦上添花,但对答辩或产品演示来说,它会把完整“服务治理”的感觉做出来,也顺带多了两张统计表的写法。
4.3 开药与处方审核:权限强控,流程完整
开药是全系统里最容易因为“看得简单”而翻车的模块。医生点击“开处方”,前端弹出药品选择器,通过搜索关键字调后端药品接口,选择后加入处方明细。每一条明细都要记录剂量、频次、天数、数量,后端生成金额时要拿数据库里药品表和明细中数量相乘,不能用前端传过来的 amount,因为金额必须可信。
处方生成后建议加上“待审核”状态。简单系统可以由管理员/药师在后台人工审核,复杂一点可以做规则校验,比如药品库存是否充足、有无配伍禁忌提醒。哪怕不做专家系统,也至少要提醒医生注意患者填写的过敏史与药品是否冲突。比如患者档案里如果标记了“青霉素过敏”,处方明细里出现青霉素类药物时,后端应给出明确警告或直接阻断提交,这是医疗项目里非常出彩的细节。
处方通过审核后,用户可以发起药品订单支付。这里要和普通商品订单一个套路:订单拆成药品费、邮费,支付完成后生成发货单。但订单与处方之间应该一对一或一对多明确关联,溯源逻辑要清晰:这个订单是给哪个患者的哪个问诊单下的,处方是谁开的、谁审核的,每一步在订单详情中能看到,这就能打动真正关注业务安全的评审老师。
5. 真实开发与联调里最容易翻车的细节
5.1 wx.login、openid、token:登录链路按顺序打通
很多新手在做登录时,只想“拿到用户手机号/头像”,前端在 onLoad 里直接调 wx.getUserProfile,后端却没有建立 openid 关联。真正规范的登录链路是:前端调 uni.login() 获得一个临时 code;将 code 传给自己后端;后端拿 code 调微信接口 code2session,得到 openid 和 session_key;后端查用户表,找到则更新,没找到则创建用户,然后签发自己的 token 返回给前端。前端后续请求都携带这个 token,不需要关心 openid 是什么。
有个很容易踩的坑是,许多初学者把 session_key 也存到前端或当 token 用。session_key 是微信解密用户敏感数据用的,不应出现在前端存储里,也不应作为身份凭证兜底。后端应该用 session_key 去解密手机号等数据,用 token 标识当前登录用户。如果你问为什么换设备登录后 token 会失效、或者同一个账号在多个设备同时用会出现异常,大多数都是因为设计 token 时绑死了设备标识,建议 token 表只存 user_id 和过期时间,不要在 token 串里拼接太多设备信息。
5.2 支付回调、订单状态和用户手动关闭页面的拉扯
在线问诊的挂号费和药费,通常都需要微信支付。但开发环境中,不一定每个人都有商户号,很多同学卡在这里就放弃了。实际上,做课设和毕设时完全可以先做一个“模拟支付”开关。后端在测试环境下收到支付请求后直接标记成支付成功,前端出一个确认弹窗。系统架构上保留统一的 pay_callback 接口结构,等以后拿到真实商户号后,把模拟支付替换为微信支付回调即可。这样核心的业务闭环不会被支付资质卡住。
真正接微信支付回调时有个高发坑:回调可能重复通知,比如用户付完款后网络不好,微信服务器会重试几次;你的回调接口如果没有幂等处理,同一个订单就可能被标记两次“已支付”,库存也会扣两次。最稳妥的做法是回调里先查一下订单当前状态,如果已经是“已支付”,直接返回成功,不再修改数据。
关于“用户支付完没有点返回按钮,直接杀掉了小程序”的场景,很多项目会出现“扣了钱但订单还是‘待支付’”的状况。解决办法是:前端在特定页面 onShow 时主动调一次查询订单状态接口,以订单当前状态为准刷新界面,而不是只依赖支付成功回调后的本地跳转。这样即使用户手动清后台,再次打开页面也能自动恢复;这个细节会大幅提升你系统的稳定性评价。
5.3 问诊图片上传、跨端 video 和 webview 白屏的“环境病”
很多问诊流程需要患者上传病历照片、检验报告图片。这里最正规的做法是后端提供“获取上传凭证”的接口,由后端返回 OSS 直传的地址和临时凭证,前端把图片直接传到 OSS/CDN,再把返回的文件地址回传给后端保存业务数据。课设如果不方便搭 OSS,也可以让后端接收 multipart 文件并存到服务器静态目录,但这种方案在多人同时访问时压力较大,注意在回显时不要硬编码本机 localhost,必须使用服务器的公网地址配置项。
拼小程序页面时还有一个“跑不起来但不知为何”的问题:用 web-view 组件嵌入了第三方 H5,结果 iOS 真机上白屏;或者页面里有 video 组件,在 iOS 的 swiper 嵌套中全屏播放后错位。这类问题属于跨端兼容问题,网上有很多零散帖子,但核心原则是:在业务能力可以覆盖的前提下,尽量少在核心问诊流程中依赖 web-view 和 video。所有外链 URL 必须先通过域名白名单校验,在小程序后台配置业务域名并校验文件,否则上线后开发者工具可以打开,真机上一定会白屏。
HBuilderX 和微信开发者工具之间也存在执行顺序差异,比如 uni.request 在某些低版本基础库上会有缓存问题。如果遇到接口状态明明变了但页面不刷新,多半是前端没有在 onShow 时重新请求列表,而不是协议问题;此时在页面的 onShow 生命周期里重新拉取数据能解决大部分“模拟器没问题,真机不更新”的诡异情况。
5.4 manifest.json、AppID 与隐私弹窗:上线前的基础配置
项目能本地跑和能上线是两码事。用 HBuilderX 做 uni-app,打开 manifest.json 可视化配置时,你需要确认三件事:一是微信小程序 AppID 已经填成你自己的;二是“小程序ID已经修改了,但运行到开发者工具还是旧的”时,到微信开发者工具里点“清缓存 -> 清除全部缓存”并重启项目,因为开发者工具经常缓存旧的配置;三是尽量在 manifest 里把基础库版本设置为 2.x 以上的稳定版,避免低版本基础库不支持某些 API。
医疗类小程序的真实上线会涉及额外的资质要求,普通个人主体很难过审。对于学生项目或内测演示,通常使用“测试号”即可。需要明确的是,如果你把这款系统包装成对外可运营的产品,资质、隐私政策、用户协议都是绕不开的合规项;但做课程设计/毕业设计时,更多是自建测试数据,模拟演示,所以“能稳定运行、数据正确、边界处理齐全”比“形式上拥有医疗牌照”更现实。
6. 药品库存、幂等与用药安全:比“能付款”再进一步的设计
6.1 高并发下药品扣减与库存回补
药品库存扣减与普通商品库存扣减思路一致,核心就是防止超卖。用 SQL 一条语句完成扣减最容易:
sql复制UPDATE medicine SET stock = stock - 1 WHERE id = ? AND stock >= 1;
然后检查受影响行数,如果为0说明库存不足,返回错误;同时对订单创建和扣库存要放在同一数据库事务里。用户取消处方订单时,除了把状态置为“已取消”,还要同步执行库存回补。值得注意的一点是回补数量必须来自订单明细表里该药品的真实数量,而不是固定加1;常见错误是在取消接口里把每个明细都加1,结果买了3盒的订单取消后只回补了1盒。
如果项目演示时需要体现“多人同时抢号/购药”的高并发场景,单纯靠事务还不够。建议给排班表、药品表加悲观锁或乐观锁版本号。悲观锁适用低频写场景,使用 SELECT ... FOR UPDATE;乐观锁则是更新时比较版本号,失败重试。实际问诊系统的并发量并没有电商秒杀那么高,所以掌握事务和唯一约束基本就足够了。真正考验你的是把“下单扣减失败 -> 提示用户 -> 用户重新提交”这条路径跑通,让用户在页面有感反馈,而不是接口报错后状态卡死。
6.2 支付回调与消息通知里的重复消费与幂等
不只支付回调有重复消费的问题,问诊系统的消息通知、异步任务都有类似场景。比如医生收到“新问诊提醒”的微信模板消息,如果投递系统重试了,会不会给同一个患者发送两条一模一样的通知?处理原则是:在接收回调或消息的入口记录一个业务主键(如 appointment_id、order_id、medicine_id),在写入前查重,保证对同一主键的消费只生效一次。
在数据库层面,可以给业务单据增加唯一索引,比如预约单表里对 (schedule_id, patient_id, status) 并不是一个稳定唯一键,建议直接使用类似 biz_id 的全局业务号,在创建时就利用 UUID 或“日期+随机序列”生成。回调里拿这个 biz_id 做 update,只有影响行数为1时才继续处理。若终端用户短时间内连点多次“提交订单”按钮,前端按钮要做防重;后端则靠前端传入的 client_token 或者单据号去重。这些细节虽然不是每个教程都会写,但它们才是系统能真实上线运行的底气。
6.3 合理用药校验与药品数据维护的几条规则
没有真实医学知识也可以写出基础的用药安全模块:首先,药品规格、剂量单位必须在数据字典里维护统一,比如“mg”“g”“ml”,别在一张表里既有“0.25g”又有“250mg”,这是安全隐患。在前端选药时,默认按药品名称去搜索,选中的药品把规格展示出来;医生填写用法用量时,用“每次用量X单位,每日Y次,持续Z天”的结构化字段,而不是一个自由文本框,这样后续做剂量校验更容易。
其次,后端在保存处方前做一次库存充足性和过敏史校验。过敏史不是必填字段时,要给医生一个提示“该患者未填写过敏史”,由医生决定是否继续开药;患者明确填写过过敏史时,药品表里可以维护一个过敏原标签,如果处方里出现匹配项,后端直接阻断并让医生更换药品。这个环节不要依赖复杂 AI,正则和标签匹配就能完成。
再有,处方审核通过前,不要允许患者支付药品订单。审核环节不是摆设,它能让系统在演示时多一个“后台任务队列”的体感。如果项目想体现得更有深度,可以在后台增加“处方超时未审核自动提醒”“低库存药品列表”等页面,让管理员真正有事可做,也让项目的业务完整度从“能写接口”提升到“能运营系统”。
7. 部署和上线基础:把项目从本地搬到服务器的注意事项
7.1 后端部署:Linux、Nginx、进程守护
部署方式因人而异。课设和实训项目通常会用一台云服务器,把 Flask 应用跑起来,再用 Nginx 反向代理。后端如果是 Flask,本地开发时可以 python app.py 直接运行,但生产环境必须用 gunicorn 这类 WSGI 服务器来启动,避免开发服务器性能达不到要求。Nginx 需要配置两个重要部分:监听 80/443 端口后将 /api/ 开头的请求转发给本地的 Flask 服务;同时托管前端上传的静态图片文件。不要直接把 Flask 的 5000 端口暴露到公网,配置上不安全也不专业。
服务器遇到 “不能解析域名” 或 “connot connect to MySQL” 时,多半是没放行安全组端口,或者 MySQL 配置的 bind-address 默认只允许本机连接。建议后端服务与 MySQL 装在同一台服务器上,连接地址写 127.0.0.1,本地开发时才连远程库。进程守护可以简单使用 supervisor 或 systemd,保证服务不会因为 ssh 断开被杀掉。这是最容易忽视的坑:本地一切正常,一关闭终端 python 进程就没了,前端请求全部失败。
7.2 小程序的合法域名和 HTTPS 要求
正式上线时,微信小程序后台的 request 合法域名必须是 HTTPS,并且域名要备案。如果你的服务器只有 IP、没有域名,开发阶段可以在微信开发者工具里勾选“不校验合法域名”,但上线后必须配置。避免在代码里把接口地址写死成 IP,建议封装一个全局配置文件(如 config.js),里面写 BASE_URL,以后换域名只改这一处。
HTTPS 证书可以在服务器上通过 certbot 之类的工具申请免费证书,也可以直接在云厂商控制台申请并下载,再配置到 Nginx。这一步做完之后,记得在微信小程序后台配置 request 合法域名和 uploadFile 合法域名,配置后有一定的生效延迟,需要耐心等。而且开发者工具里可能仍提示不在合法域名列表,通常是后台清除缓存或重启工具才能生效。
7.3 隐私协议、用户同意弹窗与页面提示的普适做法
在用户第一次进入小程序时,最好做一个隐私政策和用户协议的弹窗,用户勾选同意后再进入主流程。小程序端获取头像和昵称、获取手机号等能力,都必须以用户主动触发为前提,不能页面一加载就静默调用。这个设计不是空话:你在真机上调试时如果发现“获取手机号按钮点不动”,多半是开发者工具中的隐私接口授权没有处理。把用户协议、隐私政策、注销账号说明这几个页面做好,即使用户不同意也不会直接卡死。
我常建议把“用户同意”弹窗的语义做轻一点:弹窗内给出协议名称,点击“同意并继续”就关闭,点击“不同意”就退出小程序或仅保留浏览模式。对于问诊这种包含敏感健康信息的场景,在问诊提交页、处方支付页还可以二次提示“你的健康信息将仅用于本次问诊服务”,这是在现有商品化小程序里很常见的做法,对项目观感提升很有帮助。
8. 迭代扩展与我的个人建议
这个项目跑通基本流程后,我通常建议再补两个模块,性价比最高。第一个是“医生端工作台”的独立界面与通知角标:医生登录后能看到待处理问诊数、待审核处方数,这会让系统的角色区分更加明显。第二个是“患者用药提醒”:根据处方明细中的频次字段,生成一条本地定时提醒,患者可以在小程序里收到“该吃药了”的服务通知。这两个模块对算法要求不高,却非常容易在演示时让人直观感受到系统的实用价值。
在实际开发时还有个小技巧:因为前端和后端相互依赖,可以把接口文档的字段定义放在代码注释或接口约定文件里,前后端同时启动前先跑一次简单的冒烟接口,确认登录、排班、下单几个主链路能通,再进入页面细节开发,这样能避免大量返工。每完成一个功能模块,就手动走一遍“从前端点按钮到后端查库”的完整链路,把中间的报错日志随手记下来,比最后统一排查高效得多。
我自己在最初做类似系统时,最常犯的毛病就是总觉得“界面好看、交互流畅”最重要,反复调页面和动画,结果后端数据结构没过关,导致联调时反复改接口。后来我调整顺序:先定义数据库表和接口响应结构,再写后端代码,最后做前端界面。整个开发体验顺畅了很多。希望这篇内容能帮你少走这段弯路,真正把“在线问诊挂号开药系统”做成一个拿得出手的完整项目,而不是又一个“看起来能点但经不起问”的页面合集。
