所属项目:面向全场景用药安全的医师助手 Agent
团队:ColdX · 山东大学软件学院 2026年春季项目实训
个人分工:前端开发 & 界面设计
目录
- 一、背景说明
- 二、Axios 封装设计
- 2.1 实例化与基础配置
- 2.2 请求拦截器
- 2.3 响应拦截器
- 三、接口封装
- 四、联调中的关键问题
- 4.1 CORS 预检失败
- 4.2 字段命名不一致
- 4.3 请求超时
- 五、与 Pinia 的协作模式
- 六、小结
- 相关链接
一、背景说明
上篇确定了技术栈:Vue 3 + Pinia + Vite。后端使用 FastAPI,前端通过 HTTP 请求调用 Agent 接口。
首先需要落地的是网络层。表面上只是封装 Axios 并配置拦截器,但在实际联调过程中遇到了一些非预期问题,其中一部分甚至来自协作层面。
本文记录 Axios 封装过程及与 FastAPI 联调时的关键问题与解决方案。
二、Axios 封装设计
2.1 实例化与基础配置
文件:src/api/request.js
importaxiosfrom'axios'constrequest=axios.create({baseURL:import.meta.env.VITE_API_BASE_URL||'/api',timeout:30000,headers:{'Content-Type':'application/json',},})exportdefaultrequest环境变量配置(.env.development):
VITE_API_BASE_URL=/api配合vite.config.js中的代理配置,可以避免在前端硬编码后端地址。
2.2 请求拦截器
功能:
- 注入 token
- 开发环境日志输出
request.interceptors.request.use((config)=>{consttoken=localStorage.getItem('access_token')if(token){config.headers.Authorization=`Bearer${token}`}if(import.meta.env.DEV){console.log(`[Request]${config.method?.toUpperCase()}${config.url}`,config.data)}returnconfig},(error)=>Promise.reject(error))2.3 响应拦截器
后端统一返回格式:
{"code":200,"message":"success","data":{}}但 Agent 接口(/consult)直接返回业务数据,因此需要区分处理。
request.interceptors.response.use((response)=>{const{config,data}=responseif(config.url?.startsWith('/consult')){returndata}if(data.code!==200){consterror=newError(data.message||'请求失败')error.code=data.codereturnPromise.reject(error)}returndata.data},(error)=>{if(error.code==='ECONNABORTED'||error.message.includes('timeout')){console.error('请求超时,请稍后重试')}elseif(error.response){const{status}=error.responseif(status===401){console.warn('未授权')}elseif(status===500){console.error('服务器错误')}}returnPromise.reject(error)})三、接口封装
文件:src/api/consult.js
importrequestfrom'./request'exportfunctionconsult(payload){returnrequest({url:'/consult',method:'post',data:payload,})}示例请求参数:
{symptoms:"患者主诉文本",patient_info:{age:45,gender:"female"}}四、联调中的关键问题
4.1 CORS 预检失败
问题:前端报 CORS 错误,后端声称已配置。
原因:
- 使用
Content-Type: application/json - 存在自定义 Header
- 触发 OPTIONS 预检请求
- 后端未正确处理 OPTIONS
解决方案:
app.add_middleware(CORSMiddleware,allow_origins=["*"],allow_credentials=True,allow_methods=["*"],allow_headers=["*"],)4.2 字段命名不一致
问题:
- 部分字段使用下划线命名
- 部分字段使用驼峰命名
- 前端解析失败导致页面异常
解决方案:
- 与后端统一命名规范(最终统一为下划线)
- 在 store 层增加字段映射(防御性处理)
4.3 请求超时
问题:
- 初始 timeout 为 10 秒
- Agent 推理耗时较长
- 请求被中断
解决方案:
- timeout 调整为 30 秒
- 增加 loading 状态提示用户
五、与 Pinia 的协作模式
通过 store 封装调用逻辑,避免组件直接操作请求。
import{consult}from'@/api/consult'exportconstuseConsultationStore=defineStore('consultation',{actions:{asyncsubmitConsultation(payload){try{constdata=awaitconsult(payload)this.processAgentResponse(data)return{success:true,status:data.status}}catch(error){console.error('会诊请求失败',error)return{success:false,error:error.message}}}}})组件使用方式:
conststore=useConsultationStore()constresult=awaitstore.submitConsultation({symptoms:'...'})这种设计将网络层完全隔离,组件只关注业务状态。
六、小结
本文主要内容:
- Axios 实例与拦截器设计
- 普通接口与 Agent 接口的差异化处理
- 接口函数封装方式
- 三个联调问题:CORS、字段规范、超时
- 网络层与 Pinia 的协作模式
当前网络层已稳定,可支持后续接口扩展。
相关链接
- 项目地址:https://gitee.com/aemond/innovation-training/tree/master
- 团队博客:https://blog.csdn.net/curufin/category_13140668.html