RuoYi-VuePlus:前端指定接口不显示错误提示
场景描述
在基于RuoYi-VuePlus进行二次开发时,为了优化用户体验,要求:对某些指定的接口,在前端不显示data.code非200接口返回的错误提示信息,例如:
解决思路
RuoYi-VuePlus前端部分使用Axios发起api接口请求与响应结果处理,包括:请求方法的指定、请求参数/请求体的定义、特定请求头参数的配置、响应数据中状态码、数据、登录状态、请求参数加密与响应结果解密等的拦截和处理。
因此,要实现:使data.code非200状态的接口/api/xxx-a携带的错误信息,不在前端进行展示,也可以通过配置请求头实现。
具体步骤
由于,大多数情况下,上面的错误信息是需要在前端进行展示的,只有少部分情况下不需要进行展示,因此,可以在请求头中配置一个开关:axios.defaults.headers['isErrorMsg'] = 'true';,默认为true,表示需要展示错误信息,对于少部分特殊接口不需要展示的,只要将该请求头的参数设置为false即可。
1. 设置通用请求头参数isErrorMsg
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers['clientid'] = import.meta.env.VITE_APP_CLIENT_ID;
//TODO:新增请求头参数
axios.defaults.headers['isErrorMsg'] = 'true';// 创建 axios 实例
const service = axios.create({baseURL: import.meta.env.VITE_APP_BASE_APItimeout: 1000
});
2. 修改axios实例的相应拦截器逻辑
-- 关键部分:对于非401状态情况的处理
// 响应拦截器
service.interceptors.response.use((res: AxiosResponse) => {if (import.meta.env.VITE_APP_ENCRYPT === 'true') {// 加密后的 AES 秘钥const keyStr = res.headers[encryptHeader];// 加密if (keyStr != null && keyStr != '') {const data = res.data;// 请求体 AES 解密const base64Str = decrypt(keyStr);// base64 解码 得到请求头的 AES 秘钥const aesKey = decryptBase64(base64Str.toString());// aesKey 解码 dataconst decryptData = decryptWithAes(data, aesKey);// 将结果 (得到的是 JSON 字符串) 转为 JSONres.data = JSON.parse(decryptData);}}//是否显示错误信息const isErrorMsg = res.config.headers?.['isErrorMsg'] === 'true';// 未设置状态码则默认成功状态const code = res.data.code || HttpStatus.SUCCESS;// 获取错误信息const msg = errorCode[code] || res.data.msg || errorCode['default'];// 二进制数据则直接返回if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {return res.data;}if (code === 401) {// prettier-ignoreif (!isRelogin.show) {isRelogin.show = true;ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {isRelogin.show = false;useUserStore().logout().then(() => {router.replace({path: '/login',query: {redirect: encodeURIComponent(router.currentRoute.value.fullPath || '/')}})});}).catch(() => {isRelogin.show = false;});}return Promise.reject('无效的会话,或者会话已过期,请重新登录。');} else if (isErrorMsg) {if (code === HttpStatus.SERVER_ERROR) {ElMessage({ message: msg, type: 'error' });return Promise.reject(new Error(msg));} else if (code === HttpStatus.WARN) {ElMessage({ message: msg, type: 'warning' });return Promise.reject(new Error(msg));} else if (code !== HttpStatus.SUCCESS) {ElNotification.error({ title: msg });return Promise.reject('error');} else {return Promise.resolve(res.data);}}},(error: any) => {let { message } = error;if (message == 'Network Error') {message = '后端接口连接异常';} else if (message.includes('timeout')) {message = '系统接口请求超时';} else if (message.includes('Request failed with status code')) {message = '系统接口' + message.substr(message.length - 3) + '异常';}ElMessage({ message: message, type: 'error', duration: 5 * 1000 });return Promise.reject(error);}
);
3. 定义特殊接口的请头参数(不需要展示错误信息的):isErrorMsg=false
/*** 获取图层样式*/
export const getLayerStyle = (sourceId: number | string, layerName: string): AxiosPromise<LayerStyle> => {return request({url: `/api/map/style/${sourceId}`,method: 'get',params: {mapname: layerName},headers: {isErrorMsg: true}});
};