diff --git a/yudao-ui-admin-vue3/.vscode/settings.json b/yudao-ui-admin-vue3/.vscode/settings.json index 7b2554efc..38cc3052a 100644 --- a/yudao-ui-admin-vue3/.vscode/settings.json +++ b/yudao-ui-admin-vue3/.vscode/settings.json @@ -39,5 +39,6 @@ "i18n-ally.sourceLanguage": "en", "i18n-ally.displayLanguage": "zh-CN", "i18n-ally.enabledFrameworks": ["vue", "react"], - "god.tsconfig": "./tsconfig.json" + "god.tsconfig": "./tsconfig.json", + "vue-i18n.i18nPaths": "src/locales" } diff --git a/yudao-ui-admin-vue3/package.json b/yudao-ui-admin-vue3/package.json index ab056d30b..b36f0cfd2 100644 --- a/yudao-ui-admin-vue3/package.json +++ b/yudao-ui-admin-vue3/package.json @@ -38,6 +38,7 @@ "echarts-wordcloud": "^2.0.0", "element-plus": "2.2.18", "intro.js": "^6.0.0", + "js-cookie": "^3.0.1", "jsencrypt": "^3.2.1", "lodash-es": "^4.17.21", "mitt": "^3.0.0", diff --git a/yudao-ui-admin-vue3/src/App.vue b/yudao-ui-admin-vue3/src/App.vue index 08d6b9997..20b5730bf 100644 --- a/yudao-ui-admin-vue3/src/App.vue +++ b/yudao-ui-admin-vue3/src/App.vue @@ -4,7 +4,7 @@ import { useAppStore } from '@/store/modules/app' import { ConfigGlobal } from '@/components/ConfigGlobal' import { isDark } from '@/utils/is' import { useDesign } from '@/hooks/web/useDesign' -import { useCache } from '@/hooks/web/useCache' +import Cookies from 'js-cookie' const { getPrefixCls } = useDesign() @@ -16,18 +16,19 @@ const currentSize = computed(() => appStore.getCurrentSize) const greyMode = computed(() => appStore.getGreyMode) -const { wsCache } = useCache() - // 根据浏览器当前主题设置系统主题色 const setDefaultTheme = () => { - if (wsCache.get('isDark')) { - appStore.setIsDark(wsCache.get('isDark')) + if (Cookies.get('isDark')) { + if (Cookies.get('isDark') === 'true') { + appStore.setIsDark(true) + } else { + appStore.setIsDark(false) + } return } const isDarkTheme = isDark() appStore.setIsDark(isDarkTheme) } - setDefaultTheme() diff --git a/yudao-ui-admin-vue3/src/api/system/user/profile/index.ts b/yudao-ui-admin-vue3/src/api/system/user/profile/index.ts index 3eab59e01..34bbaf8c0 100644 --- a/yudao-ui-admin-vue3/src/api/system/user/profile/index.ts +++ b/yudao-ui-admin-vue3/src/api/system/user/profile/index.ts @@ -16,7 +16,7 @@ export const updateUserProfileApi = (params) => { export const updateUserPwdApi = (oldPassword: string, newPassword: string) => { return request.put({ url: '/system/user/profile/update-password', - params: { + data: { oldPassword: oldPassword, newPassword: newPassword } diff --git a/yudao-ui-admin-vue3/src/config/axios/index.ts b/yudao-ui-admin-vue3/src/config/axios/index.ts index 064cb2268..60dad6aa0 100644 --- a/yudao-ui-admin-vue3/src/config/axios/index.ts +++ b/yudao-ui-admin-vue3/src/config/axios/index.ts @@ -96,6 +96,7 @@ service.interceptors.request.use( service.interceptors.response.use( async (response: AxiosResponse) => { const { data } = response + const config = response.config if (!data) { // 返回“[HTTP]请求没有返回值”; throw new Error() @@ -127,13 +128,13 @@ service.interceptors.response.use( try { const refreshTokenRes = await refreshToken() // 2.1 刷新成功,则回放队列的请求 + 当前请求 - setToken(refreshTokenRes.data) - ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() + setToken(refreshTokenRes.data.data) + config.headers!.Authorization = 'Bearer ' + getAccessToken() requestList.forEach((cb: any) => { cb() }) requestList = [] - return service(response.config) + return service(config) } catch (e) { // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。 // 2.2 刷新失败,只回放队列的请求 @@ -150,8 +151,8 @@ service.interceptors.response.use( // 添加到队列,等待刷新获取到新的令牌 return new Promise((resolve) => { requestList.push(() => { - ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改 - resolve(service(response.config)) + config.headers!.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改 + resolve(service(config)) }) }) } diff --git a/yudao-ui-admin-vue3/src/styles/var.css b/yudao-ui-admin-vue3/src/styles/var.css index 23d8b6824..d0badc16b 100644 --- a/yudao-ui-admin-vue3/src/styles/var.css +++ b/yudao-ui-admin-vue3/src/styles/var.css @@ -65,3 +65,9 @@ --transition-time-02: 0.2s; } + +html, +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/yudao-ui-admin-vue3/src/utils/jsencrypt.ts b/yudao-ui-admin-vue3/src/utils/jsencrypt.ts index c752b2f10..374d5f646 100644 --- a/yudao-ui-admin-vue3/src/utils/jsencrypt.ts +++ b/yudao-ui-admin-vue3/src/utils/jsencrypt.ts @@ -1,4 +1,4 @@ -import { JSEncrypt } from 'jsencrypt/bin/jsencrypt.min' +import { JSEncrypt } from 'jsencrypt' // 密钥对生成 http://web.chacuo.net/netrsakeypair diff --git a/yudao-ui-admin-vue3/src/utils/routerHelper.ts b/yudao-ui-admin-vue3/src/utils/routerHelper.ts index 73e673037..79fd410d8 100644 --- a/yudao-ui-admin-vue3/src/utils/routerHelper.ts +++ b/yudao-ui-admin-vue3/src/utils/routerHelper.ts @@ -65,30 +65,49 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord redirect: route.redirect, meta: meta } - // 目录 - if (route.children) { + //处理顶级非目录路由 + if (!route.children && route.parentId == 0 && route.component) { data.component = Layout - data.redirect = getRedirect(route.path, route.children) - // 外链 - } else if (isUrl(route.path)) { - data = { - path: '/external-link', - component: Layout, - meta: { - name: route.name - }, - children: [data] - } as AppRouteRecordRaw - // 菜单 - } else { - // 对后端传component组件路径和不传做兼容(如果后端传component组件路径,那么path可以随便写,如果不传,component组件路径会根path保持一致) + data.meta = {} + data.name = toCamelCase(route.path, true) + 'Parent' + data.redirect = '' + const childrenData: AppRouteRecordRaw = { + path: '', + name: toCamelCase(route.path, true), + redirect: route.redirect, + meta: meta + } const index = route?.component ? modulesRoutesKeys.findIndex((ev) => ev.includes(route.component)) : modulesRoutesKeys.findIndex((ev) => ev.includes(route.path)) - data.component = modules[modulesRoutesKeys[index]] - } - if (route.children) { - data.children = generateRoute(route.children) + childrenData.component = modules[modulesRoutesKeys[index]] + data.children = [childrenData] + } else { + // 目录 + if (route.children) { + data.component = Layout + data.redirect = getRedirect(route.path, route.children) + // 外链 + } else if (isUrl(route.path)) { + data = { + path: '/external-link', + component: Layout, + meta: { + name: route.name + }, + children: [data] + } as AppRouteRecordRaw + // 菜单 + } else { + // 对后端传component组件路径和不传做兼容(如果后端传component组件路径,那么path可以随便写,如果不传,component组件路径会根path保持一致) + const index = route?.component + ? modulesRoutesKeys.findIndex((ev) => ev.includes(route.component)) + : modulesRoutesKeys.findIndex((ev) => ev.includes(route.path)) + data.component = modules[modulesRoutesKeys[index]] + } + if (route.children) { + data.children = generateRoute(route.children) + } } res.push(data) } diff --git a/yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue b/yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue index 04a4eb8c8..44c13ea39 100644 --- a/yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue +++ b/yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue @@ -13,14 +13,7 @@ import { } from 'element-plus' import { reactive, ref, unref, onMounted, computed, watch } from 'vue' import * as LoginApi from '@/api/login' -import { - setToken, - setTenantId, - getUsername, - getRememberMe, - getPassword, - getTenantName -} from '@/utils/auth' +import { setToken, setTenantId } from '@/utils/auth' import { usePermissionStore } from '@/store/modules/permission' import { useRouter } from 'vue-router' import { useI18n } from '@/hooks/web/useI18n' @@ -29,6 +22,8 @@ import { Icon } from '@/components/Icon' import { LoginStateEnum, useLoginState, useFormValid } from './useLogin' import type { RouteLocationNormalizedLoaded } from 'vue-router' import { Verify } from '@/components/Verifition' +import Cookies from 'js-cookie' +import { decrypt, encrypt } from '@/utils/jsencrypt' const { currentRoute, push } = useRouter() const permissionStore = usePermissionStore() @@ -72,7 +67,7 @@ const captchaType = ref('blockPuzzle') // 获取验证码 const getCode = async () => { // 情况一,未开启:则直接登录 - if (!loginData.captchaEnable) { + if (loginData.captchaEnable === 'false') { await handleLogin({}) return } @@ -88,15 +83,15 @@ const getTenantId = async () => { } // 记住我 const getCookie = () => { - const username = getUsername() - const password = getPassword() - const rememberMe = getRememberMe() - const tenantName = getTenantName() + const username = Cookies.get('username') + const password = Cookies.get('password') ? decrypt(Cookies.get('password')) : undefined + const rememberMe = Cookies.get('rememberMe') + const tenantName = Cookies.get('tenantName') loginData.loginForm = { ...loginData.loginForm, username: username ? username : loginData.loginForm.username, password: password ? password : loginData.loginForm.password, - rememberMe: rememberMe ? getRememberMe() : false, + rememberMe: rememberMe ? true : false, tenantName: tenantName ? tenantName : loginData.loginForm.tenantName } } @@ -114,6 +109,17 @@ const handleLogin = async (params) => { if (!res) { return } + if (loginData.loginForm.rememberMe) { + Cookies.set('username', loginData.loginForm.username, { expires: 30 }) + Cookies.set('password', encrypt(loginData.loginForm.password), { expires: 30 }) + Cookies.set('rememberMe', loginData.loginForm.rememberMe, { expires: 30 }) + Cookies.set('tenantName', loginData.loginForm.tenantName, { expires: 30 }) + } else { + Cookies.remove('username') + Cookies.remove('password') + Cookies.remove('rememberMe') + Cookies.remove('tenantName') + } setToken(res) if (!redirect.value) { redirect.value = '/' diff --git a/yudao-ui-admin-vue3/types/env.d.ts b/yudao-ui-admin-vue3/types/env.d.ts index b42713656..b8cff557a 100644 --- a/yudao-ui-admin-vue3/types/env.d.ts +++ b/yudao-ui-admin-vue3/types/env.d.ts @@ -11,8 +11,8 @@ interface ImportMetaEnv { readonly VITE_APP_TITLE: string readonly VITE_PORT: number readonly VITE_OPEN: boolean - readonly VITE_APP_CAPTCHA_ENABLE: boolean - readonly VITE_APP_TENANT_ENABLE: boolean + readonly VITE_APP_CAPTCHA_ENABLE: string + readonly VITE_APP_TENANT_ENABLE: string readonly VITE_BASE_URL: string readonly VITE_UPLOAD_URL: string readonly VITE_API_BASEPATH: string diff --git a/yudao-ui-admin-vue3/types/router.d.ts b/yudao-ui-admin-vue3/types/router.d.ts index ba24ac588..7cc1c2f3b 100644 --- a/yudao-ui-admin-vue3/types/router.d.ts +++ b/yudao-ui-admin-vue3/types/router.d.ts @@ -74,5 +74,6 @@ declare global { children?: AppCustomRouteRecordRaw[] keepAlive?: boolean visible?: boolean + parentId?: number } }