updete
Some checks failed
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m4s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m29s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m27s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m42s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been cancelled

This commit is contained in:
2026-01-02 01:59:44 +08:00
parent 82c1a6a266
commit f46741a84b
44 changed files with 10502 additions and 1486 deletions

View File

@@ -1,4 +1,4 @@
import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios'
import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type AxiosError } from 'axios'
// Token 管理
const TOKEN_KEY = 'gotunnel_token'
@@ -7,6 +7,30 @@ export const getToken = (): string | null => localStorage.getItem(TOKEN_KEY)
export const setToken = (token: string): void => localStorage.setItem(TOKEN_KEY, token)
export const removeToken = (): void => localStorage.removeItem(TOKEN_KEY)
// 统一 API 响应结构
export interface ApiResponse<T = any> {
code: number
data?: T
message?: string
}
// 业务错误码
export const ErrorCodes = {
Success: 0,
BadRequest: 400,
Unauthorized: 401,
Forbidden: 403,
NotFound: 404,
Conflict: 409,
InternalError: 500,
BadGateway: 502,
ClientNotOnline: 1001,
PluginNotFound: 1002,
InvalidClientID: 1003,
PluginDisabled: 1004,
ConfigSyncFailed: 1005,
}
// 创建 axios 实例
const instance: AxiosInstance = axios.create({
baseURL: '/api',
@@ -30,10 +54,39 @@ instance.interceptors.request.use(
}
)
// 响应拦截器
// 响应拦截器 - 处理统一响应格式
instance.interceptors.response.use(
(response) => response,
(error) => {
(response: AxiosResponse<ApiResponse>) => {
const apiResponse = response.data
// 检查业务错误码
if (apiResponse.code !== undefined && apiResponse.code !== ErrorCodes.Success) {
// 处理认证错误
if (apiResponse.code === ErrorCodes.Unauthorized && !isRedirecting) {
isRedirecting = true
removeToken()
setTimeout(() => {
window.location.replace('/login')
isRedirecting = false
}, 0)
}
// 返回包含业务错误信息的 rejected promise
return Promise.reject({
code: apiResponse.code,
message: apiResponse.message || 'Unknown error',
response: response
})
}
// 成功时返回 data 字段
return {
...response,
data: apiResponse.data !== undefined ? apiResponse.data : apiResponse
} as AxiosResponse
},
(error: AxiosError<ApiResponse>) => {
// 处理 HTTP 错误
if (error.response?.status === 401 && !isRedirecting) {
isRedirecting = true
removeToken()
@@ -42,6 +95,17 @@ instance.interceptors.response.use(
isRedirecting = false
}, 0)
}
// 尝试从响应中提取业务错误信息
const apiResponse = error.response?.data
if (apiResponse?.message) {
return Promise.reject({
code: apiResponse.code || error.response?.status,
message: apiResponse.message,
response: error.response
})
}
return Promise.reject(error)
}
)