From 2e5be29a43a181ac8f352e962809b6bc70d9d698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B0=E9=A6=99=E7=90=AA?= <624506849@qq.com> Date: Wed, 1 Jul 2026 11:41:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E8=81=9A=E5=90=88=E6=8E=A5=E5=8F=A3=E5=8F=8A?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E7=B1=BB=E7=AB=99=E5=86=85=E4=BF=A1=E9=82=AE?= =?UTF-8?q?=E7=AE=B1=E7=8A=B6=E6=80=81=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20-=20=E5=9C=A8=20setting.js=20=E4=B8=AD=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E6=B6=88=E6=81=AF=E6=A8=A1=E6=9D=BF=E8=81=9A=E5=90=88?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=8E=A5=E5=8F=A3=E5=92=8C=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E7=B1=BB=E7=AB=99=E5=86=85=E4=BF=A1=E9=82=AE?= =?UTF-8?q?=E7=AE=B1=E6=B8=A0=E9=81=93=E5=BC=80=E5=85=B3=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E3=80=82=20-=20=E5=9C=A8=20axios.js=20=E4=B8=AD?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BA=86=20token=20=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E5=92=8C=E7=99=BB=E5=BD=95=E9=87=8D=E5=AE=9A=E5=90=91=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E9=81=BF=E5=85=8D=E5=BE=AA=E7=8E=AF=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E3=80=82=20-=20=E6=96=B0=E5=A2=9E=20router-holder.js?= =?UTF-8?q?=20=E6=96=87=E4=BB=B6=E4=BB=A5=E5=BB=B6=E8=BF=9F=E6=8C=81?= =?UTF-8?q?=E6=9C=89=20router=20=E5=AE=9E=E4=BE=8B=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=BE=9D=E8=B5=96=E7=AE=A1=E7=90=86=E3=80=82=20-=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20util.js=20=E4=B8=AD=E7=9A=84=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=B7=AF=E7=94=B1=E7=AE=A1=E7=90=86=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E5=9C=A8=E6=97=A0=20router=20?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E6=97=B6=E4=B8=8D=E6=89=A7=E8=A1=8C=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=93=8D=E4=BD=9C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manager/src/api/setting.js | 10 +++++++ manager/src/libs/axios.js | 46 +++++++++++++++++++------------ manager/src/libs/router-holder.js | 10 +++++++ manager/src/libs/util.js | 11 ++++++-- manager/src/router/index.js | 3 ++ 5 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 manager/src/libs/router-holder.js diff --git a/manager/src/api/setting.js b/manager/src/api/setting.js index 43665c98..c021b57c 100644 --- a/manager/src/api/setting.js +++ b/manager/src/api/setting.js @@ -196,3 +196,13 @@ export const verificationPage = (params) => { export const getNoticeMessageDetail = (id, params) => { return getRequest(`/setting/noticeMessage/${id}`, params) } + +// 消息模板聚合分页(站内信 + 微信服务号 + 小程序) +export const getMessageTemplateAggregatePage = params => { + return getRequest("/setting/noticeMessage/aggregate", params); +}; + +// 修改通知类站内信邮箱渠道开关 +export const updateNoticeMessageEmailStatus = (id, status) => { + return putRequest(`/setting/noticeMessage/${id}/email/${status}`); +}; diff --git a/manager/src/libs/axios.js b/manager/src/libs/axios.js index 4113949e..af167735 100644 --- a/manager/src/libs/axios.js +++ b/manager/src/libs/axios.js @@ -1,9 +1,8 @@ import axios from "axios"; import { getStore, setStore } from "./storage.js"; -import { router } from "../router/index"; +import { getRouter } from "./router-holder"; import { Message } from "@/utils/message"; import Cookies from "js-cookie"; -import { handleRefreshToken } from "../api/index"; import {v4 as uuidv4} from 'uuid'; // 统一请求路径前缀 @@ -23,6 +22,27 @@ const service = axios.create({ timeout: 8000, baseURL: managerUrl }); + +function refreshAccessToken(token) { + return service({ + method: "get", + url: `/passport/user/refresh/${token}`, + }); +} + +function redirectToLogin(message) { + const router = getRouter(); + Cookies.set("userInfoManager", ""); + setStore("accessToken", ""); + if (router && router.currentRoute.value.name !== "login") { + if (message) { + Message.error(message); + } else { + Message.error("未知错误,请重新登录"); + } + router.push("/login"); + } +} var isRefreshToken = 0; const refreshToken = getTokenDebounce(); service.interceptors.request.use( @@ -65,17 +85,7 @@ service.interceptors.response.use( break; case 20004: case 401: - // 未登录 清除已登录状态 - Cookies.set("userInfoManager", ""); - setStore("accessToken", ""); - if (router.history.current.name != "login") { - if (data.message !== null) { - Message.error(data.message); - } else { - Message.error("未知错误,请重新登录"); - } - router.push("/login"); - } + redirectToLogin(data.message !== null ? data.message : null); return data; break; case 500: @@ -109,11 +119,11 @@ service.interceptors.response.use( ); return service(error.response.config); } else { - router.go(0); + const router = getRouter(); + if (router) router.go(0); } } else { - Cookies.set("userInfoManager", ""); - router.push("/login"); + redirectToLogin(null); } isRefreshToken = 0; } @@ -135,7 +145,7 @@ function getTokenDebounce() { if (!lock) { lock = true; let oldRefreshToken = getStore("refreshToken"); - handleRefreshToken(oldRefreshToken) + refreshAccessToken(oldRefreshToken) .then(res => { if (res.success) { let { accessToken, refreshToken } = res.result; @@ -147,7 +157,7 @@ function getTokenDebounce() { } else { success = false; lock = false; - router.push("/login"); + redirectToLogin(null); } }) .catch(err => { diff --git a/manager/src/libs/router-holder.js b/manager/src/libs/router-holder.js new file mode 100644 index 00000000..f79ca463 --- /dev/null +++ b/manager/src/libs/router-holder.js @@ -0,0 +1,10 @@ +/** 延迟持有 router 实例,避免 router ↔ util ↔ axios ↔ api 循环依赖 */ +let routerInstance = null; + +export function setRouter(router) { + routerInstance = router; +} + +export function getRouter() { + return routerInstance; +} diff --git a/manager/src/libs/util.js b/manager/src/libs/util.js index faf1b574..d5998aa2 100644 --- a/manager/src/libs/util.js +++ b/manager/src/libs/util.js @@ -1,6 +1,5 @@ -import { getCurrentPermissionList } from "@/api/index"; import lazyLoading from "./lazyLoading.js"; -import { router } from "@/router/index"; +import { getRouter } from "./router-holder"; import Cookies from "js-cookie"; let util = {}; @@ -9,6 +8,8 @@ let util = {}; util.dynamicRouteNames = []; util.clearDynamicRoutes = function () { + const router = getRouter(); + if (!router) return; util.dynamicRouteNames.forEach((name) => { if (router.hasRoute(name)) { router.removeRoute(name); @@ -44,6 +45,8 @@ util.collectLeafRoutes = function (routes, result = [], parentPath = "") { /** Vue Router 4:动态路由必须挂到 otherRouter 下,且刷新/热更新后需重新注册 */ util.registerDynamicRoutes = function (menuData, options = {}) { + const router = getRouter(); + if (!router) return; const { rematch = true } = options; const pendingPath = router.currentRoute.value.fullPath; const pendingUnmatched = router.currentRoute.value.matched.length === 0; @@ -231,7 +234,8 @@ util.initRouter = function(vm) { if (!vm.$store.state.app.added) { // 第一次加载 读取数据 // 加载菜单 - getCurrentPermissionList().then(res => { + import("@/api/index").then(({ getCurrentPermissionList }) => { + getCurrentPermissionList().then(res => { if (!res.success) return false; let menuData = res.result; @@ -261,6 +265,7 @@ util.initRouter = function(vm) { // 缓存数据 修改加载标识 window.localStorage.setItem("menuData", JSON.stringify(menuData)); vm.$store.commit("setAdded", true); + }); }); } else { // 读取缓存数据 diff --git a/manager/src/router/index.js b/manager/src/router/index.js index 60d22ff1..e996481b 100644 --- a/manager/src/router/index.js +++ b/manager/src/router/index.js @@ -2,6 +2,7 @@ import { createRouter, createWebHistory } from "vue-router"; import NProgress from "nprogress"; import "nprogress/nprogress.css"; import Util from "../libs/util"; +import { setRouter } from "../libs/router-holder"; import Cookies from "js-cookie"; import store from "@/store"; import { routers } from "./router"; @@ -13,6 +14,8 @@ export const router = createRouter({ routes: routers, }); +setRouter(router); + router.beforeEach((to, from, next) => { NProgress.start(); Util.title(to.meta.title);