Feature: Russian language support & Vehicle Requests improvements

- Add Russian language support (title_ru, subtitle_ru) for hero banners
- Add fuel/transmission translations for Mongolian (경유→Дизель, 오토→Автомат)
- Improve Vehicle Requests admin page:
  - Display real request ID and user email
  - Show detailed request info (maker, grade, year, fuel, mileage)
  - Replace modal search with Cars page integration
- Add "Add to Request" flow in Cars page for vehicle recommendations
- Fix image URL handling in FilmStripSlider and car detail page

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
AutonetSellCar Deploy
2025-12-30 18:56:28 +09:00
parent 0ccc2f75c5
commit 1d8e4435b3
13 changed files with 306 additions and 271 deletions

View File

@@ -23,23 +23,24 @@ ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".webp"}
def get_localized_field(obj, field: str, lang: str) -> Optional[str]:
"""Get localized field value with fallback to Korean then English"""
"""Get localized field value with fallback to English"""
# 1. 선택된 언어의 필드
localized = getattr(obj, f"{field}_{lang}", None)
if localized:
return localized
# Fallback to Korean
ko_value = getattr(obj, f"{field}_ko", None)
if ko_value:
return ko_value
# Fallback to English
return getattr(obj, f"{field}_en", None)
# 2. 영어 폴백
en_value = getattr(obj, f"{field}_en", None)
if en_value:
return en_value
# 3. 한국어 폴백 (마지막 수단)
return getattr(obj, f"{field}_ko", None)
# ==================== Public Endpoints ====================
@router.get("/", response_model=List[HeroBannerLocalizedResponse])
def get_hero_banners(
lang: str = Query("ko", regex="^(ko|en|mn)$"),
lang: str = Query("ko", regex="^(ko|en|mn|ru)$"),
db: Session = Depends(get_db)
):
"""활성 히어로 배너 목록 조회 (Public)"""

View File

@@ -143,7 +143,36 @@ def admin_get_all_requests(
query = query.filter(VehicleRequest.status == status)
requests = query.order_by(VehicleRequest.created_at.desc()).all()
return requests
# User 정보 추가
result = []
for req in requests:
user = db.query(User).filter(User.id == req.user_id).first()
req_dict = {
"id": req.id,
"user_id": req.user_id,
"user_email": user.email if user else None,
"user_name": user.name if user else None,
"maker_code": req.maker_code,
"maker_name": req.maker_name,
"model_code": req.model_code,
"model_name": req.model_name,
"grade_code": req.grade_code,
"grade_name": req.grade_name,
"year_from": req.year_from,
"year_to": req.year_to,
"mileage_min": req.mileage_min,
"mileage_max": req.mileage_max,
"fuel": req.fuel,
"displacement_min": req.displacement_min,
"displacement_max": req.displacement_max,
"status": req.status,
"admin_reviewed_at": req.admin_reviewed_at,
"created_at": req.created_at,
}
result.append(req_dict)
return result
@router.get("/admin/{request_id}", response_model=VehicleRequestWithVehicles)

View File

@@ -38,11 +38,13 @@ class HeroBanner(Base):
title_ko = Column(String(100))
title_en = Column(String(100))
title_mn = Column(String(100)) # 몽골어
title_ru = Column(String(100)) # 러시아어
# 다국어 서브타이틀
subtitle_ko = Column(String(200))
subtitle_en = Column(String(200))
subtitle_mn = Column(String(200))
subtitle_ru = Column(String(200)) # 러시아어
# 이미지 URL
image_url = Column(String(500), nullable=False)

View File

@@ -36,9 +36,11 @@ class HeroBannerBase(BaseModel):
title_ko: Optional[str] = None
title_en: Optional[str] = None
title_mn: Optional[str] = None
title_ru: Optional[str] = None # 러시아어
subtitle_ko: Optional[str] = None
subtitle_en: Optional[str] = None
subtitle_mn: Optional[str] = None
subtitle_ru: Optional[str] = None # 러시아어
image_url: str
link_url: Optional[str] = None
car_id: Optional[int] = None
@@ -54,9 +56,11 @@ class HeroBannerUpdate(BaseModel):
title_ko: Optional[str] = None
title_en: Optional[str] = None
title_mn: Optional[str] = None
title_ru: Optional[str] = None # 러시아어
subtitle_ko: Optional[str] = None
subtitle_en: Optional[str] = None
subtitle_mn: Optional[str] = None
subtitle_ru: Optional[str] = None # 러시아어
image_url: Optional[str] = None
link_url: Optional[str] = None
car_id: Optional[int] = None

View File

@@ -23,6 +23,8 @@ class VehicleRequestCreate(BaseModel):
class VehicleRequestResponse(BaseModel):
id: int
user_id: int
user_email: Optional[str] = None # 관리자용
user_name: Optional[str] = None # 관리자용
maker_code: Optional[str]
maker_name: Optional[str]
model_code: Optional[str]