diff --git a/src/api/interceptors/request.js b/src/api/interceptors/request.js index 6e180c1..865360c 100644 --- a/src/api/interceptors/request.js +++ b/src/api/interceptors/request.js @@ -7,7 +7,8 @@ export function setupRequestInterceptors(instance) { // 判断 token 是否存在 if (token) { // 如果存在,则将 token 添加到请求头中的 Authorization 字段 - config.headers.Authorization = token + // config.headers.Authorization = token + config.headers.Authorization = `Bearer ${token}` } // 返回修改后的请求配置,继续发送请求 return config diff --git a/src/api/interceptors/response.js b/src/api/interceptors/response.js index a5207d6..7708482 100644 --- a/src/api/interceptors/response.js +++ b/src/api/interceptors/response.js @@ -1,35 +1,21 @@ -//响应拦截器 import axios from 'axios'; // 引入axios用于创建新请求 import { ElMessage, ElMessageBox } from 'element-plus'; // 引入Element Plus的消息组件 -import store from '../../store'; // 引入store用于统一处理登出 +import store from '../../store/Index'; // 引入store用于统一处理登出 import axiosInstance from '../../utils/axios'; // 引入已配置的axios实例 export function setupResponseInterceptors(instance) { - // 用于存储正在刷新token的Promise let isRefreshing = false; - // 存储等待token刷新的请求队列 let requests = []; - - // 统一处理登录过期的函数 + const handleTokenExpired = (message = '登录已过期,请重新登录') => { - // 显示确认对话框 - ElMessageBox.confirm( - message, - '提示', - { - confirmButtonText: '重新登录', - type: 'warning', - showCancelButton: false, - center: true - } - ).then(() => { - // 用户点击确认按钮后执行 - // 使用store的logout action清除认证状态 + ElMessageBox.confirm(message, '提示', { + confirmButtonText: '重新登录', + type: 'warning', + showCancelButton: false, + center: true + }).then(() => { store.dispatch('logout'); - // 跳转到登录页 window.location.href = '/login'; - }).catch(() => { - // 用户关闭对话框,不做任何操作 }); }; @@ -45,108 +31,79 @@ export function setupResponseInterceptors(instance) { } return data; }, - async error => { - // 获取原始请求配置 + async error => { const originalRequest = error.config; - - // 检查是否有响应 + if (!error.response) { - // 网络错误或请求被中断 return Promise.reject(error); } - - // 检查错误响应中的各种可能的错误信息位置 - const errorResponse = error.response; - console.log('错误响应:', errorResponse); - const errorData = errorResponse.data || {}; - const errorMessage = errorData.status || errorData.message || errorData.error || errorResponse.statusText || ''; - const errorStack = errorData.stack || ''; - const statusCode = errorResponse.status; - console.log('错误响应:', statusCode); - // 处理403错误(权限不足) - if (errorResponse.status === "403") { - // 显示权限不足提示,但不重定向 - ElMessage.error(errorMessage || '您没有权限执行此操作'); - return Promise.reject("您没有权限执行此操作"); - } - - // 检查是否为令牌错误(检查多种可能的错误信息格式) - const isTokenError = statusCode === 500 - // 如果是令牌错误,尝试刷新令牌或直接跳转登录页 - if (isTokenError) { - // 如果是401错误且没有在刷新中,尝试刷新令牌 - if (statusCode === 401 || statusCode === 500 || statusCode === 403 && !originalRequest._retry ) { - // 标记该请求已尝试过重试 - originalRequest._retry = true; - - // 如果当前没有在刷新token - if (!isRefreshing) { - isRefreshing = true; - - try { - // 从localStorage获取refreshToken - const refreshToken = localStorage.getItem('refreshToken'); - if (!refreshToken) { - // 无refreshToken,跳转到登录页 - handleTokenExpired(); - return Promise.reject(error); - } - - // 创建表单数据 - const formData = new FormData(); - formData.append('refreshToken', refreshToken); - - // 调用刷新token接口,使用配置好的axios实例 - const response = await axiosInstance.post('/admin/getAccessToken', formData); - - // 根据实际返回的数据结构获取token - const responseData = response.data; - const accessToken = responseData.accessToken; - const newRefreshToken = responseData.refreshToken; - - // 更新本地存储 - localStorage.setItem('accessToken', accessToken); - localStorage.setItem('refreshToken', newRefreshToken); - - // 更新当前请求的Authorization头 - originalRequest.headers.Authorization = `Bearer ${accessToken}`; - - // 更新全局axios和axiosInstance的默认Authorization头,确保后续所有请求都带上新token - axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`; - axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`; - - console.log('新token设置成功:', accessToken); - - // 执行队列中的所有请求 - requests.forEach(cb => cb(accessToken)); - requests = []; - - // 重新发送之前失败的请求 - return instance(originalRequest); - } catch (refreshError) { - // 刷新token失败,清除token并跳转到登录页 + const statusCode = error.response.status; + console.log("statusCode", statusCode) + // 401表示accessToken过期,尝试用refreshToken刷新 + if ((statusCode === 401 || statusCode === 500) && !originalRequest._retry) { + originalRequest._retry = true; + console.log("isRefreshing", isRefreshing) + if (!isRefreshing) { + isRefreshing = true; + + try { + const refreshToken = localStorage.getItem('refreshToken'); + if (!refreshToken) { handleTokenExpired(); - return Promise.reject(refreshError); - } finally { - isRefreshing = false; + return Promise.reject(error); } - } else { - // 如果已经在刷新中,将请求加入队列 - return new Promise(resolve => { - requests.push(token => { - originalRequest.headers.Authorization = token; - resolve(instance(originalRequest)); - }); - }); + + // 调用刷新接口 + const formData = new FormData(); + formData.append('refreshToken', refreshToken); + + const response = await axiosInstance.post('/admin/refreshToken', formData); + console.log('刷新token响应:', response); + + // 后端返回格式: { code: 200, data: { accessToken: "xxx", refreshToken: "xxx" } } + // 由于axios拦截器已经处理了response.data,所以这里直接使用response.data + const responseData = response.data || response; + console.log('响应数据:', responseData); + + const accessToken = responseData.accessToken; + const newRefreshToken = responseData.refreshToken; + + if (!accessToken) { + throw new Error('刷新token失败:未获取到新的accessToken'); + } + + // 更新本地存储 + localStorage.setItem('accessToken', accessToken); + if (newRefreshToken) { + localStorage.setItem('refreshToken', newRefreshToken); + } + + // 更新请求头 + originalRequest.headers.Authorization = `Bearer ${accessToken}`; + + // 处理队列中的请求 + requests.forEach(cb => cb(accessToken)); + requests = []; + + return instance(originalRequest); + } catch (refreshError) { + handleTokenExpired(); + return Promise.reject(refreshError); + } finally { + isRefreshing = false; } } else { - // 其他令牌错误,直接处理登录过期 - handleTokenExpired(); - return Promise.reject(error); + // 正在刷新中,将请求加入队列 + return new Promise(resolve => { + requests.push(token => { + originalRequest.headers.Authorization = `Bearer ${token}`; + resolve(instance(originalRequest)); + }); + }); } } - + return Promise.reject(error); } ); diff --git a/src/api/role.js b/src/api/role.js index 71c2877..a22773f 100644 --- a/src/api/role.js +++ b/src/api/role.js @@ -47,7 +47,7 @@ export function deleteRole(id) { */ export function getRolePermissions(roleId) { return axios({ - url: `/admin/role/permissions/${roleId}`, + url: `/admin/role/permissions/selectRoleAndPermissions/${roleId}`, method: 'get' }) } diff --git a/src/views/User/List.vue b/src/views/User/List.vue index eb2de0b..e574b36 100644 --- a/src/views/User/List.vue +++ b/src/views/User/List.vue @@ -95,8 +95,8 @@ - - + + { form[key] = res.data[key] } }) + + // 处理角色数据 + if (res.data.roleIds) { + form.roleIds = res.data.roleIds + } else if (res.data.roleId) { + // 兼容单角色数据 + form.roleIds = res.data.roleId ? [res.data.roleId] : [] + } } else { ElMessage.error(res.message || '获取用户信息失败') dialogVisible.value = false diff --git a/src/views/User/Permission.vue b/src/views/User/Permission.vue index cb7157e..142da05 100644 --- a/src/views/User/Permission.vue +++ b/src/views/User/Permission.vue @@ -114,7 +114,7 @@ export default { id: '', parentId: null, permissionName: '', - permissionCode: '', + permissionCode: null, description: '', type: 1, path: '', @@ -171,7 +171,7 @@ export default { permissionForm.id = '' permissionForm.parentId = parentNode ? parentNode.id : null permissionForm.permissionName = '' - permissionForm.permissionCode = '' + permissionForm.permissionCode = null permissionForm.description = '' permissionForm.type = 1 permissionForm.path = '' @@ -179,7 +179,7 @@ export default { permissionForm.icon = '' permissionForm.sort = 0 permissionForm.status = 1 - permissionForm.isDel = 0 + // permissionForm.isDel = 0 parentPermissionName.value = parentNode ? parentNode.name : '无(根权限)' @@ -233,7 +233,7 @@ export default { try { // 如果是目录类型,自动设置一个空的编码值 if (permissionForm.type === 1) { - permissionForm.permissionCode = ''; + permissionForm.permissionCode = null; } const data = {