UNPKG

create-vvt

Version:

一个基于 Vite + Vue3 + TypeScript/JavaScript 的项目模板脚手架

199 lines (178 loc) 6.38 kB
// import { useUserStoreHook } from '@/store/modules/user'; // import { message } from '@/utils/message'; import type { PureHttpResponse, IResponse } from './types'; // import { getToken } from '@/utils/auth'; export const DEFAULT_API = import.meta.env.VITE_PROXY; export const TIMEOUT_EXEMPT_URLS = ['/upload', '/download']; // 超时豁免接口 export const DIRECT_RETURN_PATTERNS = [/\/download/]; // 直接返回数据流接口 export const WHITE_LIST = ['/login', '/public-key']; // 不需要 token 校验接口 const ERROR_MESSAGES = { NETWORK: { 301: '请求资源被永久移动到新位置,请访问我们的新网址', 302: '网站正在维护中', 400: '请检查您的输入是否正确,或者联系管理员获得帮助', 401: '登录失效,需要重新登录。', 403: '您正在尝试访问未授权的资源,请联系管理员获得进一步帮助', 404: '您请求访问的资源不存在', 405: '请求方法未允许', 408: '服务器响应时间较长,请您稍后再试', 422: '请求的数据格式不符合要求,请检查', 500: '很抱歉,系统似乎出了些问题,请稍后再试', 501: '网络未实现', 502: '网络错误', 503: '服务不可用', 504: '网络超时', 505: 'http版本不支持该请求' } as Record<number, string>, AUTH: { '4001': '用户名或密码错误', '4002': '很抱歉,您没有访问权限', '4003': '登录信息无效,请重新登录', '4004': '登录失效,需要重新登录', '4006': '该账户已被禁用,请联系超级管理员', '10034': '该用户未注册,请联系管理员注册用户', '10038': '账号未找到' } as Record<string, string> } as const; /** * @description blob转 json */ async function blobToJson(blob: Blob) { const response = new Response(blob); return await response.json(); } /** * 请求的调整 给请求头带上token等 * @param config */ export const handleChangeRequestHeader = (config: any) => { if (!WHITE_LIST.some((url) => config.url?.endsWith(url))) { // const token = getToken(); const token = 'mocked_token'; // mock数据,请按需替换 if (token) { config.headers['Authorization'] = 'Bearer ' + token; } } return config; }; /** 处理网络错误:HTTP响应失败(未到达业务层) * @param errStatus 错误状态码 */ export const handleNetworkError = (errStatus: number) => { const errMessage = errStatus ? ERROR_MESSAGES.NETWORK[errStatus] || `其他连接错误 --${errStatus}` : `无法连接到服务器!`; /** isTokenExpiredHandle: token是否已过期 * 如果没有过期,就是其他错误,合并提示网络错误信息 * 如果过期,直接提示一次过期并重新登录 * 合并提示? * 网络错误会导致所有接口请求受阻,不合并的话当一个页面初始化时有很多请求,页面就会出现很多一样的错误提示 * 合并是用的 elementplus 的 message 组件自带的功能,其他框架需自行处理 * 后期增加了用户信息和 token 之后可以解开注释,取消 console.log,并删掉此段注释 */ // const userStore = useUserStoreHook(); // if (userStore.isTokenExpiredHandle) { // message(errMessage, { // type: 'error' // }); // } else { // message(errMessage, { // type: 'error', // grouping: true // }); // } console.log(errMessage); /** * 对401或403错误的额外处理,说明用户未授权或登录失效,设置 token 为已过期,并退出登录 * 还有其他错误需要特殊处理的也可以写在这里,设置完成请删掉此段注释 */ // if (errStatus === 401 || errStatus === 403) { // userStore.setTokenHandle(true); // userStore.logOut(); // } }; /** * 响应拦截 授权错误处理 * @param errno 错误码 */ const handleAuthError = (errno: string | number) => { // const userStore = useUserStoreHook(); const errMessage = ERROR_MESSAGES.AUTH[errno]; if (errMessage) { /** 解释同handleNetworkError */ // if (userStore.isTokenExpiredHandle) { // message(errMessage, { // type: 'error' // }); // } else { // message(errMessage, { // type: 'error', // grouping: true // }); // } // userStore.setTokenHandle(true); // userStore.logOut(); console.log(errMessage); return false; } return true; }; /** * 响应拦截 请求成功后的普通业务错误处理 * @param response 响应数据 */ const handleGeneralError = async (response: PureHttpResponse) => { let data: IResponse<any>; // 因为对下载接口做了封装,定义了返回类型为 blob,但是接口响应失败的时候返回的是 json,需要单独处理才能触发正常的错误提示 if ( response.data instanceof Blob && response.headers['content-type'] === 'application/json' ) { data = await blobToJson(response.data); } else { data = response.data; } if (data instanceof Blob) { return true; } else if (data.code !== 200) { // const userStore = useUserStoreHook(); const msg = ERROR_MESSAGES.NETWORK[data.code] || data.msg; // message(msg || '未知错误', { // type: 'error', // grouping: true // }); console.log(msg || '未知错误'); // 401 直接退出,也可以进行其他处理,比如只提示不退出等。按需处理后删除注释 if (data.code === 401) { // userStore.setTokenHandle(true); // userStore.logOut(); } return false; } return true; }; /** * 错误处理函数 * @param response 已响应(响应数据存在错误) * @param data 响应数据 */ async function handleError(response: PureHttpResponse, data: IResponse<any>) { if (!handleAuthError(data.code)) { throw new Error('认证错误'); } const generalErrorResult = await handleGeneralError(response); if (!generalErrorResult) { throw new Error(data.msg || '未知错误'); } else { return data; } } // 主要的Axios响应处理函数 直接返回服务器结果 export function handleResponseData(response: PureHttpResponse) { const { data } = response; try { return handleError(response, data); } catch (error) { return Promise.reject(error); } }