import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:nomo/app/constants/iconfont/iconfont.dart'; import 'package:nomo/config/theme/dark_theme_colors.dart'; import 'package:nomo/config/theme/theme_extensions/theme_extension.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(), 16.verticalSpaceFromWidth, _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 Padding( padding: EdgeInsets.symmetric(vertical: 40.w), child: Center( child: CircularProgressIndicator( color: DarkThemeColors.subscriptionColor, ), ), ); } // 空数据状态 if (controller.planCount == 0) { return Padding( padding: EdgeInsets.symmetric(vertical: 40.w), child: Center( child: Text( '暂无可用套餐', style: TextStyle( fontSize: 14.sp, color: DarkThemeColors.hintTextColor, ), ), ), ); } // 套餐列表 return Column( children: List.generate( controller.planCount, (index) => _buildPlanItem(index), ), ); }); } 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.cardColor, 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: [ _buildFeatureItem( IconFont.icon60, Strings.unlockAllFreeLocations.tr, ), _buildFeatureItem(IconFont.icon61, Strings.unlockSmartMode.tr), _buildFeatureItem(IconFont.icon62, Strings.unlockMultiHopMode.tr), Obx( () => _buildFeatureItem( IconFont.icon63, Strings.premiumCanShareXDevices.trParams({ 'count': controller.selectedPlanDeviceLimit, }), ), ), _buildFeatureItem( IconFont.icon64, Strings.ownYourOwnPrivateServer.tr, ), _buildFeatureItem(IconFont.icon65, Strings.closeAds.tr), ], ), ), ], ); } Widget _buildFeatureItem(IconData icon, String title) { return SizedBox( height: 44.w, child: Row( children: [ Icon( icon, color: ReactiveTheme.isLightTheme ? LightThemeColors.primaryColor : DarkThemeColors.subscriptionColor, size: 24.w, ), 12.horizontalSpace, Expanded( child: Text( title, style: TextStyle( fontSize: 13.sp, color: Get.reactiveTheme.hintColor, ), ), ), Container( width: 20.w, height: 20.w, decoration: BoxDecoration( shape: BoxShape.circle, color: DarkThemeColors.subscriptionSelectColor, ), child: Icon(Icons.check, color: Colors.white, size: 12.w), ), ], ), ); } // 底部按钮区域 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, // 底部链接 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, ), ), ], ), ], ), ); } }