From 18a0004d579865a6a009ed0135511a09199ae155 Mon Sep 17 00:00:00 2001 From: JiWoong Sul Date: Wed, 14 Jan 2026 00:18:37 +0900 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=EA=B2=B0=EC=A0=9C=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20UI=20=ED=91=9C=EC=8B=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analysis/subscription_pie_chart_card.dart | 9 +++++-- lib/widgets/detail/detail_header_section.dart | 2 +- lib/widgets/main_summary_card.dart | 5 ++-- lib/widgets/subscription_card.dart | 27 +++++++++++++++---- lib/widgets/subscription_list_widget.dart | 14 +++++++--- 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/lib/widgets/analysis/subscription_pie_chart_card.dart b/lib/widgets/analysis/subscription_pie_chart_card.dart index 9d7786b..9767493 100644 --- a/lib/widgets/analysis/subscription_pie_chart_card.dart +++ b/lib/widgets/analysis/subscription_pie_chart_card.dart @@ -12,6 +12,7 @@ import 'analysis_badge.dart'; import '../../l10n/app_localizations.dart'; import '../../providers/locale_provider.dart'; import '../../utils/reduce_motion.dart'; +import '../../utils/billing_cost_util.dart'; /// 구독 서비스 비율을 파이 차트로 보여주는 카드 위젯 class SubscriptionPieChartCard extends StatefulWidget { @@ -94,9 +95,13 @@ class _SubscriptionPieChartCardState extends State { // 개별 구독의 비율 계산을 위한 값들 (기본 통화로 환산) List sectionValues = []; - // 각 구독의 현재 가격을 언어별 기본 통화로 환산 + // 각 구독의 실제 결제 금액을 언어별 기본 통화로 환산 for (var subscription in widget.subscriptions) { - double value = subscription.currentPrice; + // 월 환산 금액을 실제 결제 금액으로 역변환 + double value = BillingCostUtil.convertFromMonthlyCost( + subscription.currentPrice, + subscription.billingCycle, + ); if (subscription.currency == defaultCurrency) { // 이미 기본 통화인 경우 그대로 사용 diff --git a/lib/widgets/detail/detail_header_section.dart b/lib/widgets/detail/detail_header_section.dart index 905f453..5432aa1 100644 --- a/lib/widgets/detail/detail_header_section.dart +++ b/lib/widgets/detail/detail_header_section.dart @@ -235,7 +235,7 @@ class DetailHeaderSection extends StatelessWidget { builder: (context, snapshot) { return _InfoColumn( label: AppLocalizations.of(context) - .monthlyExpense, + .billingAmount, value: snapshot.data ?? '-', alignment: CrossAxisAlignment.end, wrapValue: true, diff --git a/lib/widgets/main_summary_card.dart b/lib/widgets/main_summary_card.dart index c085a9a..cf95fcc 100644 --- a/lib/widgets/main_summary_card.dart +++ b/lib/widgets/main_summary_card.dart @@ -203,7 +203,7 @@ class MainScreenSummaryCard extends StatelessWidget { // 연간 비용 및 총 구독 수 표시 FutureBuilder( future: CurrencyUtil - .calculateTotalMonthlyExpenseInDefaultCurrency( + .calculateTotalAnnualExpenseInDefaultCurrency( provider.subscriptions, locale, ), @@ -211,8 +211,7 @@ class MainScreenSummaryCard extends StatelessWidget { if (!snapshot.hasData) { return const SizedBox(); } - final monthlyCost = snapshot.data!; - final yearlyCost = monthlyCost * 12; + final yearlyCost = snapshot.data!; final decimals = (defaultCurrency == 'KRW' || defaultCurrency == 'JPY') ? 0 diff --git a/lib/widgets/subscription_card.dart b/lib/widgets/subscription_card.dart index a11ef07..e627547 100644 --- a/lib/widgets/subscription_card.dart +++ b/lib/widgets/subscription_card.dart @@ -7,6 +7,7 @@ import '../providers/locale_provider.dart'; import '../services/subscription_url_matcher.dart'; import '../services/currency_util.dart'; import '../utils/billing_date_util.dart'; +import '../utils/billing_cost_util.dart'; import '../utils/payment_card_utils.dart'; import 'website_icon.dart'; import 'app_navigator.dart'; @@ -272,25 +273,41 @@ class _SubscriptionCardState extends State } } - // 가격 포맷팅 함수 (언어별 통화) + // 가격 포맷팅 함수 (언어별 통화) - 실제 결제 금액 표시 Future _getFormattedPrice() async { final locale = context.read().locale.languageCode; + final billingCycle = widget.subscription.billingCycle; + if (widget.subscription.isCurrentlyInEvent) { - // 이벤트 중인 경우 원래 가격과 현재 가격 모두 표시 - final originalPrice = await CurrencyUtil.formatAmountWithLocale( + // 이벤트 중인 경우: 월 비용을 실제 결제 금액으로 역변환 + final actualOriginalPrice = BillingCostUtil.convertFromMonthlyCost( widget.subscription.monthlyCost, + billingCycle, + ); + final actualCurrentPrice = BillingCostUtil.convertFromMonthlyCost( + widget.subscription.currentPrice, + billingCycle, + ); + + final originalPrice = await CurrencyUtil.formatAmountWithLocale( + actualOriginalPrice, widget.subscription.currency, locale, ); final currentPrice = await CurrencyUtil.formatAmountWithLocale( - widget.subscription.currentPrice, + actualCurrentPrice, widget.subscription.currency, locale, ); return '$originalPrice|$currentPrice'; } else { - return CurrencyUtil.formatAmountWithLocale( + // 월 비용을 실제 결제 금액으로 역변환 (연간이면 x12, 분기면 x3 등) + final actualPrice = BillingCostUtil.convertFromMonthlyCost( widget.subscription.currentPrice, + billingCycle, + ); + return CurrencyUtil.formatAmountWithLocale( + actualPrice, widget.subscription.currency, locale, ); diff --git a/lib/widgets/subscription_list_widget.dart b/lib/widgets/subscription_list_widget.dart index 3517ee8..f379009 100644 --- a/lib/widgets/subscription_list_widget.dart +++ b/lib/widgets/subscription_list_widget.dart @@ -12,6 +12,7 @@ import './dialogs/delete_confirmation_dialog.dart'; import './common/snackbar/app_snackbar.dart'; import '../l10n/app_localizations.dart'; import '../utils/logger.dart'; +import '../utils/billing_cost_util.dart'; import '../utils/subscription_grouping_helper.dart'; import 'native_ad_widget.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; @@ -159,12 +160,17 @@ class SubscriptionListWidget extends StatelessWidget { ); } - /// 특정 통화의 총 합계를 계산합니다. + /// 특정 통화의 실제 결제 금액 총 합계를 계산합니다. double _calculateTotalByCurrency( List subscriptions, String currency) { - return subscriptions - .where((sub) => sub.currency == currency) - .fold(0.0, (sum, sub) => sum + sub.monthlyCost); + return subscriptions.where((sub) => sub.currency == currency).fold( + 0.0, + (sum, sub) => + sum + + BillingCostUtil.convertFromMonthlyCost( + sub.currentPrice, + sub.billingCycle, + )); } }