mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	refactor:login
This commit is contained in:
		| @@ -1,279 +0,0 @@ | ||||
| <script setup lang="ts"> | ||||
| import { reactive, ref, unref, watch, onMounted } from 'vue' | ||||
| import { Form } from '@/components/Form' | ||||
| import { useI18n } from '@/hooks/web/useI18n' | ||||
| import { ElCheckbox, ElLink } from 'element-plus' | ||||
| import { required } from '@/utils/formRules' | ||||
| import { useForm } from '@/hooks/web/useForm' | ||||
| import { getTenantIdByNameApi, getCodeImgApi, loginApi, getAsyncRoutesApi } from '@/api/login' | ||||
| import { useCache } from '@/hooks/web/useCache' | ||||
| import { usePermissionStore } from '@/store/modules/permission' | ||||
| import { useRouter } from 'vue-router' | ||||
| import { setToken } from '@/utils/auth' | ||||
| import { useUserStoreWithOut } from '@/store/modules/user' | ||||
| import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router' | ||||
| import { UserLoginVO } from '@/api/login/types' | ||||
|  | ||||
| const { wsCache } = useCache() | ||||
|  | ||||
| const userStore = useUserStoreWithOut() | ||||
|  | ||||
| const permissionStore = usePermissionStore() | ||||
|  | ||||
| const { currentRoute, addRoute, push } = useRouter() | ||||
|  | ||||
| const { t } = useI18n() | ||||
|  | ||||
| const rules = { | ||||
|   tenantName: [required], | ||||
|   username: [required], | ||||
|   password: [required], | ||||
|   code: [required] | ||||
| } | ||||
| const loginData = reactive({ | ||||
|   codeImg: '', | ||||
|   isShowPassword: false, | ||||
|   captchaEnable: true, | ||||
|   tenantEnable: true, | ||||
|   token: '', | ||||
|   loading: { | ||||
|     signIn: false | ||||
|   }, | ||||
|   loginForm: { | ||||
|     tenantName: '芋道源码', | ||||
|     username: 'admin', | ||||
|     password: 'admin123', | ||||
|     code: '', | ||||
|     uuid: '' | ||||
|   } | ||||
| }) | ||||
| const schema = reactive<FormSchema[]>([ | ||||
|   { | ||||
|     field: 'title', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'tenantName', | ||||
|     label: t('login.tenantname'), | ||||
|     value: loginData.loginForm.tenantName, | ||||
|     component: 'Input', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     }, | ||||
|     componentProps: { | ||||
|       placeholder: t('login.tenantNamePlaceholder') | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'username', | ||||
|     label: t('login.username'), | ||||
|     value: loginData.loginForm.username, | ||||
|     component: 'Input', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     }, | ||||
|     componentProps: { | ||||
|       placeholder: t('login.usernamePlaceholder') | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'password', | ||||
|     label: t('login.password'), | ||||
|     value: loginData.loginForm.password, | ||||
|     component: 'InputPassword', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     }, | ||||
|     componentProps: { | ||||
|       style: { | ||||
|         width: '100%' | ||||
|       }, | ||||
|       placeholder: t('login.passwordPlaceholder') | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'code', | ||||
|     label: t('login.code'), | ||||
|     value: loginData.loginForm.code, | ||||
|     component: 'Input', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     }, | ||||
|     componentProps: { | ||||
|       style: { | ||||
|         width: '100%' | ||||
|       }, | ||||
|       placeholder: t('login.codePlaceholder') | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'codeImg', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'tool', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'login', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'other', | ||||
|     component: 'Divider', | ||||
|     label: t('login.otherLogin'), | ||||
|     componentProps: { | ||||
|       contentPosition: 'center' | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     field: 'otherIcon', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     } | ||||
|   } | ||||
| ]) | ||||
|  | ||||
| const iconSize = 30 | ||||
| const remember = ref(false) | ||||
| const { register, elFormRef, methods } = useForm() | ||||
| const loading = ref(false) | ||||
| const iconColor = '#999' | ||||
| const redirect = ref<string>('') | ||||
|  | ||||
| watch( | ||||
|   () => currentRoute.value, | ||||
|   (route: RouteLocationNormalizedLoaded) => { | ||||
|     redirect.value = route?.query?.redirect as string | ||||
|   }, | ||||
|   { | ||||
|     immediate: true | ||||
|   } | ||||
| ) | ||||
| // 获取验证码 | ||||
| const getCode = async () => { | ||||
|   const res = await getCodeImgApi() | ||||
|   loginData.codeImg = 'data:image/gif;base64,' + res.img | ||||
|   loginData.loginForm.uuid = res.uuid | ||||
| } | ||||
| //获取租户ID | ||||
| const getTenantId = async () => { | ||||
|   const res = await getTenantIdByNameApi(loginData.loginForm.tenantName) | ||||
|   wsCache.set('tenantId', res) | ||||
| } | ||||
| // 登录 | ||||
| const signIn = async () => { | ||||
|   await getTenantId() | ||||
|   const formRef = unref(elFormRef) | ||||
|   await formRef?.validate(async (isValid) => { | ||||
|     if (isValid) { | ||||
|       loading.value = true | ||||
|       const { getFormData } = methods | ||||
|       const formData = await getFormData<UserLoginVO>() | ||||
|       formData.uuid = loginData.loginForm.uuid | ||||
|       await loginApi(formData) | ||||
|         .then(async (res) => { | ||||
|           setToken(res) | ||||
|           getRoutes() | ||||
|           await userStore.getUserInfoAction() | ||||
|         }) | ||||
|         .catch(() => { | ||||
|           getCode() | ||||
|         }) | ||||
|         .finally(() => (loading.value = false)) | ||||
|     } | ||||
|   }) | ||||
| } | ||||
| // 获取路由 | ||||
| const getRoutes = async () => { | ||||
|   // 后端过滤菜单 | ||||
|   const routers = await getAsyncRoutesApi() | ||||
|   wsCache.set('roleRouters', routers) | ||||
|   await permissionStore.generateRoutes(routers).catch(() => {}) | ||||
|   permissionStore.getAddRouters.forEach((route) => { | ||||
|     addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 | ||||
|   }) | ||||
|   permissionStore.setIsAddRouters(true) | ||||
|   push({ path: redirect.value || permissionStore.addRouters[0].path }) | ||||
| } | ||||
| onMounted(() => { | ||||
|   getCode() | ||||
| }) | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <Form | ||||
|     :schema="schema" | ||||
|     :rules="rules" | ||||
|     label-position="top" | ||||
|     hide-required-asterisk | ||||
|     size="large" | ||||
|     @register="register" | ||||
|     v-show="false" | ||||
|   > | ||||
|     <template #header> | ||||
|       <h2 class="text-2xl font-bold text-center w-[100%]">{{ t('login.login') }}</h2> | ||||
|     </template> | ||||
|     <template #codeImg> | ||||
|       <img :src="loginData.codeImg" @click="getCode" alt="" /> | ||||
|     </template> | ||||
|  | ||||
|     <template #tool> | ||||
|       <div class="flex justify-between items-center w-[100%]"> | ||||
|         <ElCheckbox v-model="remember" :label="t('login.remember')" size="small" /> | ||||
|         <ElLink type="primary" :underline="false">{{ t('login.forgetPassword') }}</ElLink> | ||||
|       </div> | ||||
|     </template> | ||||
|  | ||||
|     <template #login> | ||||
|       <ElButton :loading="loading" type="primary" class="w-[100%]" @click="signIn"> | ||||
|         {{ t('login.login') }} | ||||
|       </ElButton> | ||||
|     </template> | ||||
|  | ||||
|     <template #otherIcon> | ||||
|       <div class="flex justify-between w-[100%]"> | ||||
|         <Icon | ||||
|           icon="ant-design:github-filled" | ||||
|           :size="iconSize" | ||||
|           class="cursor-pointer anticon" | ||||
|           :color="iconColor" | ||||
|         /> | ||||
|         <Icon | ||||
|           icon="ant-design:wechat-filled" | ||||
|           :size="iconSize" | ||||
|           class="cursor-pointer anticon" | ||||
|           :color="iconColor" | ||||
|         /> | ||||
|         <Icon | ||||
|           icon="ant-design:alipay-circle-filled" | ||||
|           :size="iconSize" | ||||
|           :color="iconColor" | ||||
|           class="cursor-pointer anticon" | ||||
|         /> | ||||
|         <Icon | ||||
|           icon="ant-design:weibo-circle-filled" | ||||
|           :size="iconSize" | ||||
|           :color="iconColor" | ||||
|           class="cursor-pointer anticon" | ||||
|         /> | ||||
|       </div> | ||||
|     </template> | ||||
|   </Form> | ||||
| </template> | ||||
|  | ||||
| <style lang="less" scoped> | ||||
| :deep(.anticon) { | ||||
|   &:hover { | ||||
|     color: var(--el-color-primary) !important; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -40,9 +40,6 @@ const rules = { | ||||
| } | ||||
| const loginData = reactive({ | ||||
|   codeImg: '', | ||||
|   // TODO @jinz:多余的变量 isShowPassword、captchaEnable | ||||
|   isShowPassword: false, | ||||
|   captchaEnable: true, | ||||
|   tenantEnable: true, | ||||
|   token: '', | ||||
|   loading: { | ||||
| @@ -55,8 +52,7 @@ const loginData = reactive({ | ||||
|     code: '' | ||||
|   } | ||||
| }) | ||||
| // TODO @jinz:smsVO 小写哈 | ||||
| const SmsVO = reactive({ | ||||
| const smsVO = reactive({ | ||||
|   smsCode: { | ||||
|     mobile: '', | ||||
|     scene: 21 | ||||
| @@ -70,9 +66,9 @@ const mobileCodeTimer = ref(0) | ||||
| const redirect = ref<string>('') | ||||
| const getSmsCode = async () => { | ||||
|   await getTenantId() | ||||
|   SmsVO.smsCode.mobile = loginData.loginForm.mobileNumber | ||||
|   console.log('getSmsCode begin:', SmsVO.smsCode) | ||||
|   await sendSmsCodeApi(SmsVO.smsCode) | ||||
|   smsVO.smsCode.mobile = loginData.loginForm.mobileNumber | ||||
|   console.log('getSmsCode begin:', smsVO.smsCode) | ||||
|   await sendSmsCodeApi(smsVO.smsCode) | ||||
|     .then(async (res) => { | ||||
|       // 提示验证码发送成功 | ||||
|       ElMessage({ | ||||
| @@ -119,9 +115,9 @@ const signIn = async () => { | ||||
|   const data = await validForm() | ||||
|   if (!data) return | ||||
|   loginLoading.value = true | ||||
|   SmsVO.loginSms.mobile = loginData.loginForm.mobileNumber | ||||
|   SmsVO.loginSms.code = loginData.loginForm.code | ||||
|   await smsLoginApi(SmsVO.loginSms) | ||||
|   smsVO.loginSms.mobile = loginData.loginForm.mobileNumber | ||||
|   smsVO.loginSms.code = loginData.loginForm.code | ||||
|   await smsLoginApi(smsVO.loginSms) | ||||
|     .then(async (res) => { | ||||
|       setToken(res?.token) | ||||
|       await userStore.getUserInfoAction() | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| export { default as LoginForm } from './LoginForm.vue' | ||||
| export { default as MobileForm } from './MobileForm.vue' | ||||
| export { default as LoginFormOld } from './LoginFormOld.vue' // TODO jinz:old 是不是可以删除哈,git 可以管理的 | ||||
| export { default as LoginFormTitle } from './LoginFormTitle.vue' | ||||
| import LoginForm from './LoginForm.vue' | ||||
| import MobileForm from './MobileForm.vue' | ||||
| import LoginFormTitle from './LoginFormTitle.vue' | ||||
|  | ||||
| export {LoginForm, MobileForm, LoginFormTitle} | ||||
|   | ||||
| @@ -41,31 +41,6 @@ export function useFormValid<T extends Object = any>(formRef: Ref<any>) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| // TODO @jinz:多余的,是不是可以删除哈 | ||||
| export function useFormRules(formData?: Recordable) { | ||||
|   const { t } = useI18n() | ||||
|  | ||||
|   const getAccountFormRule = computed(() => createRule(t('sys.login.accountPlaceholder'))) | ||||
|   const getPasswordFormRule = computed(() => createRule(t('sys.login.passwordPlaceholder'))) | ||||
|   const getSmsFormRule = computed(() => createRule(t('sys.login.smsPlaceholder'))) | ||||
|   const getMobileFormRule = computed(() => createRule(t('sys.login.mobilePlaceholder'))) | ||||
|  | ||||
|   const validatePolicy = async (_: RuleObject, value: boolean) => { | ||||
|     return !value ? Promise.reject(t('sys.login.policyPlaceholder')) : Promise.resolve() | ||||
|   } | ||||
|  | ||||
|   const validateConfirmPassword = (password: string) => { | ||||
|     return async (_: RuleObject, value: string) => { | ||||
|       if (!value) { | ||||
|         return Promise.reject(t('sys.login.passwordPlaceholder')) | ||||
|       } | ||||
|       if (value !== password) { | ||||
|         return Promise.reject(t('sys.login.diffPwd')) | ||||
|       } | ||||
|       return Promise.resolve() | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   const getFormRules = computed( | ||||
|     (): { | ||||
|       [k: string]: ValidationRule | ValidationRule[] | ||||
|   | ||||
| @@ -27,7 +27,6 @@ const loading = ref(false) | ||||
| const activeName = ref('cloum') | ||||
| const basicInfoRef = ref<ComponentRef<typeof BasicInfoForm>>() | ||||
| const genInfoRef = ref<ComponentRef<typeof GenInfoFormVue>>() | ||||
| // TODO: 提交 | ||||
| const submitForm = async () => { | ||||
|   const basicInfo = unref(basicInfoRef) | ||||
|   const genInfo = unref(genInfoRef) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 xingyu
					xingyu