/** axios 实例:自动携带 token、统一处理 401/付费墙 */ import axios from 'axios' import { ElMessage } from 'element-plus' import router from '../router' export const http = axios.create({ baseURL: '/', timeout: 30000 }) http.interceptors.request.use(cfg => { const token = localStorage.getItem('hmc_token') if (token) cfg.headers.Authorization = `Bearer ${token}` return cfg }) http.interceptors.response.use( res => { const d = res.data if (d && typeof d === 'object' && 'code' in d) { if (d.code === 1) return res if (String(d.code) === '10086') { ElMessage.warning(d.message ?? '该功能需要购买解锁') return Promise.reject(new Error(d.message)) } if (Number(d.code) === 401) { localStorage.removeItem('hmc_token') router.push('/login') return Promise.reject(new Error(d.message)) } ElMessage.error(d.message ?? '操作失败') return Promise.reject(new Error(d.message)) } return res }, err => { ElMessage.error(err.message ?? '网络错误') return Promise.reject(err) }, ) /** 提取 envelope 的 data */ export async function api(method: string, url: string, body?: object): Promise { const res = await http.request({ method, url, data: body }) return res.data.data as T } /** 下载二进制文件(自动带 token),filename 为保存文件名 */ export async function apiDownload(url: string, filename: string): Promise { const res = await http.get(url, { responseType: 'blob' }) const link = document.createElement('a') link.href = URL.createObjectURL(res.data) link.download = filename link.click() URL.revokeObjectURL(link.href) } /** 上传文件(multipart,自动带 token),返回 envelope data */ export async function apiUpload(url: string, file: File): Promise { const fd = new FormData() fd.append('file', file) const res = await http.post(url, fd, { headers: { 'Content-Type': 'multipart/form-data' } }) return res.data.data as T }