From fa3ac93010bea3805438ee3ab0a182bfbf7423da Mon Sep 17 00:00:00 2001 From: baoshiwei <baoshiwei@shlanbao.cn> Date: 星期一, 27 五月 2024 16:19:31 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- src/utils/http/axios/index.ts | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 288 insertions(+), 0 deletions(-) diff --git a/src/utils/http/axios/index.ts b/src/utils/http/axios/index.ts new file mode 100644 index 0000000..113ae24 --- /dev/null +++ b/src/utils/http/axios/index.ts @@ -0,0 +1,288 @@ +// axios閰嶇疆 鍙嚜琛屾牴鎹」鐩繘琛屾洿鏀癸紝鍙渶鏇存敼璇ユ枃浠跺嵆鍙紝鍏朵粬鏂囦欢鍙互涓嶅姩 +// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged + +import type { AxiosResponse } from 'axios' +import { VAxios } from './Axios' +import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform' +import { checkStatus } from './checkStatus' +import { formatRequestDate, joinTimestamp } from './helper' +import type { RequestOptions, Result } from '/#/axios' +import { ConfigEnum, ContentTypeEnum, RequestEnum, ResultEnum } from '/@/enums/httpEnum' +import { useGlobSetting } from '/@/hooks/setting' +import { useI18n } from '/@/hooks/web/useI18n' +import { useMessage } from '/@/hooks/web/useMessage' +import { router } from '/@/router' +import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog' +import { useUserStoreWithOut } from '/@/store/modules/user' +import { deepMerge, setObjToUrlParams } from '/@/utils' +import { getTenantId, getToken } from '/@/utils/auth' +import signMd5Utils from '/@/utils/encryption/signMd5Utils' +import { isString } from '/@/utils/is' +const globSetting = useGlobSetting() +const urlPrefix = globSetting.urlPrefix +const { createMessage, createErrorModal } = useMessage() + +/** + * @description: 鏁版嵁澶勭悊锛屾柟渚垮尯鍒嗗绉嶅鐞嗘柟寮� + */ +const transform: AxiosTransform = { + /** + * @description: 澶勭悊璇锋眰鏁版嵁銆傚鏋滄暟鎹笉鏄鏈熸牸寮忥紝鍙洿鎺ユ姏鍑洪敊璇� + */ + transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => { + //console.log(`output->res`, res) + //console.log(`output->options`, options) + const { t } = useI18n() + const { isTransformResponse, isReturnNativeResponse } = options + // 鏄惁杩斿洖鍘熺敓鍝嶅簲澶� 姣斿锛氶渶瑕佽幏鍙栧搷搴斿ご鏃朵娇鐢ㄨ灞炴�� + if (isReturnNativeResponse) { + return res + } + // 涓嶈繘琛屼换浣曞鐞嗭紝鐩存帴杩斿洖 + // 鐢ㄤ簬椤甸潰浠g爜鍙兘闇�瑕佺洿鎺ヨ幏鍙朿ode锛宒ata锛宮essage杩欎簺淇℃伅鏃跺紑鍚� + if (!isTransformResponse) { + return res.data + } + // 閿欒鐨勬椂鍊欒繑鍥� + + const { data } = res + if (!data) { + // return '[HTTP] Request has no return value'; + throw new Error(t('sys.api.apiRequestFailed')) + } + // 杩欓噷 code锛宺esult锛宮essage涓� 鍚庡彴缁熶竴鐨勫瓧娈碉紝闇�瑕佸湪 types.ts鍐呬慨鏀逛负椤圭洰鑷繁鐨勬帴鍙h繑鍥炴牸寮� + const { code, result, message, success } = data + // 杩欓噷閫昏緫鍙互鏍规嵁椤圭洰杩涜淇敼 + const hasSuccess = data && Reflect.has(data, 'code') && (code === ResultEnum.SUCCESS || code === 200) + if (hasSuccess) { + if (success && message && options.successMessageMode === 'success') { + //淇℃伅鎴愬姛鎻愮ず + createMessage.success(message) + } + return result + } + + // 鍦ㄦ澶勬牴鎹嚜宸遍」鐩殑瀹為檯鎯呭喌瀵逛笉鍚岀殑code鎵ц涓嶅悓鐨勬搷浣� + // 濡傛灉涓嶅笇鏈涗腑鏂綋鍓嶈姹傦紝璇穜eturn鏁版嵁锛屽惁鍒欑洿鎺ユ姏鍑哄紓甯稿嵆鍙� + let timeoutMsg = '' + switch (code) { + case ResultEnum.TIMEOUT: + timeoutMsg = t('sys.api.timeoutMessage') + const userStore = useUserStoreWithOut() + userStore.setToken(undefined) + userStore.logout(true) + break + default: + if (message) { + timeoutMsg = message + } + } + + // errorMessageMode=鈥榤odal鈥欑殑鏃跺�欎細鏄剧ずmodal閿欒寮圭獥锛岃�屼笉鏄秷鎭彁绀猴紝鐢ㄤ簬涓�浜涙瘮杈冮噸瑕佺殑閿欒 + // errorMessageMode='none' 涓�鑸槸璋冪敤鏃舵槑纭〃绀轰笉甯屾湜鑷姩寮瑰嚭閿欒鎻愮ず + if (options.errorMessageMode === 'modal') { + createErrorModal({ title: t('sys.api.errorTip'), content: timeoutMsg }) + } else if (options.errorMessageMode === 'message') { + createMessage.error(timeoutMsg) + } + + throw new Error(timeoutMsg || t('sys.api.apiRequestFailed')) + }, + + // 璇锋眰涔嬪墠澶勭悊config + beforeRequestHook: (config, options) => { + const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options + + if (joinPrefix) { + config.url = `${urlPrefix}${config.url}` + } + + if (apiUrl && isString(apiUrl)) { + config.url = `${apiUrl}${config.url}` + } + const params = config.params || {} + const data = config.data || false + formatDate && data && !isString(data) && formatRequestDate(data) + if (config.method?.toUpperCase() === RequestEnum.GET) { + if (!isString(params)) { + // 缁� get 璇锋眰鍔犱笂鏃堕棿鎴冲弬鏁帮紝閬垮厤浠庣紦瀛樹腑鎷挎暟鎹�� + config.params = Object.assign(params || {}, joinTimestamp(joinTime, false)) + } else { + // 鍏煎restful椋庢牸 + config.url = config.url + params + `${joinTimestamp(joinTime, true)}` + config.params = undefined + } + } else { + if (!isString(params)) { + formatDate && formatRequestDate(params) + if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) { + config.data = data + config.params = params + } else { + // 闈濭ET璇锋眰濡傛灉娌℃湁鎻愪緵data锛屽垯灏唒arams瑙嗕负data + config.data = params + config.params = undefined + } + if (joinParamsToUrl) { + config.url = setObjToUrlParams(config.url as string, Object.assign({}, config.params, config.data)) + } + } else { + // 鍏煎restful椋庢牸 + config.url = config.url + params + config.params = undefined + } + } + return config + }, + + /** + * @description: 璇锋眰鎷︽埅鍣ㄥ鐞� + */ + requestInterceptors: (config: Recordable, options) => { + // console.log(`output->config`, config); + // 璇锋眰涔嬪墠澶勭悊config + const token = getToken() + let tenantid = getTenantId() + //--update-begin--author:liusq---date:20220325---for: 澧炲姞vue3鏍囪 + config.headers[ConfigEnum.VERSION] = 'v3' + //--update-end--author:liusq---date:20220325---for:澧炲姞vue3鏍囪 + if (token && (config as Recordable)?.requestOptions?.withToken !== false) { + // jwt token + config.headers.Authorization = options.authenticationScheme ? `${options.authenticationScheme} ${token}` : token + config.headers[ConfigEnum.TOKEN] = token + //--update-begin--author:liusq---date:20210831---for:灏嗙鍚嶅拰鏃堕棿鎴筹紝娣诲姞鍦ㄨ姹傛帴鍙� Header + + // update-begin--author:taoyan---date:20220421--for: VUEN-410銆愮鍚嶆敼閫犮�� X-TIMESTAMP鐗垫壇 + config.headers[ConfigEnum.TIMESTAMP] = signMd5Utils.getTimestamp() + // update-end--author:taoyan---date:20220421--for: VUEN-410銆愮鍚嶆敼閫犮�� X-TIMESTAMP鐗垫壇 + + config.headers[ConfigEnum.Sign] = signMd5Utils.getSign(config.url, config.params) + //--update-end--author:liusq---date:20210831---for:灏嗙鍚嶅拰鏃堕棿鎴筹紝娣诲姞鍦ㄨ姹傛帴鍙� Header + //--update-begin--author:liusq---date:20211105---for: for:灏嗗绉熸埛id锛屾坊鍔犲湪璇锋眰鎺ュ彛 Header + if (!tenantid) { + tenantid = '0' + } + config.headers[ConfigEnum.TENANT_ID] = tenantid + + //--update-end--author:liusq---date:20211105---for:灏嗗绉熸埛id锛屾坊鍔犲湪璇锋眰鎺ュ彛 Header + + // ======================================================================================== + // update-begin--author:sunjianlei---date:20220624--for: 娣诲姞浣庝唬鐮佸簲鐢↖D + const routeParams = router.currentRoute.value.params + if (routeParams.appId) { + config.headers[ConfigEnum.X_LOW_APP_ID] = routeParams.appId + // lowApp鑷畾涔夌瓫閫夋潯浠� + if (routeParams.lowAppFilter) { + config.params = { ...config.params, ...JSON.parse(routeParams.lowAppFilter as string) } + delete routeParams.lowAppFilter + } + } + // update-end--author:sunjianlei---date:20220624--for: 娣诲姞浣庝唬鐮佸簲鐢↖D + // ======================================================================================== + } + return config + }, + + /** + * @description: 鍝嶅簲鎷︽埅鍣ㄥ鐞� + */ + responseInterceptors: (res: AxiosResponse<any>) => { + return res + }, + + /** + * @description: 鍝嶅簲閿欒澶勭悊 + */ + responseInterceptorsCatch: (error: any) => { + const { t } = useI18n() + const errorLogStore = useErrorLogStoreWithOut() + errorLogStore.addAjaxErrorInfo(error) + const { response, code, message, config } = error || {} + const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none' + //scott 20211022 token澶辨晥鎻愮ず淇℃伅 + //const msg: string = response?.data?.error?.message ?? ''; + const msg: string = response?.data?.message ?? '' + const err: string = error?.toString?.() ?? '' + let errMessage = '' + + try { + if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) { + errMessage = t('sys.api.apiTimeoutMessage') + } + if (err?.includes('Network Error')) { + errMessage = t('sys.api.networkExceptionMsg') + } + + if (errMessage) { + if (errorMessageMode === 'modal') { + createErrorModal({ title: t('sys.api.errorTip'), content: errMessage }) + } else if (errorMessageMode === 'message') { + createMessage.error(errMessage) + } + return Promise.reject(error) + } + } catch (error) { + throw new Error(error) + } + + checkStatus(error?.response?.status, msg, errorMessageMode) + return Promise.reject(error) + }, +} + +function createAxios(opt?: Partial<CreateAxiosOptions>) { + return new VAxios( + deepMerge( + { + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes + // authentication schemes锛宔.g: Bearer + // authenticationScheme: 'Bearer', + authenticationScheme: '', + timeout: 10 * 1000, + // 鍩虹鎺ュ彛鍦板潃 + // baseURL: globSetting.apiUrl, + headers: { 'Content-Type': ContentTypeEnum.JSON }, + // 濡傛灉鏄痜orm-data鏍煎紡 + // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED }, + // 鏁版嵁澶勭悊鏂瑰紡 + transform, + // 閰嶇疆椤癸紝涓嬮潰鐨勯�夐」閮藉彲浠ュ湪鐙珛鐨勬帴鍙h姹備腑瑕嗙洊 + requestOptions: { + // 榛樿灏唒refix 娣诲姞鍒皍rl + joinPrefix: true, + // 鏄惁杩斿洖鍘熺敓鍝嶅簲澶� 姣斿锛氶渶瑕佽幏鍙栧搷搴斿ご鏃朵娇鐢ㄨ灞炴�� + isReturnNativeResponse: false, + // 闇�瑕佸杩斿洖鏁版嵁杩涜澶勭悊 + isTransformResponse: true, + // post璇锋眰鐨勬椂鍊欐坊鍔犲弬鏁板埌url + joinParamsToUrl: false, + // 鏍煎紡鍖栨彁浜ゅ弬鏁版椂闂� + formatDate: true, + // 寮傚父娑堟伅鎻愮ず绫诲瀷 + errorMessageMode: 'message', + // 鎴愬姛娑堟伅鎻愮ず绫诲瀷 + successMessageMode: 'success', + // 鎺ュ彛鍦板潃 + apiUrl: globSetting.apiUrl, + // 鎺ュ彛鎷兼帴鍦板潃 + urlPrefix: urlPrefix, + // 鏄惁鍔犲叆鏃堕棿鎴� + joinTime: true, + // 蹇界暐閲嶅璇锋眰 + ignoreCancelToken: true, + // 鏄惁鎼哄甫token + withToken: true, + }, + }, + opt || {} + ) + ) +} +export const defHttp = createAxios() + +// other api url +// export const otherHttp = createAxios({ +// requestOptions: { +// apiUrl: 'xxx', +// }, +// }); -- Gitblit v1.9.3