封装 HttpClient,统一管理 Token、Loading 和异常处理
This commit is contained in:
@@ -0,0 +1,168 @@
|
|||||||
|
import { ApiResponse, LoadingManager, RequestConfig } from "@/types/HttpClientType.uts"
|
||||||
|
import { Config } from "@/config.uts"
|
||||||
|
import { HttpMethod } from "@/enum/HttpMethod"
|
||||||
|
import { Auth } from "@/utils/Auth.uts"
|
||||||
|
import { XiaoZhi } from "@/utils/XiaoZhi"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP请求客户端
|
||||||
|
*
|
||||||
|
* 职责:
|
||||||
|
* 1. 统一管理网络请求
|
||||||
|
* 2. 自动注入认证信息
|
||||||
|
* 3. 统一处理请求参数
|
||||||
|
* 4. 统一处理响应数据结构
|
||||||
|
* 5. 管理全局Loading状态
|
||||||
|
* 6. 统一异常处理
|
||||||
|
*/
|
||||||
|
export class HttpClient {
|
||||||
|
|
||||||
|
private static instance : HttpClient | null = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单例实例
|
||||||
|
*/
|
||||||
|
static getInstance() : HttpClient {
|
||||||
|
if (this.instance == null) {
|
||||||
|
this.instance = new HttpClient()
|
||||||
|
}
|
||||||
|
return this.instance!
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起HTTP请求
|
||||||
|
*
|
||||||
|
* @param config 请求配置
|
||||||
|
* @returns 标准响应对象
|
||||||
|
*/
|
||||||
|
async request<T>(config : RequestConfig) : Promise<ApiResponse<T>> {
|
||||||
|
console.log("请求拦截")
|
||||||
|
|
||||||
|
let url : string = Config.BASE_URL + config.url
|
||||||
|
let data = config.data ?? null
|
||||||
|
let header : UTSJSONObject = {}
|
||||||
|
|
||||||
|
let method : RequestMethod = (config.method ?? HttpMethod.GET).toString() as RequestMethod
|
||||||
|
|
||||||
|
let timeout : number = 60000
|
||||||
|
let enableQuic : boolean = false
|
||||||
|
let withCredentials : boolean = false
|
||||||
|
let firstIpv4 : boolean = false
|
||||||
|
let enableChunked : boolean = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求扩展配置
|
||||||
|
*
|
||||||
|
* isToken:
|
||||||
|
* false -> 不携带Token
|
||||||
|
*
|
||||||
|
* repeatSubmit:
|
||||||
|
* false -> 开启重复提交校验
|
||||||
|
*
|
||||||
|
* isEncrypt:
|
||||||
|
* true -> 启用请求参数加密
|
||||||
|
*/
|
||||||
|
const isToken = config.headers?.isToken === false
|
||||||
|
const isRepeatSubmit = config.headers?.repeatSubmit === false
|
||||||
|
const isEncrypt = config.headers?.isEncrypt === true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动注入身份认证信息
|
||||||
|
*/
|
||||||
|
if (Auth.getToken() != "" && !isToken) {
|
||||||
|
header['Authorization'] = 'Bearer ' + Auth.getToken()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET请求参数自动拼接至URL
|
||||||
|
*/
|
||||||
|
if (config.method == HttpMethod.GET && config.params != null) {
|
||||||
|
url = Config.BASE_URL + config.url + XiaoZhi.tansParams(config.params as UTSJSONObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 防重复提交处理
|
||||||
|
*
|
||||||
|
* 仅针对新增、修改类请求生效
|
||||||
|
*/
|
||||||
|
if (!isRepeatSubmit && (config.method === HttpMethod.POST || config.method === HttpMethod.PUT)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求参数加密处理
|
||||||
|
*/
|
||||||
|
if (Config.VITE_APP_ENCRYPT) {
|
||||||
|
if (isEncrypt && (config.method === HttpMethod.POST || config.method === HttpMethod.PUT)) {
|
||||||
|
console.log("加密")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.loading == true) {
|
||||||
|
LoadingManager.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await new Promise<ApiResponse<T>>((resolve, reject) => {
|
||||||
|
uni.request({
|
||||||
|
url,
|
||||||
|
method,
|
||||||
|
data,
|
||||||
|
header,
|
||||||
|
timeout,
|
||||||
|
enableQuic,
|
||||||
|
withCredentials,
|
||||||
|
firstIpv4,
|
||||||
|
enableChunked,
|
||||||
|
success: (res) => {
|
||||||
|
const responseData = res["data"] as UTSJSONObject
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"响应拦截-响应状态码:" +
|
||||||
|
JSON.stringify(responseData["code"])
|
||||||
|
)
|
||||||
|
|
||||||
|
const apiResponse = new ApiResponse<T>()
|
||||||
|
|
||||||
|
if (responseData != null) {
|
||||||
|
apiResponse.code = (responseData["code"] as number) ?? 0
|
||||||
|
apiResponse.msg = (responseData["msg"] as string) ?? ""
|
||||||
|
apiResponse.data = responseData["data"] as T
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(apiResponse)
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
reject(err)
|
||||||
|
},
|
||||||
|
complete: () => {}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一网络异常提示
|
||||||
|
*/
|
||||||
|
if (config.showError != false) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "网络异常",
|
||||||
|
icon: "none"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保Loading状态正确关闭
|
||||||
|
*/
|
||||||
|
if (config.loading != false) {
|
||||||
|
LoadingManager.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { createRsaPair, base64Decode, base64Encode, } from "@/uni_modules/laoqianjunzi-crypto";
|
import { createRsaPair, base64Decode, base64Encode, } from "@/uni_modules/laoqianjunzi-crypto";
|
||||||
|
// 在插件中,h5不会导出CryptoRsaPair,需要自定义,等待后续作者处理
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
type CryptoRsaPair = {
|
type CryptoRsaPair = {
|
||||||
publicKey : string;
|
publicKey : string;
|
||||||
|
|||||||
Reference in New Issue
Block a user