|
|
@@ -3,20 +3,24 @@ import { useUserStore } from '@/store'
|
|
|
import storage from 'store'
|
|
|
import { Notification } from '@arco-design/web-vue';
|
|
|
import { VueAxios } from './axios'
|
|
|
-import { generateAesKey, aesEncrypt, rsaEncryptKey } from './encrypt'
|
|
|
+import { v4 as uuidv4 } from 'uuid'
|
|
|
+import { LRUCache } from 'lru-cache'
|
|
|
+import { generateAesKey, aesEncrypt, aesDecrypt, rsaEncryptKey } from './encrypt'
|
|
|
|
|
|
-// 创建 axios 实例
|
|
|
const request = axios.create({
|
|
|
- // API 请求的默认前缀
|
|
|
baseURL: import.meta.env.VITE_APP_API_BASE_URL,
|
|
|
- timeout: 30000 // 请求超时时间
|
|
|
+ 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)
|
|
|
+ console.log(error.stack)
|
|
|
|
|
|
if (error.response) {
|
|
|
if (error.response.status === 401) {
|
|
|
@@ -34,7 +38,7 @@ const errorHandler = (error) => {
|
|
|
} else {
|
|
|
console.error('无法连接到服务器,请检查网络')
|
|
|
|
|
|
-
|
|
|
+
|
|
|
Notification.error({
|
|
|
title: '服务器维护中',
|
|
|
content: '服务器停机维护中,请耐心等待'
|
|
|
@@ -43,29 +47,50 @@ const errorHandler = (error) => {
|
|
|
}
|
|
|
|
|
|
request.interceptors.request.use(config => {
|
|
|
- const userStore = useUserStore() // 使用 Pinia store
|
|
|
+ const userStore = useUserStore()
|
|
|
|
|
|
const user = userStore.$state
|
|
|
- if (user && config.headers['Content-Type'] !== 'multipart/form-data') {
|
|
|
- if (config.method === 'get') {
|
|
|
+ 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 = {
|
|
|
- ...config.params,
|
|
|
- uuid: user.uuid,
|
|
|
- session: user.session
|
|
|
+ encryptedData,
|
|
|
+ encryptedKey
|
|
|
}
|
|
|
- } else {
|
|
|
+ else
|
|
|
config.data = {
|
|
|
- ...config.data,
|
|
|
- uuid: user.uuid,
|
|
|
- session: user.session
|
|
|
+ encryptedData,
|
|
|
+ encryptedKey
|
|
|
}
|
|
|
- }
|
|
|
}
|
|
|
+
|
|
|
return config
|
|
|
}, errorHandler)
|
|
|
|
|
|
-// response interceptor
|
|
|
-request.interceptors.response.use((response) => {
|
|
|
+request.interceptors.response.use(async (response) => {
|
|
|
+ if (response.data.encryptedData) {
|
|
|
+ const requestId = response.config.headers['X-Request-ID']
|
|
|
+ const aesKey = aesKeyCache.get(requestId)
|
|
|
+
|
|
|
+ response.data.data = aesDecrypt(response.data.encryptedData, aesKey)
|
|
|
+ aesKeyCache.delete(requestId)
|
|
|
+ }
|
|
|
+
|
|
|
return response.data
|
|
|
}, errorHandler)
|
|
|
|