chendeben 1 рік тому
батько
коміт
72d0cda02b
1 змінених файлів з 255 додано та 120 видалено
  1. 255 120
      entry/src/main/ets/pages/UserCenter.ets

+ 255 - 120
entry/src/main/ets/pages/UserCenter.ets

@@ -59,6 +59,21 @@ interface WechatUserInfoApiResponse {
   data: GeneratedTypeLiteralInterface_1;
 }
 
+interface VipFeature {
+  icon: Resource;
+  title: string;
+  description: string;
+  isVipOnly: boolean;
+}
+
+interface VipPlan {
+  name: string;
+  price: string;
+  originalPrice: string;
+  duration: string;
+  features: string[];
+}
+
 @Component
 @Entry
 export struct UserCenter {
@@ -86,6 +101,16 @@ export struct UserCenter {
     .setOnLeftClickListener(() => {
       router.back();
     });
+  @State vipFeatures: VipFeature[] = [
+    { icon: $r('app.media.small_music'), title: '无损音质', description: '支持FLAC、WAV等无损格式', isVipOnly: true },
+    { icon: $r('app.media.small_music'), title: '歌词显示', description: '支持LRC歌词同步显示', isVipOnly: false },
+    { icon: $r('app.media.small_music'), title: '智能歌单', description: 'AI智能推荐歌单', isVipOnly: true },
+    { icon: $r('app.media.small_music'), title: '主题定制', description: '自定义播放器主题', isVipOnly: true }
+  ];
+  @State vipPlans: VipPlan[] = [
+    { name: '月度会员', price: '¥18', originalPrice: '¥30', duration: '30天', features: ['无损音质', '智能歌单', '主题定制'] },
+    { name: '年度会员', price: '¥128', originalPrice: '¥360', duration: '365天', features: ['无损音质', '智能歌单', '主题定制', '专属客服'] }
+  ];
 
   // 微信回调处理
   private onWXResp: OnWXResp = (resp) => {
@@ -179,150 +204,260 @@ export struct UserCenter {
 
   build() {
     Column() {
-      // 顶部安全区和标题栏
       Column() {
         Line().width('100%').height('100%')
       }
-      .height(this.isPhoneLan()?0:px2vp(AppUtil.getStatusBarHeight()))
+      .height(this.isPhoneLan() ? 0 : px2vp(AppUtil.getStatusBarHeight()))
       .backgroundColor($r('app.color.title_bar_bg'))
       .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
       TitleBar({ model: this.titleBarModel })
 
-      // 用户信息卡片
-      Column() {
-        // 头像居中
-        Row() {
-          Blank().layoutWeight(1)
-          Image(this.userAvatarUrl && this.userAvatarUrl.length > 0 ? this.userAvatarUrl : this.userAvatar)
-            .width(80)
-            .height(80)
-            .borderRadius('50%')
-            .clip(true)
-            .backgroundColor(Color.White)
-            .shadow({ radius: 8, color: 0x11000000, offsetX: 0, offsetY: 2 })
-          Blank().layoutWeight(1)
+      Scroll() {
+        Column() {
+          this.buildUserInfoCard()
+          this.buildVipFeatures()
+          this.buildVipPlans()
+          this.buildFunctionMenu()
+          this.buildLoginButton()
         }
-        .margin({ top: 32, bottom: 12 })
-
-        // 昵称
-        Text(this.isLogin ? this.userName : '未登录用户')
-          .fontSize(22)
-          .fontWeight(FontWeight.Bold)
-          .fontColor(Color.Black)
-          .margin({ bottom: 4 })
-          .alignSelf(ItemAlign.Center)
+        .width('100%')
+      }
+      .scrollBar(BarState.Off)
+      .edgeEffect(EdgeEffect.Spring)
+    }
+    .backgroundColor(0xFFF6F7FA)
+    .width('100%')
+    .height('100%')
+  }
 
-        // 身份信息
-        if (this.isLogin) {
-          if (this.hasActiveSubscription) {
-            Text(this.subscriptionName)
-              .fontSize(16)
-              .fontColor(Color.Red)
-              .alignSelf(ItemAlign.Center)
-            Text('到期:' + this.subscriptionEndDate)
-              .fontSize(14)
-              .fontColor(Color.Gray)
-              .alignSelf(ItemAlign.Center)
-          } else {
-            Text('普通用户')
-              .fontSize(15)
-              .fontColor(Color.Grey)
-              .alignSelf(ItemAlign.Center)
+  // 用户信息卡片
+  @Builder
+  buildUserInfoCard() {
+    Column() {
+      Row() {
+        Image(this.userAvatarUrl && this.userAvatarUrl.length > 0 ? this.userAvatarUrl : this.userAvatar)
+          .width(80)
+          .height(80)
+          .borderRadius('50%')
+          .clip(true)
+          .backgroundColor(Color.White)
+          .shadow({ radius: 8, color: 0x11000000, offsetX: 0, offsetY: 2 })
+        Column() {
+          Text(this.isLogin ? this.userName : '未登录用户')
+            .fontSize(22)
+            .fontWeight(FontWeight.Bold)
+            .fontColor(Color.Black)
+          if (this.isLogin) {
+            if (this.hasActiveSubscription) {
+              Text(this.subscriptionName)
+                .fontSize(16)
+                .fontColor(Color.Red)
+              Text('到期:' + this.subscriptionEndDate)
+                .fontSize(14)
+                .fontColor(Color.Gray)
+            } else {
+              Text('普通用户')
+                .fontSize(15)
+                .fontColor(Color.Grey)
+            }
           }
-        } else {
-          Text('请先登录')
-            .fontSize(15)
-            .fontColor(Color.Grey)
-            .alignSelf(ItemAlign.Center)
         }
+        .alignItems(HorizontalAlign.Start)
+        .margin({ left: 16 })
       }
-      .backgroundColor(Color.White)
-      .borderRadius(24)
-      .margin({ left: 20, right: 20, top: 20, bottom: 0 })
-      .shadow({ radius: 12, color: 0x11000000, offsetX: 0, offsetY: 2 })
+      .width('100%')
+      .padding(16)
+    }
+    .backgroundColor(Color.White)
+    .borderRadius(24)
+    .margin({ left: 20, right: 20, top: 20 })
+    .shadow({ radius: 12, color: 0x11000000, offsetX: 0, offsetY: 2 })
+  }
 
-      // 操作列表
-      Column() {
-        this.menuItem($r('app.media.icon_favorite'), '我的收藏', () => {
-          if (!this.isLogin) {
-            ToastUtil.showToast('请先登录')
-            return
-          }
-          ToastUtil.showToast('我的收藏')
-        })
-        Line().width('90%').height(0.5).backgroundColor(0xFFEFEFEF).alignSelf(ItemAlign.Center)
-        this.menuItem($r('app.media.icon_history'), '历史记录', () => {
-          if (!this.isLogin) {
-            ToastUtil.showToast('请先登录')
-            return
+  // 会员权益展示
+  @Builder
+  buildVipFeatures() {
+    Column() {
+      Text('会员权益')
+        .fontSize(18)
+        .fontWeight(FontWeight.Bold)
+        .margin({ top: 24, bottom: 16 })
+      Grid() {
+        ForEach(this.vipFeatures, (feature: VipFeature) => {
+          GridItem() {
+            Column() {
+              Image(feature.icon)
+                .width(32)
+                .height(32)
+                .margin({ bottom: 8 })
+              Text(feature.title)
+                .fontSize(16)
+                .fontWeight(FontWeight.Medium)
+              Text(feature.description)
+                .fontSize(12)
+                .fontColor(Color.Gray)
+                .margin({ top: 4 })
+              if (feature.isVipOnly) {
+                Text('VIP专享')
+                  .fontSize(10)
+                  .fontColor(Color.Red)
+                  .backgroundColor('#FFF0F0')
+                  .borderRadius(8)
+                  .padding({ left: 6, right: 6, top: 2, bottom: 2 })
+                  .margin({ top: 4 })
+              }
+            }
+            .width('100%')
+            .height(120)
+            .backgroundColor(Color.White)
+            .borderRadius(12)
+            .padding(12)
           }
-          ToastUtil.showToast('历史记录')
-        })
-        Line().width('90%').height(0.5).backgroundColor(0xFFEFEFEF).alignSelf(ItemAlign.Center)
-        this.menuItem($r('app.media.icon_person2'), '联系客服', () => {
-          Utility.copyText(CommonConstants.CONTACT_MAIL)
-          ToastUtil.showToast('已复制客服邮箱')
         })
       }
-      .backgroundColor(Color.White)
-      .borderRadius(24)
-      .margin({ left: 20, right: 20, top: 24, bottom: 0 })
-      .shadow({ radius: 8, color: 0x11000000, offsetX: 0, offsetY: 2 })
+      .columnsTemplate('1fr 1fr')
+      .columnsGap(12)
+      .rowsGap(12)
+      .margin({ left: 20, right: 20 })
+    }
+  }
 
-      // 退出登录/登录按钮
-      Row() {
-        Blank().layoutWeight(1)
-        if (this.isLogin) {
-          Button('退出登录')
+  // 会员套餐选择
+  @Builder
+  buildVipPlans() {
+    Column() {
+      Text('会员套餐')
+        .fontSize(18)
+        .fontWeight(FontWeight.Bold)
+        .margin({ top: 24, bottom: 16 })
+      ForEach(this.vipPlans, (plan: VipPlan) => {
+        Row() {
+          Column() {
+            Text(plan.name)
+              .fontSize(16)
+              .fontWeight(FontWeight.Bold)
+            Text(plan.duration)
+              .fontSize(12)
+              .fontColor(Color.Gray)
+              .margin({ top: 4 })
+          }
+          .layoutWeight(1)
+          Column() {
+            Text(plan.price)
+              .fontSize(20)
+              .fontWeight(FontWeight.Bold)
+              .fontColor(Color.Red)
+            Text(plan.originalPrice)
+              .fontSize(12)
+              .fontColor(Color.Gray)
+              .decoration({ type: TextDecorationType.LineThrough })
+          }
+          Button('立即开通')
+            .fontSize(14)
             .fontColor(Color.White)
             .backgroundColor(Color.Red)
-            .height(48)
-            .width('70%')
-            .borderRadius(24)
+            .borderRadius(16)
+            .height(32)
+            .width(80)
+            .margin({ left: 16 })
             .onClick(() => {
-              this.isLogin = false
-              this.userName = '未登录用户'
-              this.userAvatar = $r('app.media.icon_person2')
-              this.userAvatarUrl = ''
-              this.isVip = false
-              this.vipExpire = ''
-              this.hasActiveSubscription = false;
-              this.subscriptionName = '';
-              this.subscriptionEndDate = '';
-              PreferencesUtil.putSync('isLogin', false);
-              PreferencesUtil.putSync('userName', '未登录用户');
-              PreferencesUtil.putSync('userAvatarUrl', '');
-              PreferencesUtil.putSync('subscriptionName', '');
-              PreferencesUtil.putSync('subscriptionEndDate', '');
-              PreferencesUtil.putSync('hasActiveSubscription', false);
-              ToastUtil.showToast('已退出登录')
-              // 这里可以添加退出登录逻辑
-            })
-        } else {
-          Button('登录')
-            .fontColor(Color.White)
-            .backgroundColor($r('app.color.title_bar_bg'))
-            .height(48)
-            .width('70%')
-            .borderRadius(24)
-            .onClick(async () => {
-              let req = new wxopensdk.SendAuthReq
-              req.isOption1 = false
-              req.nonAutomatic = true
-              req.scope = 'snsapi_userinfo,snsapi_friend,snsapi_message,snsapi_contact'
-              req.state = 'none'
-              req.transaction = 'test123'
-              let finished = await this.wxApi.sendReq(getContext(this) as common.UIAbilityContext, req)
-              console.log('send request finished: ', finished)
+              if (!this.isLogin) {
+                ToastUtil.showToast('请先登录')
+                return
+              }
+              // 处理购买逻辑
             })
         }
-        Blank().layoutWeight(1)
+        .width('100%')
+        .padding(16)
+        .backgroundColor(Color.White)
+        .borderRadius(12)
+        .margin({ bottom: 12 })
+      })
+    }
+    .margin({ left: 20, right: 20 })
+  }
+
+  // 功能菜单
+  @Builder
+  buildFunctionMenu() {
+    Column() {
+      this.menuItem($r('app.media.icon_favorite'), '我的收藏', () => {
+        if (!this.isLogin) {
+          ToastUtil.showToast('请先登录')
+          return
+        }
+        // 跳转到收藏页面
+      })
+      Line().width('90%').height(0.5).backgroundColor(0xFFEFEFEF)
+      this.menuItem($r('app.media.icon_history'), '播放历史', () => {
+        if (!this.isLogin) {
+          ToastUtil.showToast('请先登录')
+          return
+        }
+        // 跳转到历史记录页面
+      })
+      Line().width('90%').height(0.5).backgroundColor(0xFFEFEFEF)
+      this.menuItem($r('app.media.setting'), '设置', () => {
+        // 跳转到设置页面
+      })
+    }
+    .backgroundColor(Color.White)
+    .borderRadius(24)
+    .margin({ left: 20, right: 20, top: 24 })
+  }
+
+  // 登录/退出按钮
+  @Builder
+  buildLoginButton() {
+    Row() {
+      Blank().layoutWeight(1)
+      if (this.isLogin) {
+        Button('退出登录')
+          .fontColor(Color.White)
+          .backgroundColor(Color.Red)
+          .height(48)
+          .width('70%')
+          .borderRadius(24)
+          .onClick(() => {
+            this.isLogin = false
+            this.userName = '未登录用户'
+            this.userAvatar = $r('app.media.icon_person2')
+            this.userAvatarUrl = ''
+            this.isVip = false
+            this.vipExpire = ''
+            this.hasActiveSubscription = false;
+            this.subscriptionName = '';
+            this.subscriptionEndDate = '';
+            PreferencesUtil.putSync('isLogin', false);
+            PreferencesUtil.putSync('userName', '未登录用户');
+            PreferencesUtil.putSync('userAvatarUrl', '');
+            PreferencesUtil.putSync('subscriptionName', '');
+            PreferencesUtil.putSync('subscriptionEndDate', '');
+            PreferencesUtil.putSync('hasActiveSubscription', false);
+            ToastUtil.showToast('已退出登录')
+          })
+      } else {
+        Button('登录')
+          .fontColor(Color.White)
+          .backgroundColor($r('app.color.title_bar_bg'))
+          .height(48)
+          .width('70%')
+          .borderRadius(24)
+          .onClick(async () => {
+            let req = new wxopensdk.SendAuthReq
+            req.isOption1 = false
+            req.nonAutomatic = true
+            req.scope = 'snsapi_userinfo,snsapi_friend,snsapi_message,snsapi_contact'
+            req.state = 'none'
+            req.transaction = 'test123'
+            let finished = await this.wxApi.sendReq(getContext(this) as common.UIAbilityContext, req)
+            console.log('send request finished: ', finished)
+          })
       }
-      .margin({ top: 48, bottom: 0 })
+      Blank().layoutWeight(1)
     }
-    .backgroundColor(0xFFF6F7FA)
-    .width('100%')
-    .height('100%')
+    .margin({ top: 48, bottom: 0 })
   }
 
   isPhoneLan() {