/** @format */ import { HeaderType } from "../constants/enum/header-type.enum"; import { tokenStore } from "../stores/token.store"; import { MethodType } from "../constants/enum/method-type.enum"; import { StatusCode } from "../constants/enum/status-code.enum"; import { RestfulResponse } from "../model/RestfulResponse"; import { Code } from "../constants/enum/code.enum"; import { eventService } from "../services/event.service"; import { AuthEventType } from "../constants/enum/auth-event-type.enum"; import axios, { Axios, AxiosRequestConfig } from "axios"; import { oauthService, OauthService } from "./oauth.service"; import { DialogPlugin } from "tdesign-vue"; interface Query { [key: string]: any; } /** * @description: REST请求服务 * @author ChenRui * @date 2020/7/29 18:45 */ class ApiService { logoutNoticeSign = false; // 登出通知标志 axiosInner: Axios; constructor() { const requestConfig: any = this.createBasicHeaders(); this.axiosInner = axios.create(requestConfig); this.axiosInner.interceptors.request.use( (config: AxiosRequestConfig | any) => { // Do something before request is sent if (this.verificationToken(config)) { return config; } else { if (!this.logoutNoticeSign) { this.logoutNoticeSign = true; return oauthService.refreshToken().then((response: RestfulResponse) => { this.logoutNoticeSign = false; if (response && response.code === Code.SUCCESS.code) { config.headers = config.headers ? config.headers : {}; config.headers.Authorization = "bearer " + tokenStore.token?.access_token; config.headers["user-identity"] = tokenStore.token?.jti as string; return Promise.resolve(config); } else { if (oauthService.authConfig.enableNoticeMode) { eventService.emit(OauthService.AUTH_EVENT_NAME, { type: AuthEventType.LOGOUT.code, }); } else { const dialog: any = DialogPlugin.confirm({ header: "会话已失效", body: "会话已失效,请重新登录", theme: "warning", cancelBtn: null, closeBtn: false, onConfirm: () => { dialog.destroy(); return oauthService.logOut(); }, }); // Modal.warning({ // title: "会话已失效", // content: "会话已失效,请重新登录", // okText: "确定", // onOk: () => { // return oauthService.logOut(); // }, // }); } return Promise.reject("会话已失效"); } }); } } }, (error) => { return Promise.reject("网络异常,请稍后再试"); } ); } /** * @description: 创建基础消息头 * @author ChenRui * @date 2020/8/28 15:18 */ createBasicHeaders(): any { return { headers: { "Content-Type": "application/json", kaptchaKey: localStorage.getItem("kapt") || "", Accept: "application/json", }, }; } /** * @description: 创建认证消息头 * @author ChenRui * @date 2020/8/28 15:18 */ createAuthHeaders(): any { return { headers: { Authorization: "bearer " + tokenStore.token?.access_token, "user-identity": tokenStore.token?.jti, "Content-Type": "application/json", Accept: "application/json", }, }; } /** * @description: 创建上传认证消息头 * @author ChenRui * @date 2021/4/6 11:17 */ createFileUploadAuthorizationHeader() { return { headers: { Accept: "application/json", Authorization: "bearer " + tokenStore.token?.access_token, "user-identity": tokenStore.token?.jti, }, }; } /** * @description: 创建认证下载消息头 * @author ChenRui * @date 2020/8/28 15:18 */ createFileDownloadAuthorizationHeader() { return { headers: { "Content-Type": "application/json", Authorization: "bearer " + tokenStore.token?.access_token, "user-identity": tokenStore.token?.jti, }, responseType: "blob", }; } get(path: string, query: Query | undefined, requestConfig: AxiosRequestConfig): any { path = query != null ? this.urlQueryConvert(path, query) : path; return this.axiosInner.get(`${path}`, requestConfig).then(this.createBusCodeHander()).catch(this.createErrorHander()); } post(path: string, params: any, query: Query | undefined, requestConfig: AxiosRequestConfig): any { path = query != null ? this.urlQueryConvert(path, query) : path; return this.axiosInner.post(`${path}`, params, requestConfig).then(this.createBusCodeHander()).catch(this.createErrorHander()); } put(path: string, params: any, query: Query | undefined, requestConfig: AxiosRequestConfig): any { path = query != null ? this.urlQueryConvert(path, query) : path; return this.axiosInner.put(`${path}`, params, requestConfig).then(this.createBusCodeHander()).catch(this.createErrorHander()); } delete(path: string, query: Query | undefined, requestConfig: AxiosRequestConfig): any { path = query != null ? this.urlQueryConvert(path, query) : path; return this.axiosInner.delete(path, requestConfig).then(this.createBusCodeHander()).catch(this.createErrorHander()); } /** * @description: 通用请求函数 * @author ChenRui * @date 2020/8/28 15:19 * @param api 调用接口的对象 * @param query 问号?后参数 * @param params post、put、delete参数 非必须 * @param requestConfig 请求配置,如果上传文件、form提交等配置 非必须 */ general(api: any, query?: Query | undefined, params?: any | undefined, requestConfig?: AxiosRequestConfig | any): any { if (!!api.url && !!api.method) { if (requestConfig == null) { switch (api.header) { case HeaderType.BASE.code: requestConfig = this.createBasicHeaders(); break; case HeaderType.AUTH.code: requestConfig = this.createAuthHeaders(); break; case HeaderType.UPLOAD_AUTH.code: requestConfig = this.createFileUploadAuthorizationHeader(); break; case HeaderType.DOWNLOAD_AUTH.code: requestConfig = this.createFileDownloadAuthorizationHeader(); break; } } else { let requestConfigBase: any = {}; switch (api.header) { case HeaderType.BASE.code: requestConfigBase = this.createBasicHeaders(); break; case HeaderType.AUTH.code: requestConfigBase = this.createAuthHeaders(); break; case HeaderType.UPLOAD_AUTH.code: requestConfigBase = this.createFileUploadAuthorizationHeader(); break; case HeaderType.DOWNLOAD_AUTH.code: requestConfigBase = this.createFileDownloadAuthorizationHeader(); break; } Object.keys(requestConfig).forEach((value, index, array) => { requestConfigBase[value] = requestConfig[value]; }); requestConfig = requestConfigBase; } switch (api.method) { case MethodType.GET.code: return this.get(api.url, query, requestConfig); break; case MethodType.PUT.code: return this.put(api.url, params, query, requestConfig); break; case MethodType.POST.code: return this.post(api.url, params, query, requestConfig); break; case MethodType.DELETE.code: return this.delete(api.url, query, requestConfig); break; } } } /** * @description: 错误码处理器 * @author ChenRui * @date 2020/8/28 15:19 */ createBusCodeHander() { return function (response: any) { if (response.status === 200) { if (response.data && response.data.meta && (String(response.data.meta.statusCode) === StatusCode.USER_CACHE_DOES_NOT_EXIST.code || String(response.data.code) === StatusCode.USER_CACHE_DOES_NOT_EXIST.code)) { oauthService.refreshToken(); } return response.data; } return response; }; } /** * @description: 异常处理器 * @author ChenRui * @date 2020/8/28 15:19 */ createErrorHander() { return function (error: any) { let msg = "未知异常,稍后请重试或联系管理员"; if (error.request) { msg = error.request?.data?.msg || "网络连接异常,稍后请重试或联系管理员"; } else if (error.response) { msg = error.response?.data?.msg || "服务器异常,稍后请重试或联系管理员"; } else if (error && typeof error === "string") { msg = error; } else if (error && error.code && error.msg) { msg = error.msg; } return RestfulResponse.failure(msg); }; } /** * @description: 校验令牌 * @author ChenRui * @date 2021/8/11 15:02 */ verificationToken(config: AxiosRequestConfig) { if (config.headers && config.headers.Authorization && (config.headers.Authorization as string).indexOf(OauthService.BASE_TOKEN_TYPE) != 0) { if (tokenStore.token) { return oauthService.isTokenExpiration; } else { return false; } } return true; } /** * @description: 日期格式化 * @author ChenRui * @date 2020/8/28 15:20 */ formatDate(date: any) { date = new Date(date); const YY = date.getFullYear() + "-"; const MM = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-"; const DD = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); const hh = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":"; const mm = (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":"; const ss = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds(); return YY + MM + DD + " " + hh + mm + ss; } /** * @description: json格式转表单格式 * @author ChenRui * @date 2020/8/28 15:20 */ jsonToFormData(params: any) { if (params != null) { const formData = new FormData(); Object.keys(params).forEach((key) => { formData.append(key, params[key]); }); return formData; } } /** * @description: url请求参数组装 * @author ChenRui * @date 2020/8/28 15:21 */ urlQueryConvert(url: string, query: Query) { let connectiveSymbol = ""; if (url.indexOf("?") !== -1) { connectiveSymbol = "&"; } else { connectiveSymbol = "?"; } if (query) { Object.keys(query).forEach((key, idx) => { const val = query[key]; if (idx === 0) { if (val != null && val !== "null" && val !== "undefined") { url += connectiveSymbol + key + "=" + val; } else { url += connectiveSymbol + key + "="; } } else { if (val != null && val !== "null" && val !== "undefined") { url += "&" + key + "=" + val; } else { url += "&" + key + "="; } } }); } return url; } } const apiService = new ApiService(); export { apiService };