Bladeren bron

修改了登录界面和编辑界面

yujiahui 8 maanden geleden
bovenliggende
commit
8e9be3723d

+ 134 - 2
myapp/src/app/tab1/tab1.page.html

@@ -125,13 +125,145 @@
                     </div>
                 </div>
             </div>
+        </div>
+                <div (click)="goTravel()" class="recommend-section">
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/xiaoyuan.jpeg" alt="推荐内容">
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">和家人果断在北京续住3天的神仙小院</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/44.jpg" class="user-avatar">
+                        <span class="user-name">晚风心里吹</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 1.9万
+                        </span>
+                    </div>
+                </div>
+            </div>
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/zhandao.jpeg" alt="推荐内容">
+                    <div class="video-tag">
+                        <ion-icon name="play"></ion-icon>
+                        <span>视频</span>
+                    </div>
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">北京海拔2000米的木栈道帝都最高观景平台</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/22.jpg" class="user-avatar">
+                        <span class="user-name">美腻的猫</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 2.1万
+                        </span>
+                    </div>
+                </div>
+            </div>
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/jiudian.jpeg" alt="推荐内容">
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">北京郊区大自然山景私汤山酒店</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/33.jpg" class="user-avatar">
+                        <span class="user-name">美美在旅行</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 1.1万
+                        </span>
+                    </div>
+                </div>
+            </div>
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/yun.jpeg" alt="推荐内容">
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">北京周末去哪,找到了人少景美的仙境了!</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/44.jpg" class="user-avatar">
+                        <span class="user-name">晚风心里吹</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 2.1万
+                        </span>
+                    </div>
+                </div>
+            </div>
+        </div>
+                <div (click)="goTravel()" class="recommend-section">
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/xiaoyuan.jpeg" alt="推荐内容">
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">和家人果断在北京续住3天的神仙小院</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/44.jpg" class="user-avatar">
+                        <span class="user-name">晚风心里吹</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 1.9万
+                        </span>
+                    </div>
+                </div>
+            </div>
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/zhandao.jpeg" alt="推荐内容">
+                    <div class="video-tag">
+                        <ion-icon name="play"></ion-icon>
+                        <span>视频</span>
+                    </div>
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">北京海拔2000米的木栈道帝都最高观景平台</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/22.jpg" class="user-avatar">
+                        <span class="user-name">美腻的猫</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 2.1万
+                        </span>
+                    </div>
+                </div>
+            </div>
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/jiudian.jpeg" alt="推荐内容">
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">北京郊区大自然山景私汤山酒店</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/33.jpg" class="user-avatar">
+                        <span class="user-name">美美在旅行</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 1.1万
+                        </span>
+                    </div>
+                </div>
+            </div>
+            <div class="recommend-item">
+                <div class="recommend-image">
+                    <img src="/assets/yun.jpeg" alt="推荐内容">
+                </div>
+                <div class="recommend-content">
+                    <h3 class="recommend-title">北京周末去哪,找到了人少景美的仙境了!</h3>
+                    <div class="recommend-footer">
+                        <img src="https://randomuser.me/api/portraits/women/44.jpg" class="user-avatar">
+                        <span class="user-name">晚风心里吹</span>
+                        <span class="like-count">
+                            <ion-icon name="heart"></ion-icon> 2.1万
+                        </span>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
     
-    <!-- 登录提示 -->
+    <!-- 登录提示
     <div class="login-prompt">
         <p>登录查看更多精彩内容</p>
         <a href="#" class="login-btn">立即登录</a>
-    </div>
+    </div> -->
 </div>
 </ion-content>

+ 5 - 0
myapp/src/lib/ncloud.ts

