feat:登录-新增用户账号登录 验证码 ipBlock

1. 新增 登录的 图形校验码
2. 遗落问题,登录页的提交,表单全部统一了。没有区分类型,而且类型的枚举和校验没真正使用。还有其他功能如注册,改密码都没开出来
This commit is contained in:
lvjunzhao
2025-04-10 17:12:15 +08:00
parent 54fa34028e
commit daae3c89e7
6 changed files with 231 additions and 7 deletions

View File

@ -117,6 +117,100 @@
/>
</a-form-item>
· <a-form-item name="checkErrorLoginCaptcha">
<div class="flex">
<div
class="gouBox"
:class="formState.checkErrorLoginCaptcha ? 'active' : ''"
@click="handleCaptchaClick()"
>{{ t('密码错误超过最大次数需要填写验证码') }}
<div class="triangle" v-if="formState.checkErrorLoginCaptcha"
><Icon color="#fff" icon="uil:check"
/></div>
</div>
</div>
<template #label>
<div>验证码策略</div>
<a-tooltip placement="bottomLeft" class="left-reset">
<template #title>
<div style="max-width: 336px">
<p>1.登录验证码策略是指在登录过程中出现密码错误情况时的系统处理方式</p>
<p>2.默认密码错误超过最大次需要验证码登录的策略状态为启用</p>
<p>3.如果设置验证码最大次数为0 即每次登录都需要验证码</p>
</div>
</template>
<QuestionCircleFilled
style="
font-size: 16px;
color: rgb(204 204 204);
position: absolute;
left: -90px;
top: 8px;
"
/>
</a-tooltip>
</template>
</a-form-item>
<a-form-item :label="t('最大次数')" name="checkErrorLoginCaptchaCount">
<a-input-number
v-model:value="formState.checkErrorLoginCaptchaCount"
:placeholder="t('请输入最大次数')"
style="width: 50%"
:min="0"
/>
</a-form-item>
<a-form-item :label="t('锁ip策略')" name="checkErrorLoginBlockIp">
<div class="flex">
<div
class="gouBox"
:class="formState.checkErrorLoginBlockIp ? 'active' : ''"
@click="handleBlockIpClick()"
>{{ t('密码错误超过最大次数锁定') }}
<div class="triangle" v-if="formState.checkErrorLoginBlockIp"
><Icon color="#fff" icon="uil:check"
/></div>
</div>
</div>
<a-tooltip placement="bottomLeft">
<template #title>
<div style="max-width: 336px">
<p>1.锁定ip策略是指在登录过程中出现密码错误情况时的系统处理方式</p>
<p>2.默认密码错误超过最大次数锁定ip的策略状态为启用</p>
<p
>3.当用户的ip被锁定后需要等待配置时间恢复后才能重新登录或者请联系管理员</p
>
</div>
</template>
<QuestionCircleFilled
style="
font-size: 16px;
color: rgb(204 204 204);
position: absolute;
left: -90px;
top: 8px;
"
/>
</a-tooltip>
</a-form-item>
<a-form-item :label="t('最大次数')" name="checkErrorLoginBlockIpCount">
<a-input-number
v-model:value="formState.checkErrorLoginBlockIpCount"
:placeholder="t('请输入最大次数')"
style="width: 50%"
:min="1"
/>
</a-form-item>
<a-form-item :label="t('恢复时间(小时)')" name="checkErrorLoginBlockIpRestoreTime">
<a-input-number
v-model:value="formState.checkErrorLoginBlockIpRestoreTime"
:placeholder="t('请输入恢复时间(小时)')"
style="width: 50%"
:min="1"
/>
</a-form-item>
<a-form-item :wrapper-col="{ offset: 6, span: 24 }">
<a-button type="primary" html-type="submit" class="ml-4">{{ t('提交') }}</a-button>
</a-form-item>
@ -145,6 +239,11 @@
withoutLogin?: number;
strategyMaxNumber?: number | null;
passwordStrategy?: number;
checkErrorLoginCaptcha?: boolean;
checkErrorLoginCaptchaCount?: number | null;
checkErrorLoginBlockIp?: boolean;
checkErrorLoginBlockIpCount?: number | null;
checkErrorLoginBlockIpRestoreTime?: number | null;
}
let formState = ref<FormState>({});
@ -162,6 +261,11 @@
withoutLogin: res.withoutLogin,
strategyMaxNumber: res.strategyMaxNumber,
passwordStrategy: res.passwordStrategy,
checkErrorLoginCaptcha: res.checkErrorLoginCaptcha,
checkErrorLoginCaptchaCount: res.checkErrorLoginCaptchaCount,
checkErrorLoginBlockIp: res.checkErrorLoginBlockIp,
checkErrorLoginBlockIpCount: res.checkErrorLoginBlockIpCount,
checkErrorLoginBlockIpRestoreTime: res.checkErrorLoginBlockIpRestoreTime,
};
id.value = res.id;
});
@ -198,6 +302,22 @@
}
}
function handleCaptchaClick() {
if (formState.value.checkErrorLoginCaptcha) {
formState.value.checkErrorLoginCaptcha = false;
} else {
formState.value.checkErrorLoginCaptcha = true;
}
}
function handleBlockIpClick() {
if (formState.value.checkErrorLoginBlockIp) {
formState.value.checkErrorLoginBlockIp = false;
} else {
formState.value.checkErrorLoginBlockIp = true;
}
}
function handleClick(val) {
if (proDisabled.value) return;
if (formState.value.mulLogin?.includes(val)) {