import axios from 'axios' import { useUserStore } from '@/store' import storage from 'store' import { Notification, Message } from '@arco-design/web-vue'; import { VueAxios } from './axios' import { v4 as uuidv4 } from 'uuid' import { LRUCache } from 'lru-cache' import { generateAesKey, aesEncrypt, aesDecrypt, rsaEncryptKey } from './encrypt' import { isElectron } from './electron' const electron = isElectron() const request = axios.create({ baseURL: import.meta.env.VITE_APP_API_BASE_URL, timeout: 10000 }) const aesKeyCache = new LRUCache({ max: 200, ttl: 1000 * 60 * 5 }) const errorHandler = (error) => { const userStore = useUserStore() const user = storage.get('user') console.log(error.stack) if (error.response) { if (error.response.status === 401) { Message.error('登录失效,请重新登录') if (user) { userStore.logout() // 调用 Pinia store 中的 logout 方法 setTimeout(() => { window.location.reload() }, 1500) } } } else { console.error('无法连接到服务器,请检查网络') Notification.error({ title: '请求失败', content: '网络不畅或服务器停机维护中,请稍后再试' }) } } request.interceptors.request.use(config => { const userStore = useUserStore() const user = userStore.$state if (config.headers['Content-Type'] !== 'multipart/form-data') { const data = { ...(config.method === 'get' ? config.params : config.data), time: Date.now(), uuid: user?.uuid, session: user?.session } const aesKey = generateAesKey() const encryptedData = aesEncrypt(data, aesKey) const encryptedKey = rsaEncryptKey(aesKey) const requestId = uuidv4() config.headers['X-Request-ID'] = requestId aesKeyCache.set(requestId, aesKey) if (config.method === 'get') config.params = { a: encryptedData, b: encryptedKey } else config.data = { a: encryptedData, b: encryptedKey } } if (electron) config.headers["Device-Type"] = 'RunForge Desktop Client' return config }, errorHandler) request.interceptors.response.use(async (response) => { if (response.data.b) { const requestId = response.config.headers['X-Request-ID'] const aesKey = aesKeyCache.get(requestId) response.data.data = aesDecrypt(response.data.b, aesKey) aesKeyCache.delete(requestId) } return response.data }, errorHandler) const installer = { vm: {}, install(Vue) { Vue.use(VueAxios, request) } } export default request export { installer as VueAxios, request as axios }