import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:nomo/config/theme/dark_theme_colors.dart'; import 'package:nomo/config/theme/theme_extensions/theme_extension.dart'; import 'package:shimmer/shimmer.dart'; import 'package:video_player/video_player.dart'; import '../../../../config/theme/light_theme_colors.dart'; import '../../../../config/translations/strings_enum.dart'; import '../../../constants/assets.dart'; import '../../../widgets/info_card.dart'; import '../../../widgets/ix_image.dart'; import '../controllers/subscription_controller.dart'; class SubscriptionView extends GetView { const SubscriptionView({super.key}); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Get.reactiveTheme.scaffoldBackgroundColor, body: Stack( children: [ // 视频背景层(只显示顶部214高度) Obx(() { if (controller.isVideoInitialized.value) { return Positioned( top: 0, left: 0, right: 0, height: 214.w, child: ClipRect( child: FittedBox( fit: BoxFit.cover, child: SizedBox( width: controller.videoController.value.size.width, height: controller.videoController.value.size.height, child: VideoPlayer(controller.videoController), ), ), ), ); } return const SizedBox.shrink(); }), // 渐变遮罩层(只在视频区域) Positioned( top: 0, left: 0, right: 0, height: 214.w, child: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: ReactiveTheme.isLightTheme ? [Colors.black, Color(0x99F5D89F), Color(0xFFEFF1F5)] : [Colors.black.withValues(alpha: 0.6), Colors.black], stops: ReactiveTheme.isLightTheme ? const [0.0, 0.7, 1.0] : const [0.0, 1.0], ), ), ), ), // 内容层 SafeArea( child: Column( children: [ _buildAppBar(), Expanded( child: SingleChildScrollView( padding: EdgeInsets.symmetric(horizontal: 20.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 16.verticalSpaceFromWidth, _buildCurrentSubscription(), 24.verticalSpaceFromWidth, _buildPlanOptions(), // 仅 userLevel == 3 时显示套餐变更信息 // if (controller.showPlanChangeInfo) // _buildPlanChangeInfo(), _buildPremiumFeatures(), 16.verticalSpaceFromWidth, ], ), ), ), _buildBottomSection(), ], ), ), ], ), ); } // 顶部标题栏 Widget _buildAppBar() { return Padding( padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 12.h), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox(width: 32.w), Text( Strings.subscription.tr, style: TextStyle( fontSize: 16.sp, height: 1.4, fontWeight: FontWeight.w500, color: Colors.white, ), ), GestureDetector( onTap: () => Get.back(), child: Container( width: 24.w, height: 24.w, decoration: BoxDecoration( color: ReactiveTheme.isLightTheme ? LightThemeColors.strokes1 : Color(0xFF333333), shape: BoxShape.circle, ), child: Icon( Icons.close_rounded, color: ReactiveTheme.isLightTheme ? LightThemeColors.text2 : Colors.white, size: 16.w, ), ), ), ], ), ); } // 当前订阅信息 Widget _buildCurrentSubscription() { return Obx(() { // 判断是否有订阅 if (!controller.hasCurrentSubscription) { // 没有订阅,只显示钻石图标 return Center( child: IXImage( source: Assets.subscriptionDiamond, width: 92.w, height: 80.w, sourceType: ImageSourceType.asset, ), ); } // 有订阅,显示当前套餐信息 return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // 钻石图标 IXImage( source: Assets.subscriptionDiamond, width: 92.w, height: 80.w, sourceType: ImageSourceType.asset, ), 12.horizontalSpace, Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ IXImage( source: Assets.subscriptionWallet, width: 20.w, height: 20.w, sourceType: ImageSourceType.asset, ), 4.horizontalSpace, Text( Strings.currentSubscription.tr, style: TextStyle( fontSize: 14.sp, height: 1.4, color: ReactiveTheme.isLightTheme ? LightThemeColors.text1 : DarkThemeColors.subscriptionColor, fontWeight: FontWeight.w700, ), ), ], ), 10.verticalSpaceFromWidth, Text( controller.currentPlanPriceDisplay, style: TextStyle( fontSize: 14.sp, height: 1.4, color: Get.reactiveTheme.textTheme.bodyLarge!.color, ), ), ], ), ), ], ); }); } // 订阅计划选项 Widget _buildPlanOptions() { return Obx(() { // 加载中状态 if (controller.isLoadingPlans.value) { return Column( children: List.generate(3, (index) => _buildPlanShimmer()), ); } // 空数据状态 if (controller.planCount == 0) { return Padding( padding: EdgeInsets.all(20.w), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset(Assets.oops, width: 170.w, height: 170.w), 10.verticalSpaceFromWidth, Text( Strings.oops.tr, style: TextStyle( fontSize: 22.sp, fontWeight: FontWeight.w400, height: 1.3, color: Get.reactiveTheme.textTheme.bodyLarge!.color, ), ), 4.verticalSpace, Padding( padding: EdgeInsets.symmetric(horizontal: 32.w), child: Text( Strings.connectionIssueDetected.tr, textAlign: TextAlign.center, style: TextStyle( fontSize: 14.sp, height: 1.4, color: Get.reactiveTheme.hintColor, ), ), ), ], ), ), ); } // 套餐列表 return Column( children: List.generate( controller.planCount, (index) => _buildPlanItem(index), ), ); }); } Widget _buildPlanShimmer() { final baseColor = ReactiveTheme.isLightTheme ? Colors.grey[300]! : Colors.grey[700]!; final highlightColor = ReactiveTheme.isLightTheme ? Colors.grey[100]! : Colors.grey[600]!; return Container( margin: EdgeInsets.only(bottom: 18.w), decoration: BoxDecoration( color: Get.reactiveTheme.cardColor, borderRadius: BorderRadius.circular(12.r), border: Border.all(color: Get.reactiveTheme.dividerColor, width: 2.w), ), child: Shimmer.fromColors( baseColor: baseColor, highlightColor: highlightColor, child: Padding( padding: EdgeInsets.all(10.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // 左侧:模拟价格信息 Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 120.w, height: 18.w, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4.r), ), ), 8.verticalSpace, Container( width: 80.w, height: 14.w, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4.r), ), ), ], ), // 右侧:模拟标题 Container( width: 60.w, height: 16.w, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4.r), ), ), ], ), ), ), ); } Widget _buildPlanItem(int index) { return Obx(() { final isSelected = controller.selectedPlanIndex.value == index; final badge = controller.getPlanBadge(index); final badgeBgColor = controller.getPlanBadgeBgColor(index); final badgeTextColor = controller.getPlanBadgeTextColor(index); final badgeBorderColor = controller.getPlanBadgeBorderColor(index); return GestureDetector( onTap: () => controller.selectPlan(index), child: Container( margin: EdgeInsets.only(bottom: 18.w), decoration: BoxDecoration( color: Get.reactiveTheme.cardColor, borderRadius: BorderRadius.circular(12.r), border: Border.all( color: isSelected ? DarkThemeColors.subscriptionColor : Get.reactiveTheme.dividerColor, width: 2.w, ), ), child: Stack( clipBehavior: Clip.none, children: [ // 主要内容 Padding( padding: EdgeInsets.all(10.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // 左侧:价格信息 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( controller.getPlanTitle(index), style: TextStyle( fontSize: 18.sp, height: 1.4, color: Get.reactiveTheme.textTheme.bodyLarge!.color, fontWeight: FontWeight.w600, ), ), Text( controller.getPlanSubTitle(index), style: TextStyle( fontSize: 12.sp, height: 1.6, color: Get.reactiveTheme.hintColor, ), ), ], ), ), // 右侧:标题和选择框 Row( children: [ Text( controller.getPlanIntroduce(index), style: TextStyle( fontSize: 13.sp, height: 1.4, color: Get.reactiveTheme.textTheme.bodyLarge!.color, ), ), // 8.horizontalSpace, // Container( // width: 20.w, // height: 20.w, // decoration: BoxDecoration( // shape: BoxShape.circle, // border: Border.all( // color: isSelected // ? DarkThemeColors.primaryColor // : ReactiveTheme.isLightTheme // ? LightThemeColors.strokes1 // : Colors.white30, // width: 1.5.w, // ), // color: isSelected // ? DarkThemeColors.primaryColor // : Colors.transparent, // ), // child: isSelected // ? Icon( // Icons.check, // color: Colors.white, // size: 12.w, // ) // : null, // ), ], ), ], ), ), // 标签固定在右上角,压在边框线上 if (badge.isNotEmpty) Positioned( top: -11.h, right: 12.w, child: Container( padding: EdgeInsets.symmetric(horizontal: 6.w), decoration: BoxDecoration( color: badgeBgColor ?? Colors.black, borderRadius: BorderRadius.circular(4.r), border: badgeBorderColor != null ? Border.all(color: badgeBorderColor, width: 1) : null, ), child: Text( badge, style: TextStyle( fontSize: 12.sp, color: badgeTextColor ?? Colors.white, height: 1.6, ), ), ), ), ], ), ), ); }); } // 计划变更信息 Widget _buildPlanChangeInfo() { return InfoCard( title: Strings.planChangeInfo.tr, items: [ InfoItem( imageSource: Assets.subscriptionPlanChange1, title: Strings.whenItStarts.tr, description: Strings.yourNewPlanBeginsRightAway.tr, iconColor: DarkThemeColors.primaryColor, ), InfoItem( imageSource: Assets.subscriptionPlanChange2, title: Strings.whatHappensToYourBalance.tr, description: Strings.anyUnusedAmountFromYourOldPlan.tr, iconColor: DarkThemeColors.primaryColor, ), InfoItem( imageSource: Assets.subscriptionPlanChange3, title: Strings.extraTime.tr, description: Strings.youllGetExtraDays.tr, iconColor: DarkThemeColors.primaryColor, ), ], ); } // Premium 功能列表 Widget _buildPremiumFeatures() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( Strings.premiumsIncluded.tr, style: TextStyle( fontSize: 16.sp, color: ReactiveTheme.isLightTheme ? LightThemeColors.primaryColor : DarkThemeColors.subscriptionColor, fontWeight: FontWeight.w500, ), ), 16.verticalSpace, Container( padding: EdgeInsets.symmetric(vertical: 4.w, horizontal: 10.w), decoration: BoxDecoration( color: Get.reactiveTheme.cardColor, borderRadius: BorderRadius.circular(12.r), ), child: Column( children: [ Obx( () => _buildFeatureItem( Assets.equity1, Strings.equity1Title.trParams({ 'count': controller.selectedPlanDeviceLimit, }), Strings.equity1Desc.trParams({ 'count': controller.selectedPlanDeviceLimit, }), ), ), Divider(height: 1.w, color: Get.reactiveTheme.dividerColor), _buildFeatureItem( Assets.equity2, Strings.equity2Title.tr, Strings.equity2Desc.tr, ), Divider(height: 1.w, color: Get.reactiveTheme.dividerColor), _buildFeatureItem( Assets.equity3, Strings.equity3Title.tr, Strings.equity3Desc.tr, ), Divider(height: 1.w, color: Get.reactiveTheme.dividerColor), _buildFeatureItem( Assets.equity4, Strings.equity4Title.tr, Strings.equity4Desc.tr, ), Divider(height: 1.w, color: Get.reactiveTheme.dividerColor), _buildFeatureItem( Assets.equity5, Strings.equity5Title.tr, Strings.equity5Desc.tr, ), Divider(height: 1.w, color: Get.reactiveTheme.dividerColor), _buildFeatureItem( Assets.equity6, Strings.equity6Title.tr, Strings.equity6Desc.tr, ), ], ), ), ], ); } Widget _buildFeatureItem(String imagePath, String title, String subtitle) { return Padding( padding: EdgeInsets.symmetric(vertical: 10.w), child: Row( children: [ Image.asset(imagePath, width: 24.w, height: 24.w), 16.horizontalSpace, Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, color: Get.reactiveTheme.textTheme.bodyLarge!.color, ), ), 4.verticalSpace, Text( subtitle, style: TextStyle( fontSize: 12.sp, color: Get.reactiveTheme.hintColor, ), ), ], ), ), ], ), ); } // 底部按钮区域 Widget _buildBottomSection() { return Container( padding: EdgeInsets.symmetric(vertical: 10.w, horizontal: 14.w), decoration: BoxDecoration( border: Border( top: BorderSide(color: Get.reactiveTheme.dividerColor, width: 1), ), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // 确认按钮 GestureDetector( onTap: controller.subscribe, child: Container( width: double.infinity, height: 48.w, decoration: BoxDecoration( color: DarkThemeColors.backgroundColor, borderRadius: BorderRadius.circular(12.r), ), child: Center( child: Text( controller.showPlanChangeInfo ? Strings.confirmChange.tr : Strings.subscription.tr, style: TextStyle( fontSize: 16.sp, color: DarkThemeColors.subscriptionColor, fontWeight: FontWeight.w600, ), ), ), ), ), 14.verticalSpaceFromWidth, // 底部链接 if (controller.apiController.fp.channel == 'google' || controller.apiController.fp.channel == 'apple') ...[ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( onTap: controller.restorePurchases, child: Text( Strings.restorePurchases.tr, style: TextStyle( fontSize: 16.sp, color: Get.reactiveTheme.textTheme.bodyLarge!.color, ), ), ), // Text( // ' | ', // style: TextStyle( // fontSize: 16.sp, // color: Get.reactiveTheme.hintColor, // ), // ), // GestureDetector( // onTap: controller.handlePaymentIssue, // child: Text( // Strings.paymentIssue.tr, // style: TextStyle( // fontSize: 16.sp, // color: Get.reactiveTheme.textTheme.bodyLarge!.color, // ), // ), // ), ], ), 14.verticalSpaceFromWidth, Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IXImage( source: Assets.subscriptionGreenShield, width: 20.w, height: 20.w, sourceType: ImageSourceType.asset, ), 10.horizontalSpace, Text( Strings.yearlyAutoRenewCancelAnytime.tr, style: TextStyle( fontSize: 13.sp, color: Get.reactiveTheme.hintColor, ), ), ], ), ], ], ), ); } }