@@ -218,6 +218,11 @@ export class CloudQuery {
 
 // CloudUser.ts
 export class CloudUser extends CloudObject {
+    birthday: any;
+  age: any;
+  gender: any;
+  location: any;
+  username: any;
     constructor() {
         super("_User"); // 假设用户类在Parse中是"_User"
         // 读取用户缓存信息

+ 125 - 36
myapp/src/lib/user/page-mine/page-mine.component.html

@@ -4,44 +4,83 @@
   </ion-toolbar>
 </ion-header>
 
-<ion-content class="ion-padding" style="background-color: white;">
-  <!-- 用户已登录状态 -->
+<ion-content class="ion-padding" style="background-color: #f5f5f5;">
+  <!-- 用户已登录状态 - 旅游APP风格 -->
   @if(currentUser?.id) {
-    <div class="profile-container">
-      <!-- 头像和用户名 -->
-      <div class="profile-header">
-        <img src="/assets/tx.jpeg" alt="用户头像" class="profile-avatar">
-        <h2 class="profile-name">{{ currentUser?.get("username") }}</h2>
+    <div class="travel-profile-container">
+      <!-- 顶部用户信息卡片 -->
+      <div class="user-card">
+        <div class="user-info">
+          <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="用户头像" class="user-avatar">
+          <div class="user-details">
+            <h2>{{ currentUser?.get("username") }}</h2>
+            <p class="user-bio">热爱旅行,探索世界</p>
+            <div class="user-stats">
+              <div class="stat-item">
+                <span class="stat-number">12</span>
+                <span class="stat-label">关注</span>
+              </div>
+              <div class="stat-item">
+                <span class="stat-number">356</span>
+                <span class="stat-label">粉丝</span>
+              </div>
+              <div class="stat-item">
+                <span class="stat-number">24</span>
+                <span class="stat-label">足迹</span>
+              </div>
+            </div>
+          </div>
+        </div>
       </div>
 
-      <!-- 功能列表 - 确保每个item只有一个右侧箭头 -->
-      <ion-list lines="full" class="function-list">
-        <ion-item button detail>
-          <ion-icon slot="start" name="notifications-outline" color="medium"></ion-icon>
-          <ion-label>通知</ion-label>
+      <!-- 快捷功能入口 -->
+      <div class="quick-actions">
+        <ion-button fill="clear" class="action-button" (click)="navigateTo('myTrips')">
+          <ion-icon slot="icon-only" name="airplane-outline"></ion-icon>
+          <span class="action-label">我的行程</span>
+        </ion-button>
+        <ion-button fill="clear" class="action-button" (click)="navigateTo('favorites')">
+          <ion-icon slot="icon-only" name="heart-outline"></ion-icon>
+          <span class="action-label">收藏</span>
+        </ion-button>
+        <ion-button fill="clear" class="action-button" (click)="navigateTo('reviews')">
+          <ion-icon slot="icon-only" name="pencil-outline"></ion-icon>
+          <span class="action-label">点评</span>
+        </ion-button>
+        <ion-button fill="clear" class="action-button" (click)="navigateTo('photos')">
+          <ion-icon slot="icon-only" name="camera-outline"></ion-icon>
+          <span class="action-label">相册</span>
+        </ion-button>
+      </div>
+
+      <!-- 功能列表 -->
+      <ion-list lines="none" class="travel-function-list">
+        <ion-item button detail (click)="navigateTo('settings')">
+          <ion-icon slot="start" name="settings-outline" color="medium"></ion-icon>
+          <ion-label>设置</ion-label>
         </ion-item>
         
-        <ion-item button detail>
-          <ion-icon slot="start" name="people-outline" color="medium"></ion-icon>
-          <ion-label>粉丝 <span class="fans-count">120</span></ion-label>
+        <ion-item button detail (click)="navigateTo('wallet')">
+          <ion-icon slot="start" name="wallet-outline" color="medium"></ion-icon>
+          <ion-label>钱包</ion-label>
         </ion-item>
         
-        <ion-item button detail>
-          <ion-icon slot="start" name="bookmark-outline" color="medium"></ion-icon>
-          <ion-label>收藏</ion-label>
+        <ion-item button detail (click)="navigateTo('coupons')">
+          <ion-icon slot="start" name="ticket-outline" color="medium"></ion-icon>
+          <ion-label>优惠券</ion-label>
+          <ion-badge slot="end" color="danger">3</ion-badge>
         </ion-item>
         
-        <ion-item button detail>
-          <ion-icon slot="start" name="help-circle-outline" color="medium"></ion-icon>
-          <ion-label>帮助</ion-label>
+        <ion-item button detail (click)="navigateTo('history')">
+          <ion-icon slot="start" name="time-outline" color="medium"></ion-icon>
+          <ion-label>浏览历史</ion-label>
         </ion-item>
         
-        <ion-item button detail>
-          <ion-icon slot="start" name="mail-outline" color="medium"></ion-icon>
-          <ion-label>联系我们</ion-label>
+        <ion-item button detail (click)="navigateTo('help')">
+          <ion-icon slot="start" name="help-circle-outline" color="medium"></ion-icon>
+          <ion-label>帮助中心</ion-label>
         </ion-item>
 
-        <!-- 编辑资料 -->
         <ion-item button detail (click)="edit()">
           <ion-icon slot="start" name="create-outline" color="medium"></ion-icon>
           <ion-label>编辑资料</ion-label>
@@ -50,7 +89,7 @@
 
       <!-- 退出登录按钮 -->
       <div class="logout-button">
-        <ion-button expand="block" color="primary" fill="outline" shape="round" (click)="logout()">
+        <ion-button expand="block" color="medium" fill="outline" shape="round" (click)="logout()">
           <ion-icon name="log-out-outline" slot="start"></ion-icon>
           退出登录
         </ion-button>
@@ -58,18 +97,68 @@
     </div>
   }
 
-  <!-- 用户未登录状态 -->
+  <!-- 用户未登录状态 - 保持不变 -->
   @if(!currentUser?.id) {
-    <div class="login-prompt">
-      <div class="login-icon">
-        <ion-icon name="lock-closed"></ion-icon>
+    <div class="auth-container">
+      <!-- 顶部欢迎语 -->
+      <div class="welcome-section">
+        <h1>欢迎回来</h1>
+        <p>登录后享受个性化体验</p>
+      </div>
+
+      <!-- 登录表单 -->
+      <div class="form-section">
+        <ion-item class="form-item">
+          <ion-icon slot="start" name="person-outline"></ion-icon>
+          <ion-input [(ngModel)]="loginForm.username" placeholder="手机号/用户名/邮箱" type="text"></ion-input>
+        </ion-item>
+
+        <ion-item class="form-item">
+          <ion-icon slot="start" name="lock-closed-outline"></ion-icon>
+          <ion-input [(ngModel)]="loginForm.password" placeholder="密码" type="password"></ion-input>
+        </ion-item>
+
+        <div class="action-row">
+          <ion-button fill="clear" size="small" color="medium" (click)="forgotPassword()">忘记密码</ion-button>
+        </div>
+
+        <ion-button expand="block" class="login-button" (click)="login()" [disabled]="!loginForm.username || !loginForm.password">
+          登录
+        </ion-button>
+      </div>
+
+      <!-- 快速登录分隔线 -->
+      <div class="divider-section">
+        <div class="divider-line"></div>
+        <span class="divider-text">或</span>
+        <div class="divider-line"></div>
+      </div>
+
+      <!-- 第三方登录 -->
+      <div class="social-login">
+        <ion-button fill="clear" class="social-button wechat" (click)="loginWithWeChat()">
+          <ion-icon slot="icon-only" name="logo-wechat"></ion-icon>
+        </ion-button>
+        <ion-button fill="clear" class="social-button apple" (click)="loginWithApple()">
+          <ion-icon slot="icon-only" name="logo-apple"></ion-icon>
+        </ion-button>
+        <ion-button fill="clear" class="social-button google" (click)="loginWithGoogle()">
+          <ion-icon slot="icon-only" name="logo-google"></ion-icon>
+        </ion-button>
+      </div>
+
+      <!-- 注册引导 -->
+      <div class="register-section">
+        <p>还没有账号?</p>
+        <ion-button fill="clear" color="primary" (click)="goToRegister()">立即注册</ion-button>
+      </div>
+
+      <!-- 用户协议 -->
+      <div class="agreement-section">
+        <p class="agreement-text">
+          登录即表示您同意<span class="highlight" (click)="openUserAgreement()">用户协议</span>和<span class="highlight" (click)="openPrivacyPolicy()">隐私政策</span>
+        </p>
       </div>
-      <h2>登录后体验更精彩</h2>
-      <p class="prompt-text">与全世界的经历、人物和故事相遇</p>
-      <ion-button expand="block" color="primary" shape="round" class="login-button" (click)="login()">
-        <ion-icon name="log-in" slot="start"></ion-icon>
-        立即登录
-      </ion-button>
     </div>
   }
 </ion-content>

+ 253 - 91
myapp/src/lib/user/page-mine/page-mine.component.scss

@@ -1,112 +1,274 @@
-.login-prompt {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  height: 70vh;
-  text-align: center;
+/* 旅游APP风格的已登录界面样式 */
+.travel-profile-container {
+  max-width: 600px;
+  margin: 0 auto;
+  
+  .user-card {
+    background: white;
+    border-radius: 12px;
+    padding: 20px;
+    margin-bottom: 16px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+    
+    .user-info {
+      display: flex;
+      align-items: center;
+      
+      .user-avatar {
+        width: 80px;
+        height: 80px;
+        border-radius: 50%;
+        object-fit: cover;
+        margin-right: 16px;
+        border: 2px solid var(--ion-color-light);
+      }
+      
+      .user-details {
+        flex: 1;
+        
+        h2 {
+          margin: 0 0 4px 0;
+          font-size: 1.4rem;
+          font-weight: bold;
+          color: var(--ion-color-dark);
+        }
+        
+        .user-bio {
+          margin: 0 0 12px 0;
+          font-size: 0.9rem;
+          color: var(--ion-color-medium);
+        }
+        
+        .user-stats {
+          display: flex;
+          gap: 16px;
+          
+          .stat-item {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            
+            .stat-number {
+              font-weight: bold;
+              color: var(--ion-color-dark);
+            }
+            
+            .stat-label {
+              font-size: 0.8rem;
+              color: var(--ion-color-medium);
+            }
+          }
+        }
+      }
+    }
+  }
+  
+  .quick-actions {
+    display: flex;
+    justify-content: space-around;
+    background: white;
+    border-radius: 12px;
+    padding: 16px 0;
+    margin-bottom: 16px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+    
+    .action-button {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      --padding-start: 0;
+      --padding-end: 0;
+      
+      ion-icon {
+        font-size: 1.5rem;
+        margin-bottom: 4px;
+        color: var(--ion-color-primary);
+      }
+      
+      .action-label {
+        font-size: 0.9rem;
+        color: var(--ion-color-medium);
+      }
+    }
+  }
+  
+  .travel-function-list {
+    background: white;
+    border-radius: 12px;
+    margin-bottom: 16px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+    
+    ion-item {
+      --padding-start: 16px;
+      --padding-end: 16px;
+      --min-height: 56px;
+      
+      ion-icon {
+        margin-right: 15px;
+      }
+    }
+  }
+  
+  .logout-button {
+    padding: 0 16px;
+    
+    ion-button {
+      --border-width: 1px;
+      --border-color: var(--ion-color-medium);
+      --color: var(--ion-color-medium);
+    }
+  }
+}
+
+/* 未登录界面样式保持不变 */
+.auth-container {
+  max-width: 400px;
+  margin: 0 auto;
   padding: 20px;
 
-  .login-icon {
-    background: var(--ion-color-primary);
-    width: 80px;
-    height: 80px;
-    border-radius: 50%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    margin-bottom: 20px;
+  .welcome-section {
+    text-align: center;
+    margin: 40px 0 30px;
 
-    ion-icon {
-      font-size: 2.5rem;
-      color: white;
+    h1 {
+      font-size: 1.8rem;
+      font-weight: bold;
+      color: var(--ion-color-dark);
+      margin-bottom: 8px;
     }
-  }
 
-  h2 {
-    font-size: 1.5rem;
-    font-weight: bold;
-    margin-bottom: 10px;
-    color: var(--ion-color-dark);
+    p {
+      font-size: 1rem;
+      color: var(--ion-color-medium);
+      margin: 0;
+    }
   }
 
-  .prompt-text {
-    font-size: 1rem;
-    color: var(--ion-color-medium);
+  .form-section {
     margin-bottom: 30px;
-    max-width: 80%;
-    line-height: 1.4;
-  }
 
-  .login-button {
-    max-width: 250px;
-    --padding-top: 15px;
-    --padding-bottom: 15px;
-    font-weight: bold;
+    .form-item {
+      --padding-start: 0;
+      --inner-padding-end: 0;
+      --border-radius: 8px;
+      --background: #f5f5f5;
+      margin-bottom: 15px;
+      border-radius: 8px;
+
+      ion-icon {
+        color: var(--ion-color-medium);
+        margin-right: 10px;
+      }
+    }
+
+    .action-row {
+      display: flex;
+      justify-content: flex-end;
+      margin: 10px 0 20px;
+    }
+
+    .login-button {
+      --border-radius: 8px;
+      --padding-top: 16px;
+      --padding-bottom: 16px;
+      font-weight: bold;
+      height: 48px;
+      --background: var(--ion-color-primary);
+      --background-activated: var(--ion-color-primary-shade);
+      --background-focused: var(--ion-color-primary-shade);
+      --background-hover: var(--ion-color-primary-shade);
+      
+      &:disabled {
+        --background: var(--ion-color-medium);
+        opacity: 0.7;
+      }
+    }
   }
-}
 
-.profile-container {
-  max-width: 500px;
-  margin: 0 auto;
-}
+  .divider-section {
+    display: flex;
+    align-items: center;
+    margin: 25px 0;
 
-.profile-header {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  margin: 20px 0 30px;
-  
-  .profile-avatar {
-    width: 100px;
-    height: 100px;
-    border-radius: 10px; /* 修改为正方形带圆角 */
-    object-fit: cover;
-    margin-bottom: 15px;
-    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+    .divider-line {
+      flex: 1;
+      height: 1px;
+      background-color: var(--ion-color-light-shade);
+    }
+
+    .divider-text {
+      padding: 0 15px;
+      color: var(--ion-color-medium);
+      font-size: 0.9rem;
+    }
   }
-  
-  .profile-name {
-    margin: 0;
-    font-size: 1.5rem; /* 修改字体大小 */
-    font-weight: bold;
-    color: var(--ion-color-dark);
+
+  .social-login {
+    display: flex;
+    justify-content: center;
+    gap: 20px;
+    margin-bottom: 30px;
+
+    .social-button {
+      --border-radius: 50%;
+      --padding: 0;
+      width: 50px;
+      height: 50px;
+      transition: transform 0.2s ease;
+
+      &:active {
+        transform: scale(0.95);
+      }
+
+      &.wechat ion-icon {
+        color: #09bb07;
+        font-size: 1.8rem;
+      }
+
+      &.apple ion-icon {
+        color: #000000;
+        font-size: 1.8rem;
+      }
+
+      &.google ion-icon {
+        color: #4285F4;
+        font-size: 1.8rem;
+      }
+    }
   }
-}
 
-.function-list {
-  background: transparent;
-  margin: 20px 0;
-  
-  ion-item {
-    --padding-start: 16px;
-    --padding-end: 16px;
-    --min-height: 56px;
-    --background: transparent;
-    
-    ion-icon[slot="start"] {
-      font-size: 1.2rem;
-      margin-right: 12px;
+  .register-section {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin: 20px 0;
+
+    p {
+      margin: 0;
+      color: var(--ion-color-medium);
     }
-    
-    .fans-count {
-      color: var(--ion-color-primary);
-      font-weight: bold;
-      margin-left: 8px;
+
+    ion-button {
+      --padding-start: 5px;
+      --padding-end: 5px;
     }
   }
-}
 
-.logout-button {
-  margin-top: 40px;
-  
-  ion-button {
-    --padding-top: 15px;
-    --padding-bottom: 15px;
-    font-weight: 500;
-  }
-}
+  .agreement-section {
+    text-align: center;
+    margin-top: 30px;
+
+    .agreement-text {
+      font-size: 0.8rem;
+      color: var(--ion-color-medium);
+      margin: 0;
 
-ion-button {
-  --border-radius: 50px;
+      .highlight {
+        color: var(--ion-color-primary);
+        margin: 0 3px;
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
 }

+ 128 - 15
myapp/src/lib/user/page-mine/page-mine.component.ts

@@ -1,11 +1,13 @@
 import { Component } from '@angular/core';
 import { CloudUser } from 'src/lib/ncloud';
-import { ModalController } from "@ionic/angular/standalone";
+import { ModalController, AlertController } from "@ionic/angular/standalone";
 import { UserEditComponent } from '../user-edit/user-edit.component';
 import { 
   IonHeader, IonToolbar, IonTitle, IonContent, IonList, 
-  IonItem, IonLabel, IonIcon, IonButton, IonBadge 
+  IonItem, IonLabel, IonIcon, IonButton, IonBadge, IonInput 
 } from '@ionic/angular/standalone';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
 
 @Component({
   selector: 'app-page-mine',
@@ -13,34 +15,145 @@ import {
   styleUrls: ['./page-mine.component.scss'],
   standalone: true,
   imports: [
+    CommonModule,
+    FormsModule,
     IonHeader, IonToolbar, IonTitle, IonContent, IonList,
-    IonItem, IonLabel, IonIcon, IonButton, IonBadge
+    IonItem, IonLabel, IonIcon, IonButton, IonBadge, IonInput
   ]
 })
 export class PageMineComponent {
-  currentUser: CloudUser | undefined;
+  currentUser: CloudUser = new CloudUser();
+  loginForm = {
+    username: '',
+    password: ''
+  };
 
-  constructor(private modalCtrl: ModalController) {
-    this.currentUser = new CloudUser();
+
+  constructor(private modalCtrl: ModalController, private alertCtrl: AlertController) {
+    this.loadUserData();
+  }
+
+  private loadUserData() {
+    const savedUser = localStorage.getItem('currentUser');
+    if (savedUser) {
+      try {
+        const parsedUser = JSON.parse(savedUser);
+        this.currentUser = Object.assign(new CloudUser(), parsedUser);
+      } catch (e) {
+        console.error('Failed to parse user data', e);
+        this.currentUser = new CloudUser();
+      }
+    }
+  }
+
+  private saveUserData(user: CloudUser) {
+    localStorage.setItem('currentUser', JSON.stringify(user));
+  }
+
+  async login() {
+    try {
+      const user = await new CloudUser().login(this.loginForm.username, this.loginForm.password);
+      if (user?.id) {
+        this.currentUser = Object.assign(new CloudUser(), user);
+        this.saveUserData(this.currentUser);
+      }
+    } catch (error) {
+      console.error('Login failed:', error);
+      // 这里可以添加登录失败的提示
+    }
+  }
+
+  async loginWithWeChat() {
+    console.log('WeChat login');
+    // 实现微信登录逻辑
+  }
+
+  async loginWithApple() {
+    console.log('Apple login');
+    // 实现Apple登录逻辑
+  }
+
+  async loginWithGoogle() {
+    console.log('Google login');
+    // 实现Google登录逻辑
+  }
+
+  goToRegister() {
+    console.log('Navigate to register page');
+    // 导航到注册页面
+  }
+
+  forgotPassword() {
+    console.log('Forgot password');
+    // 实现忘记密码逻辑
+  }
+
+  async openUserAgreement() {
+    const alert = await this.alertCtrl.create({
+      header: '用户协议',
+      message: `
+        欢迎使用我们的服务!
+        请仔细阅读以下条款和条件:
+          您必须遵守所有适用的法律和法规。
+          您不得使用本服务进行任何非法活动。
+          我们保留随时修改本协议的权利。
+          您的使用行为将被视为对本协议的接受。
+          我们将在必要时通知您任何变更。
+          如果您不同意本协议,请不要使用我们的服务。
+      `,
+      buttons: ['我已阅读并同意']
+    });
+    await alert.present();
+  }
+
+  async openPrivacyPolicy() {
+    const alert = await this.alertCtrl.create({
+      header: '隐私政策',
+      message: `
+        我们尊重并保护您的隐私。
+        以下是我们的隐私政策:
+          我们不会收集您的个人信息,除非您明确同意。
+          我们不会将您的信息用于任何非法目的。
+          我们保留随时修改本隐私政策的权利。
+      `,
+      buttons: ['我已阅读并同意']
+    });
+    await alert.present();
+  }
+
+  navigateTo(page: string) {
+    console.log(`Navigate to ${page}`);
+    // 导航到对应页面
   }
 
   async edit() {
     const modal = await this.modalCtrl.create({
       component: UserEditComponent,
+      componentProps: {
+        initialData: {
+          username: this.currentUser.username,
+          gender: this.currentUser.gender,
+          age: this.currentUser.age,
+          birthday: this.currentUser.birthday,
+          location: this.currentUser.location,
+          password: ''
+        }
+      }
     });
-    await modal.present();
-  }
 
-  async login() {
-    let user: any = new CloudUser();
-    user = await user?.login("yuabc", "123");
-    if (user?.id) {
-      this.currentUser = user;
-    }
+    modal.onDidDismiss().then(({ data }) => {
+      if (data?.saved) {
+        Object.assign(this.currentUser, data.data);
+        this.saveUserData(this.currentUser);
+      }
+    });
+
+    await modal.present();
   }
 
   logout() {
     this.currentUser?.logout();
-    this.currentUser = undefined;
+    this.currentUser = new CloudUser();
+    localStorage.removeItem('currentUser');
   }
 }

+ 50 - 27
myapp/src/lib/user/user-edit/user-edit.component.html

@@ -1,49 +1,72 @@
 <ion-header>
   <ion-toolbar color="primary">
+    <ion-buttons slot="start">
+      <ion-button (click)="dismiss()" fill="clear">
+        <ion-icon name="chevron-back" slot="icon-only"></ion-icon>
+      </ion-button>
+    </ion-buttons>
     <ion-title>编辑资料</ion-title>
     <ion-buttons slot="end">
-      <ion-button (click)="dismiss()">
-        <ion-icon name="close"></ion-icon>
+      <ion-button (click)="saveChanges()" fill="clear" [strong]="true">
+        完成
       </ion-button>
     </ion-buttons>
   </ion-toolbar>
 </ion-header>
 
-<ion-content class="ion-padding">
-  <ion-list>
-    <ion-item>
-      <ion-label position="stacked">用户名</ion-label>
-      <ion-input type="text" placeholder="输入新用户名"></ion-input>
-    </ion-item>
+<ion-content class="ion-padding" [fullscreen]="true">
+  <!-- 头像编辑区域 -->
+  <div class="avatar-section" (click)="changeAvatar()">
+    <div class="avatar-container">
+      <img [src]="userData.avatar || 'https://randomuser.me/api/portraits/men/32.jpg'" alt="用户头像" class="user-avatar">
+      <div class="edit-avatar-btn">
+        <ion-icon name="camera-outline"></ion-icon>
+      </div>
+    </div>
+    <ion-note class="avatar-note">点击修改头像</ion-note>
+  </div>
 
-        <ion-item>
-      <ion-label position="stacked">性别</ion-label>
-      <ion-input type="text" placeholder="输入您的性别"></ion-input>
+  <!-- 表单区域 -->
+  <ion-list lines="none" class="form-list">
+    <!-- 昵称 -->
+    <ion-item class="form-item" button detail (click)="editUsername()">
+      <ion-label class="form-label">昵称</ion-label>
+      <ion-note slot="end" class="form-value">{{userData.username || '未设置'}}</ion-note>
+      <ion-icon  slot="end"  color="medium"></ion-icon>
     </ion-item>
 
-        <ion-item>
-      <ion-label position="stacked">年龄</ion-label>
-      <ion-input type="text" placeholder="输入您的年龄"></ion-input>
+    <!-- 性别 -->
+    <ion-item class="form-item" button detail (click)="editGender()">
+      <ion-label class="form-label">性别</ion-label>
+      <ion-note slot="end" class="form-value">{{getGenderText(userData.gender)}}</ion-note>
+      <ion-icon  slot="end" color="medium"></ion-icon>
     </ion-item>
 
-        <ion-item>
-      <ion-label position="stacked">生日</ion-label>
-      <ion-input type="text" placeholder="输入您的生日"></ion-input>
+    <!-- 地区 -->
+    <ion-item class="form-item" button detail (click)="editLocation()">
+      <ion-label class="form-label">地区</ion-label>
+      <ion-note slot="end" class="form-value">{{userData.location || '未设置'}}</ion-note>
+      <ion-icon  slot="end" color="medium"></ion-icon>
     </ion-item>
 
-            <ion-item>
-      <ion-label position="stacked">所在地</ion-label>
-      <ion-input type="text" placeholder="输入您的地址"></ion-input>
+    <!-- 手机号 -->
+    <ion-item class="form-item" button detail (click)="editPhone()">
+      <ion-label class="form-label">手机号</ion-label>
+      <ion-note slot="end" class="form-value">{{userData.phone || '未绑定'}}</ion-note>
+      <ion-icon  slot="end" color="medium"></ion-icon>
     </ion-item>
 
-    <ion-item>
-      <ion-label position="stacked">密码</ion-label>
-      <ion-input type="password" placeholder="输入新密码"></ion-input>
+    <!-- 个性签名 -->
+    <ion-item class="form-item" button detail (click)="editBio()">
+      <ion-label class="form-label">个性签名</ion-label>
+      <ion-note slot="end" class="form-value bio">{{userData.bio || '未设置'}}</ion-note>
+      <ion-icon  slot="end" color="medium"></ion-icon>
     </ion-item>
   </ion-list>
 
-  <ion-button expand="block" color="primary">
-    <ion-icon name="save" slot="start"></ion-icon>
-    保存更改
-  </ion-button>
+  <!-- 其他信息 -->
+  <div class="other-info">
+    <ion-note>注册时间: {{userData.registerTime | date: 'yyyy-MM-dd'}}</ion-note>
+    <ion-note>UID: {{userData.uid}}</ion-note>
+  </div>
 </ion-content>

+ 114 - 0
myapp/src/lib/user/user-edit/user-edit.component.scss

@@ -0,0 +1,114 @@
+/* 旅游APP风格 - 个人资料编辑页面样式 */
+ion-header {
+  ion-toolbar {
+    --background: var(--ion-color-primary);
+    --color: white;
+    
+    ion-button {
+      --color: white;
+    }
+  }
+}
+
+.avatar-section {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin: 20px 0 30px;
+  padding: 0 16px;
+  
+  .avatar-container {
+    position: relative;
+    width: 80px;
+    height: 80px;
+    margin-bottom: 8px;
+    
+    .user-avatar {
+      width: 100%;
+      height: 100%;
+      border-radius: 50%;
+      object-fit: cover;
+      border: 2px solid var(--ion-color-light);
+    }
+    
+    .edit-avatar-btn {
+      position: absolute;
+      right: -4px;
+      bottom: -4px;
+      width: 28px;
+      height: 28px;
+      border-radius: 50%;
+      background: var(--ion-color-primary);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      
+      // ion-icon {
+      //   color: white;
+      //   font-size: 1rem;
+      // }
+    }
+  }
+  
+  .avatar-note {
+    color: var(--ion-color-medium);
+    font-size: 0.85rem;
+  }
+}
+
+.form-list {
+  background: white;
+  border-radius: 12px;
+  padding: 0 12px;
+  margin: 0 0 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+  
+  .form-item {
+    --padding-start: 0;
+    --inner-padding-end: 0;
+    --min-height: 56px;
+    border-bottom: 1px solid var(--ion-color-light);
+    
+    &:last-child {
+      border-bottom: none;
+    }
+    
+    .form-label {
+      font-size: 1rem;
+      color: var(--ion-color-dark);
+      flex: 0 0 80px;
+    }
+    
+    .form-value {
+      font-size: 0.95rem;
+      color: var(--ion-color-medium);
+      text-align: right;
+      padding-right: 8px;
+      
+      &.bio {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        max-width: 180px;
+      }
+    }
+    
+    ion-icon {
+      color: var(--ion-color-medium);
+      font-size: 1rem;
+    }
+  }
+}
+
+.other-info {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 12px 0;
+  
+  ion-note {
+    font-size: 0.8rem;
+    color: var(--ion-color-medium);
+    margin-bottom: 4px;
+  }
+}

+ 203 - 5
myapp/src/lib/user/user-edit/user-edit.component.ts

@@ -1,18 +1,216 @@
-import { Component } from '@angular/core';
-import { IonHeader, IonToolbar, IonTitle, IonButtons, IonButton, IonIcon, IonContent, IonList, IonItem, IonLabel, IonInput } from '@ionic/angular/standalone';
-import { ModalController } from '@ionic/angular/standalone';
+import { Component, Input } from '@angular/core';
+import { 
+  IonHeader, IonToolbar, IonTitle, IonButtons, IonButton, 
+  IonIcon, IonContent, IonList, IonItem, IonLabel, IonNote,
+  ModalController, AlertController
+} from '@ionic/angular/standalone';
+import { DatePipe } from '@angular/common';
+import { FormsModule } from '@angular/forms';
 
 @Component({
   selector: 'app-user-edit',
   templateUrl: './user-edit.component.html',
   styleUrls: ['./user-edit.component.scss'],
   standalone: true,
-  imports: [IonHeader, IonToolbar, IonTitle, IonButtons, IonButton, IonIcon, IonContent, IonList, IonItem, IonLabel, IonInput]
+  imports: [
+    IonHeader, IonToolbar, IonTitle, IonButtons, IonButton, 
+    IonIcon, IonContent, IonList, IonItem, IonLabel, IonNote,
+    FormsModule, DatePipe
+  ]
 })
 export class UserEditComponent {
-  constructor(private modalCtrl: ModalController) {}
+  @Input() initialData: any;
+  
+  userData = {
+    avatar: '',
+    username: '旅行达人',
+    gender: 'male',
+    location: '北京',
+    phone: '138****1234',
+    bio: '热爱旅行,分享美好生活',
+    registerTime: new Date().toISOString(),
+    uid: 'TC123456'
+  };
+
+  constructor(
+    private modalCtrl: ModalController,
+    private alertCtrl: AlertController
+  ) {}
+
+  ngOnInit() {
+    if (this.initialData) {
+      this.userData = {
+        ...this.userData,
+        ...this.initialData
+      };
+    }
+  }
+
+  getGenderText(gender: string): string {
+    switch(gender) {
+      case 'male': return '男';
+      case 'female': return '女';
+      default: return '未知';
+    }
+  }
 
   dismiss() {
     this.modalCtrl.dismiss();
   }
+
+  async saveChanges() {
+    const alert = await this.alertCtrl.create({
+      header: '保存成功',
+      message: '个人资料已更新',
+      buttons: ['确定']
+    });
+    await alert.present();
+    
+    this.modalCtrl.dismiss({
+      saved: true,
+      data: this.userData
+    });
+  }
+
+  async changeAvatar() {
+    console.log('Change avatar clicked');
+    // 实现头像修改逻辑
+  }
+
+  async editUsername() {
+    const alert = await this.alertCtrl.create({
+      header: '修改昵称',
+      inputs: [
+        {
+          name: 'username',
+          type: 'text',
+          value: this.userData.username,
+          placeholder: '请输入新昵称'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '确定',
+          handler: (data) => {
+            if (data.username) {
+              this.userData.username = data.username;
+            }
+          }
+        }
+      ]
+    });
+    await alert.present();
+  }
+
+  async editGender() {
+    const alert = await this.alertCtrl.create({
+      header: '选择性别',
+      inputs: [
+        {
+          name: 'gender',
+          type: 'radio',
+          label: '男',
+          value: 'male',
+          checked: this.userData.gender === 'male'
+        },
+        {
+          name: 'gender',
+          type: 'radio',
+          label: '女',
+          value: 'female',
+          checked: this.userData.gender === 'female'
+        },
+        {
+          name: 'gender',
+          type: 'radio',
+          label: '保密',
+          value: 'secret',
+          checked: this.userData.gender === 'secret'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '确定',
+          handler: (data) => {
+            this.userData.gender = data;
+          }
+        }
+      ]
+    });
+    await alert.present();
+  }
+
+  async editLocation() {
+    const alert = await this.alertCtrl.create({
+      header: '修改地区',
+      inputs: [
+        {
+          name: 'location',
+          type: 'text',
+          value: this.userData.location,
+          placeholder: '请输入新地区'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '确定',
+          handler: (data) => {
+            if (data.location) {
+              this.userData.location = data.location;
+            }
+          }
+        }
+      ]
+    });
+    await alert.present();
+  }
+
+  async editPhone() {
+    console.log('Edit phone');
+    // 实现手机号修改
+  }
+
+  async editBio() {
+    const alert = await this.alertCtrl.create({
+      header: '个性签名',
+      inputs: [
+        {
+          name: 'bio',
+          type: 'textarea',
+          value: this.userData.bio,
+          placeholder: '请输入个性签名(最多50字)',
+          attributes: {
+            maxlength: 50
+          }
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '确定',
+          handler: (data) => {
+            if (data.bio) {
+              this.userData.bio = data.bio;
+            }
+          }
+        }
+      ]
+    });
+    await alert.present();
+  }
 }