From cbaa3318311877075c19eade6afdf3be1222998e Mon Sep 17 00:00:00 2001
From: yuhawu <15545526+yuhawu@user.noreply.gitee.com>
Date: Tue, 15 Jul 2025 18:05:11 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/interceptors/response.js | 170 ++++++++++++++++--------
src/api/modules/task.js | 13 ++
src/layout/Sidebar.vue | 17 ++-
src/router/index.js | 20 +--
src/views/Task/List.vue | 219 +++++++++++++++++++++++++++++++
src/views/User/Role.vue | 9 +-
6 files changed, 370 insertions(+), 78 deletions(-)
create mode 100644 src/api/modules/task.js
create mode 100644 src/views/Task/List.vue
diff --git a/src/api/interceptors/response.js b/src/api/interceptors/response.js
index 38df3d4..8a5e4d3 100644
--- a/src/api/interceptors/response.js
+++ b/src/api/interceptors/response.js
@@ -1,11 +1,27 @@
//响应拦截器
import axios from 'axios'; // 引入axios用于创建新请求
+import { ElMessage } from 'element-plus'; // 引入Element Plus的消息组件
+import store from '../../store'; // 引入store用于统一处理登出
export function setupResponseInterceptors(instance) {
// 用于存储正在刷新token的Promise
let isRefreshing = false;
// 存储等待token刷新的请求队列
let requests = [];
+
+ // 统一处理登录过期的函数
+ const handleTokenExpired = (message = '登录已过期,请重新登录') => {
+ // 显示提示消息
+ ElMessage.error(message);
+
+ // 使用store的logout action清除认证状态
+ store.dispatch('logout');
+
+ // 延迟跳转,让用户有时间看到提示
+ setTimeout(() => {
+ window.location.href = '/login';
+ }, 1500);
+ };
instance.interceptors.response.use(
response => {
@@ -20,70 +36,110 @@ export function setupResponseInterceptors(instance) {
return data;
},
async error => {
+ console.log('响应错误:', error);
+
// 获取原始请求配置
const originalRequest = error.config;
-
- // 判断是否401错误(token过期)且没有在刷新中
- if (error.response?.status === 401 && !originalRequest._retry) {
- // 标记该请求已尝试过重试
- originalRequest._retry = true;
-
- // 如果当前没有在刷新token
- if (!isRefreshing) {
- isRefreshing = true;
+
+ // 检查是否有响应
+ if (!error.response) {
+ // 网络错误或请求被中断
+ return Promise.reject(error);
+ }
+
+ // 检查错误响应中的各种可能的错误信息位置
+ const errorResponse = error.response;
+ console.log('错误响应:', errorResponse);
+ const errorData = errorResponse.data || {};
+ const errorMessage = errorData.message || errorData.error || errorResponse.statusText || '';
+ const errorStack = errorData.stack || '';
+ const statusCode = errorResponse.status;
+
+ // 处理403错误(权限不足)
+ if (errorResponse.status === "403") {
+ // 显示权限不足提示,但不重定向
+ ElMessage.error(errorMessage || '您没有权限执行此操作');
+ return Promise.reject("您没有权限执行此操作");
+ }
+
+ // 检查是否为令牌错误(检查多种可能的错误信息格式)
+ const isTokenError =
+ statusCode === 401 ||
+ (statusCode === 500 && (
+ errorMessage.includes('令牌') ||
+ errorMessage.includes('token') ||
+ errorMessage.includes('Token') ||
+ errorStack.includes('TokenIllegal') ||
+ errorStack.includes('TheTokenIllegalException') ||
+ (typeof errorData === 'string' && errorData.includes('令牌'))
+ ));
+
+ // 如果是令牌错误,尝试刷新令牌或直接跳转登录页
+ if (isTokenError) {
+ // 如果是401错误且没有在刷新中,尝试刷新令牌
+ if (statusCode === 401 && !originalRequest._retry) {
+ // 标记该请求已尝试过重试
+ originalRequest._retry = true;
- try {
- // 从localStorage获取refreshToken
- const refreshToken = localStorage.getItem('refreshToken');
+ // 如果当前没有在刷新token
+ if (!isRefreshing) {
+ isRefreshing = true;
- if (!refreshToken) {
- // 无refreshToken,跳转到登录页
- window.location.href = '/login';
- return Promise.reject(error);
+ 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接口
+ const response = await axios.post('/admin/getAccessToken', formData);
+
+ // 获取新的token
+ const { accessToken, refreshToken: newRefreshToken } = response.data.data;
+
+ // 更新本地存储
+ localStorage.setItem('accessToken', accessToken);
+ if (newRefreshToken) {
+ localStorage.setItem('refreshToken', newRefreshToken);
+ }
+
+ // 更新当前请求的Authorization头
+ originalRequest.headers.Authorization = accessToken;
+
+ // 执行队列中的所有请求
+ requests.forEach(cb => cb(accessToken));
+ requests = [];
+
+ // 重新发送之前失败的请求
+ return instance(originalRequest);
+ } catch (refreshError) {
+ // 刷新token失败,清除token并跳转到登录页
+ handleTokenExpired();
+ return Promise.reject(refreshError);
+ } finally {
+ isRefreshing = false;
}
-
- // 创建表单数据
- const formData = new FormData();
- formData.append('refreshToken', refreshToken);
-
- // 调用刷新token接口
- const response = await axios.post('/admin/getAccessToken', formData);
-
- // 获取新的token
- const { accessToken, refreshToken: newRefreshToken } = response.data.data;
-
- // 更新本地存储
- localStorage.setItem('accessToken', accessToken);
- if (newRefreshToken) {
- localStorage.setItem('refreshToken', newRefreshToken);
- }
-
- // 更新当前请求的Authorization头
- originalRequest.headers.Authorization = accessToken;
-
- // 执行队列中的所有请求
- requests.forEach(cb => cb(accessToken));
- requests = [];
-
- // 重新发送之前失败的请求
- return instance(originalRequest);
- } catch (refreshError) {
- // 刷新token失败,清除token并跳转到登录页
- localStorage.removeItem('accessToken');
- localStorage.removeItem('refreshToken');
- window.location.href = '/login';
- return Promise.reject(refreshError);
- } finally {
- isRefreshing = false;
+ } else {
+ // 如果已经在刷新中,将请求加入队列
+ return new Promise(resolve => {
+ requests.push(token => {
+ originalRequest.headers.Authorization = token;
+ resolve(instance(originalRequest));
+ });
+ });
}
} else {
- // 如果已经在刷新中,将请求加入队列
- return new Promise(resolve => {
- requests.push(token => {
- originalRequest.headers.Authorization = token;
- resolve(instance(originalRequest));
- });
- });
+ // 其他令牌错误,直接处理登录过期
+ handleTokenExpired();
+ return Promise.reject(error);
}
}
diff --git a/src/api/modules/task.js b/src/api/modules/task.js
new file mode 100644
index 0000000..ac79878
--- /dev/null
+++ b/src/api/modules/task.js
@@ -0,0 +1,13 @@
+import instance from '../../utils/axios.js'
+
+// 任务相关API
+const taskApi = {
+ // 获取运行中的任务列表
+ getRunningTasks: () => instance.get('/task/test'),
+
+ // 停止指定任务
+ stopTask: (taskId) => instance.get(`/task/stopTask?taskId=${taskId}`),
+};
+
+// 导出模块
+export { taskApi };
\ No newline at end of file
diff --git a/src/layout/Sidebar.vue b/src/layout/Sidebar.vue
index 06f232c..50910e2 100644
--- a/src/layout/Sidebar.vue
+++ b/src/layout/Sidebar.vue
@@ -57,10 +57,6 @@
{
title: '权限管理',
path: '/user/permission'
- },
- {
- title: '用户角色管理',
- path: '/user/userRole'
}
]
},
@@ -164,6 +160,19 @@
}]
}]
},
+ {
+ title: '任务管理',
+ path: '/task',
+ icon: TrendCharts,
+ children:[{
+ title: '任务列表',
+ path: '/task/list',
+ children:[{
+ title: '任务列表',
+ path: '/task/list'
+ }]
+ }]
+ },
{
title: '功能模块',
path: '/useModule',
diff --git a/src/router/index.js b/src/router/index.js
index 1bd2893..566d884 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -28,11 +28,6 @@ const routes = [{
component: () => import('@/views/User/List.vue'),
meta: { title: '用户列表' }
},
- {
- path: '/user/edit',
- component: () => import('@/views/User/Edit.vue'),
- meta: { title: '新增用户' }
- },
{
path: '/user/role',
component: () => import('@/views/User/Role.vue'),
@@ -43,11 +38,6 @@ const routes = [{
component: () => import('@/views/User/Permission.vue'),
meta: { title: '权限管理' }
},
- {
- path: '/user/userRole',
- component: () => import('@/views/User/UserRole.vue'),
- meta: { title: '用户角色管理' }
- },
{
path: '/shop/list',
component: () => import('@/views/Shop/index.vue'),
@@ -83,11 +73,6 @@ const routes = [{
component: () => import('@/views/order/wechat/list.vue'),
meta: { title: '订单列表' }
},
- {
- path: '/websocket/demo',
- component: () => import('@/views/websocket/index.vue'),
- meta: { title: 'WebSocket演示' }
- },
{
path: '/book/selection/center',
component: () => import('@/views/baseInfo/index.vue'),
@@ -97,6 +82,11 @@ const routes = [{
path: '/warehouse/depot/list',
component: () => import('@/views/Warehouse/Depot/List.vue'),
meta: { title: '货区管理' }
+ },
+ {
+ path: '/task/list',
+ component: () => import('@/views/Task/List.vue'),
+ meta: { title: '任务列表' }
}
]
}]
diff --git a/src/views/Task/List.vue b/src/views/Task/List.vue
new file mode 100644
index 0000000..af0cf90
--- /dev/null
+++ b/src/views/Task/List.vue
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+
+
+
+
+ 暂无运行中的任务
+
+
+
+
+
+
+
+
+
+ {{ getTaskStatusText(scope.row.taskStatus) }}
+
+
+
+
+
+
+
+ 停止任务
+
+
+
+
+
+
+
+ {{ currentTask.id }}
+ {{ currentTask.fileName }}
+ {{ currentTask.shopNames }}
+ {{ currentTask.dataNum }}
+ {{ currentTask.createTime }}
+
+
+
+
+ {{ currentTask.msg }}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/User/Role.vue b/src/views/User/Role.vue
index 143e47d..01462ad 100644
--- a/src/views/User/Role.vue
+++ b/src/views/User/Role.vue
@@ -119,8 +119,13 @@ export default {
const res = await getRoleList()
roleList.value = res.data || []
} catch (error) {
- console.error('获取角色列表失败', error)
- ElMessage.error('获取角色列表失败')
+ console.log(error)
+ if(error.status === 403){
+ ElMessage.error("您没有权限执行此操作")
+ }else{
+ console.error('获取角色列表失败', error)
+ ElMessage.error('获取角色列表失败')
+ }
} finally {
loading.value = false
}