membership_offer_view.dart 7.25 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 PopScope(
        canPop: !controller.isFromOnboard,
        onPopInvokedWithResult: (didPop, _) {
          if (!didPop) {
            controller.onBackPressed();
          }
        },
        child: GuideCommonScaffold(
          showGradientBg: true,
          onBackPressed: () {
            controller.onBackPressed();
          },
          backIcon: 'assets/images/common/ic_close.png',
          bottom: OnboardingBottomButton(
            label: controller.isFromOnboard
                ? l10n.continueButton
                : l10n.freeRedemptionOffer,
            enabled: true,
            onPressed: () {
              controller.unlock();
            },
          ),
          child: SingleChildScrollView(
            physics: const ClampingScrollPhysics(),
            padding: EdgeInsets.fromLTRB(
              0,
              MediaQuery.paddingOf(context).top + 4,
              0,
              0,
            ),
            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);
  }
}