一、项目背景与UI拆解
这是一个典型的“智慧医院患者服务大厅”,设计风格以医疗绿(#0E7A6B)为主基调,界面清晰、操作直观。核心功能模块包括:
顶部导航栏:首页、预约挂号、在线客服、AI咨询、管理后台。
核心Hero区域:问候语“您好,请问哪里不舒服?”,提供“立即预约挂号”与“AI智能问诊”两大核心入口,并展示门诊时间与24小时急诊信息。
侧边查询卡片:“查询我的预约”,通过输入手机号快速检索预约记录。
在线服务卡片区:预约挂号、AI智能问诊、在线客服三个功能入口,底部附有“出诊科室”等更多信息。
要实现这样一个高可用、实时交互的系统,我们采用Vue3(前端) + Flask(后端) + EMQX(MQTT Broker)的架构。
二、系统架构设计
前端(Vue3):采用 Vite 构建,UI 组件可使用 Element Plus 或 TailwindCSS。使用 Pinia 管理全局状态(如用户信息、预约记录),Vue Router 管理路由。
后端(Flask):提供 RESTful API,处理业务逻辑(挂号、查询、排班)。使用 SQLAlchemy 操作 MySQL 数据库。
实时消息(EMQX/MQTT):负责推送排队叫号、预约状态变更、在线客服聊天消息。前端通过 MQTT.js 使用 WebSocket 连接 EMQX。
AI 服务(Flask + LangChain):在 Flask 中集成大模型,处理“AI智能问诊”模块的症状描述,通过 SSE 或 MQTT 流式返回初步建议。
三、前端 Vue3 实现:组件化与实时交互
3.1 首页核心布局
根据截图,首页主要由Header.vue、HeroBanner.vue、AppointmentQuery.vue和ServiceCards.vue组成。
vue
<!-- views/Home.vue --> <template> <div class="home-container"> <Header /> <main class="main-content"> <div class="hero-section"> <HeroBanner @appointment="goToAppointment" @aiConsult="goToAIConsult" /> <AppointmentQuery @query="handleQuery" /> </div> <ServiceCards /> </main> </div> </template>
3.2 预约查询组件(侧边栏)
截图右侧的“查询我的预约”卡片,逻辑是输入手机号后调用 Flask API。
vue
<!-- components/AppointmentQuery.vue --> <script setup> import { ref } from 'vue' import axios from 'axios' const phone = ref('') const appointment = ref(null) const queryAppointment = async () => { if (!phone.value) return try { const { data } = await axios.get(`/api/appointment/query?phone=${phone.value}`) if (data.success) { appointment.value = data.data } else { alert('未查询到该手机号的预约记录') } } catch (error) { console.error('查询失败', error) } } </script> <template> <div class="query-card"> <h3>查询我的预约</h3> <input v-model="phone" placeholder="输入预约时使用的手机号" /> <button @click="queryAppointment">查询</button> <p class="tip">仅支持查询本系统内已提交的预约记录</p> </div> </template>3.3 前端接入 MQTT:实时排队与客服消息
在 Vue3 中,我们使用mqtt包通过 WebSocket 连接 EMQX,订阅用户的专属通知。
ts
// src/composables/useMQTT.ts import mqtt from 'mqtt' import { ref } from 'vue' export function useMQTT(userId: string) { const queueNumber = ref(null) const chatMessages = ref([]) const client = mqtt.connect('wss://your-emqx:8084/mqtt', { clientId: `web_${userId}_${Date.now()}`, username: userId, password: 'your-token' }) client.on('connect', () => { // 订阅排队叫号通知 client.subscribe(`hospital/queue/${userId}`, { qos: 1 }) // 订阅在线客服消息 client.subscribe(`hospital/chat/${userId}`, { qos: 1 }) }) client.on('message', (topic, payload) => { const data = JSON.parse(payload.toString()) if (topic.includes('/queue')) { queueNumber.value = data.number // 弹出提示:您的前面还有 X 人 } else if (topic.includes('/chat')) { chatMessages.value.push(data) } }) return { queueNumber, chatMessages, client } }四、后端 Flask 实现:业务逻辑与 API
4.1 预约挂号与查询 API
在 Flask 中,我们需要处理预约的增删改查。表结构设计为Appointment(id, patient_name, phone, department, doctor_id, time_slot, status)。
python
from flask import Blueprint, request, jsonify from models import db, Appointment appointment_bp = Blueprint('appointment', __name__) @appointment_bp.route('/api/appointment/query', methods=['GET']) def query_appointment(): phone = request.args.get('phone') if not phone: return jsonify({'success': False, 'message': '手机号不能为空'}), 400 records = Appointment.query.filter_by(phone=phone).all() if not records: return jsonify({'success': False, 'message': '未找到记录'}) return jsonify({ 'success': True, 'data': [record.to_dict() for record in records] }) @appointment_bp.route('/api/appointment/book', methods=['POST']) def book_appointment(): data = request.get_json() new_appointment = Appointment( patient_name=data['name'], phone=data['phone'], department=data['department'], doctor_id=data['doctorId'], time_slot=data['timeSlot'], status='pending' ) db.session.add(new_appointment) db.session.commit() # 触发 MQTT 通知(此处调用 MQTT 发布函数) # publish_mqtt_notification(new_appointment) return jsonify({'success': True, 'data': new_appointment.to_dict()})4.2 AI 智能问诊接口
当用户点击“AI智能问诊”后,前端发送症状描述,Flask 调用 AI 模型返回初步建议。
python
from flask import Blueprint, request, Response import json from ai_service import medical_ai_chain ai_bp = Blueprint('ai', __name__) @ai_bp.route('/api/ai/consult', methods=['POST']) def ai_consult(): data = request.get_json() symptoms = data.get('symptoms') session_id = data.get('session_id') def generate(): # 调用医疗知识库 RAG 和 LLM for token in medical_ai_chain.stream({'symptoms': symptoms}): yield f"data: {json.dumps({'type': 'delta', 'text': token})}\n\n" yield f"data: {json.dumps({'type': 'done'})}\n\n" return Response(generate(), mimetype='text/event-stream')五、MQTT 在智慧医院中的核心应用场景
结合截图中的“在线客服”、“预约挂号”,MQTT 主要发挥以下作用:
5.1 排队叫号实时推送
患者挂号后,系统会分配一个排队号。当医生叫号时,后端通过 MQTT 向该患者的专属主题发布消息:
Topic:
hospital/queue/{patient_id}Payload:
{"number": "A024", "doctor": "张医生", "status": "calling"}
前端订阅后,实时更新顶部状态或弹出提醒。
5.2 在线客服(人工介入)
截图中的“在线客服”模块,用户在前端发送消息,通过 MQTT 发送到客服端。
用户端发布:
hospital/chat/user/{user_id}客服端订阅:
hospital/chat/agent/#(客服订阅所有用户消息)客服回复: 客服系统发布到
hospital/chat/user/{user_id},前端订阅并展示。
5.3 预约状态变更通知
用户预约成功后,如果医生停诊或时间变更,后端立即发布 MQTT 消息:
Topic:
hospital/notice/{user_id}Payload:
{"type": "appointment_change", "message": "您的预约时间已变更为..."}
前端收到后通过 Toast 或弹窗提醒用户。
六、AI 客服与人工客服的无缝切换
在“智慧医院”中,AI 客服承担了初筛和简单咨询的工作。如果 AI 无法解决,需要转接人工。
AI 处理:用户进入“AI咨询”,Flask 后端通过 RAG 检索医院知识库(如科室介绍、挂号规则),生成回复。
转人工触发:当 AI 检测到用户意图为“投诉”、“复杂病情”或用户点击“转人工”时,后端通过 MQTT 向客服工作台发送
hospital/chat/escalation消息。人工接管:客服工作台接收到消息后,接入对话。前端订阅的
hospital/chat/{user_id}主题会无缝切换到人工客服的回复。
七、部署与总结
前端:Vue3 打包为静态文件,通过 Nginx 部署,反向代理 API 和 WebSocket (
wss://)。后端:Flask 使用 Gunicorn 部署,配合 Nginx 处理 HTTP 请求。
EMQX:配置好认证(JWT 或用户名密码),开启 WebSocket 端口(8084)。
数据库:MySQL 存储业务数据,Redis 缓存会话和排队状态。
总结:
通过Vue3 + Flask + MQTT的组合,智慧医院系统实现了:
极致的用户体验:Vue3 响应式前端配合 MQTT 实时推送,患者无需刷新即可获知排队进度和客服回复。
高效的业务处理:Flask 轻量级后端快速响应挂号、查询等请求。
智能化的服务:AI 客服分流了基础咨询,人工客服通过 MQTT 精准接管复杂问题。
下载地址
https://download.csdn.net/download/suny8/93708187?spm=1001.2014.3001.5501