feat: 验证码请求限流处理

This commit is contained in:
rd
2025-09-08 17:59:19 +08:00
parent 8597ad67f0
commit 9d150ee292
3 changed files with 35 additions and 12 deletions

View File

@ -72,3 +72,8 @@ export const getImagePreSignedUrl = (params = {}) => {
export const getVideoPreSignedUrl = (params = {}) => { export const getVideoPreSignedUrl = (params = {}) => {
return Http.get('/v1/oss/video-pre-signed-url', params); return Http.get('/v1/oss/video-pre-signed-url', params);
}; };
// 清除限流
export const postClearRateLimiter = (params = {}) => {
return Http.post(`/v1/rate-limiter/clear`, params);
};

View File

@ -117,6 +117,7 @@ const { TabPane } = Tabs;
import PuzzleVerification from '../PuzzleVerification.vue'; import PuzzleVerification from '../PuzzleVerification.vue';
import SelectAccountModal from '../select-account-modal/index.vue'; import SelectAccountModal from '../select-account-modal/index.vue';
import { fetchLoginCaptCha, fetchAuthorizationsCaptcha, fetchProfileInfo, postLoginPassword } from '@/api/all/login'; import { fetchLoginCaptCha, fetchAuthorizationsCaptcha, fetchProfileInfo, postLoginPassword } from '@/api/all/login';
import { postClearRateLimiter } from '@/api/all/common';
import { joinEnterpriseByInviteCode } from '@/api/all'; import { joinEnterpriseByInviteCode } from '@/api/all';
import { ref, reactive, onUnmounted, computed } from 'vue'; import { ref, reactive, onUnmounted, computed } from 'vue';
import { useUserStore } from '@/stores'; import { useUserStore } from '@/stores';
@ -239,27 +240,35 @@ const getCode = async () => {
if (!canGetCaptcha.value) return; if (!canGetCaptcha.value) return;
formRef.value.validateFields('mobile').then(() => { formRef.value.validateFields('mobile').then(() => {
isVerificationVisible.value = true; getCaptcha();
}); });
}; };
// 验证码验证通过后 const getCaptcha = async () => {
const handleVerificationSubmit = async () => {
isVerificationVisible.value = false;
startCountdown();
try { try {
const { code, message: msg } = await fetchLoginCaptCha({ mobile: loginForm.mobile }); const { code, message: msg } = await fetchLoginCaptCha({ mobile: loginForm.mobile });
if (code === 200) { if (code === 200) {
startCountdown();
message.success(msg); message.success(msg);
} }
} catch (error) { } catch (error) {
// 重置倒计时 // 重置倒计时
countdown.value = 0; countdown.value = 0;
clearInterval(timer.value); clearInterval(timer.value);
if (error.status === 429) {
isVerificationVisible.value = true;
}
} }
}; };
// 验证码验证通过后
const handleVerificationSubmit = () => {
isVerificationVisible.value = false;
postClearRateLimiter();
getCaptcha();
};
const onTabChange = () => { const onTabChange = () => {
errMsg.value = ''; errMsg.value = '';
}; };

View File

@ -103,6 +103,7 @@ const { Link } = Typography;
const { TabPane } = Tabs; const { TabPane } = Tabs;
import PuzzleVerification from '../PuzzleVerification.vue'; import PuzzleVerification from '../PuzzleVerification.vue';
import SelectAccountModal from '../select-account-modal/index.vue'; import SelectAccountModal from '../select-account-modal/index.vue';
import { postClearRateLimiter } from '@/api/all/common';
import { postRegisterCaptcha,postForgetPasswordCaptcha, fetchProfileInfo, postRegister, postForgetPassword } from '@/api/all/login'; import { postRegisterCaptcha,postForgetPasswordCaptcha, fetchProfileInfo, postRegister, postForgetPassword } from '@/api/all/login';
import { joinEnterpriseByInviteCode } from '@/api/all'; import { joinEnterpriseByInviteCode } from '@/api/all';
import { ref, reactive, onUnmounted, computed } from 'vue'; import { ref, reactive, onUnmounted, computed } from 'vue';
@ -258,28 +259,36 @@ const getCode = async () => {
} }
formRef.value.validateFields('mobile').then(() => { formRef.value.validateFields('mobile').then(() => {
isVerificationVisible.value = true; getCaptcha();
}); });
}; };
// 验证码验证通过后 const getCaptcha = async () => {
const handleVerificationSubmit = async () => {
isVerificationVisible.value = false;
startCountdown();
try { try {
const fn = isResetPassword.value ? postForgetPasswordCaptcha : postRegisterCaptcha; const fn = isResetPassword.value ? postForgetPasswordCaptcha : postRegisterCaptcha;
const { code, message: msg } = await fn({ mobile: formData.value.mobile }); const { code, message: msg } = await fn({ mobile: formData.value.mobile });
if (code === 200) { if (code === 200) {
startCountdown()
message.success(msg); message.success(msg);
} }
} catch (error) { } catch (error) {
// 重置倒计时 // 重置倒计时
countdown.value = 0; countdown.value = 0;
clearInterval(timer.value); clearInterval(timer.value);
if (error.status === 429) {
isVerificationVisible.value = true;
}
} }
}; };
// 验证码验证通过后
const handleVerificationSubmit = () => {
isVerificationVisible.value = false;
postClearRateLimiter();
getCaptcha();
};
// 获取用户信息 // 获取用户信息
const getProfileInfo = async () => { const getProfileInfo = async () => {
const { code, data } = await fetchProfileInfo(); const { code, data } = await fetchProfileInfo();