feat(ui): 결제 금액 UI 표시 적용

This commit is contained in:
JiWoong Sul
2026-01-14 00:18:37 +09:00
parent 6e7a7d2477
commit 18a0004d57
5 changed files with 42 additions and 15 deletions

View File

@@ -12,6 +12,7 @@ import 'analysis_badge.dart';
import '../../l10n/app_localizations.dart'; import '../../l10n/app_localizations.dart';
import '../../providers/locale_provider.dart'; import '../../providers/locale_provider.dart';
import '../../utils/reduce_motion.dart'; import '../../utils/reduce_motion.dart';
import '../../utils/billing_cost_util.dart';
/// 구독 서비스 비율을 파이 차트로 보여주는 카드 위젯 /// 구독 서비스 비율을 파이 차트로 보여주는 카드 위젯
class SubscriptionPieChartCard extends StatefulWidget { class SubscriptionPieChartCard extends StatefulWidget {
@@ -94,9 +95,13 @@ class _SubscriptionPieChartCardState extends State<SubscriptionPieChartCard> {
// 개별 구독의 비율 계산을 위한 값들 (기본 통화로 환산) // 개별 구독의 비율 계산을 위한 값들 (기본 통화로 환산)
List<double> sectionValues = []; List<double> sectionValues = [];
// 각 구독의 현재 가격을 언어별 기본 통화로 환산 // 각 구독의 실제 결제 금액을 언어별 기본 통화로 환산
for (var subscription in widget.subscriptions) { for (var subscription in widget.subscriptions) {
double value = subscription.currentPrice; // 월 환산 금액을 실제 결제 금액으로 역변환
double value = BillingCostUtil.convertFromMonthlyCost(
subscription.currentPrice,
subscription.billingCycle,
);
if (subscription.currency == defaultCurrency) { if (subscription.currency == defaultCurrency) {
// 이미 기본 통화인 경우 그대로 사용 // 이미 기본 통화인 경우 그대로 사용

View File

@@ -235,7 +235,7 @@ class DetailHeaderSection extends StatelessWidget {
builder: (context, snapshot) { builder: (context, snapshot) {
return _InfoColumn( return _InfoColumn(
label: AppLocalizations.of(context) label: AppLocalizations.of(context)
.monthlyExpense, .billingAmount,
value: snapshot.data ?? '-', value: snapshot.data ?? '-',
alignment: CrossAxisAlignment.end, alignment: CrossAxisAlignment.end,
wrapValue: true, wrapValue: true,

View File

@@ -203,7 +203,7 @@ class MainScreenSummaryCard extends StatelessWidget {
// 연간 비용 및 총 구독 수 표시 // 연간 비용 및 총 구독 수 표시
FutureBuilder<double>( FutureBuilder<double>(
future: CurrencyUtil future: CurrencyUtil
.calculateTotalMonthlyExpenseInDefaultCurrency( .calculateTotalAnnualExpenseInDefaultCurrency(
provider.subscriptions, provider.subscriptions,
locale, locale,
), ),
@@ -211,8 +211,7 @@ class MainScreenSummaryCard extends StatelessWidget {
if (!snapshot.hasData) { if (!snapshot.hasData) {
return const SizedBox(); return const SizedBox();
} }
final monthlyCost = snapshot.data!; final yearlyCost = snapshot.data!;
final yearlyCost = monthlyCost * 12;
final decimals = (defaultCurrency == 'KRW' || final decimals = (defaultCurrency == 'KRW' ||
defaultCurrency == 'JPY') defaultCurrency == 'JPY')
? 0 ? 0

View File

@@ -7,6 +7,7 @@ import '../providers/locale_provider.dart';
import '../services/subscription_url_matcher.dart'; import '../services/subscription_url_matcher.dart';
import '../services/currency_util.dart'; import '../services/currency_util.dart';
import '../utils/billing_date_util.dart'; import '../utils/billing_date_util.dart';
import '../utils/billing_cost_util.dart';
import '../utils/payment_card_utils.dart'; import '../utils/payment_card_utils.dart';
import 'website_icon.dart'; import 'website_icon.dart';
import 'app_navigator.dart'; import 'app_navigator.dart';
@@ -272,25 +273,41 @@ class _SubscriptionCardState extends State<SubscriptionCard>
} }
} }
// 가격 포맷팅 함수 (언어별 통화) // 가격 포맷팅 함수 (언어별 통화) - 실제 결제 금액 표시
Future<String> _getFormattedPrice() async { Future<String> _getFormattedPrice() async {
final locale = context.read<LocaleProvider>().locale.languageCode; final locale = context.read<LocaleProvider>().locale.languageCode;
final billingCycle = widget.subscription.billingCycle;
if (widget.subscription.isCurrentlyInEvent) { if (widget.subscription.isCurrentlyInEvent) {
// 이벤트 중인 경우 원래 가격과 현재 가격 모두 표시 // 이벤트 중인 경우: 월 비용을 실제 결제 금액으로 역변환
final originalPrice = await CurrencyUtil.formatAmountWithLocale( final actualOriginalPrice = BillingCostUtil.convertFromMonthlyCost(
widget.subscription.monthlyCost, widget.subscription.monthlyCost,
billingCycle,
);
final actualCurrentPrice = BillingCostUtil.convertFromMonthlyCost(
widget.subscription.currentPrice,
billingCycle,
);
final originalPrice = await CurrencyUtil.formatAmountWithLocale(
actualOriginalPrice,
widget.subscription.currency, widget.subscription.currency,
locale, locale,
); );
final currentPrice = await CurrencyUtil.formatAmountWithLocale( final currentPrice = await CurrencyUtil.formatAmountWithLocale(
widget.subscription.currentPrice, actualCurrentPrice,
widget.subscription.currency, widget.subscription.currency,
locale, locale,
); );
return '$originalPrice|$currentPrice'; return '$originalPrice|$currentPrice';
} else { } else {
return CurrencyUtil.formatAmountWithLocale( // 월 비용을 실제 결제 금액으로 역변환 (연간이면 x12, 분기면 x3 등)
final actualPrice = BillingCostUtil.convertFromMonthlyCost(
widget.subscription.currentPrice, widget.subscription.currentPrice,
billingCycle,
);
return CurrencyUtil.formatAmountWithLocale(
actualPrice,
widget.subscription.currency, widget.subscription.currency,
locale, locale,
); );

View File

@@ -12,6 +12,7 @@ import './dialogs/delete_confirmation_dialog.dart';
import './common/snackbar/app_snackbar.dart'; import './common/snackbar/app_snackbar.dart';
import '../l10n/app_localizations.dart'; import '../l10n/app_localizations.dart';
import '../utils/logger.dart'; import '../utils/logger.dart';
import '../utils/billing_cost_util.dart';
import '../utils/subscription_grouping_helper.dart'; import '../utils/subscription_grouping_helper.dart';
import 'native_ad_widget.dart'; import 'native_ad_widget.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart';
@@ -159,12 +160,17 @@ class SubscriptionListWidget extends StatelessWidget {
); );
} }
/// 특정 통화의 총 합계를 계산합니다. /// 특정 통화의 실제 결제 금액 총 합계를 계산합니다.
double _calculateTotalByCurrency( double _calculateTotalByCurrency(
List<SubscriptionModel> subscriptions, String currency) { List<SubscriptionModel> subscriptions, String currency) {
return subscriptions return subscriptions.where((sub) => sub.currency == currency).fold(
.where((sub) => sub.currency == currency) 0.0,
.fold(0.0, (sum, sub) => sum + sub.monthlyCost); (sum, sub) =>
sum +
BillingCostUtil.convertFromMonthlyCost(
sub.currentPrice,
sub.billingCycle,
));
} }
} }