membership_offer_view.dart 6.5 KB
import 'package:doublefeel_flutter/app/modules/membership_offer/controllers/membership_offer_controller.dart';
import 'package:doublefeel_flutter/app/routes/app_pages.dart';
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:doublefeel_flutter/data/models/pay/pay_models.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:doublefeel_flutter/pigeon/platform_api.g.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';

import '../../user_onboarding/widget/guide_common_scaffold.dart';
import '../../user_onboarding/widget/onboarding_common_widgets.dart';

class MembershipOfferView extends GetView<MembershipOfferController> {
  const MembershipOfferView({super.key});

  @override
  Widget build(BuildContext context) {
    final l10n = context.l10n;
    return GuideCommonScaffold(
      showGradientBg: true,
      onBackPressed: () {
        controller.onBackPressed();
      },
      bottom: OnboardingBottomButton(
        label: controller.isFromOnboard ? l10n.continueButton : '免费兑换优惠',
        enabled: true,
        onPressed: () {
          controller.unlock();
        },
      ),
      child: SingleChildScrollView(
        physics: const ClampingScrollPhysics(),
        padding: EdgeInsets.fromLTRB(
          0,
          MediaQuery.paddingOf(context).top + 4,
          0,
          140,
        ),
        child: Stack(
          children: [
            IgnorePointer(
              child: Lottie.asset('assets/lottie/scatter_flowers.json'),
            ),
            Column(
              mainAxisSize: MainAxisSize.max,
              children: [
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  child: Column(
                    children: [
                      SizedBox(height: 48),
                      OnboardingTitleText(l10n.onboardingMemberTitle),
                      const SizedBox(height: 12),
                      OnboardingBodyText(
                        l10n.onboardingMemberBody,
                        fontSize: 14,
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 12),
                Image.asset(
                    'assets/images/user_onboarding/ic_membership_box.png'),
                const SizedBox(height: 4),
                Obx(() {
                  final yearInfo = controller.yearlyProductAppleInfo.value;
                  final yearProduct = controller.yearlyProduct.value;

                  return yearInfo == null || yearProduct == null
                      ? const SizedBox(child: CircularProgressIndicator())
                      : Column(
                          children: [
                            Text(
                              '原价${_originDisplayPrice(yearInfo)}/年',
                              textAlign: TextAlign.center,
                              style: const TextStyle(
                                color: Color(0xFFB0B0B6),
                                fontSize: 16,
                                decoration: TextDecoration.lineThrough,
                                decorationColor: Color(0xFFB0B0B6),
                                letterSpacing: 0,
                              ),
                            ),
                            const SizedBox(height: 6),
                            Text(
                              _displayPrice(yearInfo),
                              textAlign: TextAlign.center,
                              style: TextStyle(
                                color: context.colors.primary,
                                fontSize: 28,
                                fontWeight: FontWeight.w600,
                                letterSpacing: 0,
                              ),
                            ),
                            const SizedBox(height: 6),
                            Text(
                              _planSubtitle(yearProduct, yearInfo),
                              textAlign: TextAlign.center,
                              style: const TextStyle(
                                color: Color(0xFFB0B0B6),
                                fontSize: 12,
                                letterSpacing: 0,
                              ),
                            ),
                          ],
                        );
                }),
                const SizedBox(height: 58),
                GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  onTap: () {
                    Get.offNamed(Routes.PURCHASE);
                  },
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                      vertical: 12,
                      horizontal: 24,
                    ),
                    child: Text(
                      l10n.onboardingMemberAllOptions,
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        color: context.colors.textPrimary,
                        fontSize: 12,
                        decoration: TextDecoration.underline,
                        decorationColor: context.colors.textPrimary,
                        letterSpacing: 0,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  String _originDisplayPrice(AppleProductInfo appleInfo) {
    final actual =
        appleInfo.price > 0 ? appleInfo.price : appleInfo.originPrice;
    final inflated = actual / 100.0 * 1.2;
    // 保留两位小数,单位与 currencyCode 一致
    return '${appleInfo.currencyCode}${inflated.toStringAsFixed(2)}';
  }

  String _displayPrice(AppleProductInfo appleInfo) {
    final price = appleInfo.price;
    if (price > 0) {
      final priceDescription = appleInfo.priceDescription.trim();
      if (priceDescription.isNotEmpty) {
        return priceDescription;
      }
    }
    return appleInfo.originPriceDescription;
  }

  String? _nonEmpty(String? value) {
    final trimmed = value?.trim();
    if (trimmed == null || trimmed.isEmpty) return null;
    return trimmed;
  }

  String _planSubtitle(PayProduct product, AppleProductInfo? appleInfo) {
    if (product.content?.isYearProduct() != true) {
      return _nonEmpty(product.content?.description) ?? '';
    }

    final unitPrice = _nonEmpty(appleInfo?.unitPrice);
    return unitPrice == null ? '' : l10n.purchaseMonthlyUnitPrice(unitPrice);
  }
}