Commit ce33b5c2197893c5b0e43a3112195bc62cab4f69
Committed by
Gitee
!283 fix:vue3 bug
Merge pull request !283 from weikun/master
Showing
11 changed files
with
86 additions
and
50 deletions
yudao-ui-admin-vue3/.vscode/settings.json
| ... | ... | @@ -39,5 +39,6 @@ |
| 39 | 39 | "i18n-ally.sourceLanguage": "en", |
| 40 | 40 | "i18n-ally.displayLanguage": "zh-CN", |
| 41 | 41 | "i18n-ally.enabledFrameworks": ["vue", "react"], |
| 42 | - "god.tsconfig": "./tsconfig.json" | |
| 42 | + "god.tsconfig": "./tsconfig.json", | |
| 43 | + "vue-i18n.i18nPaths": "src/locales" | |
| 43 | 44 | } | ... | ... |
yudao-ui-admin-vue3/package.json
yudao-ui-admin-vue3/src/App.vue
| ... | ... | @@ -4,7 +4,7 @@ import { useAppStore } from '@/store/modules/app' |
| 4 | 4 | import { ConfigGlobal } from '@/components/ConfigGlobal' |
| 5 | 5 | import { isDark } from '@/utils/is' |
| 6 | 6 | import { useDesign } from '@/hooks/web/useDesign' |
| 7 | -import { useCache } from '@/hooks/web/useCache' | |
| 7 | +import Cookies from 'js-cookie' | |
| 8 | 8 | |
| 9 | 9 | const { getPrefixCls } = useDesign() |
| 10 | 10 | |
| ... | ... | @@ -16,18 +16,19 @@ const currentSize = computed(() => appStore.getCurrentSize) |
| 16 | 16 | |
| 17 | 17 | const greyMode = computed(() => appStore.getGreyMode) |
| 18 | 18 | |
| 19 | -const { wsCache } = useCache() | |
| 20 | - | |
| 21 | 19 | // 根据浏览器当前主题设置系统主题色 |
| 22 | 20 | const setDefaultTheme = () => { |
| 23 | - if (wsCache.get('isDark')) { | |
| 24 | - appStore.setIsDark(wsCache.get('isDark')) | |
| 21 | + if (Cookies.get('isDark')) { | |
| 22 | + if (Cookies.get('isDark') === 'true') { | |
| 23 | + appStore.setIsDark(true) | |
| 24 | + } else { | |
| 25 | + appStore.setIsDark(false) | |
| 26 | + } | |
| 25 | 27 | return |
| 26 | 28 | } |
| 27 | 29 | const isDarkTheme = isDark() |
| 28 | 30 | appStore.setIsDark(isDarkTheme) |
| 29 | 31 | } |
| 30 | - | |
| 31 | 32 | setDefaultTheme() |
| 32 | 33 | </script> |
| 33 | 34 | ... | ... |
yudao-ui-admin-vue3/src/api/system/user/profile/index.ts
| ... | ... | @@ -16,7 +16,7 @@ export const updateUserProfileApi = (params) => { |
| 16 | 16 | export const updateUserPwdApi = (oldPassword: string, newPassword: string) => { |
| 17 | 17 | return request.put({ |
| 18 | 18 | url: '/system/user/profile/update-password', |
| 19 | - params: { | |
| 19 | + data: { | |
| 20 | 20 | oldPassword: oldPassword, |
| 21 | 21 | newPassword: newPassword |
| 22 | 22 | } | ... | ... |
yudao-ui-admin-vue3/src/config/axios/index.ts
| ... | ... | @@ -96,6 +96,7 @@ service.interceptors.request.use( |
| 96 | 96 | service.interceptors.response.use( |
| 97 | 97 | async (response: AxiosResponse<Recordable>) => { |
| 98 | 98 | const { data } = response |
| 99 | + const config = response.config | |
| 99 | 100 | if (!data) { |
| 100 | 101 | // 返回“[HTTP]请求没有返回值”; |
| 101 | 102 | throw new Error() |
| ... | ... | @@ -127,13 +128,13 @@ service.interceptors.response.use( |
| 127 | 128 | try { |
| 128 | 129 | const refreshTokenRes = await refreshToken() |
| 129 | 130 | // 2.1 刷新成功,则回放队列的请求 + 当前请求 |
| 130 | - setToken(refreshTokenRes.data) | |
| 131 | - ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() | |
| 131 | + setToken(refreshTokenRes.data.data) | |
| 132 | + config.headers!.Authorization = 'Bearer ' + getAccessToken() | |
| 132 | 133 | requestList.forEach((cb: any) => { |
| 133 | 134 | cb() |
| 134 | 135 | }) |
| 135 | 136 | requestList = [] |
| 136 | - return service(response.config) | |
| 137 | + return service(config) | |
| 137 | 138 | } catch (e) { |
| 138 | 139 | // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。 |
| 139 | 140 | // 2.2 刷新失败,只回放队列的请求 |
| ... | ... | @@ -150,8 +151,8 @@ service.interceptors.response.use( |
| 150 | 151 | // 添加到队列,等待刷新获取到新的令牌 |
| 151 | 152 | return new Promise((resolve) => { |
| 152 | 153 | requestList.push(() => { |
| 153 | - ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改 | |
| 154 | - resolve(service(response.config)) | |
| 154 | + config.headers!.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改 | |
| 155 | + resolve(service(config)) | |
| 155 | 156 | }) |
| 156 | 157 | }) |
| 157 | 158 | } | ... | ... |
yudao-ui-admin-vue3/src/styles/var.css
yudao-ui-admin-vue3/src/utils/jsencrypt.ts
yudao-ui-admin-vue3/src/utils/routerHelper.ts
| ... | ... | @@ -65,30 +65,49 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord |
| 65 | 65 | redirect: route.redirect, |
| 66 | 66 | meta: meta |
| 67 | 67 | } |
| 68 | - // 目录 | |
| 69 | - if (route.children) { | |
| 68 | + //处理顶级非目录路由 | |
| 69 | + if (!route.children && route.parentId == 0 && route.component) { | |
| 70 | 70 | data.component = Layout |
| 71 | - data.redirect = getRedirect(route.path, route.children) | |
| 72 | - // 外链 | |
| 73 | - } else if (isUrl(route.path)) { | |
| 74 | - data = { | |
| 75 | - path: '/external-link', | |
| 76 | - component: Layout, | |
| 77 | - meta: { | |
| 78 | - name: route.name | |
| 79 | - }, | |
| 80 | - children: [data] | |
| 81 | - } as AppRouteRecordRaw | |
| 82 | - // 菜单 | |
| 83 | - } else { | |
| 84 | - // 对后端传component组件路径和不传做兼容(如果后端传component组件路径,那么path可以随便写,如果不传,component组件路径会根path保持一致) | |
| 71 | + data.meta = {} | |
| 72 | + data.name = toCamelCase(route.path, true) + 'Parent' | |
| 73 | + data.redirect = '' | |
| 74 | + const childrenData: AppRouteRecordRaw = { | |
| 75 | + path: '', | |
| 76 | + name: toCamelCase(route.path, true), | |
| 77 | + redirect: route.redirect, | |
| 78 | + meta: meta | |
| 79 | + } | |
| 85 | 80 | const index = route?.component |
| 86 | 81 | ? modulesRoutesKeys.findIndex((ev) => ev.includes(route.component)) |
| 87 | 82 | : modulesRoutesKeys.findIndex((ev) => ev.includes(route.path)) |
| 88 | - data.component = modules[modulesRoutesKeys[index]] | |
| 89 | - } | |
| 90 | - if (route.children) { | |
| 91 | - data.children = generateRoute(route.children) | |
| 83 | + childrenData.component = modules[modulesRoutesKeys[index]] | |
| 84 | + data.children = [childrenData] | |
| 85 | + } else { | |
| 86 | + // 目录 | |
| 87 | + if (route.children) { | |
| 88 | + data.component = Layout | |
| 89 | + data.redirect = getRedirect(route.path, route.children) | |
| 90 | + // 外链 | |
| 91 | + } else if (isUrl(route.path)) { | |
| 92 | + data = { | |
| 93 | + path: '/external-link', | |
| 94 | + component: Layout, | |
| 95 | + meta: { | |
| 96 | + name: route.name | |
| 97 | + }, | |
| 98 | + children: [data] | |
| 99 | + } as AppRouteRecordRaw | |
| 100 | + // 菜单 | |
| 101 | + } else { | |
| 102 | + // 对后端传component组件路径和不传做兼容(如果后端传component组件路径,那么path可以随便写,如果不传,component组件路径会根path保持一致) | |
| 103 | + const index = route?.component | |
| 104 | + ? modulesRoutesKeys.findIndex((ev) => ev.includes(route.component)) | |
| 105 | + : modulesRoutesKeys.findIndex((ev) => ev.includes(route.path)) | |
| 106 | + data.component = modules[modulesRoutesKeys[index]] | |
| 107 | + } | |
| 108 | + if (route.children) { | |
| 109 | + data.children = generateRoute(route.children) | |
| 110 | + } | |
| 92 | 111 | } |
| 93 | 112 | res.push(data) |
| 94 | 113 | } | ... | ... |
yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue
| ... | ... | @@ -13,14 +13,7 @@ import { |
| 13 | 13 | } from 'element-plus' |
| 14 | 14 | import { reactive, ref, unref, onMounted, computed, watch } from 'vue' |
| 15 | 15 | import * as LoginApi from '@/api/login' |
| 16 | -import { | |
| 17 | - setToken, | |
| 18 | - setTenantId, | |
| 19 | - getUsername, | |
| 20 | - getRememberMe, | |
| 21 | - getPassword, | |
| 22 | - getTenantName | |
| 23 | -} from '@/utils/auth' | |
| 16 | +import { setToken, setTenantId } from '@/utils/auth' | |
| 24 | 17 | import { usePermissionStore } from '@/store/modules/permission' |
| 25 | 18 | import { useRouter } from 'vue-router' |
| 26 | 19 | import { useI18n } from '@/hooks/web/useI18n' |
| ... | ... | @@ -29,6 +22,8 @@ import { Icon } from '@/components/Icon' |
| 29 | 22 | import { LoginStateEnum, useLoginState, useFormValid } from './useLogin' |
| 30 | 23 | import type { RouteLocationNormalizedLoaded } from 'vue-router' |
| 31 | 24 | import { Verify } from '@/components/Verifition' |
| 25 | +import Cookies from 'js-cookie' | |
| 26 | +import { decrypt, encrypt } from '@/utils/jsencrypt' | |
| 32 | 27 | |
| 33 | 28 | const { currentRoute, push } = useRouter() |
| 34 | 29 | const permissionStore = usePermissionStore() |
| ... | ... | @@ -72,7 +67,7 @@ const captchaType = ref('blockPuzzle') |
| 72 | 67 | // 获取验证码 |
| 73 | 68 | const getCode = async () => { |
| 74 | 69 | // 情况一,未开启:则直接登录 |
| 75 | - if (!loginData.captchaEnable) { | |
| 70 | + if (loginData.captchaEnable === 'false') { | |
| 76 | 71 | await handleLogin({}) |
| 77 | 72 | return |
| 78 | 73 | } |
| ... | ... | @@ -88,15 +83,15 @@ const getTenantId = async () => { |
| 88 | 83 | } |
| 89 | 84 | // 记住我 |
| 90 | 85 | const getCookie = () => { |
| 91 | - const username = getUsername() | |
| 92 | - const password = getPassword() | |
| 93 | - const rememberMe = getRememberMe() | |
| 94 | - const tenantName = getTenantName() | |
| 86 | + const username = Cookies.get('username') | |
| 87 | + const password = Cookies.get('password') ? decrypt(Cookies.get('password')) : undefined | |
| 88 | + const rememberMe = Cookies.get('rememberMe') | |
| 89 | + const tenantName = Cookies.get('tenantName') | |
| 95 | 90 | loginData.loginForm = { |
| 96 | 91 | ...loginData.loginForm, |
| 97 | 92 | username: username ? username : loginData.loginForm.username, |
| 98 | 93 | password: password ? password : loginData.loginForm.password, |
| 99 | - rememberMe: rememberMe ? getRememberMe() : false, | |
| 94 | + rememberMe: rememberMe ? true : false, | |
| 100 | 95 | tenantName: tenantName ? tenantName : loginData.loginForm.tenantName |
| 101 | 96 | } |
| 102 | 97 | } |
| ... | ... | @@ -114,6 +109,17 @@ const handleLogin = async (params) => { |
| 114 | 109 | if (!res) { |
| 115 | 110 | return |
| 116 | 111 | } |
| 112 | + if (loginData.loginForm.rememberMe) { | |
| 113 | + Cookies.set('username', loginData.loginForm.username, { expires: 30 }) | |
| 114 | + Cookies.set('password', encrypt(loginData.loginForm.password), { expires: 30 }) | |
| 115 | + Cookies.set('rememberMe', loginData.loginForm.rememberMe, { expires: 30 }) | |
| 116 | + Cookies.set('tenantName', loginData.loginForm.tenantName, { expires: 30 }) | |
| 117 | + } else { | |
| 118 | + Cookies.remove('username') | |
| 119 | + Cookies.remove('password') | |
| 120 | + Cookies.remove('rememberMe') | |
| 121 | + Cookies.remove('tenantName') | |
| 122 | + } | |
| 117 | 123 | setToken(res) |
| 118 | 124 | if (!redirect.value) { |
| 119 | 125 | redirect.value = '/' | ... | ... |
yudao-ui-admin-vue3/types/env.d.ts
| ... | ... | @@ -11,8 +11,8 @@ interface ImportMetaEnv { |
| 11 | 11 | readonly VITE_APP_TITLE: string |
| 12 | 12 | readonly VITE_PORT: number |
| 13 | 13 | readonly VITE_OPEN: boolean |
| 14 | - readonly VITE_APP_CAPTCHA_ENABLE: boolean | |
| 15 | - readonly VITE_APP_TENANT_ENABLE: boolean | |
| 14 | + readonly VITE_APP_CAPTCHA_ENABLE: string | |
| 15 | + readonly VITE_APP_TENANT_ENABLE: string | |
| 16 | 16 | readonly VITE_BASE_URL: string |
| 17 | 17 | readonly VITE_UPLOAD_URL: string |
| 18 | 18 | readonly VITE_API_BASEPATH: string | ... | ... |