🎨 use alova / add nprogress
This commit is contained in:
17
src/utils/alova/adapter/localforageStorageAdapter.ts
Normal file
17
src/utils/alova/adapter/localforageStorageAdapter.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import {handleLocalforage} from "@/utils/localforage";
|
||||
|
||||
export const localforageStorageAdapter = {
|
||||
set(key: string, value: any) {
|
||||
handleLocalforage.setItem(key, value);
|
||||
},
|
||||
get(key: string) {
|
||||
const data: string = handleLocalforage.getItem(key);
|
||||
return data ? JSON.parse(data) : data;
|
||||
},
|
||||
remove(key: any) {
|
||||
handleLocalforage.removeItem(key);
|
||||
},
|
||||
clear() {
|
||||
handleLocalforage.clear().then();
|
||||
}
|
||||
};
|
153
src/utils/alova/service.ts
Normal file
153
src/utils/alova/service.ts
Normal file
@@ -0,0 +1,153 @@
|
||||
import {createAlova} from 'alova';
|
||||
|
||||
import VueHook from 'alova/vue';
|
||||
import useStore from "@/store";
|
||||
import {axiosRequestAdapter} from "@alova/adapter-axios";
|
||||
import {AxiosError, AxiosResponse} from "axios";
|
||||
import {message} from "ant-design-vue";
|
||||
import {localforageStorageAdapter} from "@/utils/alova/adapter/localforageStorageAdapter.ts";
|
||||
|
||||
export const service = createAlova({
|
||||
timeout: 5000,
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||
statesHook: VueHook,
|
||||
// 请求适配器
|
||||
requestAdapter: axiosRequestAdapter(),
|
||||
l2Cache: localforageStorageAdapter,
|
||||
cacheFor: {
|
||||
GET: {
|
||||
mode: 'restore',
|
||||
expire: 60 * 10 * 1000
|
||||
},
|
||||
},
|
||||
cacheLogger: import.meta.env.VITE_NODE_ENV === 'development',
|
||||
// 设置全局的请求拦截器
|
||||
beforeRequest(method) {
|
||||
if (!method.meta?.ignoreToken) {
|
||||
const user = useStore().user;
|
||||
method.config.headers.token = user.getUser()?.token;
|
||||
}
|
||||
|
||||
},
|
||||
// 响应拦截器
|
||||
responded: {
|
||||
onSuccess: async (response: AxiosResponse) => {
|
||||
if (response.data instanceof Blob) {
|
||||
return response;
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
},
|
||||
onError(error: AxiosError) {
|
||||
const {response} = error;
|
||||
if (response) {
|
||||
handleCode(response.status);
|
||||
}
|
||||
if (!window.navigator.onLine) {
|
||||
message.error("网络连接失败").then();
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handleCode(code: number): void {
|
||||
switch (code) {
|
||||
case 400:
|
||||
message
|
||||
.open({
|
||||
content: "请求错误(400)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 401:
|
||||
message
|
||||
.open({
|
||||
content: "未授权,请重新登录(401)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 403:
|
||||
message
|
||||
.open({
|
||||
content: "拒绝访问(403)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 404:
|
||||
message
|
||||
.open({
|
||||
content: "请求出错(404)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 408:
|
||||
message
|
||||
.open({
|
||||
content: "请求超时(408)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 500:
|
||||
message
|
||||
.open({
|
||||
content: "服务器错误(500)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 501:
|
||||
message
|
||||
.open({
|
||||
content: "服务未实现(501)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 502:
|
||||
message
|
||||
.open({
|
||||
content: "网络错误(502)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 503:
|
||||
message
|
||||
.open({
|
||||
content: "服务不可用(503)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 504:
|
||||
message
|
||||
.open({
|
||||
content: "网络超时(504)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 505:
|
||||
message
|
||||
.open({
|
||||
content: "HTTP版本不受支持(505)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
default:
|
||||
message
|
||||
.open({
|
||||
content: `连接出错(${code})!`,
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
}
|
||||
}
|
@@ -1,163 +1,164 @@
|
||||
/** @format */
|
||||
|
||||
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
|
||||
import { message } from "ant-design-vue";
|
||||
import { getStorageFromKey } from "@/utils/localStorage/config.ts";
|
||||
import axios, {AxiosInstance, AxiosRequestConfig} from "axios";
|
||||
import {message} from "ant-design-vue";
|
||||
import useStore from "@/store";
|
||||
|
||||
class Request {
|
||||
private instance: AxiosInstance | undefined;
|
||||
private instance: AxiosInstance | undefined;
|
||||
|
||||
constructor(config: AxiosRequestConfig) {
|
||||
this.instance = axios.create(config);
|
||||
// 全局请求拦截
|
||||
this.instance.interceptors.request.use(
|
||||
(config) => {
|
||||
const token: string | null = getStorageFromKey("token");
|
||||
if (token) {
|
||||
config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
constructor(config: AxiosRequestConfig) {
|
||||
this.instance = axios.create(config);
|
||||
// 全局请求拦截
|
||||
this.instance.interceptors.request.use(
|
||||
(config) => {
|
||||
const user = useStore().user;
|
||||
const token: string | undefined = user.getUser()?.token;
|
||||
if (token) {
|
||||
config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
// 全局响应拦截
|
||||
this.instance.interceptors.response.use(
|
||||
(response) => {
|
||||
if (response.data instanceof Blob) {
|
||||
return response;
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
const { response } = error;
|
||||
if (response) {
|
||||
this.handleCode(response.status);
|
||||
}
|
||||
if (!window.navigator.onLine) {
|
||||
message.error("网络连接失败");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
// 全局响应拦截
|
||||
this.instance.interceptors.response.use(
|
||||
(response) => {
|
||||
if (response.data instanceof Blob) {
|
||||
return response;
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
const {response} = error;
|
||||
if (response) {
|
||||
this.handleCode(response.status);
|
||||
}
|
||||
if (!window.navigator.onLine) {
|
||||
message.error("网络连接失败");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
handleCode(code: number): void {
|
||||
switch (code) {
|
||||
case 400:
|
||||
message
|
||||
.open({
|
||||
content: "请求错误(400)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 401:
|
||||
message
|
||||
.open({
|
||||
content: "未授权,请重新登录(401)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 403:
|
||||
message
|
||||
.open({
|
||||
content: "拒绝访问(403)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 404:
|
||||
message
|
||||
.open({
|
||||
content: "请求出错(404)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 408:
|
||||
message
|
||||
.open({
|
||||
content: "请求超时(408)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 500:
|
||||
message
|
||||
.open({
|
||||
content: "服务器错误(500)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 501:
|
||||
message
|
||||
.open({
|
||||
content: "服务未实现(501)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 502:
|
||||
message
|
||||
.open({
|
||||
content: "网络错误(502)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 503:
|
||||
message
|
||||
.open({
|
||||
content: "服务不可用(503)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 504:
|
||||
message
|
||||
.open({
|
||||
content: "网络超时(504)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 505:
|
||||
message
|
||||
.open({
|
||||
content: "HTTP版本不受支持(505)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
default:
|
||||
message
|
||||
.open({
|
||||
content: `连接出错(${code})!`,
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
}
|
||||
}
|
||||
handleCode(code: number): void {
|
||||
switch (code) {
|
||||
case 400:
|
||||
message
|
||||
.open({
|
||||
content: "请求错误(400)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 401:
|
||||
message
|
||||
.open({
|
||||
content: "未授权,请重新登录(401)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 403:
|
||||
message
|
||||
.open({
|
||||
content: "拒绝访问(403)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 404:
|
||||
message
|
||||
.open({
|
||||
content: "请求出错(404)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 408:
|
||||
message
|
||||
.open({
|
||||
content: "请求超时(408)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 500:
|
||||
message
|
||||
.open({
|
||||
content: "服务器错误(500)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 501:
|
||||
message
|
||||
.open({
|
||||
content: "服务未实现(501)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 502:
|
||||
message
|
||||
.open({
|
||||
content: "网络错误(502)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 503:
|
||||
message
|
||||
.open({
|
||||
content: "服务不可用(503)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 504:
|
||||
message
|
||||
.open({
|
||||
content: "网络超时(504)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
case 505:
|
||||
message
|
||||
.open({
|
||||
content: "HTTP版本不受支持(505)",
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
default:
|
||||
message
|
||||
.open({
|
||||
content: `连接出错(${code})!`,
|
||||
type: "error",
|
||||
})
|
||||
.then();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
request<T>(config: AxiosRequestConfig<T>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
this.instance
|
||||
?.request<T, T>(config)
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
request<T>(config: AxiosRequestConfig<T>): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
this.instance
|
||||
?.request<T, T>(config)
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default Request;
|
||||
|
@@ -5,87 +5,86 @@
|
||||
*/
|
||||
|
||||
interface Options {
|
||||
/** key前缀 */
|
||||
prefix?: string;
|
||||
/** key前缀 */
|
||||
prefix?: string;
|
||||
}
|
||||
|
||||
/** 默认配置 */
|
||||
const defaultOptions: Options = {
|
||||
prefix: "",
|
||||
prefix: "",
|
||||
};
|
||||
|
||||
class CookieStorage {
|
||||
private prefix: string;
|
||||
private prefix: string;
|
||||
|
||||
constructor(options: Options = defaultOptions) {
|
||||
const { prefix } = options;
|
||||
this.prefix = prefix ?? "";
|
||||
}
|
||||
constructor(options: Options = defaultOptions) {
|
||||
const {prefix} = options;
|
||||
this.prefix = prefix ?? "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 设置cookie
|
||||
* @param {string} key 键
|
||||
* @param {any} value 值
|
||||
* @param {number} expires 过期时间s毫秒,不传默认2年有效
|
||||
* @Date: 2023-05-17 18:10:34
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public setItem(key: string, value: string | number, expires?: number): void {
|
||||
const timestamp = Date.now();
|
||||
if (typeof expires === "number") {
|
||||
expires = timestamp + expires;
|
||||
} else {
|
||||
expires = timestamp + 2 * 365 * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
document.cookie = `${this.prefix}${key}=${value};expires=${new Date(expires).toUTCString()}`;
|
||||
}
|
||||
/**
|
||||
* @description: 设置cookie
|
||||
* @param {string} key 键
|
||||
* @param {any} value 值
|
||||
* @param {number} expires 过期时间s毫秒,不传默认2年有效
|
||||
* @Date: 2023-05-17 18:10:34
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public setItem(key: string, value: string | number, expires?: number): void {
|
||||
const timestamp = Date.now();
|
||||
if (typeof expires === "number") {
|
||||
expires = timestamp + expires;
|
||||
} else {
|
||||
expires = timestamp + 2 * 365 * 24 * 60 * 60 * 1000;
|
||||
}
|
||||
document.cookie = `${this.prefix}${key}=${value};expires=${new Date(expires).toUTCString()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 获取cookie
|
||||
* @param {string} key 键
|
||||
* @Date: 2023-05-17 18:31:50
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public getItem(key: string): string | undefined {
|
||||
const cookies = document.cookie.split("; ");
|
||||
let val: string | undefined = undefined;
|
||||
cookies.find((item) => {
|
||||
const [k, v] = item.split("=");
|
||||
if (k === `${this.prefix}${key}`) {
|
||||
val = v;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
/**
|
||||
* @description: 获取cookie
|
||||
* @param {string} key 键
|
||||
* @Date: 2023-05-17 18:31:50
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public getItem(key: string): string | undefined {
|
||||
const cookies = document.cookie.split("; ");
|
||||
let val: string | undefined = undefined;
|
||||
cookies.find((item) => {
|
||||
const [k, v] = item.split("=");
|
||||
if (k === `${this.prefix}${key}`) {
|
||||
val = v;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 删除指定key的cookie
|
||||
* @param {string} key 键
|
||||
* @Date: 2023-05-17 18:32:56
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public removeItem(key: string): void {
|
||||
this.setItem(key, "", -1);
|
||||
}
|
||||
/**
|
||||
* @description: 删除指定key的cookie
|
||||
* @param {string} key 键
|
||||
* @Date: 2023-05-17 18:32:56
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public removeItem(key: string): void {
|
||||
this.setItem(key, "", -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 清空所有cookie
|
||||
* @Date: 2023-05-17 23:13:04
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public clear(): void {
|
||||
const cookies = document.cookie.split("; ");
|
||||
cookies.forEach((item) => {
|
||||
const [k] = item.split("=");
|
||||
this.removeItem(k);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 清空所有cookie
|
||||
* @Date: 2023-05-17 23:13:04
|
||||
* @Author: mulingyuer
|
||||
*/
|
||||
public clear(): void {
|
||||
const cookies = document.cookie.split("; ");
|
||||
cookies.forEach((item) => {
|
||||
const [k] = item.split("=");
|
||||
this.removeItem(k);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const cookieStorage = new CookieStorage();
|
||||
|
||||
export default cookieStorage;
|
||||
export { CookieStorage };
|
||||
export {cookieStorage};
|
||||
|
@@ -41,7 +41,7 @@ export const decrypt = (data: string | unknown) => {
|
||||
|
||||
export const handleLocalforage = {
|
||||
config: async (options?: LocalForageOptions) => localforage.config(options || {}),
|
||||
setItem: (key: string, value: string) => {
|
||||
setItem: (key: string, value: any) => {
|
||||
localforage.setItem(key, encrypt(value));
|
||||
},
|
||||
getItem: (key: string) => {
|
||||
|
22
src/utils/nprogress/nprogress.ts
Normal file
22
src/utils/nprogress/nprogress.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import NProgress from 'nprogress';
|
||||
import 'nprogress/nprogress.css';
|
||||
|
||||
//全局进度条的配置
|
||||
NProgress.configure({
|
||||
easing: 'ease', // 动画方式
|
||||
speed: 300, // 递增进度条的速度
|
||||
showSpinner: false, // 是否显示加载ico
|
||||
trickleSpeed: 200, // 自动递增间隔
|
||||
minimum: 0.3, // 更改启动时使用的最小百分比
|
||||
parent: 'body' //指定进度条的父容器
|
||||
});
|
||||
|
||||
// 打开进度条
|
||||
export const start = () => {
|
||||
NProgress.start();
|
||||
};
|
||||
|
||||
// 关闭进度条
|
||||
export const close = () => {
|
||||
NProgress.done();
|
||||
};
|
Reference in New Issue
Block a user