feat:登录-新增用户账号登录 验证码 ipBlock
1. 新增 登录的 图形校验码 2. 遗落问题,登录页的提交,表单全部统一了。没有区分类型,而且类型的枚举和校验没真正使用。还有其他功能如注册,改密码都没开出来
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
<div>
|
||||
<FormItem class="enter-x" name="account" v-if="loginType =='pw'">
|
||||
<label class="form-title"> {{ t('账号') }}</label>
|
||||
<Input v-model:value="formData.account" :placeholder="t('账号')" class="fix-auto-fill" size="large" style="height: 58px;">
|
||||
<Input v-model:value="formData.account" :placeholder="t('账号')" class="fix-auto-fill" size="large" style="height: 58px;" @blur="handleBlur">
|
||||
<template #prefix>
|
||||
<IconFontSymbol class="user-icon" icon="yonghu-xianxing" />
|
||||
</template>
|
||||
@ -17,6 +17,22 @@
|
||||
</template>
|
||||
</InputPassword>
|
||||
</FormItem>
|
||||
<FormItem class="enter-x" name="captchaCode" v-if="loginType =='pw' && loginUseType == 'captcha'">
|
||||
<label class="form-title"> {{ t('图形验证码') }}</label>
|
||||
<Input v-model:value="formData.captchaCode" :placeholder="t('图形验证码')" class="fix-auto-fill" size="large" style="height: 58px;" visibilityToggle>
|
||||
<template #prefix>
|
||||
<PictureOutlined :style="{fontSize: '25px', color: '#717c91'}"/>
|
||||
</template>
|
||||
<template #suffix>
|
||||
<a-image
|
||||
:src="captchaImage.imgBase64 || ''"
|
||||
alt="验证码"
|
||||
class="captcha-image"
|
||||
/>
|
||||
<ReloadOutlined :style="{fontSize: '25px', color: '#717c91'}" @click="refreshCaptcha"/>
|
||||
</template>
|
||||
</Input>
|
||||
</FormItem>
|
||||
|
||||
<FormItem v-if="getAppEnvConfig().VITE_TENANT_ENABLED && loginType =='pw'" name="tenantCode" class="enter-x">
|
||||
<label class="form-title"> {{ t('租户码') }}</label>
|
||||
@ -43,8 +59,10 @@
|
||||
<FormItem class="enter-x" name="code" v-if="loginType =='mobile'">
|
||||
<label class="form-title"> {{ t('验证码') }}</label>
|
||||
<Input v-model:value="formData.code" :placeholder="t('验证码')" class="fix-auto-fill" size="large" style="height: 58px;">
|
||||
<template #prefix>
|
||||
<PhoneOutlined :style="{fontSize: '25px', color: '#717c91'}"/>
|
||||
</template>
|
||||
<template #suffix>
|
||||
<!-- <span>111</span> -->
|
||||
<Button type="link" class="f-16" @click="getLoginCode" size="small" :disabled="codeButtonDisabled">
|
||||
{{ getCodeButtonName }}
|
||||
</Button>
|
||||
@ -64,7 +82,7 @@
|
||||
<FormItem>
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<Button type="link" class="f-16" @click="changeLoginType" size="small">
|
||||
{{ loginType == 'mobile' ? t('账号密码登录') : t('验证码登录') }}
|
||||
{{ loginType == 'mobile' ? t('账号密码登录') : t('手机登录') }}
|
||||
</Button>
|
||||
</FormItem>
|
||||
</ACol>
|
||||
@ -118,7 +136,7 @@
|
||||
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from '/@/views/sys/login/useLogin';
|
||||
import { getMobileLoginCode, getMobileLoginImg, sendMobileLoginCode } from '/@/api/system/login';
|
||||
import { getMobileLoginCode, getMobileLoginImg, sendMobileLoginCode, checkAccountCaptchaApi, } from '/@/api/system/login';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
@ -126,6 +144,8 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { getAppEnvConfig } from '/@/utils/env';
|
||||
import Icon from '/@/components/Icon/index';
|
||||
|
||||
import { PhoneOutlined, PictureOutlined, ReloadOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
const ACol = Col;
|
||||
const ARow = Row;
|
||||
@ -138,7 +158,7 @@
|
||||
|
||||
const { currentRoute } = useRouter();
|
||||
|
||||
const { getLoginState } = useLoginState();
|
||||
const { getLoginState, setLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
|
||||
const formRef = ref();
|
||||
@ -146,6 +166,7 @@
|
||||
const loading = ref(false);
|
||||
const rememberMe = ref(false);
|
||||
const loginType = ref('mobile')
|
||||
const loginUseType = ref();
|
||||
const countdown = ref(60)
|
||||
|
||||
const visible = ref(false);
|
||||
@ -153,6 +174,9 @@
|
||||
const imgObj = ref({
|
||||
imgBase64: ''
|
||||
})
|
||||
const captchaImage = ref({
|
||||
imgBase64: ''
|
||||
})
|
||||
const imgCode = ref('')
|
||||
|
||||
const formData = reactive({
|
||||
@ -160,7 +184,8 @@
|
||||
password: '',
|
||||
mobile: '',
|
||||
code: '',
|
||||
tenantCode: 'system'
|
||||
tenantCode: 'system',
|
||||
captchaCode: ''
|
||||
});
|
||||
const getCodeButtonName = ref('获取验证码')
|
||||
const codeButtonDisabled = ref(false)
|
||||
@ -228,6 +253,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 账号失焦 请求后台获取业务状态
|
||||
*/
|
||||
async function handleBlur() {
|
||||
if (!formData.account) {
|
||||
return;
|
||||
}
|
||||
let checkAccountCaptcha = await checkAccountCaptchaApi({username: formData.account})
|
||||
if(checkAccountCaptcha == true) {
|
||||
loginUseType.value = 'captcha';
|
||||
// setLoginState(LoginStateEnum.LOGIN_WITH_CAPTCHA)
|
||||
refreshCaptcha();
|
||||
} else {
|
||||
loginUseType.value = '';
|
||||
// setLoginState(LoginStateEnum.LOGIN)
|
||||
}
|
||||
}
|
||||
|
||||
function refreshTodo() {
|
||||
refreshLoading.value = true
|
||||
onMobileLoginImg()
|
||||
@ -236,7 +279,12 @@
|
||||
|
||||
// 图形验证
|
||||
async function onMobileLoginImg() {
|
||||
imgObj.value = await getMobileLoginImg({mobile: formData.mobile})
|
||||
imgObj.value = await getMobileLoginImg({account: formData.mobile})
|
||||
}
|
||||
|
||||
// 图形账号验证
|
||||
async function refreshCaptcha() {
|
||||
captchaImage.value = await getMobileLoginImg({account: formData.account})
|
||||
}
|
||||
|
||||
async function handleOk() {
|
||||
@ -283,11 +331,22 @@
|
||||
if (!data) return;
|
||||
if (loginType.value == 'pw') {
|
||||
try {
|
||||
// 校验有没带图形验证码提交
|
||||
if (loginUseType.value == 'captcha' && !data.captchaCode) {
|
||||
createErrorModal({
|
||||
title: t('错误提示'),
|
||||
content: '请输入图形验证码',
|
||||
getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
const userInfo = await userStore.login({
|
||||
password: data.password,
|
||||
userName: data.account,
|
||||
tenantCode: data.tenantCode,
|
||||
captchaCode: data.captchaCode,
|
||||
deviceType: 0, //pc-0,app-1
|
||||
mode: 'none' //不要默认的错误提示
|
||||
});
|
||||
@ -309,6 +368,11 @@
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if ((error as unknown as Error).message.includes('验证码')) {
|
||||
loginUseType.value = 'captcha';
|
||||
// setLoginState(LoginStateEnum.LOGIN_WITH_CAPTCHA);
|
||||
refreshCaptcha();
|
||||
}
|
||||
createErrorModal({
|
||||
title: t('错误提示'),
|
||||
content: (error as unknown as Error).message || t('网络异常,请检查您的网络连接是否正常!'),
|
||||
@ -316,6 +380,7 @@
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
handleBlur();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
@ -400,4 +465,14 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
:deep(.captcha-image) {
|
||||
cursor: pointer;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
height: 48px;
|
||||
}
|
||||
// :deep(.phone-outlined-class) {
|
||||
// height: 25.99px;
|
||||
// width: 25.99px;
|
||||
// }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user