feat: 구독 URL 매칭 서비스 개선 및 컨트롤러 최적화
- URL 매칭 로직 개선 - 구독 추가/상세 화면 컨트롤러 리팩토링 - assets 폴더 구조 추가 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode;
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '../providers/subscription_provider.dart';
|
||||
@@ -73,6 +73,9 @@ class AddSubscriptionController {
|
||||
// 서비스명 컨트롤러에 리스너 추가
|
||||
serviceNameController.addListener(onServiceNameChanged);
|
||||
|
||||
// 웹사이트 URL 컨트롤러에 리스너 추가
|
||||
websiteUrlController.addListener(onWebsiteUrlChanged);
|
||||
|
||||
// 애니메이션 컨트롤러 초기화
|
||||
animationController = AnimationController(
|
||||
vsync: vsync,
|
||||
@@ -133,6 +136,52 @@ class AddSubscriptionController {
|
||||
void onServiceNameChanged() {
|
||||
autoSelectCategory();
|
||||
}
|
||||
|
||||
/// 웹사이트 URL 변경시 호출
|
||||
void onWebsiteUrlChanged() async {
|
||||
final url = websiteUrlController.text.trim();
|
||||
|
||||
// URL이 비어있거나 너무 짧으면 무시
|
||||
if (url.isEmpty || url.length < 5) return;
|
||||
|
||||
// 이미 서비스명이 입력되어 있으면 자동 매칭하지 않음
|
||||
if (serviceNameController.text.isNotEmpty) return;
|
||||
|
||||
try {
|
||||
// URL로 서비스 정보 찾기
|
||||
final serviceInfo = await SubscriptionUrlMatcher.findServiceByUrl(url);
|
||||
|
||||
if (serviceInfo != null && context.mounted) {
|
||||
// 서비스명 자동 입력
|
||||
serviceNameController.text = serviceInfo.serviceName;
|
||||
|
||||
// 카테고리 자동 선택
|
||||
final categoryProvider = Provider.of<CategoryProvider>(context, listen: false);
|
||||
final categories = categoryProvider.categories;
|
||||
|
||||
// 카테고리 ID로 매칭
|
||||
final matchedCategory = categories.firstWhere(
|
||||
(cat) => cat.name == serviceInfo.categoryNameKr ||
|
||||
cat.name == serviceInfo.categoryNameEn,
|
||||
orElse: () => categories.first,
|
||||
);
|
||||
|
||||
selectedCategoryId = matchedCategory.id;
|
||||
|
||||
// 스낵바로 알림
|
||||
if (context.mounted) {
|
||||
AppSnackBar.showSuccess(
|
||||
context: context,
|
||||
message: '${serviceInfo.serviceName} 서비스가 자동으로 인식되었습니다.',
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('AddSubscriptionController: URL 자동 매칭 중 오류 - $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 카테고리 자동 선택
|
||||
void autoSelectCategory() {
|
||||
@@ -254,8 +303,42 @@ class AddSubscriptionController {
|
||||
}
|
||||
|
||||
final subscription = subscriptions.first;
|
||||
|
||||
// SMS에서 서비스 정보 추출 시도
|
||||
ServiceInfo? serviceInfo;
|
||||
final smsContent = subscription['smsContent'] ?? '';
|
||||
|
||||
if (smsContent.isNotEmpty) {
|
||||
try {
|
||||
serviceInfo = await SubscriptionUrlMatcher.extractServiceFromSms(smsContent);
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print('AddSubscriptionController: SMS 서비스 추출 실패 - $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {
|
||||
serviceNameController.text = subscription['serviceName'] ?? '';
|
||||
// 서비스 정보가 있으면 우선 사용, 없으면 SMS에서 추출한 정보 사용
|
||||
if (serviceInfo != null) {
|
||||
serviceNameController.text = serviceInfo.serviceName;
|
||||
websiteUrlController.text = serviceInfo.serviceUrl ?? '';
|
||||
|
||||
// 카테고리 자동 선택
|
||||
final categoryProvider = Provider.of<CategoryProvider>(context, listen: false);
|
||||
final categories = categoryProvider.categories;
|
||||
|
||||
final matchedCategory = categories.firstWhere(
|
||||
(cat) => cat.name == serviceInfo!.categoryNameKr ||
|
||||
cat.name == serviceInfo.categoryNameEn,
|
||||
orElse: () => categories.first,
|
||||
);
|
||||
|
||||
selectedCategoryId = matchedCategory.id;
|
||||
} else {
|
||||
// 기존 로직 사용
|
||||
serviceNameController.text = subscription['serviceName'] ?? '';
|
||||
}
|
||||
|
||||
// 비용 처리 및 통화 단위 자동 감지
|
||||
final costValue = subscription['monthlyCost']?.toString() ?? '';
|
||||
@@ -289,12 +372,13 @@ class AddSubscriptionController {
|
||||
? DateTime.parse(subscription['nextBillingDate'])
|
||||
: DateTime.now();
|
||||
|
||||
// 서비스명이 있으면 URL 자동 매칭 시도
|
||||
if (subscription['serviceName'] != null &&
|
||||
// 서비스 정보가 없고 서비스명이 있으면 URL 자동 매칭 시도
|
||||
if (serviceInfo == null &&
|
||||
subscription['serviceName'] != null &&
|
||||
subscription['serviceName'].isNotEmpty) {
|
||||
final suggestedUrl =
|
||||
SubscriptionUrlMatcher.suggestUrl(subscription['serviceName']);
|
||||
if (suggestedUrl != null) {
|
||||
if (suggestedUrl != null && websiteUrlController.text.isEmpty) {
|
||||
websiteUrlController.text = suggestedUrl;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user