forked from zhouruizhe/gmTouringMiniApp
43 lines
1.7 KiB
Python
43 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from .schemas import PlanRecommendationRequest, PoiCandidate
|
|
|
|
|
|
THEME_TAGS: dict[str, set[str]] = {
|
|
"亲子": {"family_friendly", "science_learning", "indoor_venue"},
|
|
"情侣": {"photo_spot", "nature_view", "pastoral_scenery"},
|
|
"朋友": {"outdoor_leisure", "photo_spot", "culture_experience"},
|
|
"银发": {"walking", "city_park", "culture_experience", "indoor_venue"},
|
|
"研学": {"science_learning", "culture_experience", "nature_view"},
|
|
}
|
|
|
|
INTEREST_TAGS: dict[str, set[str]] = {
|
|
"自然风光": {"nature_view", "pastoral_scenery", "city_park", "outdoor_leisure"},
|
|
"文化场馆": {"culture_experience", "indoor_venue"},
|
|
"生态科普": {"science_learning", "nature_view", "pastoral_scenery"},
|
|
"美食": set(),
|
|
"摄影": {"photo_spot", "nature_view", "pastoral_scenery"},
|
|
}
|
|
|
|
|
|
def _score(candidate: PoiCandidate, request: PlanRecommendationRequest) -> int:
|
|
score = candidate.recommendation_index * 10
|
|
desired_tags: set[str] = set()
|
|
for theme in request.preferences.themes:
|
|
desired_tags.update(THEME_TAGS.get(theme, set()))
|
|
for interest in request.preferences.interests:
|
|
desired_tags.update(INTEREST_TAGS.get(interest, set()))
|
|
score += len(desired_tags.intersection(candidate.tag_codes)) * 8
|
|
if request.preferences.children and "family_friendly" in candidate.tag_codes:
|
|
score += 8
|
|
return score
|
|
|
|
|
|
def ranked_candidates(request: PlanRecommendationRequest) -> list[PoiCandidate]:
|
|
"""Provide a deterministic mock ranking without storing a second POI catalog."""
|
|
|
|
return sorted(
|
|
request.candidates,
|
|
key=lambda candidate: (-_score(candidate, request), candidate.id),
|
|
)
|