AI 诊断(兽医、机构)— 前端技术方案
依据:AI诊断(兽医、机构)功能需求.md、AI诊断(兽医、机构)技术方案.md(v1.5);实现文件 ruoyi-ui/src/views/diseaseTreatment/onlineConsult/ai/index.vue;布局参考同目录在线接诊(左右分栏 IM)。
1. 页面与路由
| 项 |
说明 |
| Vue 路径 |
ruoyi-ui/src/views/diseaseTreatment/onlineConsult/ai/index.vue |
| 组件名 |
以若依菜单 component 配置为准 |
| 菜单配置(示例) |
组件路径:diseaseTreatment/onlineConsult/ai/index |
| 权限前缀 |
diseaseTreatment:aiOnlineConsult:list、query、add(发送走大模型直连 + 落库,未使用 send 按钮权限) |
准入:列表/新建/历史消息仅需登录与 diseaseTreatment:aiOnlineConsult:* 权限;后端不校验是否绑定兽医/机构医疗资源。
2. 接口分工(双通道)
本期前端采用 会话管理走后端、对话框问答走大模型网关 的混合方案。
| 能力 |
调用方式 |
说明 |
| 会话列表 |
若依 request → GET /diseaseTreatment/onlineConsult/ai/session/list |
含 disclaimer |
| 新建会话 |
POST .../session |
返回 id/sessionId、disclaimer |
| 历史消息 |
GET .../session/{id}/messages |
打开会话、上拉加载更早 |
| 提问与 AI 回复 |
streamChatMessage(utils/llmStreamChat.js)→ {VUE_APP_LLM_BASE_URL}/v1/chat/completions |
对话框问答,支持 SSE 流式;失败可回退非流式 |
| 会话落库 |
POST .../session/{id}/message |
Body:msgType、content、aiReplyContent、realSessionId?、aiCategory?;大模型返回后落库,不再调后端 AI 网关 |
| 媒体上传 |
POST /common/upload |
先上传再随提问送 LLM |
与后端技术方案:后端 §4.4 同时支持全后端 ConsultAiGateway 通道与前端 aiReplyContent 落库通道。当前页面采用后者。
大模型上下文:session.llmSessionId / realSessionId 存网关返回的 session_id,与后端会话主键 activeSessionId 分离;落库时通过 realSessionId 写入 biz_consult_session.real_session_id。
3. API 模块(若依)
| 项 |
说明 |
| 文件 |
ruoyi-ui/src/api/diseaseTreatment/aiOnlineConsult.js |
| Base |
/diseaseTreatment/onlineConsult/ai |
| 方法 |
HTTP |
页面是否使用 |
listAiConsultSessions |
GET /session/list |
✓ |
createAiConsultSession |
POST /session |
✓ |
listAiConsultMessages |
GET /session/{sessionId}/messages |
✓ |
sendAiConsultMessage |
POST /session/{sessionId}/message(timeout 65s,repeatSubmit: false);Body 含 msgType、content、aiReplyContent、realSessionId?、aiCategory? |
✓(落库) |
列表 Query(小驼峰):pageNum(默认 1)、pageSize(默认 100)、contentKeyword、searchMode(仅点击搜索为 true)。
消息 Query:beforeId、pageSize(默认 50)。
4. 大模型对话(对话框)
| 项 |
说明 |
| 环境变量 |
VUE_APP_LLM_BASE_URL(开发常为 /llm-dev-proxy,由 vue.config.js 转发)、VUE_APP_LLM_API_KEY |
| 请求 |
POST {llmBase}/v1/chat/completions |
| 鉴权(直连上游) |
Authorization: Bearer {VUE_APP_LLM_API_KEY} |
| 鉴权(经 8010 转发) |
Authorization: Bearer {getToken()}(若依登录 Token,与 request.js 一致);不能仅用 VUE_APP_LLM_API_KEY |
| 超时 |
120000 ms |
| Body |
model、messages[]、stream: true(优先流式)、user;可选 session_id(llmSessionId) |
| 流式解析 |
utils/sseParse.js、utils/llmResponseParse.js(提取 session_id、增量 content) |
| 后端转发(可选) |
VUE_APP_LLM_BASE_URL → http://localhost:8010;KbOpenAiProxyController 须登录,详见 doc/大模型/大模型网关转发接口说明.md §3、§6 |
模型选项(前端常量)
| value |
说明 |
auto |
自动选择 |
yak-disease |
疫病诊疗助手 |
yak-general |
通用助手 |
yak-feeding |
饲喂决策助手 |
messages 构建:将当前会话 messages 转为 OpenAI 风格;senderRole === 1 → user,senderRole === 3 → assistant;msgType === 2 图片转为 image_url。
5. 页面结构
- 筛选区:会话内容关键字;搜索(须非空,
searchMode=true)、重置(默认近 3 个月)、新增会话。
- 免责声明:
disclaimer 自列表/新建响应写入,工具栏下 el-alert 常驻展示。
- 左侧历史会话:
sessionTitle、摘要、lastMessageTime(格式 M月D日);本期不改前端:隐藏会话后端已提供 POST .../session/{id}/hide(§4.5),页面未接按钮/API 封装。
- 右侧对话区:标题为当前会话标题;消息按日分组;用户气泡在右(绿)、AI 在左(蓝)。
- 输入区:文本、图片/视频/语音上传、模型选择、发送;等待时展示「AI 正在思考…」动效。
6. 业务规则(前端)
| 规则 |
实现 |
| 默认列表 |
不传 searchMode;近 3 个月有消息的会话 |
| 搜索 |
contentKeyword 非空 + searchMode=true;空关键字提示「请输入会话内容后再搜索」 |
| 会话主键 |
resolveSessionId(s):id 优先,否则 sessionId |
| 消息角色 |
senderRole:1 提问人(右)、3 AI(左) |
| 消息类型 |
msgType:1 文本、2 图片、3 视频、4 语音 |
| 发送流程 |
先本地展示提问 → streamChatMessage 调 LLM → 本地展示 AI 回复 → sendAiConsultMessage(aiReplyContent、realSessionId、aiCategory)落库并合并服务端消息 ID |
| 思考中 |
sending 且最后一条为 senderRole === 1 时显示占位气泡 |
| 上拉历史 |
scrollTop < 40 时用 beforeId 加载更早 50 条 |
| 轮询 |
选中会话后 2s 仅 refreshSessionListQuiet(不轮询消息,避免覆盖仅存在本地的 LLM 对话) |
| 媒体限制 |
图 jpg/jpeg/png/gif ≤10MB;视频 mp4/mov ≤50MB;语音 mp3/m4a/wav ≤10MB;文件名不含英文逗号 |
| 本地消息 ID |
前缀 m_(genLocalId),与服务端数字 ID 区分 |
数据持久化说明:大模型返回后调用 POST .../message 并传 aiReplyContent、可选 realSessionId(大模型 session_id)、aiCategory(提问分类);服务端仅落库、不调 ConsultAiGateway;响应 data.realSessionId 可与本地 llmSessionId 对齐。落库失败时界面仍保留本地气泡并提示「保存会话失败」。
7. 与在线接诊(兽医)差异
| 项 |
AI 诊断 |
在线接诊(兽医) |
| 列表标题 |
sessionTitle |
askerName |
| 筛选 |
仅 contentKeyword |
问诊人 + 会话内容 |
| 新建会话 |
有 |
无 |
| 对话对象 |
AI(senderRole=3) |
问诊人 / 兽医(1/2) |
| 发送接口 |
大模型 chat/completions |
POST .../vet/session/{id}/message |
| 消息轮询 |
仅刷新会话列表 |
消息 + 列表 |
8. 国际化
| 项 |
说明 |
| 语言包 |
diseaseTreatment.aiOnlineConsult(lang/zh/diseaseTreatment.js、lang/bo/diseaseTreatment.js) |
| Mixin |
diseaseTreatmentLocaleMixin,页面 dtNs = 'aiOnlineConsult',dtT / dtCommon |
9. 文件清单
| 路径 |
说明 |
src/views/diseaseTreatment/onlineConsult/ai/index.vue |
主页面(IM + LLM 流式发送 + 落库) |
src/api/diseaseTreatment/aiOnlineConsult.js |
若依会话/消息 API |
src/utils/llmStreamChat.js、sseParse.js、llmResponseParse.js |
大模型流式与响应解析 |
src/mixins/diseaseTreatmentLocaleMixin.js |
文案 |
src/lang/zh/diseaseTreatment.js |
中文 aiOnlineConsult |
src/lang/bo/diseaseTreatment.js |
藏文 aiOnlineConsult |
.env.development / .env.production |
VUE_APP_LLM_* |
vue.config.js |
开发环境 LLM_PROXY_TARGET → /llm-dev-proxy |
10. 联调说明
- 登录账号须具备 AI 诊断菜单与接口权限;不要求在「畜牧医疗资源管理」绑定兽医/机构资源。
- 配置
VUE_APP_LLM_BASE_URL、VUE_APP_LLM_API_KEY 后重启 npm run dev。
- 新建会话后左侧应出现「新会话」;发送后 Network 应先后出现
/v1/chat/completions 与 /session/.../message(aiReplyContent 落库)。
- 与在线接诊数据隔离:
consult_type=2 会话不出现在接诊列表。
- 切换全后端 AI:将
sendViaLlm 改为调用 sendAiConsultMessage,合并 res.data.userMessage / aiMessage,并恢复消息轮询或 STOMP(见后端 §5.1)。
11. 修订记录
| 版本 |
说明 |
| 1.0 |
初稿:混合架构(会话后端 + 对话 LLM 直连);对齐 onlineConsult/ai/index.vue 实现 |
| 1.1 |
落库通道:sendAiConsultMessage + aiReplyContent;realSessionId、aiCategory;LLM SSE 流式 |