feat: add verification login

pull/48/MERGE
xingyuv 2024-11-16 23:45:16 +08:00
parent 31315a7f76
commit b1038c7bb8
1 changed files with 82 additions and 47 deletions

View File

@ -1,20 +1,27 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui'; import type { VbenFormSchema } from '@vben/common-ui';
import type { Recordable } from '@vben/types';
import { computed, ref } from 'vue'; import { computed, reactive, ref } from 'vue';
import { AuthenticationLogin, z } from '@vben/common-ui'; import { AuthenticationLogin, z } from '@vben/common-ui';
import { useAppConfig } from '@vben/hooks'; import { useAppConfig } from '@vben/hooks';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { getTenantByWebsite, getTenantIdByName } from '#/api/core/auth'; import { getTenantByWebsite, getTenantIdByName } from '#/api/core/auth';
import { Verify } from '#/components/Verification';
import { useAuthStore } from '#/store'; import { useAuthStore } from '#/store';
import { setTenantId } from '#/utils'; import { setTenantId } from '#/utils';
defineOptions({ name: 'Login' }); defineOptions({ name: 'Login' });
const authStore = useAuthStore(); const authStore = useAuthStore();
/**
* 初始化验证码
* blockPuzzle 滑块
* clickWord 点击文字
*/
const verify = ref();
const captchaType = ref('blockPuzzle');
const { tenantEnable, captchaEnable } = useAppConfig( const { tenantEnable, captchaEnable } = useAppConfig(
import.meta.env, import.meta.env,
@ -26,84 +33,112 @@ const formSchema = computed((): VbenFormSchema[] => {
{ {
component: 'VbenInput', component: 'VbenInput',
componentProps: { componentProps: {
placeholder: $t('authentication.usernameTip'), placeholder: $t('page.auth.tenantNameTip'),
}, },
fieldName: 'tenantName', fieldName: 'tenantName',
label: $t('authentication.username'), label: $t('page.auth.tenantname'),
rules: z.string().min(1, { message: $t('authentication.usernameTip') }), rules: z.string().min(1, { message: $t('page.auth.tenantNameTip') }),
value: import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT || '', defaultValue: import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT || '',
}, },
{ {
component: 'VbenInput', component: 'VbenInput',
componentProps: { componentProps: {
placeholder: $t('authentication.usernameTip'), placeholder: $t('page.auth.usernameTip'),
}, },
fieldName: 'username', fieldName: 'username',
label: $t('authentication.username'), label: $t('page.auth.username'),
rules: z.string().min(1, { message: $t('authentication.usernameTip') }), rules: z.string().min(1, { message: $t('page.auth.usernameTip') }),
value: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '', defaultValue: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '',
}, },
{ {
component: 'VbenInputPassword', component: 'VbenInputPassword',
componentProps: { componentProps: {
placeholder: $t('authentication.password'), placeholder: $t('page.auth.passwordTip'),
}, },
fieldName: 'password', fieldName: 'password',
label: $t('authentication.password'), label: $t('page.auth.password'),
rules: z.string().min(1, { message: $t('authentication.passwordTip') }), rules: z.string().min(1, { message: $t('page.auth.passwordTip') }),
value: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '', defaultValue: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '',
}, },
]; ];
}); });
const loginData = ref({ const loginData = reactive({
captchaVerification: '', loginForm: {
username: '', username: '',
password: '', password: '',
tenantName: '', tenantName: '',
},
}); });
const captchaVerification = ref('');
// //
async function getCode(params: Recordable<any>) { async function getCode(params: any) {
if (params) { if (params) {
loginData.value = params; loginData.loginForm = params;
} }
getTenant() try {
.then() await getTenant();
.finally(async () => { if (captchaEnable) {
//
//
verify.value.show();
} else {
// //
if (captchaEnable === 'false') { await handleLogin({});
await handleLogin(); }
} else { } catch (error) {
// console.error('Error in getCode:', error);
// }
verify.value.show();
}
});
} }
// && ID // && ID
async function getTenant() { async function getTenant() {
if (tenantEnable === 'true') { if (tenantEnable) {
const website = location.host; const website = location.host;
const tenant = await getTenantByWebsite(website); try {
if (tenant) { const tenant = await getTenantByWebsite(website);
loginData.value.tenantName = tenant.name; if (tenant) {
setTenantId(tenant.id); loginData.loginForm.tenantName = tenant.name;
} else { setTenantId(tenant.id);
const res = await getTenantIdByName(loginData.value.tenantName); } else {
setTenantId(res); const res = await getTenantIdByName(loginData.loginForm.tenantName);
setTenantId(res);
}
} catch (error) {
console.error('Error in getTenant:', error);
} }
} }
} }
async function handleLogin() { async function handleLogin(params: any) {
authStore.authLogin(loginData.value); if (!params.captchaVerification && captchaEnable) {
console.error('Captcha verification is required');
return;
}
captchaVerification.value = params.captchaVerification;
try {
await authStore.authLogin({
...loginData.loginForm,
captchaVerification: captchaVerification.value,
});
} catch (error) {
console.error('Error in handleLogin:', error);
}
} }
</script> </script>
<template> <template>
<AuthenticationLogin <div>
:form-schema="formSchema" <AuthenticationLogin
:loading="authStore.loginLoading" :form-schema="formSchema"
@submit="getCode" :loading="authStore.loginLoading"
/> @submit="getCode"
/>
<Verify
ref="verify"
:captcha-type="captchaType"
:img-size="{ width: '400px', height: '200px' }"
mode="pop"
@success="handleLogin"
/>
</div>
</template> </template>