Commit b64261a293778d06892b073ca2543e9aac4bbfd5
1 parent
55b63c35
fix: #I5KCI6
Showing
11 changed files
with
94 additions
and
91 deletions
yudao-ui-admin-vue3/src/components/UserInfo/src/UserInfo.vue
| ... | ... | @@ -2,18 +2,10 @@ |
| 2 | 2 | import { ElDropdown, ElDropdownMenu, ElDropdownItem, ElMessageBox } from 'element-plus' |
| 3 | 3 | import { useI18n } from '@/hooks/web/useI18n' |
| 4 | 4 | import { useCache } from '@/hooks/web/useCache' |
| 5 | -import { removeToken } from '@/utils/auth' | |
| 6 | -import { resetRouter } from '@/router' | |
| 7 | 5 | import { useRouter } from 'vue-router' |
| 8 | 6 | import { useDesign } from '@/hooks/web/useDesign' |
| 9 | -import { useTagsViewStore } from '@/store/modules/tagsView' | |
| 10 | 7 | import avatarImg from '@/assets/imgs/avatar.gif' |
| 11 | - | |
| 12 | -const tagsViewStore = useTagsViewStore() | |
| 13 | - | |
| 14 | -const { getPrefixCls } = useDesign() | |
| 15 | - | |
| 16 | -const prefixCls = getPrefixCls('user-info') | |
| 8 | +import { useUserStore } from '@/store/modules/user' | |
| 17 | 9 | |
| 18 | 10 | const { t } = useI18n() |
| 19 | 11 | |
| ... | ... | @@ -21,6 +13,12 @@ const { wsCache } = useCache() |
| 21 | 13 | |
| 22 | 14 | const { push, replace } = useRouter() |
| 23 | 15 | |
| 16 | +const userStore = useUserStore() | |
| 17 | + | |
| 18 | +const { getPrefixCls } = useDesign() | |
| 19 | + | |
| 20 | +const prefixCls = getPrefixCls('user-info') | |
| 21 | + | |
| 24 | 22 | const user = wsCache.get('user') |
| 25 | 23 | |
| 26 | 24 | const avatar = user.user.avatar ? user.user.avatar : avatarImg |
| ... | ... | @@ -34,10 +32,7 @@ const loginOut = () => { |
| 34 | 32 | type: 'warning' |
| 35 | 33 | }) |
| 36 | 34 | .then(async () => { |
| 37 | - resetRouter() // 重置静态路由表 | |
| 38 | - wsCache.clear() | |
| 39 | - removeToken() | |
| 40 | - tagsViewStore.delAllViews() | |
| 35 | + userStore.loginOut() | |
| 41 | 36 | replace('/login') |
| 42 | 37 | }) |
| 43 | 38 | .catch(() => {}) | ... | ... |
yudao-ui-admin-vue3/src/config/axios/index.ts
| ... | ... | @@ -6,6 +6,7 @@ import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } f |
| 6 | 6 | import errorCode from './errorCode' |
| 7 | 7 | import { useI18n } from '@/hooks/web/useI18n' |
| 8 | 8 | import { resetRouter } from '@/router' |
| 9 | +import { useCache } from '@/hooks/web/useCache' | |
| 9 | 10 | |
| 10 | 11 | const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE |
| 11 | 12 | const BASE_URL = import.meta.env.VITE_BASE_URL |
| ... | ... | @@ -205,10 +206,12 @@ const handleAuthorized = () => { |
| 205 | 206 | type: 'warning' |
| 206 | 207 | }) |
| 207 | 208 | .then(() => { |
| 208 | - removeToken() | |
| 209 | + const { wsCache } = useCache() | |
| 209 | 210 | resetRouter() // 重置静态路由表 |
| 211 | + wsCache.clear() | |
| 212 | + removeToken() | |
| 210 | 213 | isRelogin.show = false |
| 211 | - location.href = '/' | |
| 214 | + location.href = '/login' | |
| 212 | 215 | }) |
| 213 | 216 | .catch(() => { |
| 214 | 217 | isRelogin.show = false | ... | ... |
yudao-ui-admin-vue3/src/router/index.ts
| ... | ... | @@ -2,13 +2,13 @@ import type { App } from 'vue' |
| 2 | 2 | import { getAccessToken } from '@/utils/auth' |
| 3 | 3 | import type { RouteRecordRaw } from 'vue-router' |
| 4 | 4 | import remainingRouter from './modules/remaining' |
| 5 | -import { useCache } from '@/hooks/web/useCache' | |
| 6 | 5 | import { useTitle } from '@/hooks/web/useTitle' |
| 7 | 6 | import { useNProgress } from '@/hooks/web/useNProgress' |
| 8 | 7 | import { usePageLoading } from '@/hooks/web/usePageLoading' |
| 9 | 8 | import { createRouter, createWebHashHistory } from 'vue-router' |
| 10 | 9 | import { usePermissionStoreWithOut } from '@/store/modules/permission' |
| 11 | 10 | import { useDictStoreWithOut } from '@/store/modules/dict' |
| 11 | +import { useUserStoreWithOut } from '@/store/modules/user' | |
| 12 | 12 | import { listSimpleDictDataApi } from '@/api/system/dict/dict.data' |
| 13 | 13 | import { isRelogin } from '@/config/axios' |
| 14 | 14 | |
| ... | ... | @@ -16,7 +16,7 @@ const permissionStore = usePermissionStoreWithOut() |
| 16 | 16 | |
| 17 | 17 | const dictStore = useDictStoreWithOut() |
| 18 | 18 | |
| 19 | -const { wsCache } = useCache() | |
| 19 | +const userStore = useUserStoreWithOut() | |
| 20 | 20 | |
| 21 | 21 | const { start, done } = useNProgress() |
| 22 | 22 | |
| ... | ... | @@ -48,31 +48,27 @@ router.beforeEach(async (to, from, next) => { |
| 48 | 48 | if (to.path === '/login') { |
| 49 | 49 | next({ path: '/' }) |
| 50 | 50 | } else { |
| 51 | - if (!dictStore.getIsSetDict) { | |
| 51 | + console.info(3) | |
| 52 | + // 获取所有字典 | |
| 53 | + const res = await listSimpleDictDataApi() | |
| 54 | + dictStore.setDictMap(res) | |
| 55 | + if (userStore.getRoles.length === 0) { | |
| 52 | 56 | isRelogin.show = true |
| 53 | - // 获取所有字典 | |
| 54 | - const res = await listSimpleDictDataApi() | |
| 55 | - dictStore.setDictMap(res) | |
| 56 | - dictStore.setIsSetDict(true) | |
| 57 | - } | |
| 58 | - if (permissionStore.getIsAddRouters) { | |
| 59 | 57 | isRelogin.show = false |
| 58 | + console.info(2) | |
| 59 | + // 后端过滤菜单 | |
| 60 | + await permissionStore.generateRoutes() | |
| 61 | + permissionStore.getAddRouters.forEach((route) => { | |
| 62 | + router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表 | |
| 63 | + }) | |
| 64 | + const redirectPath = from.query.redirect || to.path | |
| 65 | + const redirect = decodeURIComponent(redirectPath as string) | |
| 66 | + const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect } | |
| 67 | + next(nextData) | |
| 68 | + } else { | |
| 69 | + console.info(3) | |
| 60 | 70 | next() |
| 61 | - return | |
| 62 | 71 | } |
| 63 | - // 开发者可根据实际情况进行修改 | |
| 64 | - const roleRouters = wsCache.get('roleRouters') || [] | |
| 65 | - | |
| 66 | - await permissionStore.generateRoutes(roleRouters as AppCustomRouteRecordRaw[]) | |
| 67 | - | |
| 68 | - permissionStore.getAddRouters.forEach((route) => { | |
| 69 | - router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表 | |
| 70 | - }) | |
| 71 | - const redirectPath = from.query.redirect || to.path | |
| 72 | - const redirect = decodeURIComponent(redirectPath as string) | |
| 73 | - const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect } | |
| 74 | - permissionStore.setIsAddRouters(true) | |
| 75 | - next(nextData) | |
| 76 | 72 | } |
| 77 | 73 | } else { |
| 78 | 74 | if (whiteList.indexOf(to.path) !== -1) { | ... | ... |
yudao-ui-admin-vue3/src/store/modules/dict.ts
| ... | ... | @@ -13,14 +13,12 @@ export interface DictTypeType { |
| 13 | 13 | dictValue: DictValueType[] |
| 14 | 14 | } |
| 15 | 15 | export interface DictState { |
| 16 | - isSetDict: boolean | |
| 17 | 16 | dictMap: Recordable |
| 18 | 17 | } |
| 19 | 18 | |
| 20 | 19 | export const useDictStore = defineStore({ |
| 21 | 20 | id: 'dict', |
| 22 | 21 | state: (): DictState => ({ |
| 23 | - isSetDict: false, | |
| 24 | 22 | dictMap: {} |
| 25 | 23 | }), |
| 26 | 24 | persist: { |
| ... | ... | @@ -30,8 +28,12 @@ export const useDictStore = defineStore({ |
| 30 | 28 | getDictMap(): Recordable { |
| 31 | 29 | return this.dictMap |
| 32 | 30 | }, |
| 33 | - getIsSetDict(): boolean { | |
| 34 | - return this.isSetDict | |
| 31 | + getHasDictData(): Boolean { | |
| 32 | + if (this.dictMap.length > 0) { | |
| 33 | + return true | |
| 34 | + } else { | |
| 35 | + return false | |
| 36 | + } | |
| 35 | 37 | } |
| 36 | 38 | }, |
| 37 | 39 | actions: { |
| ... | ... | @@ -53,9 +55,6 @@ export const useDictStore = defineStore({ |
| 53 | 55 | }) |
| 54 | 56 | }) |
| 55 | 57 | this.dictMap = dictMap |
| 56 | - }, | |
| 57 | - setIsSetDict(isSetDict: boolean) { | |
| 58 | - this.isSetDict = isSetDict | |
| 59 | 58 | } |
| 60 | 59 | } |
| 61 | 60 | }) | ... | ... |
yudao-ui-admin-vue3/src/store/modules/permission.ts
| ... | ... | @@ -2,12 +2,15 @@ import { defineStore } from 'pinia' |
| 2 | 2 | import { store } from '../index' |
| 3 | 3 | import { cloneDeep } from 'lodash-es' |
| 4 | 4 | import remainingRouter from '@/router/modules/remaining' |
| 5 | -import { generateRoutes, flatMultiLevelRoutes } from '@/utils/routerHelper' | |
| 5 | +import { generateRoute, flatMultiLevelRoutes } from '@/utils/routerHelper' | |
| 6 | +import { getAsyncRoutesApi } from '@/api/login' | |
| 7 | +import { useCache } from '@/hooks/web/useCache' | |
| 8 | + | |
| 9 | +const { wsCache } = useCache() | |
| 6 | 10 | |
| 7 | 11 | export interface PermissionState { |
| 8 | 12 | routers: AppRouteRecordRaw[] |
| 9 | 13 | addRouters: AppRouteRecordRaw[] |
| 10 | - isAddRouters: boolean | |
| 11 | 14 | menuTabRouters: AppRouteRecordRaw[] |
| 12 | 15 | } |
| 13 | 16 | |
| ... | ... | @@ -16,7 +19,6 @@ export const usePermissionStore = defineStore({ |
| 16 | 19 | state: (): PermissionState => ({ |
| 17 | 20 | routers: [], |
| 18 | 21 | addRouters: [], |
| 19 | - isAddRouters: false, | |
| 20 | 22 | menuTabRouters: [] |
| 21 | 23 | }), |
| 22 | 24 | persist: { |
| ... | ... | @@ -29,18 +31,21 @@ export const usePermissionStore = defineStore({ |
| 29 | 31 | getAddRouters(): AppRouteRecordRaw[] { |
| 30 | 32 | return flatMultiLevelRoutes(cloneDeep(this.addRouters)) |
| 31 | 33 | }, |
| 32 | - getIsAddRouters(): boolean { | |
| 33 | - return this.isAddRouters | |
| 34 | - }, | |
| 35 | 34 | getMenuTabRouters(): AppRouteRecordRaw[] { |
| 36 | 35 | return this.menuTabRouters |
| 37 | 36 | } |
| 38 | 37 | }, |
| 39 | 38 | actions: { |
| 40 | - generateRoutes(routers?: AppCustomRouteRecordRaw[] | string[]): Promise<unknown> { | |
| 41 | - return new Promise<void>((resolve) => { | |
| 42 | - let routerMap: AppRouteRecordRaw[] = [] | |
| 43 | - routerMap = generateRoutes(routers as AppCustomRouteRecordRaw[]) | |
| 39 | + async generateRoutes(): Promise<unknown> { | |
| 40 | + return new Promise<void>(async (resolve) => { | |
| 41 | + let res: AppCustomRouteRecordRaw[] | |
| 42 | + if (wsCache.get('roleRouters')) { | |
| 43 | + res = wsCache.get('roleRouters') as AppCustomRouteRecordRaw[] | |
| 44 | + } else { | |
| 45 | + res = await getAsyncRoutesApi() | |
| 46 | + wsCache.set('roleRouters', res) | |
| 47 | + } | |
| 48 | + const routerMap: AppRouteRecordRaw[] = generateRoute(res as AppCustomRouteRecordRaw[]) | |
| 44 | 49 | // 动态路由,404一定要放到最后面 |
| 45 | 50 | this.addRouters = routerMap.concat([ |
| 46 | 51 | { |
| ... | ... | @@ -58,9 +63,6 @@ export const usePermissionStore = defineStore({ |
| 58 | 63 | resolve() |
| 59 | 64 | }) |
| 60 | 65 | }, |
| 61 | - setIsAddRouters(state: boolean): void { | |
| 62 | - this.isAddRouters = state | |
| 63 | - }, | |
| 64 | 66 | setMenuTabRouters(routers: AppRouteRecordRaw[]): void { |
| 65 | 67 | this.menuTabRouters = routers |
| 66 | 68 | } | ... | ... |
yudao-ui-admin-vue3/src/store/modules/user.ts
| 1 | 1 | import { store } from '../index' |
| 2 | 2 | import { defineStore } from 'pinia' |
| 3 | -import { getAccessToken } from '@/utils/auth' | |
| 3 | +import { getAccessToken, removeToken } from '@/utils/auth' | |
| 4 | 4 | import { useCache } from '@/hooks/web/useCache' |
| 5 | 5 | |
| 6 | 6 | const { wsCache } = useCache() |
| 7 | 7 | |
| 8 | +interface UserVO { | |
| 9 | + id: number | |
| 10 | + avatar: string | |
| 11 | + nickname: string | |
| 12 | +} | |
| 8 | 13 | interface UserInfoVO { |
| 9 | - permissions: [] | |
| 10 | - roles: [] | |
| 11 | - user: { | |
| 12 | - avatar: string | |
| 13 | - id: number | |
| 14 | - nickname: string | |
| 15 | - } | |
| 14 | + permissions: string[] | |
| 15 | + roles: string[] | |
| 16 | + user: UserVO | |
| 16 | 17 | } |
| 17 | 18 | |
| 18 | 19 | export const useUserStore = defineStore({ |
| ... | ... | @@ -26,6 +27,17 @@ export const useUserStore = defineStore({ |
| 26 | 27 | nickname: '' |
| 27 | 28 | } |
| 28 | 29 | }), |
| 30 | + getters: { | |
| 31 | + getPermissions(): string[] { | |
| 32 | + return this.permissions | |
| 33 | + }, | |
| 34 | + getRoles(): string[] { | |
| 35 | + return this.roles | |
| 36 | + }, | |
| 37 | + getUser(): UserVO { | |
| 38 | + return this.user | |
| 39 | + } | |
| 40 | + }, | |
| 29 | 41 | actions: { |
| 30 | 42 | async getUserInfoAction(userInfo: UserInfoVO) { |
| 31 | 43 | if (!getAccessToken()) { |
| ... | ... | @@ -37,6 +49,11 @@ export const useUserStore = defineStore({ |
| 37 | 49 | this.user = userInfo.user |
| 38 | 50 | wsCache.set('user', userInfo) |
| 39 | 51 | }, |
| 52 | + loginOut() { | |
| 53 | + removeToken() | |
| 54 | + wsCache.clear() | |
| 55 | + this.resetState() | |
| 56 | + }, | |
| 40 | 57 | resetState() { |
| 41 | 58 | this.permissions = [] |
| 42 | 59 | this.roles = [] | ... | ... |
yudao-ui-admin-vue3/src/utils/routerHelper.ts
| ... | ... | @@ -48,7 +48,7 @@ export const getRawRoute = (route: RouteLocationNormalized): RouteLocationNormal |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | // 后端控制路由生成 |
| 51 | -export const generateRoutes = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => { | |
| 51 | +export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => { | |
| 52 | 52 | const res: AppRouteRecordRaw[] = [] |
| 53 | 53 | const modulesRoutesKeys = Object.keys(modules) |
| 54 | 54 | for (const route of routes) { |
| ... | ... | @@ -88,7 +88,7 @@ export const generateRoutes = (routes: AppCustomRouteRecordRaw[]): AppRouteRecor |
| 88 | 88 | data.component = modules[modulesRoutesKeys[index]] |
| 89 | 89 | } |
| 90 | 90 | if (route.children) { |
| 91 | - data.children = generateRoutes(route.children) | |
| 91 | + data.children = generateRoute(route.children) | |
| 92 | 92 | } |
| 93 | 93 | res.push(data) |
| 94 | 94 | } | ... | ... |
yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue
| ... | ... | @@ -21,8 +21,7 @@ import { |
| 21 | 21 | getPassword, |
| 22 | 22 | getTenantName |
| 23 | 23 | } from '@/utils/auth' |
| 24 | -import { useUserStoreWithOut } from '@/store/modules/user' | |
| 25 | -import { useCache } from '@/hooks/web/useCache' | |
| 24 | +import { useUserStore } from '@/store/modules/user' | |
| 26 | 25 | import { usePermissionStore } from '@/store/modules/permission' |
| 27 | 26 | import { useRouter } from 'vue-router' |
| 28 | 27 | import { useI18n } from '@/hooks/web/useI18n' |
| ... | ... | @@ -34,10 +33,9 @@ import { Verify } from '@/components/Verifition' |
| 34 | 33 | |
| 35 | 34 | const { currentRoute, addRoute, push } = useRouter() |
| 36 | 35 | const permissionStore = usePermissionStore() |
| 37 | -const userStore = useUserStoreWithOut() | |
| 36 | +const userStore = useUserStore() | |
| 38 | 37 | const formLogin = ref() |
| 39 | 38 | const { validForm } = useFormValid(formLogin) |
| 40 | -const { wsCache } = useCache() | |
| 41 | 39 | const { setLoginState, getLoginState } = useLoginState() |
| 42 | 40 | const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN) |
| 43 | 41 | const iconSize = 30 |
| ... | ... | @@ -122,13 +120,14 @@ const handleLogin = async (params) => { |
| 122 | 120 | // 获取路由 |
| 123 | 121 | const getRoutes = async () => { |
| 124 | 122 | // 后端过滤菜单 |
| 125 | - const res = await LoginApi.getAsyncRoutesApi() | |
| 126 | - wsCache.set('roleRouters', res) | |
| 127 | - await permissionStore.generateRoutes(res) | |
| 123 | + await permissionStore.generateRoutes() | |
| 128 | 124 | permissionStore.getAddRouters.forEach((route) => { |
| 129 | 125 | addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 |
| 130 | 126 | }) |
| 131 | - permissionStore.setIsAddRouters(true) | |
| 127 | + if (!redirect.value) { | |
| 128 | + redirect.value = '/' | |
| 129 | + } | |
| 130 | + console.info(redirect.value) | |
| 132 | 131 | push({ path: redirect.value || permissionStore.addRouters[0].path }) |
| 133 | 132 | } |
| 134 | 133 | ... | ... |
yudao-ui-admin-vue3/src/views/Login/components/MobileForm.vue
| ... | ... | @@ -5,18 +5,12 @@ import LoginFormTitle from './LoginFormTitle.vue' |
| 5 | 5 | import { ElForm, ElFormItem, ElInput, ElRow, ElCol, ElMessage } from 'element-plus' |
| 6 | 6 | import { useI18n } from '@/hooks/web/useI18n' |
| 7 | 7 | import { required } from '@/utils/formRules' |
| 8 | -import { | |
| 9 | - getTenantIdByNameApi, | |
| 10 | - getAsyncRoutesApi, | |
| 11 | - sendSmsCodeApi, | |
| 12 | - smsLoginApi, | |
| 13 | - getInfoApi | |
| 14 | -} from '@/api/login' | |
| 8 | +import { getTenantIdByNameApi, sendSmsCodeApi, smsLoginApi, getInfoApi } from '@/api/login' | |
| 15 | 9 | import { useCache } from '@/hooks/web/useCache' |
| 16 | 10 | import { usePermissionStore } from '@/store/modules/permission' |
| 17 | 11 | import { useRouter } from 'vue-router' |
| 18 | 12 | import { setToken } from '@/utils/auth' |
| 19 | -import { useUserStoreWithOut } from '@/store/modules/user' | |
| 13 | +import { useUserStore } from '@/store/modules/user' | |
| 20 | 14 | import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router' |
| 21 | 15 | import { useLoginState, LoginStateEnum, useFormValid } from './useLogin' |
| 22 | 16 | const formSmsLogin = ref() |
| ... | ... | @@ -27,7 +21,7 @@ const iconHouse = useIcon({ icon: 'ep:house' }) |
| 27 | 21 | const iconCellphone = useIcon({ icon: 'ep:cellphone' }) |
| 28 | 22 | const iconCircleCheck = useIcon({ icon: 'ep:circle-check' }) |
| 29 | 23 | const { wsCache } = useCache() |
| 30 | -const userStore = useUserStoreWithOut() | |
| 24 | +const userStore = useUserStore() | |
| 31 | 25 | const permissionStore = usePermissionStore() |
| 32 | 26 | const { currentRoute, addRoute, push } = useRouter() |
| 33 | 27 | const loginLoading = ref(false) |
| ... | ... | @@ -120,13 +114,10 @@ const signIn = async () => { |
| 120 | 114 | // 获取路由 |
| 121 | 115 | const getRoutes = async () => { |
| 122 | 116 | // 后端过滤菜单 |
| 123 | - const routers = await getAsyncRoutesApi() | |
| 124 | - wsCache.set('roleRouters', routers) | |
| 125 | - await permissionStore.generateRoutes(routers).catch(() => {}) | |
| 117 | + await permissionStore.generateRoutes() | |
| 126 | 118 | permissionStore.getAddRouters.forEach((route) => { |
| 127 | 119 | addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 |
| 128 | 120 | }) |
| 129 | - permissionStore.setIsAddRouters(true) | |
| 130 | 121 | push({ path: redirect.value || permissionStore.addRouters[0].path }) |
| 131 | 122 | } |
| 132 | 123 | </script> | ... | ... |
yudao-ui-admin-vue3/src/views/system/dept/dept.data.ts
yudao-ui-admin-vue3/src/views/system/menu/index.vue
| ... | ... | @@ -253,7 +253,7 @@ onMounted(async () => { |
| 253 | 253 | </el-table> |
| 254 | 254 | </ContentWrap> |
| 255 | 255 | <!-- 添加或修改菜单对话框 --> |
| 256 | - <Dialog v-model="dialogVisible" :title="dialogTitle" maxHeight="400px" width="40%"> | |
| 256 | + <Dialog v-model="dialogVisible" :title="dialogTitle" maxHeight="400px" width="45%"> | |
| 257 | 257 | <el-form |
| 258 | 258 | :model="menuForm" |
| 259 | 259 | :rules="rules" | ... | ... |