0235624 il y a 1 semaine
Parent
commit
5ab11482bb

+ 108 - 100
travel-web/src/lib/ncloud.ts

@@ -274,51 +274,55 @@ export class CloudUser extends CloudObject {
     /** 登录 */
     /** 登录 */
     // CloudUser.ts
     // CloudUser.ts
 async login(identifier: string, password: string): Promise<CloudUser | null> {
 async login(identifier: string, password: string): Promise<CloudUser | null> {
-    try {
-      // 创建查询条件数组
-      const conditions = [
-        { username: identifier },
-        { email: identifier },
-        { phone: identifier }
-      ];
-
-      const queries = conditions.map(cond => {
-        const query = new CloudQuery(this.className);
-        query.equalTo(Object.keys(cond)[0], Object.values(cond)[0]);
-        return query.find();
-      });
-
-      const results = await Promise.all(queries);
-      
-      // 合并结果并去重
-      const users = results.flat().filter((user, index, self) =>
-        index === self.findIndex(u => u.id === user.id)
-      );
-
-      // 查找匹配密码的用户
-      const user = users.find(u => u.get('password') === password);
-
-      if (user) {
-        // 设置当前用户信息
-        this.id = user.id;
-        this.set(user.data);
-        this.sessionToken = `session_${Date.now()}`;
-        
-        // 保存到本地存储
-        localStorage.setItem("NCloud/dev/User", JSON.stringify({
-          ...this.data,
-          objectId: this.id,
-          sessionToken: this.sessionToken
-        }));
-        
-        return this;
-      }
-      return null;
-    } catch (error) {
-      console.error('登录失败:', error);
-      throw new Error('登录失败,请检查网络连接');
+        try {
+            // 使用$or查询优化登录
+            const query = new CloudQuery(this.className);
+            query.queryParams["where"] = {
+                $or: [
+                    { username: identifier },
+                    { email: identifier },
+                    { phone: identifier }
+                ]
+            };
+
+            const users = await query.find();
+            
+            // 精确匹配用户
+            const user = users.find(u => {
+                // 安全密码验证(实际应使用哈希比较)
+                return u.get('password') === password;
+            });
+
+            if (user) {
+                // 设置当前用户信息
+                this.id = user.id;
+                this.set(user.data);
+                
+                // 生成安全的sessionToken
+                this.sessionToken = this.generateSessionToken();
+                
+                // 保存到本地存储
+                localStorage.setItem("NCloud/dev/User", JSON.stringify({
+                    ...this.data,
+                    objectId: this.id,
+                    sessionToken: this.sessionToken
+                }));
+                
+                return this;
+            }
+            return null;
+        } catch (error) {
+            console.error('登录失败:', error);
+            throw new Error('登录失败,请检查凭证');
+        }
+    }
+
+    /** 生成安全的sessionToken */
+    private generateSessionToken(): string {
+        const array = new Uint32Array(10);
+        crypto.getRandomValues(array);
+        return Array.from(array, dec => dec.toString(16).padStart(8, '0')).join('');
     }
     }
-  }
 
 
     /** 登出 */
     /** 登出 */
     async logout(): Promise<boolean> {
     async logout(): Promise<boolean> {
@@ -345,66 +349,70 @@ clearUserCache() {
     // CloudUser.ts
     // CloudUser.ts
 async signUp(username: string, password: string, additionalData: Record<string, any> = {}): Promise<CloudUser | null> {
 async signUp(username: string, password: string, additionalData: Record<string, any> = {}): Promise<CloudUser | null> {
     try {
     try {
-      // 检查用户名是否已存在
-      const usernameQuery = new CloudQuery(this.className);
-      usernameQuery.equalTo("username", username);
-      const existingUsers = await usernameQuery.find();
-      
-      if (existingUsers.length > 0) {
-        throw new Error('用户名已被使用');
-      }
-      
-      // 检查邮箱是否已存在
-      if (additionalData["email"]) {
-        const emailQuery = new CloudQuery(this.className);
-        emailQuery.equalTo("email", additionalData["email"]);
-        const existingEmails = await emailQuery.find();
+        // 检查用户名是否已存在
+        const usernameQuery = new CloudQuery(this.className);
+        usernameQuery.equalTo("username", username);
+        const existingUsers = await usernameQuery.find();
         
         
-        if (existingEmails.length > 0) {
-          throw new Error('邮箱已被注册');
+        if (existingUsers.length > 0) {
+            throw new Error('用户名已被使用');
         }
         }
-      }
-      
-      // 检查手机号是否已存在
-      if (additionalData["phone"]) {
-        const phoneQuery = new CloudQuery(this.className);
-        phoneQuery.equalTo("phone", additionalData["phone"]);
-        const existingPhones = await phoneQuery.find();
         
         
-        if (existingPhones.length > 0) {
-          throw new Error('手机号已被注册');
+        // 检查邮箱是否已存在
+        if (additionalData["email"]) {
+            const emailQuery = new CloudQuery(this.className);
+            emailQuery.equalTo("email", additionalData["email"]);
+            const existingEmails = await emailQuery.find();
+            
+            if (existingEmails.length > 0) {
+                throw new Error('邮箱已被注册');
+            }
         }
         }
-      }
-    
-    // 创建新用户
-    const userObj = new CloudObject(this.className);
-    userObj.set({
-      username,
-      password,
-      ...additionalData,
-      createdAt: new Date(),
-      updatedAt: new Date()
-    });
-    
-    const savedUser = await userObj.save();
-    
-    // 设置当前用户信息
-    this.id = savedUser.id;
-    this.set(savedUser.data);
-    this.sessionToken = `session_${Date.now()}`;
-    
-    // 保存到本地存储
-    localStorage.setItem("NCloud/dev/User", JSON.stringify({
-      ...this.data,
-      objectId: this.id,
-      sessionToken: this.sessionToken
-    }));
-    
-    return this;
-  } catch (error) {
-    console.error('注册失败:', error);
-    throw error;
-  }
+        
+        // 检查手机号是否已存在
+        if (additionalData["phone"]) {
+            const phoneQuery = new CloudQuery(this.className);
+            phoneQuery.equalTo("phone", additionalData["phone"]);
+            const existingPhones = await phoneQuery.find();
+            
+            if (existingPhones.length > 0) {
+                throw new Error('手机号已被注册');
+            }
+        }
+
+        // 创建新用户
+        const userObj = new CloudObject(this.className);
+        userObj.set({
+            username,
+            password,
+            ...additionalData,
+            createdAt: new Date(),
+            updatedAt: new Date()
+        });
+        
+        const savedUser = await userObj.save();
+        
+        // 设置当前用户信息
+        this.id = savedUser.id;
+        this.set(savedUser.data);
+        this.sessionToken = `session_${Date.now()}`;
+        
+        // 保存到本地存储
+        localStorage.setItem("NCloud/dev/User", JSON.stringify({
+            ...this.data,
+            objectId: this.id,
+            sessionToken: this.sessionToken
+        }));
+        
+        // 注册后自动登录
+        return await this.login(username, password);
+
+    } catch (error) {
+        console.error('注册失败:', error);
+        throw error;
+    } finally {
+        // 可选:清理操作
+    }
 }
 }
 
 
     override async save() {
     override async save() {

+ 1 - 1
travel-web/src/modules/shared/nav-pc-top-menu/nav-pc-top-menu.html

@@ -70,7 +70,7 @@
                     <form (ngSubmit)="login()">
                     <form (ngSubmit)="login()">
                         <div class="form-group">
                         <div class="form-group">
                             <i class="fas fa-user"></i>
                             <i class="fas fa-user"></i>
-                            <input type="text" placeholder="用户名/手机号/邮箱" [(ngModel)]="loginUsername" name="loginUsername" required>
+                            <input type="text" placeholder="用户名/手机号/邮箱" [(ngModel)]="loginIdentifier" name="loginIdentifie" required>
                         </div>
                         </div>
                         <div class="form-group">
                         <div class="form-group">
                             <i class="fas fa-lock"></i>
                             <i class="fas fa-lock"></i>

+ 37 - 43
travel-web/src/modules/shared/nav-pc-top-menu/nav-pc-top-menu.ts

@@ -19,7 +19,6 @@ export class NavPcTopMenu implements OnInit {
   registerError: string = '';
   registerError: string = '';
   isLoading: boolean = true;
   isLoading: boolean = true;
   showMenu: boolean = false;
   showMenu: boolean = false;
-  loginIdentifier: string = '';
   emailError: boolean = false;
   emailError: boolean = false;
   
   
   // 登录注册模态框相关
   // 登录注册模态框相关
@@ -27,7 +26,7 @@ export class NavPcTopMenu implements OnInit {
   authType: 'login' | 'register' = 'login';
   authType: 'login' | 'register' = 'login';
   
   
   // 登录表单
   // 登录表单
-  loginUsername: string = '';
+  loginIdentifier: string = '';
   loginPassword: string = '';
   loginPassword: string = '';
   rememberMe: boolean = true;
   rememberMe: boolean = true;
   isLoggingIn: boolean = false;
   isLoggingIn: boolean = false;
@@ -84,12 +83,14 @@ export class NavPcTopMenu implements OnInit {
     this.showMenu = !this.showMenu;
     this.showMenu = !this.showMenu;
   }
   }
 
 
-  openAuthModal(type: 'login' | 'register') {
+ openAuthModal(type: 'login' | 'register') {
     this.authType = type;
     this.authType = type;
     this.showAuthModal = true;
     this.showAuthModal = true;
     this.showMenu = false;
     this.showMenu = false;
-  }
-
+    this.loginError = '';
+    this.registerError = '';
+    this.emailError = false;
+}
   closeAuthModal() {
   closeAuthModal() {
     this.showAuthModal = false;
     this.showAuthModal = false;
     this.isLoggingIn = false;
     this.isLoggingIn = false;
@@ -102,8 +103,8 @@ export class NavPcTopMenu implements OnInit {
 
 
 async login() {
 async login() {
     if (!this.loginIdentifier || !this.loginPassword) {
     if (!this.loginIdentifier || !this.loginPassword) {
-      this.loginError = '请输入用户名/手机号/邮箱和密码';
-      return;
+        this.loginError = '请输入用户名/手机号/邮箱和密码';
+        return;
     }
     }
     
     
     this.isLoggingIn = true;
     this.isLoggingIn = true;
@@ -123,13 +124,12 @@ async login() {
       } else {
       } else {
         this.loginError = '用户名或密码错误';
         this.loginError = '用户名或密码错误';
       }
       }
-    } catch (error) {
-      console.error('登录失败:', error);
-      this.loginError = '登录失败,请稍后重试';
-    } finally {
-      this.isLoggingIn = false;
+    } catch (error: any) {
+            this.loginError = error.message || '登录失败,请稍后重试';
+        } finally {
+            this.isLoggingIn = false;
+        }
     }
     }
-  }
 
 
 
 
   async register() {
   async register() {
@@ -169,39 +169,33 @@ async login() {
       return;
       return;
     }
     }
     
     
-  this.isRegistering = true;
-    
-    try {
-      const additionalData = {
-        email: this.registerEmail,
-        phone: this.registerPhone
-      };
-      
-      const user = new CloudUser();
-      const newUser = await user.signUp(
-        this.registerUsername, 
-        this.registerPassword, 
-        additionalData
-      );
-      
-      if (newUser) {
-        this.user = newUser;
-        this.generateUserInitials();
-        this.closeAuthModal();
-        // 注册成功后自动登录
-        this.loginIdentifier = this.registerUsername;
+this.isRegistering = true;
+        
+        try {
+            const user = new CloudUser();
+            const newUser = await user.signUp(
+                this.registerUsername, 
+                this.registerPassword, 
+                {
+                    email: this.registerEmail,
+                    phone: this.registerPhone
+                }
+            );
+            
+            if (newUser) {
+                this.user = newUser;
+                this.generateUserInitials();
+                this.closeAuthModal();
+            }
+            this.loginIdentifier = this.registerEmail || this.registerPhone || this.registerUsername;
         this.loginPassword = this.registerPassword;
         this.loginPassword = this.registerPassword;
         await this.login();
         await this.login();
-      } else {
-        this.registerError = '注册失败,请稍后重试';
-      }
-    } catch (error: any) {
-      console.error('注册失败:', error);
-      this.registerError = error.message || '注册失败,请稍后重试';
-    } finally {
-      this.isRegistering = false;
+        } catch (error: any) {
+            this.registerError = error.message || '注册失败';
+        } finally {
+            this.isRegistering = false;
+        }
     }
     }
-  }
 
 
 
 
   async logout() {
   async logout() {