diff --git a/utils/HttpClient.uts b/utils/HttpClient.uts new file mode 100644 index 0000000..259b337 --- /dev/null +++ b/utils/HttpClient.uts @@ -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(config : RequestConfig) : Promise> { + 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>((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() + + 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() + } + } + } +} \ No newline at end of file diff --git a/utils/crypto.uts b/utils/crypto.uts index e8b6018..aba8b45 100644 --- a/utils/crypto.uts +++ b/utils/crypto.uts @@ -1,5 +1,5 @@ import { createRsaPair, base64Decode, base64Encode, } from "@/uni_modules/laoqianjunzi-crypto"; - +// 在插件中,h5不会导出CryptoRsaPair,需要自定义,等待后续作者处理 // #ifdef H5 type CryptoRsaPair = { publicKey : string; @@ -7,9 +7,9 @@ type CryptoRsaPair = { } // #endif // #ifdef APP-ANDROID - import { CryptoRsaPair } from "@/uni_modules/laoqianjunzi-crypto"; +import { CryptoRsaPair } from "@/uni_modules/laoqianjunzi-crypto"; // #endif - + export class Crypto { /** * 随机生成32位的字符串