Commit a33120c5d5f5a3b527d268b6e3d3254283d0cba2

Authored by xingyu4j
2 parents 3cd6bb31 ce33b5c2

Merge remote-tracking branch 'origin/master' into dev

# Conflicts:
#	yudao-ui-admin-vue3/package.json
yudao-ui-admin-vue3/.vscode/settings.json
@@ -39,5 +39,6 @@ @@ -39,5 +39,6 @@
39 "i18n-ally.sourceLanguage": "en", 39 "i18n-ally.sourceLanguage": "en",
40 "i18n-ally.displayLanguage": "zh-CN", 40 "i18n-ally.displayLanguage": "zh-CN",
41 "i18n-ally.enabledFrameworks": ["vue", "react"], 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
@@ -39,6 +39,7 @@ @@ -39,6 +39,7 @@
39 "element-plus": "2.2.19", 39 "element-plus": "2.2.19",
40 "intro.js": "^6.0.0", 40 "intro.js": "^6.0.0",
41 "jsencrypt": "^3.3.0", 41 "jsencrypt": "^3.3.0",
  42 + "js-cookie": "^3.0.1",
42 "lodash-es": "^4.17.21", 43 "lodash-es": "^4.17.21",
43 "mitt": "^3.0.0", 44 "mitt": "^3.0.0",
44 "nprogress": "^0.2.0", 45 "nprogress": "^0.2.0",
yudao-ui-admin-vue3/src/App.vue
@@ -4,7 +4,7 @@ import { useAppStore } from '@/store/modules/app' @@ -4,7 +4,7 @@ import { useAppStore } from '@/store/modules/app'
4 import { ConfigGlobal } from '@/components/ConfigGlobal' 4 import { ConfigGlobal } from '@/components/ConfigGlobal'
5 import { isDark } from '@/utils/is' 5 import { isDark } from '@/utils/is'
6 import { useDesign } from '@/hooks/web/useDesign' 6 import { useDesign } from '@/hooks/web/useDesign'
7 -import { useCache } from '@/hooks/web/useCache' 7 +import Cookies from 'js-cookie'
8 8
9 const { getPrefixCls } = useDesign() 9 const { getPrefixCls } = useDesign()
10 10
@@ -16,18 +16,19 @@ const currentSize = computed(() => appStore.getCurrentSize) @@ -16,18 +16,19 @@ const currentSize = computed(() => appStore.getCurrentSize)
16 16
17 const greyMode = computed(() => appStore.getGreyMode) 17 const greyMode = computed(() => appStore.getGreyMode)
18 18
19 -const { wsCache } = useCache()  
20 -  
21 // 根据浏览器当前主题设置系统主题色 19 // 根据浏览器当前主题设置系统主题色
22 const setDefaultTheme = () => { 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 return 27 return
26 } 28 }
27 const isDarkTheme = isDark() 29 const isDarkTheme = isDark()
28 appStore.setIsDark(isDarkTheme) 30 appStore.setIsDark(isDarkTheme)
29 } 31 }
30 -  
31 setDefaultTheme() 32 setDefaultTheme()
32 </script> 33 </script>
33 34
yudao-ui-admin-vue3/src/api/system/user/profile/index.ts
@@ -16,7 +16,7 @@ export const updateUserProfileApi = (params) =&gt; { @@ -16,7 +16,7 @@ export const updateUserProfileApi = (params) =&gt; {
16 export const updateUserPwdApi = (oldPassword: string, newPassword: string) => { 16 export const updateUserPwdApi = (oldPassword: string, newPassword: string) => {
17 return request.put({ 17 return request.put({
18 url: '/system/user/profile/update-password', 18 url: '/system/user/profile/update-password',
19 - params: { 19 + data: {
20 oldPassword: oldPassword, 20 oldPassword: oldPassword,
21 newPassword: newPassword 21 newPassword: newPassword
22 } 22 }
yudao-ui-admin-vue3/src/config/axios/index.ts
@@ -96,6 +96,7 @@ service.interceptors.request.use( @@ -96,6 +96,7 @@ service.interceptors.request.use(
96 service.interceptors.response.use( 96 service.interceptors.response.use(
97 async (response: AxiosResponse<Recordable>) => { 97 async (response: AxiosResponse<Recordable>) => {
98 const { data } = response 98 const { data } = response
  99 + const config = response.config
99 if (!data) { 100 if (!data) {
100 // 返回“[HTTP]请求没有返回值”; 101 // 返回“[HTTP]请求没有返回值”;
101 throw new Error() 102 throw new Error()
@@ -127,13 +128,13 @@ service.interceptors.response.use( @@ -127,13 +128,13 @@ service.interceptors.response.use(
127 try { 128 try {
128 const refreshTokenRes = await refreshToken() 129 const refreshTokenRes = await refreshToken()
129 // 2.1 刷新成功,则回放队列的请求 + 当前请求 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 requestList.forEach((cb: any) => { 133 requestList.forEach((cb: any) => {
133 cb() 134 cb()
134 }) 135 })
135 requestList = [] 136 requestList = []
136 - return service(response.config) 137 + return service(config)
137 } catch (e) { 138 } catch (e) {
138 // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。 139 // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
139 // 2.2 刷新失败,只回放队列的请求 140 // 2.2 刷新失败,只回放队列的请求
@@ -150,8 +151,8 @@ service.interceptors.response.use( @@ -150,8 +151,8 @@ service.interceptors.response.use(
150 // 添加到队列,等待刷新获取到新的令牌 151 // 添加到队列,等待刷新获取到新的令牌
151 return new Promise((resolve) => { 152 return new Promise((resolve) => {
152 requestList.push(() => { 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
@@ -65,3 +65,9 @@ @@ -65,3 +65,9 @@
65 65
66 --transition-time-02: 0.2s; 66 --transition-time-02: 0.2s;
67 } 67 }
  68 +
  69 +html,
  70 +body {
  71 + -webkit-font-smoothing: antialiased;
  72 + -moz-osx-font-smoothing: grayscale;
  73 +}
yudao-ui-admin-vue3/src/utils/jsencrypt.ts
1 -import { JSEncrypt } from 'jsencrypt/bin/jsencrypt.min' 1 +import { JSEncrypt } from 'jsencrypt'
2 2
3 // 密钥对生成 http://web.chacuo.net/netrsakeypair 3 // 密钥对生成 http://web.chacuo.net/netrsakeypair
4 4
yudao-ui-admin-vue3/src/utils/routerHelper.ts
@@ -65,30 +65,49 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord @@ -65,30 +65,49 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord
65 redirect: route.redirect, 65 redirect: route.redirect,
66 meta: meta 66 meta: meta
67 } 67 }
68 - // 目录  
69 - if (route.children) { 68 + //处理顶级非目录路由
  69 + if (!route.children && route.parentId == 0 && route.component) {
70 data.component = Layout 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 const index = route?.component 80 const index = route?.component
86 ? modulesRoutesKeys.findIndex((ev) => ev.includes(route.component)) 81 ? modulesRoutesKeys.findIndex((ev) => ev.includes(route.component))
87 : modulesRoutesKeys.findIndex((ev) => ev.includes(route.path)) 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 res.push(data) 112 res.push(data)
94 } 113 }
yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue
@@ -13,14 +13,7 @@ import { @@ -13,14 +13,7 @@ import {
13 } from 'element-plus' 13 } from 'element-plus'
14 import { reactive, ref, unref, onMounted, computed, watch } from 'vue' 14 import { reactive, ref, unref, onMounted, computed, watch } from 'vue'
15 import * as LoginApi from '@/api/login' 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 import { usePermissionStore } from '@/store/modules/permission' 17 import { usePermissionStore } from '@/store/modules/permission'
25 import { useRouter } from 'vue-router' 18 import { useRouter } from 'vue-router'
26 import { useI18n } from '@/hooks/web/useI18n' 19 import { useI18n } from '@/hooks/web/useI18n'
@@ -29,6 +22,8 @@ import { Icon } from &#39;@/components/Icon&#39; @@ -29,6 +22,8 @@ import { Icon } from &#39;@/components/Icon&#39;
29 import { LoginStateEnum, useLoginState, useFormValid } from './useLogin' 22 import { LoginStateEnum, useLoginState, useFormValid } from './useLogin'
30 import type { RouteLocationNormalizedLoaded } from 'vue-router' 23 import type { RouteLocationNormalizedLoaded } from 'vue-router'
31 import { Verify } from '@/components/Verifition' 24 import { Verify } from '@/components/Verifition'
  25 +import Cookies from 'js-cookie'
  26 +import { decrypt, encrypt } from '@/utils/jsencrypt'
32 27
33 const { currentRoute, push } = useRouter() 28 const { currentRoute, push } = useRouter()
34 const permissionStore = usePermissionStore() 29 const permissionStore = usePermissionStore()
@@ -72,7 +67,7 @@ const captchaType = ref(&#39;blockPuzzle&#39;) @@ -72,7 +67,7 @@ const captchaType = ref(&#39;blockPuzzle&#39;)
72 // 获取验证码 67 // 获取验证码
73 const getCode = async () => { 68 const getCode = async () => {
74 // 情况一,未开启:则直接登录 69 // 情况一,未开启:则直接登录
75 - if (!loginData.captchaEnable) { 70 + if (loginData.captchaEnable === 'false') {
76 await handleLogin({}) 71 await handleLogin({})
77 return 72 return
78 } 73 }
@@ -88,15 +83,15 @@ const getTenantId = async () =&gt; { @@ -88,15 +83,15 @@ const getTenantId = async () =&gt; {
88 } 83 }
89 // 记住我 84 // 记住我
90 const getCookie = () => { 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 loginData.loginForm = { 90 loginData.loginForm = {
96 ...loginData.loginForm, 91 ...loginData.loginForm,
97 username: username ? username : loginData.loginForm.username, 92 username: username ? username : loginData.loginForm.username,
98 password: password ? password : loginData.loginForm.password, 93 password: password ? password : loginData.loginForm.password,
99 - rememberMe: rememberMe ? getRememberMe() : false, 94 + rememberMe: rememberMe ? true : false,
100 tenantName: tenantName ? tenantName : loginData.loginForm.tenantName 95 tenantName: tenantName ? tenantName : loginData.loginForm.tenantName
101 } 96 }
102 } 97 }
@@ -114,6 +109,17 @@ const handleLogin = async (params) =&gt; { @@ -114,6 +109,17 @@ const handleLogin = async (params) =&gt; {
114 if (!res) { 109 if (!res) {
115 return 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 setToken(res) 123 setToken(res)
118 if (!redirect.value) { 124 if (!redirect.value) {
119 redirect.value = '/' 125 redirect.value = '/'
yudao-ui-admin-vue3/types/env.d.ts
@@ -11,8 +11,8 @@ interface ImportMetaEnv { @@ -11,8 +11,8 @@ interface ImportMetaEnv {
11 readonly VITE_APP_TITLE: string 11 readonly VITE_APP_TITLE: string
12 readonly VITE_PORT: number 12 readonly VITE_PORT: number
13 readonly VITE_OPEN: boolean 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 readonly VITE_BASE_URL: string 16 readonly VITE_BASE_URL: string
17 readonly VITE_UPLOAD_URL: string 17 readonly VITE_UPLOAD_URL: string
18 readonly VITE_API_BASEPATH: string 18 readonly VITE_API_BASEPATH: string
yudao-ui-admin-vue3/types/router.d.ts
@@ -74,5 +74,6 @@ declare global { @@ -74,5 +74,6 @@ declare global {
74 children?: AppCustomRouteRecordRaw[] 74 children?: AppCustomRouteRecordRaw[]
75 keepAlive?: boolean 75 keepAlive?: boolean
76 visible?: boolean 76 visible?: boolean
  77 + parentId?: number
77 } 78 }
78 } 79 }