mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-15 19:02:01 +08:00
【同步】前端项目源码
【修复】工作流兼容问题
This commit is contained in:
45
frontend/packages/vue/hooks/src/axios/model/axios-cancel.ts
Normal file
45
frontend/packages/vue/hooks/src/axios/model/axios-cancel.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { AxiosRequestConfig } from 'axios'
|
||||
import { requestMiddleware } from './other'
|
||||
|
||||
// * 声明一个 Map 用于存储每个请求的标识 和 取消函数
|
||||
export const pendingMap = new Map<string, AbortController>()
|
||||
|
||||
// 获取请求的唯一标识
|
||||
// const getAbortUrl = (config: AxiosRequestConfig) => config.url
|
||||
|
||||
/**
|
||||
* 添加取消请求中间件
|
||||
* @param {AxiosRequestConfig} config 请求配置
|
||||
* @param {AbortController} controller 取消请求控制器
|
||||
* @returns {AbortController} 返回取消请求控制器
|
||||
*/
|
||||
export const addAbortMiddles = requestMiddleware((config: AxiosRequestConfig) => {
|
||||
const controller = new AbortController() // 创建取消请求控制器
|
||||
pendingMap.set(config.url as string, controller) // 设置取消请求控制器
|
||||
config.signal = controller.signal // 设置请求的信号,当调用 abort 时,会触发信号
|
||||
return config // 返回配置
|
||||
})
|
||||
|
||||
// /**
|
||||
// * 删除取消请求中间件
|
||||
// * @param {AxiosRequestConfig} config 请求配置
|
||||
// */
|
||||
// export const removeAbortMiddles = responseMiddleware((response: AxiosResponse) => {
|
||||
// pendingMap.delete(response.config.url as string)
|
||||
// return response
|
||||
// })
|
||||
|
||||
/**
|
||||
* 取消请求
|
||||
* @param {AxiosRequestConfig} config 请求配置
|
||||
*/
|
||||
export const cancelRequest = (url: string) => {
|
||||
pendingMap.get(url)?.abort()
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除所有取消请求控制器
|
||||
*/
|
||||
export const removeAllAbortController = () => {
|
||||
pendingMap.clear() // 清空取消请求控制器列表
|
||||
}
|
||||
35
frontend/packages/vue/hooks/src/axios/model/axios-options.ts
Normal file
35
frontend/packages/vue/hooks/src/axios/model/axios-options.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
import { getCookie, isDev } from '@baota/utils/browser'
|
||||
import { objectToQueryString } from '@baota/utils/data'
|
||||
import { requestMiddleware } from './other'
|
||||
|
||||
/**
|
||||
* @description 请求头处理-基础
|
||||
* @param {AxiosRequestConfig} options 请求头参数
|
||||
* @param {boolean} isDev 是否为开发环境
|
||||
*/
|
||||
export const requestDefalutOptionsMiddles = requestMiddleware((options: AxiosRequestConfig, dev: boolean = isDev()) => {
|
||||
const defaultOpt: AxiosRequestConfig = {
|
||||
baseURL: dev ? '/api' : '', // 请求基础路径,相对路径用于追加到 baseURL
|
||||
timeout: 250000, // 请求超时时间: 250s
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
transformRequest: [objectToQueryString],
|
||||
}
|
||||
return { ...options, ...defaultOpt }
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 默认配置-面板配置
|
||||
* @param options
|
||||
*/
|
||||
export const requestPanelOptionsMiddle = requestMiddleware((options: AxiosRequestConfig, dev: boolean = isDev()) => {
|
||||
if (!dev) {
|
||||
const cookies = getCookie('request_token') // 获取请求头token
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
...{ 'x-http-token': window.request_token },
|
||||
...(cookies ? { 'x-cookie-token': cookies } : {}),
|
||||
}
|
||||
}
|
||||
return options
|
||||
})
|
||||
@@ -0,0 +1,7 @@
|
||||
import { AxiosError } from 'axios'
|
||||
|
||||
export const handleResponseError = (error: AxiosError): never => {
|
||||
// 自定义错误处理逻辑通知等
|
||||
console.error('Handled Error:', error)
|
||||
throw error
|
||||
}
|
||||
188
frontend/packages/vue/hooks/src/axios/model/index.ts
Normal file
188
frontend/packages/vue/hooks/src/axios/model/index.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
|
||||
import { requestMiddleware, responseMiddleware, errorMiddleware } from './other'
|
||||
|
||||
/**
|
||||
* 中间件类型定义
|
||||
* @property request - 请求拦截器,用于处理请求配置
|
||||
* @property response - 响应拦截器,用于处理响应数据
|
||||
* @property error - 错误处理器,用于处理请求过程中的错误
|
||||
*/
|
||||
export type Middleware = {
|
||||
request?: (config: AxiosRequestConfig) => AxiosRequestConfig | Promise<AxiosRequestConfig>
|
||||
response?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>
|
||||
error?: (error: unknown) => unknown
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP客户端配置接口
|
||||
*/
|
||||
export interface HttpClientConfig extends AxiosRequestConfig {
|
||||
/** 全局中间件 */
|
||||
middlewares?: Middleware[]
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP客户端类
|
||||
* 封装axios实例,提供中间件机制和常用的HTTP方法
|
||||
*/
|
||||
class HttpClient {
|
||||
// axios实例
|
||||
private instance: AxiosInstance
|
||||
// 全局中间件数组
|
||||
private middlewares: Middleware[] = []
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param config - HTTP客户端配置
|
||||
*/
|
||||
constructor(config: HttpClientConfig = {}) {
|
||||
const { middlewares = [], ...axiosConfig } = config
|
||||
|
||||
// 创建axios实例
|
||||
this.instance = axios.create(axiosConfig)
|
||||
|
||||
// 初始化全局中间件
|
||||
this.middlewares = [...middlewares]
|
||||
|
||||
// 设置拦截器
|
||||
this.setupInterceptors()
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行中间件链
|
||||
* @param handler - 处理函数名称
|
||||
* @param context - 上下文数据
|
||||
* @returns 处理后的上下文数据
|
||||
*/
|
||||
private async executeMiddlewareChain<T>(handler: keyof Middleware, context: T): Promise<T> {
|
||||
const currentContext = { ...context }
|
||||
let Context = currentContext as T
|
||||
// 执行中间件链
|
||||
for (const middleware of this.middlewares) {
|
||||
const handlerFn = middleware[handler]
|
||||
if (handlerFn) Context = (await handlerFn(Context as any)) as T
|
||||
}
|
||||
return Context
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求和响应拦截器
|
||||
* 用于执行中间件链
|
||||
*/
|
||||
private setupInterceptors() {
|
||||
// 请求拦截器
|
||||
this.instance.interceptors.request.use(
|
||||
async (config) => {
|
||||
// 复制配置对象,避免直接修改原始配置
|
||||
let currentConfig = { ...config } as AxiosRequestConfig
|
||||
// 执行请求中间件链
|
||||
currentConfig = await this.executeMiddlewareChain('request', currentConfig)
|
||||
return currentConfig as InternalAxiosRequestConfig
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error)
|
||||
},
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
this.instance.interceptors.response.use(async (response) => {
|
||||
// 复制响应对象,避免直接修改原始响应
|
||||
let currentResponse = { ...response }
|
||||
// 执行响应中间件链
|
||||
currentResponse = await this.executeMiddlewareChain('response', currentResponse)
|
||||
return currentResponse
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加全局中间件
|
||||
* @param middleware - 中间件对象
|
||||
* @returns this - 返回实例本身,支持链式调用
|
||||
*/
|
||||
public use(middleware: Middleware) {
|
||||
this.middlewares.push(middleware)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取axios实例
|
||||
* @returns AxiosInstance - 返回当前的axios实例
|
||||
*/
|
||||
public getAxiosInstance() {
|
||||
return this.instance
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
* @param config - 请求配置
|
||||
* @returns Promise<AxiosResponse<T>> - 返回请求响应
|
||||
*/
|
||||
public async request<T = unknown>(config: HttpClientConfig): Promise<AxiosResponse<T> | void> {
|
||||
try {
|
||||
const processedConfig = await this.executeMiddlewareChain('request', config) // 执行请求中间件链
|
||||
const response = await this.instance.request(processedConfig) // 发送请求
|
||||
return this.executeMiddlewareChain('response', response) // 执行响应中间件链
|
||||
} catch (error) {
|
||||
// 执行错误处理中间件链
|
||||
const middleError = await this.executeMiddlewareChain('error', error) // 执行错误处理中间件链,返回错误信息
|
||||
return Promise.reject(middleError)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送GET请求
|
||||
* @param url - 请求地址
|
||||
* @param config - 请求配置
|
||||
* @returns Promise<AxiosResponse<T>> - 返回请求响应
|
||||
*/
|
||||
public async get<T = unknown>(url: string, config: AxiosRequestConfig = {}): Promise<AxiosResponse<T>> {
|
||||
return this.request<T>({ ...config, url, method: 'get' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求
|
||||
* @param url - 请求地址
|
||||
* @param data - 请求数据
|
||||
* @param config - 请求配置
|
||||
* @returns Promise<AxiosResponse<T>> - 返回请求响应
|
||||
*/
|
||||
public async post<T = unknown>(
|
||||
url: string,
|
||||
data?: Record<string, unknown>,
|
||||
config: AxiosRequestConfig = {},
|
||||
): Promise<AxiosResponse<T>> {
|
||||
return this.request<T>({ ...config, url, data, method: 'post' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送PUT请求
|
||||
* @param url - 请求地址
|
||||
* @param data - 请求数据
|
||||
* @param config - 请求配置
|
||||
* @returns Promise<AxiosResponse<T>> - 返回请求响应
|
||||
*/
|
||||
public async put<T = unknown>(
|
||||
url: string,
|
||||
data?: Record<string, unknown>,
|
||||
config: AxiosRequestConfig = {},
|
||||
): Promise<AxiosResponse<T>> {
|
||||
return this.request<T>({ ...config, url, data, method: 'put' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送DELETE请求
|
||||
* @param url - 请求地址
|
||||
* @param config - 请求配置
|
||||
* @returns Promise<AxiosResponse<T>> - 返回请求响应
|
||||
*/
|
||||
public async delete<T = unknown>(url: string, config: AxiosRequestConfig = {}): Promise<AxiosResponse<T>> {
|
||||
return this.request<T>({ ...config, url, method: 'delete' })
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
HttpClient,
|
||||
requestMiddleware, // 请求中间件
|
||||
responseMiddleware, // 响应中间件
|
||||
errorMiddleware, // 错误中间件
|
||||
}
|
||||
36
frontend/packages/vue/hooks/src/axios/model/other.ts
Normal file
36
frontend/packages/vue/hooks/src/axios/model/other.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
|
||||
|
||||
type RequestMiddlewareProps = (fn: (config: AxiosRequestConfig) => AxiosRequestConfig) => {
|
||||
request: (config: AxiosRequestConfig) => AxiosRequestConfig
|
||||
}
|
||||
|
||||
type ResponseMiddlewareProps = (fn: (response: AxiosResponse) => AxiosResponse) => {
|
||||
response: (response: AxiosResponse) => AxiosResponse
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Request 请求中间件
|
||||
* @param fn 请求中间件函数
|
||||
* @returns 请求中间件
|
||||
*/
|
||||
export const requestMiddleware: RequestMiddlewareProps = (fn: (config: AxiosRequestConfig) => AxiosRequestConfig) => ({
|
||||
request: fn,
|
||||
})
|
||||
|
||||
/**
|
||||
* 构建Response 响应中间件
|
||||
* @param fn 响应中间件函数
|
||||
* @returns 响应中间件
|
||||
*/
|
||||
export const responseMiddleware: ResponseMiddlewareProps = (fn: (response: AxiosResponse) => AxiosResponse) => ({
|
||||
response: fn,
|
||||
})
|
||||
|
||||
/**
|
||||
* 构建Error 错误中间件
|
||||
* @param fn 错误中间件函数
|
||||
* @returns 错误中间件
|
||||
*/
|
||||
export const errorMiddleware = (fn: (error: AxiosError) => AxiosError) => ({
|
||||
error: fn,
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
import { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
|
||||
import { getProxyConfig, type ProxyConfig } from '@baota/utils/business'
|
||||
import { isDev } from '@baota/utils/browser'
|
||||
import { requestMiddleware } from './other'
|
||||
|
||||
/**
|
||||
* 代理请求中间件
|
||||
* @param {InternalAxiosRequestConfig<any>} config 请求配置
|
||||
* @param {boolean} dev 是否为开发环境
|
||||
* @returns {InternalAxiosRequestConfig<any>} 返回请求配置
|
||||
*/
|
||||
export const proxyRequestMiddle = requestMiddleware((config: AxiosRequestConfig, dev: boolean = isDev()) => {
|
||||
if (dev) {
|
||||
const { requestTime, requestToken } = getProxyConfig('request_token') as unknown as ProxyConfig
|
||||
config.params = {
|
||||
...config.params,
|
||||
request_time: requestTime,
|
||||
request_token: requestToken,
|
||||
}
|
||||
}
|
||||
return config
|
||||
})
|
||||
@@ -0,0 +1,40 @@
|
||||
import { AxiosResponse } from 'axios'
|
||||
import { responseMiddleware } from './other'
|
||||
import { isObject, isString } from '@baota/utils/type'
|
||||
import { hasRequiredKeys } from '@baota/utils/data'
|
||||
|
||||
/*
|
||||
* 预处理响应数据中间件,该组件运行在
|
||||
*/
|
||||
export const processPanelDataMiddle = responseMiddleware((response: AxiosResponse) => {
|
||||
const defaultOption = {
|
||||
data: {}, // 请求数据
|
||||
code: 0, // 状态码,200为成功,其他为失败
|
||||
msg: 'success', // 提示信息
|
||||
status: true, // 接口状态
|
||||
default: true, // 默认状态,用于判断当前数据是否为默认数据,没有经过处理
|
||||
cache: false, // 是否缓存,基于前端缓存
|
||||
oldData: null, // 旧数据,用于保存原始shuj
|
||||
timestamp: 0, // 时间戳
|
||||
}
|
||||
const { data } = response
|
||||
const { custom } = response.config
|
||||
const result = { ...defaultOption } // 拷贝一份数据
|
||||
// 监测字段是否存在
|
||||
if (isObject(data)) {
|
||||
const hasRequiredKeysCurry = hasRequiredKeys(data)
|
||||
const hasStatus = hasRequiredKeysCurry(['status']) // 是否存在status字段
|
||||
const hasMsg = hasRequiredKeysCurry(['msg']) // 是否存在msg字段
|
||||
const hasData = hasRequiredKeysCurry(['data']) // 是否存在data字段
|
||||
if (hasStatus) result.status = (data as { status: boolean }).status
|
||||
if (hasMsg) result.msg = (data as { msg: string }).msg
|
||||
if (hasData) result.data = (data as { data: any }).data
|
||||
result.default = false
|
||||
} else {
|
||||
result.data = data
|
||||
result.default = true // 原数据,仅移动至data
|
||||
}
|
||||
result.oldData = data
|
||||
if (isString(data)) return response
|
||||
return response
|
||||
})
|
||||
Reference in New Issue
Block a user