Ver Fonte

feat: add cache key

xingyu4j há 2 anos atrás
pai
commit
3e60ff2970

+ 3 - 3
yudao-ui-admin-vue3/src/App.vue

@@ -4,7 +4,7 @@ import { isDark } from '@/utils/is'
 import { useAppStore } from '@/store/modules/app'
 import { useDesign } from '@/hooks/web/useDesign'
 import { ConfigGlobal } from '@/components/ConfigGlobal'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 
 const { getPrefixCls } = useDesign()
 const prefixCls = getPrefixCls('app')
@@ -15,8 +15,8 @@ const { wsCache } = useCache()
 
 // 根据浏览器当前主题设置系统主题色
 const setDefaultTheme = () => {
-  if (wsCache.get('isDark')) {
-    if (wsCache.get('isDark') || wsCache.get('isDark') === 'true') {
+  if (wsCache.get(CACHE_KEY.IS_DARK)) {
+    if (wsCache.get(CACHE_KEY.IS_DARK) || wsCache.get(CACHE_KEY.IS_DARK) === 'true') {
       appStore.setIsDark(true)
     } else {
       appStore.setIsDark(false)

+ 4 - 4
yudao-ui-admin-vue3/src/components/Setting/src/Setting.vue

@@ -3,7 +3,7 @@ import { ElDrawer, ElDivider, ElMessage } from 'element-plus'
 import { ref, unref, computed, watch } from 'vue'
 import { useCssVar, useClipboard } from '@vueuse/core'
 import { useI18n } from '@/hooks/web/useI18n'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { useDesign } from '@/hooks/web/useDesign'
 
 import { trim, setCssVar } from '@/utils'
@@ -188,9 +188,9 @@ const copyConfig = async () => {
 // 清空缓存
 const clear = () => {
   const { wsCache } = useCache()
-  wsCache.delete('layout')
-  wsCache.delete('theme')
-  wsCache.delete('isDark')
+  wsCache.delete(CACHE_KEY.LAYOUT)
+  wsCache.delete(CACHE_KEY.THEME)
+  wsCache.delete(CACHE_KEY.IS_DARK)
   window.location.reload()
 }
 </script>

+ 2 - 2
yudao-ui-admin-vue3/src/components/UserInfo/src/UserInfo.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElMessageBox } from 'element-plus'
 import { useI18n } from '@/hooks/web/useI18n'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { useRouter } from 'vue-router'
 import { useDesign } from '@/hooks/web/useDesign'
 import avatarImg from '@/assets/imgs/avatar.gif'
@@ -22,7 +22,7 @@ const { getPrefixCls } = useDesign()
 
 const prefixCls = getPrefixCls('user-info')
 
-const user = wsCache.get('user')
+const user = wsCache.get(CACHE_KEY.USER)
 
 const avatar = user.user.avatar ? user.user.avatar : avatarImg
 

+ 2 - 2
yudao-ui-admin-vue3/src/directives/permission/hasPermi.ts

@@ -1,5 +1,5 @@
 import type { App } from 'vue'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { useI18n } from '@/hooks/web/useI18n'
 const { t } = useI18n() // 国际化
 
@@ -8,7 +8,7 @@ export function hasPermi(app: App<Element>) {
     const { wsCache } = useCache()
     const { value } = binding
     const all_permission = '*:*:*'
-    const permissions = wsCache.get('user').permissions
+    const permissions = wsCache.get(CACHE_KEY.USER).permissions
 
     if (value && value instanceof Array && value.length > 0) {
       const permissionFlag = value

+ 2 - 2
yudao-ui-admin-vue3/src/directives/permission/hasRole.ts

@@ -1,5 +1,5 @@
 import type { App } from 'vue'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { useI18n } from '@/hooks/web/useI18n'
 const { t } = useI18n() // 国际化
 
@@ -8,7 +8,7 @@ export function hasRole(app: App<Element>) {
     const { wsCache } = useCache()
     const { value } = binding
     const super_admin = 'admin'
-    const roles = wsCache.get('user').roles
+    const roles = wsCache.get(CACHE_KEY.USER).roles
 
     if (value && value instanceof Array && value.length > 0) {
       const roleFlag = value

+ 10 - 0
yudao-ui-admin-vue3/src/hooks/web/useCache.ts

@@ -6,6 +6,16 @@ import WebStorageCache from 'web-storage-cache'
 
 type CacheType = 'localStorage' | 'sessionStorage'
 
+export const CACHE_KEY = {
+  IS_DARK: 'isDark',
+  USER: 'user',
+  LANG: 'lang',
+  THEME: 'theme',
+  LAYOUT: 'layout',
+  ROLE_ROUTERS: 'roleRouters',
+  DICT_CACHE: 'dictCache'
+}
+
 export const useCache = (type: CacheType = 'localStorage') => {
   const wsCache: WebStorageCache = new WebStorageCache({
     storage: type

+ 7 - 7
yudao-ui-admin-vue3/src/router/index.ts

@@ -1,18 +1,18 @@
 import type { App } from 'vue'
-import { getAccessToken } from '@/utils/auth'
 import type { RouteRecordRaw } from 'vue-router'
+import { createRouter, createWebHashHistory } from 'vue-router'
 import remainingRouter from './modules/remaining'
+import { isRelogin } from '@/config/axios/service'
+import { getAccessToken } from '@/utils/auth'
 import { useTitle } from '@/hooks/web/useTitle'
 import { useNProgress } from '@/hooks/web/useNProgress'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { usePageLoading } from '@/hooks/web/usePageLoading'
-import { createRouter, createWebHashHistory } from 'vue-router'
-import { usePermissionStoreWithOut } from '@/store/modules/permission'
 import { useDictStoreWithOut } from '@/store/modules/dict'
 import { useUserStoreWithOut } from '@/store/modules/user'
-import { listSimpleDictDataApi } from '@/api/system/dict/dict.data'
-import { isRelogin } from '@/config/axios/service'
+import { usePermissionStoreWithOut } from '@/store/modules/permission'
 import { getInfoApi } from '@/api/login'
-import { useCache } from '@/hooks/web/useCache'
+import { listSimpleDictDataApi } from '@/api/system/dict/dict.data'
 
 const { wsCache } = useCache('sessionStorage')
 
@@ -50,7 +50,7 @@ router.beforeEach(async (to, from, next) => {
       const dictStore = useDictStoreWithOut()
       const userStore = useUserStoreWithOut()
       const permissionStore = usePermissionStoreWithOut()
-      const dictMap = wsCache.get('dictCache')
+      const dictMap = wsCache.get(CACHE_KEY.DICT_CACHE)
       if (!dictMap) {
         const res = await listSimpleDictDataApi()
         dictStore.setDictMap(res)

+ 7 - 7
yudao-ui-admin-vue3/src/store/modules/app.ts

@@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
 import { store } from '../index'
 import { setCssVar, humpToUnderline } from '@/utils'
 import { ElMessage } from 'element-plus'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { ElementPlusSize } from '@/types/elementPlus'
 import { LayoutType } from '@/types/layout'
 import { ThemeTypes } from '@/types/theme'
@@ -61,10 +61,10 @@ export const useAppStore = defineStore('app', {
       greyMode: false, // 是否开始灰色模式,用于特殊悼念日
       fixedMenu: wsCache.get('fixedMenu') || false, // 是否固定菜单
 
-      layout: wsCache.get('layout') || 'classic', // layout布局
-      isDark: wsCache.get('isDark') || false, // 是否是暗黑模式
+      layout: wsCache.get(CACHE_KEY.LAYOUT) || 'classic', // layout布局
+      isDark: wsCache.get(CACHE_KEY.IS_DARK) || false, // 是否是暗黑模式
       currentSize: wsCache.get('default') || 'default', // 组件尺寸
-      theme: wsCache.get('theme') || {
+      theme: wsCache.get(CACHE_KEY.THEME) || {
         // 主题色
         elColorPrimary: '#409eff',
         // 左侧菜单边框颜色
@@ -223,7 +223,7 @@ export const useAppStore = defineStore('app', {
         return
       }
       this.layout = layout
-      wsCache.set('layout', this.layout)
+      wsCache.set(CACHE_KEY.THEME, this.layout)
     },
     setTitle(title: string) {
       this.title = title
@@ -237,7 +237,7 @@ export const useAppStore = defineStore('app', {
         document.documentElement.classList.add('light')
         document.documentElement.classList.remove('dark')
       }
-      wsCache.set('isDark', this.isDark)
+      wsCache.set(CACHE_KEY.IS_DARK, this.isDark)
     },
     setCurrentSize(currentSize: ElementPlusSize) {
       this.currentSize = currentSize
@@ -248,7 +248,7 @@ export const useAppStore = defineStore('app', {
     },
     setTheme(theme: ThemeTypes) {
       this.theme = Object.assign(this.theme, theme)
-      wsCache.set('theme', this.theme)
+      wsCache.set(CACHE_KEY.THEME, this.theme)
     },
     setCssVarTheme() {
       for (const key in this.theme) {

+ 3 - 3
yudao-ui-admin-vue3/src/store/modules/dict.ts

@@ -1,7 +1,7 @@
 import { defineStore } from 'pinia'
 import { store } from '../index'
 import { DictDataVO } from '@/api/system/dict/types'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 const { wsCache } = useCache('sessionStorage')
 
 export interface DictValueType {
@@ -24,7 +24,7 @@ export const useDictStore = defineStore('dict', {
   }),
   getters: {
     getDictMap(): Recordable {
-      const dictMap = wsCache.get('dictCache')
+      const dictMap = wsCache.get(CACHE_KEY.DICT_CACHE)
       return dictMap ? dictMap : this.dictMap
     },
     getHasDictData(): boolean {
@@ -54,7 +54,7 @@ export const useDictStore = defineStore('dict', {
         })
       })
       this.dictMap = dictDataMap
-      wsCache.set('dictCache', dictDataMap, { exp: 60 }) // 60 秒 过期
+      wsCache.set(CACHE_KEY.DICT_CACHE, dictDataMap, { exp: 60 }) // 60 秒 过期
     }
   }
 })

+ 4 - 4
yudao-ui-admin-vue3/src/store/modules/locale.ts

@@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
 import { store } from '../index'
 import zhCn from 'element-plus/es/locale/lang/zh-cn'
 import en from 'element-plus/es/locale/lang/en'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { LocaleDropdownType } from '@/types/localeDropdown'
 
 const { wsCache } = useCache()
@@ -20,8 +20,8 @@ export const useLocaleStore = defineStore('locales', {
   state: (): LocaleState => {
     return {
       currentLocale: {
-        lang: wsCache.get('lang') || 'zh-CN',
-        elLocale: elLocaleMap[wsCache.get('lang') || 'zh-CN']
+        lang: wsCache.get(CACHE_KEY.LANG) || 'zh-CN',
+        elLocale: elLocaleMap[wsCache.get(CACHE_KEY.LANG) || 'zh-CN']
       },
       // 多语言
       localeMap: [
@@ -49,7 +49,7 @@ export const useLocaleStore = defineStore('locales', {
       // this.locale = Object.assign(this.locale, localeMap)
       this.currentLocale.lang = localeMap?.lang
       this.currentLocale.elLocale = elLocaleMap[localeMap?.lang]
-      wsCache.set('lang', localeMap?.lang)
+      wsCache.set(CACHE_KEY.LANG, localeMap?.lang)
     }
   }
 })

+ 4 - 4
yudao-ui-admin-vue3/src/store/modules/permission.ts

@@ -4,7 +4,7 @@ import { cloneDeep } from 'lodash-es'
 import remainingRouter from '@/router/modules/remaining'
 import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper'
 import { getAsyncRoutesApi } from '@/api/login'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 
 const { wsCache } = useCache()
 
@@ -35,11 +35,11 @@ export const usePermissionStore = defineStore('permission', {
     async generateRoutes(): Promise<unknown> {
       return new Promise<void>(async (resolve) => {
         let res: AppCustomRouteRecordRaw[]
-        if (wsCache.get('roleRouters')) {
-          res = wsCache.get('roleRouters') as AppCustomRouteRecordRaw[]
+        if (wsCache.get(CACHE_KEY.ROLE_ROUTERS)) {
+          res = wsCache.get(CACHE_KEY.ROLE_ROUTERS) as AppCustomRouteRecordRaw[]
         } else {
           res = await getAsyncRoutesApi()
-          wsCache.set('roleRouters', res)
+          wsCache.set(CACHE_KEY.ROLE_ROUTERS, res)
         }
         const routerMap: AppRouteRecordRaw[] = generateRoute(res as AppCustomRouteRecordRaw[])
         // 动态路由,404一定要放到最后面

+ 2 - 2
yudao-ui-admin-vue3/src/store/modules/user.ts

@@ -1,7 +1,7 @@
 import { store } from '../index'
 import { defineStore } from 'pinia'
 import { getAccessToken, removeToken } from '@/utils/auth'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 
 const { wsCache } = useCache()
 
@@ -46,7 +46,7 @@ export const useUserStore = defineStore('admin-user', {
       this.permissions = userInfo.permissions
       this.roles = userInfo.roles
       this.user = userInfo.user
-      wsCache.set('user', userInfo)
+      wsCache.set(CACHE_KEY.USER, userInfo)
     },
     loginOut() {
       removeToken()

+ 6 - 6
yudao-ui-admin-vue3/src/utils/auth.ts

@@ -45,7 +45,7 @@ export const getUsername = () => {
 }
 
 export const setUsername = (username: string) => {
-  wsCache.set(UsernameKey, username)
+  wsCache.set(UsernameKey, username, { exp: 30 * 24 * 60 * 60 })
 }
 
 export const removeUsername = () => {
@@ -58,7 +58,7 @@ export const getPassword = () => {
 }
 
 export const setPassword = (password: string) => {
-  wsCache.set(PasswordKey, encrypt(password))
+  wsCache.set(PasswordKey, encrypt(password), { exp: 30 * 24 * 60 * 60 })
 }
 
 export const removePassword = () => {
@@ -66,11 +66,11 @@ export const removePassword = () => {
 }
 
 export const getRememberMe = () => {
-  return wsCache.get(RememberMeKey) === 'true'
+  return wsCache.get(RememberMeKey) === true
 }
 
-export const setRememberMe = (rememberMe: string) => {
-  wsCache.set(RememberMeKey, rememberMe)
+export const setRememberMe = (rememberMe: boolean) => {
+  wsCache.set(RememberMeKey, rememberMe, { exp: 30 * 24 * 60 * 60 })
 }
 
 export const removeRememberMe = () => {
@@ -87,7 +87,7 @@ export const getTenantName = () => {
 }
 
 export const setTenantName = (username: string) => {
-  wsCache.set(TenantNameKey, username)
+  wsCache.set(TenantNameKey, username, { exp: 30 * 24 * 60 * 60 })
 }
 
 export const removeTenantName = () => {

+ 3 - 3
yudao-ui-admin-vue3/src/utils/routerHelper.ts

@@ -18,7 +18,7 @@ export const getParentLayout = () => {
 }
 
 // 按照路由中meta下的rank等级升序来排序路由
-export function ascending(arr: any[]) {
+export const ascending = (arr: any[]) => {
   arr.forEach((v) => {
     if (v?.meta?.rank === null) v.meta.rank = undefined
     if (v?.meta?.rank === 0) {
@@ -109,7 +109,7 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord
         data.children = generateRoute(route.children)
       }
     }
-    res.push(data)
+    res.push(data as AppRouteRecordRaw)
   }
   return res
 }
@@ -203,7 +203,7 @@ const addToChildren = (
     }
   }
 }
-function toCamelCase(str: string, upperCaseFirst: boolean) {
+const toCamelCase = (str: string, upperCaseFirst: boolean) => {
   str = (str || '').toLowerCase().replace(/-(.)/g, function (group1: string) {
     return group1.toUpperCase()
   })

+ 4 - 3
yudao-ui-admin-vue3/src/views/Home/Index.vue

@@ -167,20 +167,21 @@ import { EChartsOption } from 'echarts'
 import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus'
 import { formatTime } from '@/utils'
 import { useI18n } from '@/hooks/web/useI18n'
-import { useCache } from '@/hooks/web/useCache'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { useWatermark } from '@/hooks/web/useWatermark'
 import { Echart } from '@/components/Echart'
 import { CountTo } from '@/components/CountTo'
 import { Highlight } from '@/components/Highlight'
 import type { WorkplaceTotal, Project, Notice, Shortcut } from './types'
 import { pieOptions, barOptions } from './echarts-data'
+import { Icon } from 'vxe-table'
 
 const { t } = useI18n()
 const { wsCache } = useCache()
 const { setWatermark } = useWatermark()
 const loading = ref(true)
-const avatar = wsCache.get('user').user.avatar
-const username = wsCache.get('user').user.nickname
+const avatar = wsCache.get(CACHE_KEY.USER).user.avatar
+const username = wsCache.get(CACHE_KEY.USER).user.nickname
 const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
 // 获取统计数
 let totalSate = reactive<WorkplaceTotal>({

+ 32 - 25
yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue

@@ -154,10 +154,24 @@ import { useRouter } from 'vue-router'
 import type { RouteLocationNormalizedLoaded } from 'vue-router'
 import { useI18n } from '@/hooks/web/useI18n'
 import { useIcon } from '@/hooks/web/useIcon'
-import { useCache } from '@/hooks/web/useCache'
 import { required } from '@/utils/formRules'
-import { setToken, setTenantId } from '@/utils/auth'
-import { decrypt, encrypt } from '@/utils/jsencrypt'
+import {
+  setToken,
+  setTenantId,
+  setUsername,
+  setPassword,
+  setRememberMe,
+  setTenantName,
+  removeUsername,
+  removePassword,
+  removeRememberMe,
+  removeTenantName,
+  getUsername,
+  getPassword,
+  getRememberMe,
+  getTenantName
+} from '@/utils/auth'
+import { decrypt } from '@/utils/jsencrypt'
 import { Icon } from '@/components/Icon'
 import { Verify } from '@/components/Verifition'
 import { usePermissionStore } from '@/store/modules/permission'
@@ -166,7 +180,6 @@ import { LoginStateEnum, useLoginState, useFormValid } from './useLogin'
 
 const { t } = useI18n()
 const formLogin = ref()
-const { wsCache } = useCache()
 const { validForm } = useFormValid(formLogin)
 const { setLoginState, getLoginState } = useLoginState()
 const { currentRoute, push } = useRouter()
@@ -195,11 +208,9 @@ const loginData = reactive({
     signIn: false
   },
   loginForm: {
-    tenantName: wsCache.get('tenantName') ? wsCache.get('tenantName') : '芋道源码',
-    username: wsCache.get('username') ? wsCache.get('username') : 'admin',
-    password: wsCache.get('password')
-      ? (decrypt(wsCache.get('password')) as unknown as string)
-      : 'admin123',
+    tenantName: '芋道源码',
+    username: 'admin',
+    password: 'admin123',
     captchaVerification: '',
     rememberMe: false
   }
@@ -223,12 +234,10 @@ const getTenantId = async () => {
 }
 // 记住我
 const getCookie = () => {
-  const username = wsCache.get('username')
-  const password = wsCache.get('password')
-    ? (decrypt(wsCache.get('password')) as unknown as string)
-    : undefined
-  const rememberMe = wsCache.get('rememberMe')
-  const tenantName = wsCache.get('tenantName')
+  const username = getUsername()
+  const password = getPassword() ? decrypt(getPassword() as unknown as string) : undefined
+  const rememberMe = getRememberMe()
+  const tenantName = getTenantName()
   loginData.loginForm = {
     ...loginData.loginForm,
     username: username ? username : loginData.loginForm.username,
@@ -257,17 +266,15 @@ const handleLogin = async (params) => {
       background: 'rgba(0, 0, 0, 0.7)'
     })
     if (loginData.loginForm.rememberMe) {
-      wsCache.set('username', loginData.loginForm.username, { exp: 30 * 24 * 60 * 60 })
-      wsCache.set('password', encrypt(loginData.loginForm.password as unknown as string), {
-        exp: 30
-      })
-      wsCache.set('rememberMe', loginData.loginForm.rememberMe, { exp: 30 * 24 * 60 * 60 })
-      wsCache.set('tenantName', loginData.loginForm.tenantName, { exp: 30 * 24 * 60 * 60 })
+      setUsername(loginData.loginForm.username)
+      setPassword(loginData.loginForm.password)
+      setRememberMe(loginData.loginForm.rememberMe)
+      setTenantName(loginData.loginForm.tenantName)
     } else {
-      wsCache.delete('username')
-      wsCache.delete('password')
-      wsCache.delete('rememberMe')
-      wsCache.delete('tenantName')
+      removeUsername()
+      removePassword()
+      removeRememberMe()
+      removeTenantName()
     }
     setToken(res)
     if (!redirect.value) {

+ 2 - 4
yudao-ui-admin-vue3/src/views/Login/components/MobileForm.vue

@@ -91,9 +91,8 @@ import { useRouter } from 'vue-router'
 import type { RouteLocationNormalizedLoaded } from 'vue-router'
 import { useI18n } from '@/hooks/web/useI18n'
 import { useIcon } from '@/hooks/web/useIcon'
-import { useCache } from '@/hooks/web/useCache'
 import { useMessage } from '@/hooks/web/useMessage'
-import { setToken } from '@/utils/auth'
+import { setTenantId, setToken } from '@/utils/auth'
 import { required } from '@/utils/formRules'
 import { usePermissionStore } from '@/store/modules/permission'
 import { getTenantIdByNameApi, sendSmsCodeApi, smsLoginApi } from '@/api/login'
@@ -101,7 +100,6 @@ import LoginFormTitle from './LoginFormTitle.vue'
 import { useLoginState, LoginStateEnum, useFormValid } from './useLogin'
 
 const { t } = useI18n()
-const { wsCache } = useCache()
 const message = useMessage()
 const permissionStore = usePermissionStore()
 const { currentRoute, push } = useRouter()
@@ -172,7 +170,7 @@ watch(
 // 获取租户 ID
 const getTenantId = async () => {
   const res = await getTenantIdByNameApi(loginData.loginForm.tenantName)
-  wsCache.set('tenantId', res)
+  setTenantId(res)
 }
 // 登录
 const signIn = async () => {

+ 3 - 0
yudao-ui-admin-vue3/src/views/system/menu/index.vue

@@ -215,6 +215,7 @@
 // 全局相关的 import
 import { onMounted, reactive, ref } from 'vue'
 import { useI18n } from '@/hooks/web/useI18n'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { useMessage } from '@/hooks/web/useMessage'
 import {
   ElForm,
@@ -241,6 +242,7 @@ import { handleTree, defaultProps } from '@/utils/tree'
 
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
+const { wsCache } = useCache()
 // 列表相关的变量
 const xTable = ref<VxeTableInstance>()
 const tableLoading = ref(false)
@@ -380,6 +382,7 @@ const submitForm = async () => {
   } finally {
     dialogVisible.value = false
     actionLoading.value = false
+    wsCache.delete(CACHE_KEY.ROLE_ROUTERS)
     // 操作成功,重新加载列表
     await getList()
   }