mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	fix: #I5KCI6
This commit is contained in:
		| @ -2,18 +2,10 @@ | ||||
| import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElMessageBox } from 'element-plus' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
| import { removeToken } from '@/utils/auth' | ||||
| import { resetRouter } from '@/router' | ||||
| import { useRouter } from 'vue-router' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| import { useTagsViewStore } from '@/store/modules/tagsView' | ||||
| import avatarImg from '@/assets/imgs/avatar.gif' | ||||
|  | ||||
| const tagsViewStore = useTagsViewStore() | ||||
|  | ||||
| const { getPrefixCls } = useDesign() | ||||
|  | ||||
| const prefixCls = getPrefixCls('user-info') | ||||
| import { useUserStore } from '@/store/modules/user' | ||||
|  | ||||
| const { t } = useI18n() | ||||
|  | ||||
| @ -21,6 +13,12 @@ const { wsCache } = useCache() | ||||
|  | ||||
| const { push, replace } = useRouter() | ||||
|  | ||||
| const userStore = useUserStore() | ||||
|  | ||||
| const { getPrefixCls } = useDesign() | ||||
|  | ||||
| const prefixCls = getPrefixCls('user-info') | ||||
|  | ||||
| const user = wsCache.get('user') | ||||
|  | ||||
| const avatar = user.user.avatar ? user.user.avatar : avatarImg | ||||
| @ -34,10 +32,7 @@ const loginOut = () => { | ||||
|     type: 'warning' | ||||
|   }) | ||||
|     .then(async () => { | ||||
|       resetRouter() // 重置静态路由表 | ||||
|       wsCache.clear() | ||||
|       removeToken() | ||||
|       tagsViewStore.delAllViews() | ||||
|       userStore.loginOut() | ||||
|       replace('/login') | ||||
|     }) | ||||
|     .catch(() => {}) | ||||
|  | ||||
| @ -6,6 +6,7 @@ import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } f | ||||
| import errorCode from './errorCode' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { resetRouter } from '@/router' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
|  | ||||
| const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE | ||||
| const BASE_URL = import.meta.env.VITE_BASE_URL | ||||
| @ -205,10 +206,12 @@ const handleAuthorized = () => { | ||||
|       type: 'warning' | ||||
|     }) | ||||
|       .then(() => { | ||||
|         removeToken() | ||||
|         const { wsCache } = useCache() | ||||
|         resetRouter() // 重置静态路由表 | ||||
|         wsCache.clear() | ||||
|         removeToken() | ||||
|         isRelogin.show = false | ||||
|         location.href = '/' | ||||
|         location.href = '/login' | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         isRelogin.show = false | ||||
|  | ||||
| @ -2,13 +2,13 @@ import type { App } from 'vue' | ||||
| import { getAccessToken } from '@/utils/auth' | ||||
| import type { RouteRecordRaw } from 'vue-router' | ||||
| import remainingRouter from './modules/remaining' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
| import { useTitle } from '@/hooks/web/useTitle' | ||||
| import { useNProgress } from '@/hooks/web/useNProgress' | ||||
| 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' | ||||
|  | ||||
| @ -16,7 +16,7 @@ const permissionStore = usePermissionStoreWithOut() | ||||
|  | ||||
| const dictStore = useDictStoreWithOut() | ||||
|  | ||||
| const { wsCache } = useCache() | ||||
| const userStore = useUserStoreWithOut() | ||||
|  | ||||
| const { start, done } = useNProgress() | ||||
|  | ||||
| @ -48,31 +48,27 @@ router.beforeEach(async (to, from, next) => { | ||||
|     if (to.path === '/login') { | ||||
|       next({ path: '/' }) | ||||
|     } else { | ||||
|       if (!dictStore.getIsSetDict) { | ||||
|         isRelogin.show = true | ||||
|       console.info(3) | ||||
|       // 获取所有字典 | ||||
|       const res = await listSimpleDictDataApi() | ||||
|       dictStore.setDictMap(res) | ||||
|         dictStore.setIsSetDict(true) | ||||
|       } | ||||
|       if (permissionStore.getIsAddRouters) { | ||||
|       if (userStore.getRoles.length === 0) { | ||||
|         isRelogin.show = true | ||||
|         isRelogin.show = false | ||||
|         next() | ||||
|         return | ||||
|       } | ||||
|       // 开发者可根据实际情况进行修改 | ||||
|       const roleRouters = wsCache.get('roleRouters') || [] | ||||
|  | ||||
|       await permissionStore.generateRoutes(roleRouters as AppCustomRouteRecordRaw[]) | ||||
|  | ||||
|         console.info(2) | ||||
|         // 后端过滤菜单 | ||||
|         await permissionStore.generateRoutes() | ||||
|         permissionStore.getAddRouters.forEach((route) => { | ||||
|           router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表 | ||||
|         }) | ||||
|         const redirectPath = from.query.redirect || to.path | ||||
|         const redirect = decodeURIComponent(redirectPath as string) | ||||
|         const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect } | ||||
|       permissionStore.setIsAddRouters(true) | ||||
|         next(nextData) | ||||
|       } else { | ||||
|         console.info(3) | ||||
|         next() | ||||
|       } | ||||
|     } | ||||
|   } else { | ||||
|     if (whiteList.indexOf(to.path) !== -1) { | ||||
|  | ||||
| @ -13,14 +13,12 @@ export interface DictTypeType { | ||||
|   dictValue: DictValueType[] | ||||
| } | ||||
| export interface DictState { | ||||
|   isSetDict: boolean | ||||
|   dictMap: Recordable | ||||
| } | ||||
|  | ||||
| export const useDictStore = defineStore({ | ||||
|   id: 'dict', | ||||
|   state: (): DictState => ({ | ||||
|     isSetDict: false, | ||||
|     dictMap: {} | ||||
|   }), | ||||
|   persist: { | ||||
| @ -30,8 +28,12 @@ export const useDictStore = defineStore({ | ||||
|     getDictMap(): Recordable { | ||||
|       return this.dictMap | ||||
|     }, | ||||
|     getIsSetDict(): boolean { | ||||
|       return this.isSetDict | ||||
|     getHasDictData(): Boolean { | ||||
|       if (this.dictMap.length > 0) { | ||||
|         return true | ||||
|       } else { | ||||
|         return false | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   actions: { | ||||
| @ -53,9 +55,6 @@ export const useDictStore = defineStore({ | ||||
|         }) | ||||
|       }) | ||||
|       this.dictMap = dictMap | ||||
|     }, | ||||
|     setIsSetDict(isSetDict: boolean) { | ||||
|       this.isSetDict = isSetDict | ||||
|     } | ||||
|   } | ||||
| }) | ||||
|  | ||||
| @ -2,12 +2,15 @@ import { defineStore } from 'pinia' | ||||
| import { store } from '../index' | ||||
| import { cloneDeep } from 'lodash-es' | ||||
| import remainingRouter from '@/router/modules/remaining' | ||||
| import { generateRoutes, flatMultiLevelRoutes } from '@/utils/routerHelper' | ||||
| import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper' | ||||
| import { getAsyncRoutesApi } from '@/api/login' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
|  | ||||
| const { wsCache } = useCache() | ||||
|  | ||||
| export interface PermissionState { | ||||
|   routers: AppRouteRecordRaw[] | ||||
|   addRouters: AppRouteRecordRaw[] | ||||
|   isAddRouters: boolean | ||||
|   menuTabRouters: AppRouteRecordRaw[] | ||||
| } | ||||
|  | ||||
| @ -16,7 +19,6 @@ export const usePermissionStore = defineStore({ | ||||
|   state: (): PermissionState => ({ | ||||
|     routers: [], | ||||
|     addRouters: [], | ||||
|     isAddRouters: false, | ||||
|     menuTabRouters: [] | ||||
|   }), | ||||
|   persist: { | ||||
| @ -29,18 +31,21 @@ export const usePermissionStore = defineStore({ | ||||
|     getAddRouters(): AppRouteRecordRaw[] { | ||||
|       return flatMultiLevelRoutes(cloneDeep(this.addRouters)) | ||||
|     }, | ||||
|     getIsAddRouters(): boolean { | ||||
|       return this.isAddRouters | ||||
|     }, | ||||
|     getMenuTabRouters(): AppRouteRecordRaw[] { | ||||
|       return this.menuTabRouters | ||||
|     } | ||||
|   }, | ||||
|   actions: { | ||||
|     generateRoutes(routers?: AppCustomRouteRecordRaw[] | string[]): Promise<unknown> { | ||||
|       return new Promise<void>((resolve) => { | ||||
|         let routerMap: AppRouteRecordRaw[] = [] | ||||
|         routerMap = generateRoutes(routers as AppCustomRouteRecordRaw[]) | ||||
|     async generateRoutes(): Promise<unknown> { | ||||
|       return new Promise<void>(async (resolve) => { | ||||
|         let res: AppCustomRouteRecordRaw[] | ||||
|         if (wsCache.get('roleRouters')) { | ||||
|           res = wsCache.get('roleRouters') as AppCustomRouteRecordRaw[] | ||||
|         } else { | ||||
|           res = await getAsyncRoutesApi() | ||||
|           wsCache.set('roleRouters', res) | ||||
|         } | ||||
|         const routerMap: AppRouteRecordRaw[] = generateRoute(res as AppCustomRouteRecordRaw[]) | ||||
|         // 动态路由,404一定要放到最后面 | ||||
|         this.addRouters = routerMap.concat([ | ||||
|           { | ||||
| @ -58,9 +63,6 @@ export const usePermissionStore = defineStore({ | ||||
|         resolve() | ||||
|       }) | ||||
|     }, | ||||
|     setIsAddRouters(state: boolean): void { | ||||
|       this.isAddRouters = state | ||||
|     }, | ||||
|     setMenuTabRouters(routers: AppRouteRecordRaw[]): void { | ||||
|       this.menuTabRouters = routers | ||||
|     } | ||||
|  | ||||
| @ -1,18 +1,19 @@ | ||||
| import { store } from '../index' | ||||
| import { defineStore } from 'pinia' | ||||
| import { getAccessToken } from '@/utils/auth' | ||||
| import { getAccessToken, removeToken } from '@/utils/auth' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
|  | ||||
| const { wsCache } = useCache() | ||||
|  | ||||
| interface UserInfoVO { | ||||
|   permissions: [] | ||||
|   roles: [] | ||||
|   user: { | ||||
|     avatar: string | ||||
| interface UserVO { | ||||
|   id: number | ||||
|   avatar: string | ||||
|   nickname: string | ||||
|   } | ||||
| } | ||||
| interface UserInfoVO { | ||||
|   permissions: string[] | ||||
|   roles: string[] | ||||
|   user: UserVO | ||||
| } | ||||
|  | ||||
| export const useUserStore = defineStore({ | ||||
| @ -26,6 +27,17 @@ export const useUserStore = defineStore({ | ||||
|       nickname: '' | ||||
|     } | ||||
|   }), | ||||
|   getters: { | ||||
|     getPermissions(): string[] { | ||||
|       return this.permissions | ||||
|     }, | ||||
|     getRoles(): string[] { | ||||
|       return this.roles | ||||
|     }, | ||||
|     getUser(): UserVO { | ||||
|       return this.user | ||||
|     } | ||||
|   }, | ||||
|   actions: { | ||||
|     async getUserInfoAction(userInfo: UserInfoVO) { | ||||
|       if (!getAccessToken()) { | ||||
| @ -37,6 +49,11 @@ export const useUserStore = defineStore({ | ||||
|       this.user = userInfo.user | ||||
|       wsCache.set('user', userInfo) | ||||
|     }, | ||||
|     loginOut() { | ||||
|       removeToken() | ||||
|       wsCache.clear() | ||||
|       this.resetState() | ||||
|     }, | ||||
|     resetState() { | ||||
|       this.permissions = [] | ||||
|       this.roles = [] | ||||
|  | ||||
| @ -48,7 +48,7 @@ export const getRawRoute = (route: RouteLocationNormalized): RouteLocationNormal | ||||
| } | ||||
|  | ||||
| // 后端控制路由生成 | ||||
| export const generateRoutes = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => { | ||||
| export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => { | ||||
|   const res: AppRouteRecordRaw[] = [] | ||||
|   const modulesRoutesKeys = Object.keys(modules) | ||||
|   for (const route of routes) { | ||||
| @ -88,7 +88,7 @@ export const generateRoutes = (routes: AppCustomRouteRecordRaw[]): AppRouteRecor | ||||
|       data.component = modules[modulesRoutesKeys[index]] | ||||
|     } | ||||
|     if (route.children) { | ||||
|       data.children = generateRoutes(route.children) | ||||
|       data.children = generateRoute(route.children) | ||||
|     } | ||||
|     res.push(data) | ||||
|   } | ||||
|  | ||||
| @ -21,8 +21,7 @@ import { | ||||
|   getPassword, | ||||
|   getTenantName | ||||
| } from '@/utils/auth' | ||||
| import { useUserStoreWithOut } from '@/store/modules/user' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
| import { useUserStore } from '@/store/modules/user' | ||||
| import { usePermissionStore } from '@/store/modules/permission' | ||||
| import { useRouter } from 'vue-router' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| @ -34,10 +33,9 @@ import { Verify } from '@/components/Verifition' | ||||
|  | ||||
| const { currentRoute, addRoute, push } = useRouter() | ||||
| const permissionStore = usePermissionStore() | ||||
| const userStore = useUserStoreWithOut() | ||||
| const userStore = useUserStore() | ||||
| const formLogin = ref() | ||||
| const { validForm } = useFormValid(formLogin) | ||||
| const { wsCache } = useCache() | ||||
| const { setLoginState, getLoginState } = useLoginState() | ||||
| const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN) | ||||
| const iconSize = 30 | ||||
| @ -122,13 +120,14 @@ const handleLogin = async (params) => { | ||||
| // 获取路由 | ||||
| const getRoutes = async () => { | ||||
|   // 后端过滤菜单 | ||||
|   const res = await LoginApi.getAsyncRoutesApi() | ||||
|   wsCache.set('roleRouters', res) | ||||
|   await permissionStore.generateRoutes(res) | ||||
|   await permissionStore.generateRoutes() | ||||
|   permissionStore.getAddRouters.forEach((route) => { | ||||
|     addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 | ||||
|   }) | ||||
|   permissionStore.setIsAddRouters(true) | ||||
|   if (!redirect.value) { | ||||
|     redirect.value = '/' | ||||
|   } | ||||
|   console.info(redirect.value) | ||||
|   push({ path: redirect.value || permissionStore.addRouters[0].path }) | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -5,18 +5,12 @@ import LoginFormTitle from './LoginFormTitle.vue' | ||||
| import { ElForm, ElFormItem, ElInput, ElRow, ElCol, ElMessage } from 'element-plus' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { required } from '@/utils/formRules' | ||||
| import { | ||||
|   getTenantIdByNameApi, | ||||
|   getAsyncRoutesApi, | ||||
|   sendSmsCodeApi, | ||||
|   smsLoginApi, | ||||
|   getInfoApi | ||||
| } from '@/api/login' | ||||
| import { getTenantIdByNameApi, sendSmsCodeApi, smsLoginApi, getInfoApi } from '@/api/login' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
| import { usePermissionStore } from '@/store/modules/permission' | ||||
| import { useRouter } from 'vue-router' | ||||
| import { setToken } from '@/utils/auth' | ||||
| import { useUserStoreWithOut } from '@/store/modules/user' | ||||
| import { useUserStore } from '@/store/modules/user' | ||||
| import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router' | ||||
| import { useLoginState, LoginStateEnum, useFormValid } from './useLogin' | ||||
| const formSmsLogin = ref() | ||||
| @ -27,7 +21,7 @@ const iconHouse = useIcon({ icon: 'ep:house' }) | ||||
| const iconCellphone = useIcon({ icon: 'ep:cellphone' }) | ||||
| const iconCircleCheck = useIcon({ icon: 'ep:circle-check' }) | ||||
| const { wsCache } = useCache() | ||||
| const userStore = useUserStoreWithOut() | ||||
| const userStore = useUserStore() | ||||
| const permissionStore = usePermissionStore() | ||||
| const { currentRoute, addRoute, push } = useRouter() | ||||
| const loginLoading = ref(false) | ||||
| @ -120,13 +114,10 @@ const signIn = async () => { | ||||
| // 获取路由 | ||||
| const getRoutes = async () => { | ||||
|   // 后端过滤菜单 | ||||
|   const routers = await getAsyncRoutesApi() | ||||
|   wsCache.set('roleRouters', routers) | ||||
|   await permissionStore.generateRoutes(routers).catch(() => {}) | ||||
|   await permissionStore.generateRoutes() | ||||
|   permissionStore.getAddRouters.forEach((route) => { | ||||
|     addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 | ||||
|   }) | ||||
|   permissionStore.setIsAddRouters(true) | ||||
|   push({ path: redirect.value || permissionStore.addRouters[0].path }) | ||||
| } | ||||
| </script> | ||||
|  | ||||
| @ -47,7 +47,8 @@ export const modelSchema = reactive<FormSchema[]>([ | ||||
|   { | ||||
|     label: '显示排序', | ||||
|     field: 'sort', | ||||
|     component: 'InputNumber' | ||||
|     component: 'InputNumber', | ||||
|     value: 0 | ||||
|   }, | ||||
|   { | ||||
|     label: '状态', | ||||
|  | ||||
| @ -253,7 +253,7 @@ onMounted(async () => { | ||||
|     </el-table> | ||||
|   </ContentWrap> | ||||
|   <!-- 添加或修改菜单对话框 --> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle" maxHeight="400px" width="40%"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle" maxHeight="400px" width="45%"> | ||||
|     <el-form | ||||
|       :model="menuForm" | ||||
|       :rules="rules" | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 xingyu
					xingyu