fix(form): 폼 데이터 생성 시 URL 추출 로직 추가
- RestaurantFormData.fromControllers에 _extractNaverUrl 추가 - 공유 텍스트에서 순수 URL만 추출하여 저장 - 폼 필드 변경 시에도 올바른 URL 유지
This commit is contained in:
@@ -8,6 +8,15 @@ import '../providers/di_providers.dart';
|
|||||||
import '../providers/restaurant_provider.dart';
|
import '../providers/restaurant_provider.dart';
|
||||||
import '../providers/location_provider.dart';
|
import '../providers/location_provider.dart';
|
||||||
|
|
||||||
|
/// 지오코딩 실패 시 발생하는 예외
|
||||||
|
class GeocodingException implements Exception {
|
||||||
|
final String message;
|
||||||
|
const GeocodingException(this.message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => message;
|
||||||
|
}
|
||||||
|
|
||||||
/// 식당 추가 화면의 상태 모델
|
/// 식당 추가 화면의 상태 모델
|
||||||
class AddRestaurantState {
|
class AddRestaurantState {
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
@@ -128,10 +137,23 @@ class RestaurantFormData {
|
|||||||
jibunAddress: jibunAddressController.text.trim(),
|
jibunAddress: jibunAddressController.text.trim(),
|
||||||
latitude: latitudeController.text.trim(),
|
latitude: latitudeController.text.trim(),
|
||||||
longitude: longitudeController.text.trim(),
|
longitude: longitudeController.text.trim(),
|
||||||
naverUrl: naverUrlController.text.trim(),
|
naverUrl: _extractNaverUrl(naverUrlController.text.trim()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 공유 텍스트에서 네이버 지도 URL만 추출
|
||||||
|
static String _extractNaverUrl(String text) {
|
||||||
|
if (text.isEmpty) return '';
|
||||||
|
|
||||||
|
// URL 패턴 추출
|
||||||
|
final urlRegex = RegExp(
|
||||||
|
r'(https?://(?:map\.naver\.com|naver\.me)[^\s]+)',
|
||||||
|
caseSensitive: false,
|
||||||
|
);
|
||||||
|
final match = urlRegex.firstMatch(text);
|
||||||
|
return match?.group(0) ?? text;
|
||||||
|
}
|
||||||
|
|
||||||
/// Restaurant 엔티티로부터 폼 데이터 생성
|
/// Restaurant 엔티티로부터 폼 데이터 생성
|
||||||
factory RestaurantFormData.fromRestaurant(Restaurant restaurant) {
|
factory RestaurantFormData.fromRestaurant(Restaurant restaurant) {
|
||||||
return RestaurantFormData(
|
return RestaurantFormData(
|
||||||
@@ -351,7 +373,11 @@ class AddRestaurantViewModel extends StateNotifier<AddRestaurantState> {
|
|||||||
state = state.copyWith(isLoading: false);
|
state = state.copyWith(isLoading: false);
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state = state.copyWith(isLoading: false, errorMessage: e.toString());
|
// GeocodingException은 이미 사용자 친화적 메시지가 설정됨
|
||||||
|
final message = e is GeocodingException
|
||||||
|
? e.message
|
||||||
|
: '저장 중 오류가 발생했습니다. 다시 시도해주세요.';
|
||||||
|
state = state.copyWith(isLoading: false, errorMessage: message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,12 +500,9 @@ class AddRestaurantViewModel extends StateNotifier<AddRestaurantState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!allowFallbackWhenGeocodingFails) {
|
if (!allowFallbackWhenGeocodingFails) {
|
||||||
state = state.copyWith(
|
const userMessage = '위치 정보를 가져올 수 없습니다. 주소를 확인해주세요.';
|
||||||
errorMessage:
|
state = state.copyWith(errorMessage: userMessage);
|
||||||
'주소가 지도에서 인식되지 않습니다. '
|
throw GeocodingException(userMessage);
|
||||||
'도로명 주소 전체를 정확히 입력했는지 확인해 주세요.',
|
|
||||||
);
|
|
||||||
throw Exception('지오코딩 실패: $address');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user