61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, func
|
|
from app.models.service import ServiceProfile, ExpertiseTag, ServiceExpertise
|
|
from app.models.organization import Organization
|
|
from geoalchemy2.functions import ST_Distance, ST_MakePoint
|
|
|
|
class SearchService:
|
|
@staticmethod
|
|
async def find_nearby_services(
|
|
db: AsyncSession,
|
|
lat: float,
|
|
lon: float,
|
|
expertise_key: str = None,
|
|
radius_km: int = 50,
|
|
is_premium: bool = False
|
|
):
|
|
"""
|
|
Keresés távolság és szakértelem alapján.
|
|
Premium: Trust Score + Valós távolság.
|
|
Free: Trust Score + Légvonal.
|
|
"""
|
|
user_point = ST_MakePoint(lon, lat) # PostGIS pont létrehozása
|
|
|
|
# Alap lekérdezés: ServiceProfile + Organization adatok
|
|
stmt = select(ServiceProfile, Organization).join(
|
|
Organization, ServiceProfile.organization_id == Organization.id
|
|
)
|
|
|
|
# 1. Sugár alapú szűrés (radius_km * 1000 méter)
|
|
stmt = stmt.where(
|
|
func.ST_DWithin(ServiceProfile.location, user_point, radius_km * 1000)
|
|
)
|
|
|
|
# 2. Szakterület szűrése
|
|
if expertise_key:
|
|
stmt = stmt.join(ServiceProfile.expertises).join(ExpertiseTag).where(
|
|
ExpertiseTag.key == expertise_key
|
|
)
|
|
|
|
# 3. Távolság és Trust Score alapú sorrend
|
|
# A ST_Distance méterben adja vissza az eredményt
|
|
stmt = stmt.order_by(ST_Distance(ServiceProfile.location, user_point))
|
|
|
|
result = await db.execute(stmt.limit(50))
|
|
rows = result.all()
|
|
|
|
# Rangsorolási logika alkalmazása
|
|
results = []
|
|
for s_prof, org in rows:
|
|
results.append({
|
|
"id": org.id,
|
|
"name": org.full_name,
|
|
"trust_score": s_prof.trust_score,
|
|
"is_verified": s_prof.is_verified,
|
|
"phone": s_prof.contact_phone,
|
|
"website": s_prof.website,
|
|
"is_premium_partner": s_prof.trust_score >= 90
|
|
})
|
|
|
|
# Súlyozott rendezés: Prémium partnerek és Trust Score előre
|
|
return sorted(results, key=lambda x: (not is_premium, -x['trust_score'])) |