zlwu преди 10 месеца
родител
ревизия
1ad5311f61

+ 14 - 0
frontend/src/pages/FirstLoginPage.tsx

@@ -5,6 +5,7 @@ import { setStorage, STORAGE_KEYS, getUserId, getVisitedRoutes, setUserName } fr
 import { updateUserUIState, getQQAuthUrl, getUserInfo } from '@/utils/api';
 import { px2vmin } from '@/utils/viewport';
 import { getOssUrl } from '@/utils/oss';
+import { validatePhoneNumber, isValidEmail } from '@/utils/validation';
 
 // const giftProgressBar = getOssUrl('gift-progress-bar.png'); // Unused
 // const wechatLogin = getOssUrl('wechat-login.png');
@@ -439,6 +440,13 @@ export const FirstLoginPage = () => {
         onClick={() => {
           // 手机号码或邮箱登录时,跳转到验证码页面
           if (selectedLoginType === 'phone' && phoneNumber) {
+            // 校验手机号
+            const phoneValidation = validatePhoneNumber(phoneNumber, areaCode);
+            if (!phoneValidation.valid) {
+              message.error(phoneValidation.message || '手机号码格式不正确');
+              return;
+            }
+
             navigate('/verification-code', {
               state: {
                 loginType: 'phone',
@@ -447,6 +455,12 @@ export const FirstLoginPage = () => {
               },
             });
           } else if (selectedLoginType === 'email' && email) {
+            // 校验邮箱格式
+            if (!isValidEmail(email)) {
+              message.error('请输入正确的邮箱地址');
+              return;
+            }
+
             navigate('/verification-code', {
               state: {
                 loginType: 'email',

+ 14 - 0
frontend/src/pages/LoginPage.tsx

@@ -5,6 +5,7 @@ import { setStorage, STORAGE_KEYS, getUserId, getVisitedRoutes } from '@/utils/s
 import { updateUserUIState, loginWithPhone, loginWithEmail, getQQAuthUrl } from '@/utils/api';
 import { px2vmin, px2vw, px2vh } from '@/utils/viewport';
 import { getOssUrl } from '@/utils/oss';
+import { validatePhoneNumber, isValidEmail } from '@/utils/validation';
 
 const qqLogin = getOssUrl('qq-login.png');
 const phoneLogin = getOssUrl('phone-login.png');
@@ -79,6 +80,13 @@ export const LoginPage = () => {
   const handleContinue = async () => {
     // 手机号登录
     if (selectedLoginType === 'phone' && phoneNumber) {
+      // 校验手机号
+      const phoneValidation = validatePhoneNumber(phoneNumber, areaCode);
+      if (!phoneValidation.valid) {
+        message.error(phoneValidation.message || '手机号码格式不正确');
+        return;
+      }
+
       if (isChecking) return;
       setIsChecking(true);
       try {
@@ -108,6 +116,12 @@ export const LoginPage = () => {
     }
     // 邮箱登录
     else if (selectedLoginType === 'email' && email) {
+      // 校验邮箱格式
+      if (!isValidEmail(email)) {
+        message.error('请输入正确的邮箱地址');
+        return;
+      }
+
       if (isChecking) return;
       setIsChecking(true);
       try {

+ 18 - 0
frontend/src/pages/LoginVerificationCodePage.tsx

@@ -5,6 +5,7 @@ import { setStorage, STORAGE_KEYS, getUserId, getVisitedRoutes } from '@/utils/s
 import { updateUserUIState, sendCode } from '@/utils/api';
 import { px2vmin, px2vw, px2vh } from '@/utils/viewport';
 import { getOssUrl } from '@/utils/oss';
+import { validatePhoneNumber, isValidEmail } from '@/utils/validation';
 
 // const giftProgressBar = getOssUrl('gift-progress-bar.png'); // 已注释,未使用
 const sendCodeNo = getOssUrl('send-code-no.png');
@@ -94,6 +95,23 @@ export const LoginVerificationCodePage = () => {
       return;
     }
 
+    // 校验手机号
+    if (selectedLoginType === 'phone' && phoneNumber) {
+      const phoneValidation = validatePhoneNumber(phoneNumber, areaCode);
+      if (!phoneValidation.valid) {
+        message.error(phoneValidation.message || '手机号码格式不正确');
+        return;
+      }
+    }
+
+    // 校验邮箱格式
+    if (selectedLoginType === 'email' && email) {
+      if (!isValidEmail(email)) {
+        message.error('请输入正确的邮箱地址');
+        return;
+      }
+    }
+
     try {
       // 确定发送类型
       const sendType = selectedLoginType === 'email' ? 'email' : 'domestic_sms';

+ 18 - 0
frontend/src/pages/VerificationCodePage.tsx

@@ -5,6 +5,7 @@ import { setStorage, STORAGE_KEYS, getUserId, getVisitedRoutes } from '@/utils/s
 import { updateUserUIState, sendCode } from '@/utils/api';
 import { px2vmin, px2vw, px2vh } from '@/utils/viewport';
 import { getOssUrl } from '@/utils/oss';
+import { validatePhoneNumber, isValidEmail } from '@/utils/validation';
 
 // const giftProgressBar = getOssUrl('gift-progress-bar.png'); // Unused
 const sendCodeNo = getOssUrl('send-code-no.png');
@@ -94,6 +95,23 @@ export const VerificationCodePage = () => {
       return;
     }
 
+    // 校验手机号
+    if (selectedLoginType === 'phone' && phoneNumber) {
+      const phoneValidation = validatePhoneNumber(phoneNumber, areaCode);
+      if (!phoneValidation.valid) {
+        message.error(phoneValidation.message || '手机号码格式不正确');
+        return;
+      }
+    }
+
+    // 校验邮箱格式
+    if (selectedLoginType === 'email' && email) {
+      if (!isValidEmail(email)) {
+        message.error('请输入正确的邮箱地址');
+        return;
+      }
+    }
+
     try {
       // 确定发送类型
       const sendType = selectedLoginType === 'email' ? 'email' : 'domestic_sms';

+ 37 - 0
frontend/src/utils/validation.ts

@@ -0,0 +1,37 @@
+/**
+ * 校验工具函数
+ */
+
+/**
+ * 校验邮箱格式
+ * @param email 邮箱地址
+ * @returns 是否为有效邮箱格式
+ */
+export const isValidEmail = (email: string): boolean => {
+  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+  return emailRegex.test(email);
+};
+
+/**
+ * 校验手机号(根据区号)
+ * @param phoneNumber 手机号
+ * @param areaCode 区号
+ * @returns 校验结果对象 { valid: boolean, message?: string }
+ */
+export const validatePhoneNumber = (
+  phoneNumber: string,
+  areaCode: string
+): { valid: boolean; message?: string } => {
+  // 当区号为+86时,要求11位
+  if (areaCode === '+86') {
+    if (phoneNumber.length !== 11) {
+      return {
+        valid: false,
+        message: '中国手机号码必须为11位',
+      };
+    }
+  }
+  // 其他区号不做校验
+  return { valid: true };
+};
+