mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-10-31 00:57:11 +08:00 
			
		
		
		
	feat:新增密码过期修改页面逻辑
This commit is contained in:
		| @@ -14,6 +14,7 @@ export type FormType = | |||||||
|   | 'slider' |   | 'slider' | ||||||
|   | 'cascader' |   | 'cascader' | ||||||
|   | 'tree-select' |   | 'tree-select' | ||||||
|  |   | 'input-password' | ||||||
|  |  | ||||||
| export type ColumnsItemPropsKey = | export type ColumnsItemPropsKey = | ||||||
|   | keyof A.InputInstance['$props'] |   | keyof A.InputInstance['$props'] | ||||||
|   | |||||||
| @@ -146,32 +146,7 @@ const logout = () => { | |||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  |  | ||||||
| const checkPasswordExpired = () => { |  | ||||||
|   if (!userStore.pwdExpiredShow || !userStore.userInfo.pwdExpired) { |  | ||||||
|     return |  | ||||||
|   } |  | ||||||
|   Modal.confirm({ |  | ||||||
|     title: '提示', |  | ||||||
|     content: '密码已过期,需要跳转到修改密码页面?', |  | ||||||
|     hideCancel: false, |  | ||||||
|     closable: true, |  | ||||||
|     onBeforeOk: async () => { |  | ||||||
|       try { |  | ||||||
|         await router.push({ path: '/setting/profile' }) |  | ||||||
|         return true |  | ||||||
|       } catch (error) { |  | ||||||
|         return false |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     onCancel: () => { |  | ||||||
|       // 当前登录会话不再提示 |  | ||||||
|       userStore.pwdExpiredShow = false |  | ||||||
|     } |  | ||||||
|   }) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| onMounted(() => { | onMounted(() => { | ||||||
|   checkPasswordExpired() |  | ||||||
|   getMessageCount() |   getMessageCount() | ||||||
| }) | }) | ||||||
| </script> | </script> | ||||||
|   | |||||||
| @@ -53,6 +53,11 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||||||
|     component: () => import('@/views/login/social/index.vue'), |     component: () => import('@/views/login/social/index.vue'), | ||||||
|     meta: { hidden: true } |     meta: { hidden: true } | ||||||
|   }, |   }, | ||||||
|  |   { | ||||||
|  |     path: '/pwdExpired', | ||||||
|  |     component: () => import('@/views/login/pwdExpired/index.vue'), | ||||||
|  |     meta: { hidden: true } | ||||||
|  |   }, | ||||||
|   { |   { | ||||||
|     path: '/setting', |     path: '/setting', | ||||||
|     name: 'Setting', |     name: 'Setting', | ||||||
|   | |||||||
| @@ -1,10 +1,11 @@ | |||||||
|  | import { Message } from '@arco-design/web-vue' | ||||||
| import router from '@/router' | import router from '@/router' | ||||||
| import { useRouteStore, useUserStore } from '@/stores' | import { useRouteStore, useUserStore } from '@/stores' | ||||||
| import { getToken } from '@/utils/auth' | import { getToken } from '@/utils/auth' | ||||||
| import { isHttp } from '@/utils/validate' | import { isHttp } from '@/utils/validate' | ||||||
|  |  | ||||||
| /** 免登录白名单 */ | /** 免登录白名单 */ | ||||||
| const whiteList = ['/login', '/social/callback'] | const whiteList = ['/login', '/social/callback', '/pwdExpired'] | ||||||
|  |  | ||||||
| /** 是否已经生成过路由表 */ | /** 是否已经生成过路由表 */ | ||||||
| let hasRouteFlag = false | let hasRouteFlag = false | ||||||
| @@ -25,6 +26,10 @@ router.beforeEach(async (to, from, next) => { | |||||||
|       if (!hasRouteFlag) { |       if (!hasRouteFlag) { | ||||||
|         try { |         try { | ||||||
|           await userStore.getInfo() |           await userStore.getInfo() | ||||||
|  |           if (userStore.userInfo.pwdExpired && to.path !== '/pwdExpired') { | ||||||
|  |             Message.warning('密码已过期,请修改密码') | ||||||
|  |             next('/pwdExpired') | ||||||
|  |           } | ||||||
|           const accessRoutes = await routeStore.generateRoutes() |           const accessRoutes = await routeStore.generateRoutes() | ||||||
|           accessRoutes.forEach((route) => { |           accessRoutes.forEach((route) => { | ||||||
|             if (!isHttp(route.path)) { |             if (!isHttp(route.path)) { | ||||||
|   | |||||||
| @@ -1,13 +1,6 @@ | |||||||
| <template> | <template> | ||||||
|   <a-form |   <a-form ref="formRef" :model="form" :rules="rules" :label-col-style="{ display: 'none' }" | ||||||
|     ref="formRef" |     :wrapper-col-style="{ flex: 1 }" size="large" @submit="handleLogin"> | ||||||
|     :model="form" |  | ||||||
|     :rules="rules" |  | ||||||
|     :label-col-style="{ display: 'none' }" |  | ||||||
|     :wrapper-col-style="{ flex: 1 }" |  | ||||||
|     size="large" |  | ||||||
|     @submit="handleLogin" |  | ||||||
|   > |  | ||||||
|     <a-form-item field="username" hide-label> |     <a-form-item field="username" hide-label> | ||||||
|       <a-input v-model="form.username" placeholder="请输入用户名" allow-clear /> |       <a-input v-model="form.username" placeholder="请输入用户名" allow-clear /> | ||||||
|     </a-form-item> |     </a-form-item> | ||||||
|   | |||||||
							
								
								
									
										128
									
								
								src/views/login/components/modifyPassword/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/views/login/components/modifyPassword/index.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | |||||||
|  | <template> | ||||||
|  |   <a-form ref="formRef" :model="form" :rules="rules" layout="vertical" :label-col-style="{ lineHeight: '10px' }" | ||||||
|  |     :wrapper-col-style="{ flex: 1 }" size="large" @submit="onModify"> | ||||||
|  |     <a-form-item field="oldPassword" label="当前密码"> | ||||||
|  |       <a-input-password v-model="form.oldPassword" placeholder="请输入当前密码" allow-clear /> | ||||||
|  |     </a-form-item> | ||||||
|  |     <a-form-item field="newPassword" label="新密码"> | ||||||
|  |       <a-input-password v-model="form.newPassword" placeholder="请输入新密码" allow-clear /> | ||||||
|  |     </a-form-item> | ||||||
|  |     <a-form-item field="confirmPassword" label="确认密码"> | ||||||
|  |       <a-input-password v-model="form.confirmPassword" placeholder="请再次输入新密码" allow-clear /> | ||||||
|  |     </a-form-item> | ||||||
|  |     <a-form-item> | ||||||
|  |       <a-space direction="vertical" fill class="w-full"> | ||||||
|  |         <a-button class="btn" type="primary" :loading="loading" html-type="submit" size="large" long> | ||||||
|  |           立即修改 | ||||||
|  |         </a-button> | ||||||
|  |       </a-space> | ||||||
|  |     </a-form-item> | ||||||
|  |   </a-form> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import { type FormInstance, Message } from '@arco-design/web-vue' | ||||||
|  | import { updateUserPassword } from '@/apis' | ||||||
|  | import { encryptByRsa } from '@/utils/encrypt' | ||||||
|  |  | ||||||
|  | interface Form { | ||||||
|  |   oldPassword: string | ||||||
|  |   newPassword: string | ||||||
|  |   confirmPassword?: string | ||||||
|  | } | ||||||
|  | const formRef = ref<FormInstance>() | ||||||
|  | const form = reactive<Form>({ | ||||||
|  |   oldPassword: '', | ||||||
|  |   newPassword: '', | ||||||
|  |   confirmPassword: '' | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | const rules: FormInstance['rules'] = { | ||||||
|  |   oldPassword: [ | ||||||
|  |     { required: true, message: '请输入当前密码' } | ||||||
|  |   ], | ||||||
|  |   newPassword: [{ required: true, message: '请输入新密码' }, { | ||||||
|  |     validator: (value, cd) => { | ||||||
|  |       return new Promise((resolve) => { | ||||||
|  |         if (value === form.oldPassword) { | ||||||
|  |           cd('新密码不能与旧密码相同') | ||||||
|  |         } | ||||||
|  |         resolve(true) | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }], | ||||||
|  |   confirmPassword: [{ required: true, message: '请再次输入新密码' }, { | ||||||
|  |     validator: (value, cd) => { | ||||||
|  |       return new Promise((resolve) => { | ||||||
|  |         if (value !== form.newPassword) { | ||||||
|  |           cd('两次密码不一致') | ||||||
|  |         } | ||||||
|  |         resolve(true) | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }] | ||||||
|  | } | ||||||
|  | const router = useRouter() | ||||||
|  | const loading = ref(false) | ||||||
|  |  | ||||||
|  | // 登录 | ||||||
|  | const onModify = async () => { | ||||||
|  |   const isInvalid = await formRef.value?.validate() | ||||||
|  |   if (isInvalid) return | ||||||
|  |   try { | ||||||
|  |     loading.value = true | ||||||
|  |     const params = { | ||||||
|  |       oldPassword: encryptByRsa(form.oldPassword) || '', | ||||||
|  |       newPassword: encryptByRsa(form.newPassword) || '' | ||||||
|  |     } | ||||||
|  |     await updateUserPassword(params) | ||||||
|  |     router.push({ | ||||||
|  |       path: '/login' | ||||||
|  |     }) | ||||||
|  |     Message.success('修改成功') | ||||||
|  |   } catch (error) { | ||||||
|  |  | ||||||
|  |   } finally { | ||||||
|  |     loading.value = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .arco-input-wrapper, | ||||||
|  | :deep(.arco-select-view-single) { | ||||||
|  |   height: 40px; | ||||||
|  |   border-radius: 4px; | ||||||
|  |   font-size: 13px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .arco-input-wrapper.arco-input-error { | ||||||
|  |   background-color: rgb(var(--danger-1)); | ||||||
|  |   border-color: rgb(var(--danger-3)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .arco-input-wrapper.arco-input-error:hover { | ||||||
|  |   background-color: rgb(var(--danger-1)); | ||||||
|  |   border-color: rgb(var(--danger-6)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .arco-input-wrapper :deep(.arco-input) { | ||||||
|  |   font-size: 13px; | ||||||
|  |   color: var(--color-text-1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .arco-input-wrapper:hover { | ||||||
|  |   border-color: rgb(var(--arcoblue-6)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .captcha-btn { | ||||||
|  |   height: 40px; | ||||||
|  |   margin-left: 12px; | ||||||
|  |   min-width: 98px; | ||||||
|  |   border-radius: 4px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .btn { | ||||||
|  |   height: 40px; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										414
									
								
								src/views/login/pwdExpired/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								src/views/login/pwdExpired/index.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,414 @@ | |||||||
|  | <template> | ||||||
|  |     <div class="login pc"> | ||||||
|  |         <h3 class="login-logo"> | ||||||
|  |             <img v-if="logo" :src="logo" alt="logo" /> | ||||||
|  |             <img v-else src="/logo.svg" alt="logo" /> | ||||||
|  |             <span>{{ title }}</span> | ||||||
|  |         </h3> | ||||||
|  |  | ||||||
|  |         <a-row align="stretch" class="login-box"> | ||||||
|  |             <a-col :xs="0" :sm="12" :md="13"> | ||||||
|  |                 <div class="login-left"> | ||||||
|  |                     <img class="login-left__img" src="@/assets/images/banner.png" alt="banner" /> | ||||||
|  |                 </div> | ||||||
|  |             </a-col> | ||||||
|  |             <a-col :xs="24" :sm="12" :md="11"> | ||||||
|  |                 <div class="login-right"> | ||||||
|  |                     <a-tabs class="login-right__form"> | ||||||
|  |                         <template #extra> | ||||||
|  |                             <span style="color: red;">密码已过期,请修改密码</span> | ||||||
|  |                         </template> | ||||||
|  |                         <a-tab-pane key="1" title="密码修改"> | ||||||
|  |                             <span></span> | ||||||
|  |                             <ModifyPassword /> | ||||||
|  |                         </a-tab-pane> | ||||||
|  |                     </a-tabs> | ||||||
|  |                 </div> | ||||||
|  |             </a-col> | ||||||
|  |         </a-row> | ||||||
|  |  | ||||||
|  |         <div v-if="isDesktop" class="footer"> | ||||||
|  |             <div class="beian"> | ||||||
|  |                 <div class="below text"> | ||||||
|  |                     {{ appStore.getCopyright() }}{{ appStore.getForRecord() ? ` · | ||||||
|  |                     ${appStore.getForRecord()}` : '' }} | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |  | ||||||
|  |         <GiThemeBtn class="theme-btn" /> | ||||||
|  |         <Background /> | ||||||
|  |     </div> | ||||||
|  |     <div class="login h5"> | ||||||
|  |         <div class="login-logo"> | ||||||
|  |             <img v-if="logo" :src="logo" alt="logo" /> | ||||||
|  |             <img v-else src="/logo.svg" alt="logo" /> | ||||||
|  |             <span>{{ title }}</span> | ||||||
|  |         </div> | ||||||
|  |         <a-row align="stretch" class="login-box"> | ||||||
|  |             <a-col :xs="24" :sm="12" :md="11"> | ||||||
|  |                 <div class="login-right"> | ||||||
|  |                     <a-tabs class="login-right__form"> | ||||||
|  |                         <template #extra> | ||||||
|  |                             <span style="color: red;">密码已过期,请修改密码</span> | ||||||
|  |                         </template> | ||||||
|  |                         <a-tab-pane key="1" title="密码修改"> | ||||||
|  |                             <ModifyPassword /> | ||||||
|  |                         </a-tab-pane> | ||||||
|  |                     </a-tabs> | ||||||
|  |                 </div> | ||||||
|  |             </a-col> | ||||||
|  |         </a-row> | ||||||
|  |     </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import Background from '../components/background/index.vue' | ||||||
|  | import ModifyPassword from '../components/modifyPassword/index.vue' | ||||||
|  | import { useAppStore } from '@/stores' | ||||||
|  | import { useDevice } from '@/hooks' | ||||||
|  |  | ||||||
|  | defineOptions({ name: 'PwdExpired' }) | ||||||
|  |  | ||||||
|  | const { isDesktop } = useDevice() | ||||||
|  | const appStore = useAppStore() | ||||||
|  | const title = computed(() => appStore.getTitle()) | ||||||
|  | const logo = computed(() => appStore.getLogo()) | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | @media screen and (max-width: 570px) { | ||||||
|  |     .pc { | ||||||
|  |         display: none !important; | ||||||
|  |         background-color: white !important; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .login { | ||||||
|  |         height: 100%; | ||||||
|  |         display: flex; | ||||||
|  |         flex-direction: column; | ||||||
|  |         justify-content: start; | ||||||
|  |         align-items: center; | ||||||
|  |         background-color: var(--color-bg-5); | ||||||
|  |         color: #121314; | ||||||
|  |  | ||||||
|  |         &-logo { | ||||||
|  |             width: 100%; | ||||||
|  |             height: 104px; | ||||||
|  |             font-weight: 700; | ||||||
|  |             font-size: 20px; | ||||||
|  |             line-height: 32px; | ||||||
|  |             display: flex; | ||||||
|  |             padding: 0 20px; | ||||||
|  |             align-items: center; | ||||||
|  |             justify-content: start; | ||||||
|  |             background-image: url('/src/assets/images/login_h5.jpg'); | ||||||
|  |             background-size: 100% 100%; | ||||||
|  |             box-sizing: border-box; | ||||||
|  |  | ||||||
|  |             img { | ||||||
|  |                 width: 34px; | ||||||
|  |                 height: 34px; | ||||||
|  |                 margin-right: 8px; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         &-box { | ||||||
|  |             width: 100%; | ||||||
|  |             display: flex; | ||||||
|  |             z-index: 999; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .login-right { | ||||||
|  |         width: 100%; | ||||||
|  |         height: 100%; | ||||||
|  |         display: flex; | ||||||
|  |         flex-direction: column; | ||||||
|  |         padding: 30px 30px 0; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |  | ||||||
|  |         &__title { | ||||||
|  |             color: var(--color-text-1); | ||||||
|  |             font-weight: 500; | ||||||
|  |             font-size: 20px; | ||||||
|  |             line-height: 32px; | ||||||
|  |             margin-bottom: 20px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         &__form { | ||||||
|  |             :deep(.arco-tabs-nav-tab) { | ||||||
|  |                 display: flex; | ||||||
|  |                 justify-content: start; | ||||||
|  |                 align-items: center; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab) { | ||||||
|  |                 color: var(--color-text-2); | ||||||
|  |                 margin: 0 20px 0 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab-title) { | ||||||
|  |                 font-size: 16px; | ||||||
|  |                 font-weight: 500; | ||||||
|  |                 line-height: 22px; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-content) { | ||||||
|  |                 margin-top: 10px; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab-active), | ||||||
|  |             :deep(.arco-tabs-tab-title:hover) { | ||||||
|  |                 color: rgb(var(--arcoblue-6)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-nav::before) { | ||||||
|  |                 display: none; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab-title:before) { | ||||||
|  |                 display: none; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .theme-btn { | ||||||
|  |         position: fixed; | ||||||
|  |         top: 20px; | ||||||
|  |         right: 30px; | ||||||
|  |         z-index: 9999; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .footer { | ||||||
|  |         align-items: center; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |         position: absolute; | ||||||
|  |         bottom: 10px; | ||||||
|  |         z-index: 999; | ||||||
|  |  | ||||||
|  |         .beian { | ||||||
|  |             .text { | ||||||
|  |                 font-size: 12px; | ||||||
|  |                 font-weight: 400; | ||||||
|  |                 letter-spacing: 0.2px; | ||||||
|  |                 line-height: 20px; | ||||||
|  |                 text-align: center; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             .below { | ||||||
|  |                 align-items: center; | ||||||
|  |                 display: flex; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @media screen and (min-width: 571px) { | ||||||
|  |     .h5 { | ||||||
|  |         display: none !important; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .login { | ||||||
|  |         height: 100%; | ||||||
|  |         display: flex; | ||||||
|  |         flex-direction: column; | ||||||
|  |         justify-content: center; | ||||||
|  |         align-items: center; | ||||||
|  |         background-color: var(--color-bg-5); | ||||||
|  |  | ||||||
|  |         &-logo { | ||||||
|  |             position: fixed; | ||||||
|  |             top: 20px; | ||||||
|  |             left: 30px; | ||||||
|  |             z-index: 9999; | ||||||
|  |             color: var(--color-text-1); | ||||||
|  |             font-weight: 500; | ||||||
|  |             font-size: 20px; | ||||||
|  |             line-height: 32px; | ||||||
|  |             margin-bottom: 20px; | ||||||
|  |             display: flex; | ||||||
|  |             justify-content: center; | ||||||
|  |             align-items: center; | ||||||
|  |  | ||||||
|  |             img { | ||||||
|  |                 width: 34px; | ||||||
|  |                 height: 34px; | ||||||
|  |                 margin-right: 8px; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         &-box { | ||||||
|  |             width: 86%; | ||||||
|  |             max-width: 850px; | ||||||
|  |             height: 490px; | ||||||
|  |             display: flex; | ||||||
|  |             z-index: 999; | ||||||
|  |             box-shadow: 0 2px 4px 2px rgba(0, 0, 0, 0.08); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .login-left { | ||||||
|  |         width: 100%; | ||||||
|  |         height: 100%; | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: center; | ||||||
|  |         align-items: center; | ||||||
|  |         position: relative; | ||||||
|  |         overflow: hidden; | ||||||
|  |         background: linear-gradient(60deg, rgb(var(--primary-6)), rgb(var(--primary-3))); | ||||||
|  |  | ||||||
|  |         &__img { | ||||||
|  |             width: 100%; | ||||||
|  |             position: absolute; | ||||||
|  |             bottom: 0; | ||||||
|  |             right: 0; | ||||||
|  |             top: 50%; | ||||||
|  |             left: 50%; | ||||||
|  |             transform: translateX(-50%) translateY(-50%); | ||||||
|  |             transition: all 0.3s; | ||||||
|  |             object-fit: cover; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .login-right { | ||||||
|  |         width: 100%; | ||||||
|  |         height: 100%; | ||||||
|  |         background: var(--color-bg-1); | ||||||
|  |         display: flex; | ||||||
|  |         flex-direction: column; | ||||||
|  |         padding: 30px 30px 0; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |  | ||||||
|  |         &__title { | ||||||
|  |             color: var(--color-text-1); | ||||||
|  |             font-weight: 500; | ||||||
|  |             font-size: 20px; | ||||||
|  |             line-height: 32px; | ||||||
|  |             margin-bottom: 20px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         &__form { | ||||||
|  |             :deep(.arco-tabs-nav-tab) { | ||||||
|  |                 display: flex; | ||||||
|  |                 // justify-content: center; | ||||||
|  |                 align-items: center; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab) { | ||||||
|  |                 color: var(--color-text-2); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab-title) { | ||||||
|  |                 font-size: 16px; | ||||||
|  |                 font-weight: 500; | ||||||
|  |                 line-height: 22px; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-content) { | ||||||
|  |                 margin-top: 10px; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab-active), | ||||||
|  |             :deep(.arco-tabs-tab-title:hover) { | ||||||
|  |                 color: rgb(var(--arcoblue-6)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-nav::before) { | ||||||
|  |                 display: none; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             :deep(.arco-tabs-tab-title:before) { | ||||||
|  |                 display: none; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         &__oauth { | ||||||
|  |             margin-top: auto; | ||||||
|  |             margin-bottom: 20px; | ||||||
|  |  | ||||||
|  |             :deep(.arco-divider-text) { | ||||||
|  |                 color: var(--color-text-4); | ||||||
|  |                 font-size: 12px; | ||||||
|  |                 font-weight: 400; | ||||||
|  |                 line-height: 20px; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             .list { | ||||||
|  |                 align-items: center; | ||||||
|  |                 display: flex; | ||||||
|  |                 justify-content: center; | ||||||
|  |                 width: 100%; | ||||||
|  |  | ||||||
|  |                 .item { | ||||||
|  |                     margin-right: 15px; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 .mode { | ||||||
|  |                     color: var(--color-text-2); | ||||||
|  |                     font-size: 12px; | ||||||
|  |                     font-weight: 400; | ||||||
|  |                     line-height: 20px; | ||||||
|  |                     padding: 6px 10px; | ||||||
|  |                     align-items: center; | ||||||
|  |                     border: 1px solid var(--color-border-3); | ||||||
|  |                     border-radius: 32px; | ||||||
|  |                     box-sizing: border-box; | ||||||
|  |                     display: flex; | ||||||
|  |                     height: 32px; | ||||||
|  |                     justify-content: center; | ||||||
|  |                     cursor: pointer; | ||||||
|  |  | ||||||
|  |                     .icon { | ||||||
|  |                         width: 21px; | ||||||
|  |                         height: 20px; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 .mode svg { | ||||||
|  |                     font-size: 16px; | ||||||
|  |                     margin-right: 10px; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 .mode:hover, | ||||||
|  |                 .mode svg:hover { | ||||||
|  |                     background: rgba(var(--primary-6), 0.05); | ||||||
|  |                     border: 1px solid rgb(var(--primary-3)); | ||||||
|  |                     color: rgb(var(--arcoblue-6)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .theme-btn { | ||||||
|  |         position: fixed; | ||||||
|  |         top: 20px; | ||||||
|  |         right: 30px; | ||||||
|  |         z-index: 9999; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .footer { | ||||||
|  |         align-items: center; | ||||||
|  |         box-sizing: border-box; | ||||||
|  |         position: absolute; | ||||||
|  |         bottom: 10px; | ||||||
|  |         z-index: 999; | ||||||
|  |  | ||||||
|  |         .beian { | ||||||
|  |             .text { | ||||||
|  |                 font-size: 12px; | ||||||
|  |                 font-weight: 400; | ||||||
|  |                 letter-spacing: 0.2px; | ||||||
|  |                 line-height: 20px; | ||||||
|  |                 text-align: center; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             .below { | ||||||
|  |                 align-items: center; | ||||||
|  |                 display: flex; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -1,35 +1,17 @@ | |||||||
| <template> | <template> | ||||||
|   <a-modal |   <a-modal v-model:visible="visible" :title="title" :mask-closable="false" :esc-to-close="false" | ||||||
|     v-model:visible="visible" |     :width="width >= 500 ? 500 : '100%'" draggable @before-ok="save" @close="reset"> | ||||||
|     :title="title" |  | ||||||
|     :mask-closable="false" |  | ||||||
|     :esc-to-close="false" |  | ||||||
|     :width="width >= 500 ? 500 : '100%'" |  | ||||||
|     draggable |  | ||||||
|     @before-ok="save" |  | ||||||
|     @close="reset" |  | ||||||
|   > |  | ||||||
|     <GiForm ref="formRef" v-model="form" :options="options" :columns="columns"> |     <GiForm ref="formRef" v-model="form" :options="options" :columns="columns"> | ||||||
|       <template #captcha> |       <template #captcha> | ||||||
|         <a-input v-model="form.captcha" placeholder="请输入验证码" :max-length="6" allow-clear style="flex: 1 1" /> |         <a-input v-model="form.captcha" placeholder="请输入验证码" :max-length="6" allow-clear style="flex: 1 1" /> | ||||||
|         <a-button |         <a-button class="captcha-btn" :loading="captchaLoading" :disabled="captchaDisable" size="large" | ||||||
|           class="captcha-btn" |           @click="onCaptcha"> | ||||||
|           :loading="captchaLoading" |  | ||||||
|           :disabled="captchaDisable" |  | ||||||
|           size="large" |  | ||||||
|           @click="onCaptcha" |  | ||||||
|         > |  | ||||||
|           {{ captchaBtnName }} |           {{ captchaBtnName }} | ||||||
|         </a-button> |         </a-button> | ||||||
|       </template> |       </template> | ||||||
|     </GiForm> |     </GiForm> | ||||||
|     <Verify |     <Verify ref="VerifyRef" :captcha-type="captchaType" :mode="captchaMode" | ||||||
|       ref="VerifyRef" |       :img-size="{ width: '330px', height: '155px' }" @success="getCaptcha" /> | ||||||
|       :captcha-type="captchaType" |  | ||||||
|       :mode="captchaMode" |  | ||||||
|       :img-size="{ width: '330px', height: '155px' }" |  | ||||||
|       @success="getCaptcha" |  | ||||||
|     /> |  | ||||||
|   </a-modal> |   </a-modal> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| @@ -40,7 +22,7 @@ import { getEmailCaptcha, updateUserEmail, updateUserPassword } from '@/apis' | |||||||
|  |  | ||||||
| import { encryptByRsa } from '@/utils/encrypt' | import { encryptByRsa } from '@/utils/encrypt' | ||||||
| import { useUserStore } from '@/stores' | import { useUserStore } from '@/stores' | ||||||
| import { type Columns, GiForm } from '@/components/GiForm' | import { type Columns, GiForm, type Options } from '@/components/GiForm' | ||||||
| import { useForm } from '@/hooks' | import { useForm } from '@/hooks' | ||||||
| import * as Regexp from '@/utils/regexp' | import * as Regexp from '@/utils/regexp' | ||||||
|  |  | ||||||
|   | |||||||
| @@ -34,7 +34,8 @@ | |||||||
|         </a-form-item> |         </a-form-item> | ||||||
|         <a-form-item field="PASSWORD_REPETITION_TIMES" :label="securityConfig.PASSWORD_REPETITION_TIMES.name" |         <a-form-item field="PASSWORD_REPETITION_TIMES" :label="securityConfig.PASSWORD_REPETITION_TIMES.name" | ||||||
|           :help="securityConfig.PASSWORD_REPETITION_TIMES.description" hide-asterisk> |           :help="securityConfig.PASSWORD_REPETITION_TIMES.description" hide-asterisk> | ||||||
|           <a-input-number v-model="form.PASSWORD_REPETITION_TIMES" class="input-width" :precision="0" :min="3" :max="32"> |           <a-input-number v-model="form.PASSWORD_REPETITION_TIMES" class="input-width" :precision="0" :min="3" | ||||||
|  |             :max="32"> | ||||||
|             <template #append>次</template> |             <template #append>次</template> | ||||||
|           </a-input-number> |           </a-input-number> | ||||||
|         </a-form-item> |         </a-form-item> | ||||||
| @@ -49,10 +50,8 @@ | |||||||
|             <template #unchecked>否</template> |             <template #unchecked>否</template> | ||||||
|           </a-switch> |           </a-switch> | ||||||
|         </a-form-item> |         </a-form-item> | ||||||
|         <a-form-item field="PASSWORD_REQUIRE_SYMBOLS" |         <a-form-item field="PASSWORD_REQUIRE_SYMBOLS" :label="securityConfig.PASSWORD_REQUIRE_SYMBOLS.name"> | ||||||
|           :label="securityConfig.PASSWORD_REQUIRE_SYMBOLS.name"> |           <a-switch v-model="form.PASSWORD_REQUIRE_SYMBOLS" type="round" :checked-value="1" :unchecked-value="0"> | ||||||
|           <a-switch v-model="form.PASSWORD_REQUIRE_SYMBOLS" type="round" :checked-value="1" |  | ||||||
|             :unchecked-value="0"> |  | ||||||
|             <template #checked>是</template> |             <template #checked>是</template> | ||||||
|             <template #unchecked>否</template> |             <template #unchecked>否</template> | ||||||
|           </a-switch> |           </a-switch> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 秋帆
					秋帆