import ApiCofig from "@/common/config/ApiCofig"; import AppCofig, { isDev } from "@/common/config/AppCofig"; import { useAuthStore } from "@/stores/auth"; import { RequestCoreInstance, RequestApiError, StringUtils, appendGetUrlParams, appendPostParams, RequestResponse, RequestOptions, type RequestApiInfoStruct, RequestApiResult, type RequestApiErrorType, defaultResponseDataGetErrorInfo, defaultResponseDataHandlerCatch, WebFetchImplementer, RequestApiConfig } from "@imengyu/imengyu-utils"; import type { DataModel, KeyValue, NewDataModel } from "@imengyu/js-request-transform"; import { Modal } from "ant-design-vue"; /** * 说明:业务相关的请求模块 * * 请求数据处理函数。 * * 自定义请求模块。 * * 自定义错误报告处理函数。 */ function matchNotReportMessage(code: number, str: string) { if (ApiCofig.notReportErrorCode.includes(code)) return true; for (let i = 0; i < ApiCofig.notReportMessages.length; i++) { if (ApiCofig.notReportMessages[i]?.test(str)) return true; } return false; } //错误报告处理 export function reportError(instance: RequestCoreInstance, response: RequestApiError | Error) { if (isDev) { //开发模式下直接弹窗显示 if (response instanceof RequestApiError) { console.error({ message: `请求错误 ${response.apiName} : ${response.errorMessage}`, detail: response.toString() + '\r\n请求接口:' + response.apiName + '\r\n请求地址:' + response.apiUrl + '\r\n请求参数:' + JSON.stringify(response.apiRawReq) + '\r\n返回参数:' + JSON.stringify(response.rawData) + '\r\n状态码:' + response.code + '\r\n信息:' + response.errorCodeMessage, type: 'error', }); } else { console.error({ message: '错误报告 代码错误', detail: response?.stack || ('' + response), type: 'error', }); } } else { let errMsg = ''; if (response instanceof RequestApiError) errMsg = response.errorMessage + '。'; errMsg += '服务出现了异常,请稍后重试或联系客服。'; errMsg += '版本:' + AppCofig.version; Modal.error({ title: '抱歉', content: errMsg, }); } } export class BaseAppServerRequestModule extends RequestCoreInstance { constructor(baseUrl: string) { super(WebFetchImplementer); this.config.baseUrl = baseUrl; this.config.errCodes = []; //请求拦截器 this.config.requestInterceptor = (url, req) => { //获取store中的token,追加到头; const autoStore = useAuthStore(); if (StringUtils.isNullOrEmpty((req.headers as KeyValue).token as string)) { if (!StringUtils.isNullOrEmpty(autoStore.token)) { req.headers['token'] = autoStore.token; req.headers['__token__'] = autoStore.token; } } if (req.method == 'GET') { //追加GET参数 url = appendGetUrlParams(url, 'main_body_id', ApiCofig.mainBodyId); //url = appendGetUrlParams(url, 'platform', ApiCofig.platformId); } else { if (!(req.data instanceof FormData)) { req.data = appendPostParams(req.data,'main_body_id', ApiCofig.mainBodyId); //req.data = appendPostParams(req.data,'platform', ApiCofig.platformId); } else { req.data.append('main_body_id', ApiCofig.mainBodyId.toString()); //req.data = appendPostParams(req.data,'platform', ApiCofig.platformId); } } return { newUrl: url, newReq: req }; }; //响应数据处理函数 this.config.responseDataHandler = async function responseDataHandler(response: RequestResponse, req: RequestOptions, resultModelClass: NewDataModel | undefined, instance: RequestCoreInstance, apiInfo: RequestApiInfoStruct): Promise> { const method = req.method || 'GET'; try { const json = await response.json(); if (response.ok) { if (!json) { throw new RequestApiError( 'businessError', '后端未返回数据', '', response.status, null, null, response.headers, apiInfo ); } //code == 0 错误 if (json.code === 0) { throw createError(json); } //处理后端的数据 let message = '未知错误'; let data = {} as any; //后端返回格式不统一,所以在这里处理格式 if (typeof json.data === 'object') { data = json.data; message = json.data?.msg || response.statusText; } else { //否则返回上层对象 data = json; message = json.msg || response.statusText; } return new RequestApiResult( resultModelClass ?? instance.config.modelClassCreator, json?.code || response.status, message, data, json, response.headers, apiInfo ); } else { throw createError(json); } function createError(json: any): RequestApiError { let errType : RequestApiErrorType = 'unknow'; let errString = ''; let errCodeStr = ''; if (typeof json.message === 'string') errString = json.message; if (typeof json.msg === 'string') errString += json.msg; if (StringUtils.isStringAllEnglish(errString)) errString = '服务器返回:' + errString; //错误处理 if (errString) { //如果后端有返回错误信息,则收集错误信息并返回 errType = 'businessError'; if (typeof json.data === 'object' && json.data?.errmsg) { errString += '\n' + json.data.errmsg; } if (typeof json.errors === 'object') { for (const key in json.errors) { if (Object.prototype.hasOwnProperty.call(json.errors, key)) { errString += '\n' + json.errors[key]; } } } } else { const res = defaultResponseDataGetErrorInfo(response, json); errType = res.errType; errString = res.errString; errCodeStr = res.errCodeStr; } const res = new RequestApiError( errType, errString, errCodeStr, response.status, null, null, response.headers, apiInfo ); console.log(res); return res; } } catch (err) { if (err instanceof RequestApiError) { throw err; } //错误统一处理 return new Promise>((resolve, reject) => { defaultResponseDataHandlerCatch(method, req, response, null, err as any, apiInfo, response.url, reject, instance); }); } }; /** * 此函数用于请求失败时,如何处理错误信息 * * NOTE: 这里配置Api请求时要如何处理错误 * @param err 错误信息实例 * @param response 返回数据 * @returns 返回一个 Promise,可以定义最终调用该接口的代码会接收到什么样的错误对象。 */ this.config.responseErrorHandler = (err, instance, apiInfo) => { function createErr(errorType: RequestApiErrorType, message: string) { return new RequestApiError(errorType, message, undefined, undefined, undefined, err, undefined, apiInfo); } if (err instanceof Error) { if (err.message == 'Network Error') return createErr('networkError', '请求失败,请检查您的网络连接?'); if (err.message.includes('Timeout') || err.message.includes('timeout') || err.message.includes('singal')) return createErr('networkError', '请求超时'); if (err.message.includes('cancelled') || err.message.includes('aborted')) return createErr('networkError', '请求已取消'); if (err.message.includes('AbortError')) return createErr('networkError', '请求失败,请检查您的网络连接?'); return createErr('scriptError', err.message); } else if (err instanceof RequestApiError) { return err; } return createErr('unknow', '请求失败,未知错误:' + err); }; //错误报告处理 this.config.responseErrorReportInterceptor = (instance, response) => { return ( (response.errorType !== 'businessError' && response.errorType !== 'networkError') || matchNotReportMessage(response.code, response.errorMessage) === true ); }; //错误报告处理函数 this.config.reportError = reportError; } } RequestApiConfig.setConfig({ ...RequestApiConfig.getConfig(), EnableApiDataLog: false, EnableApiRequestLog: import.meta.env.DEV, })