55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
# /opt/docker/dev/service_finder/backend/app/services/search_service.py
|
|
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 PostGIS funkciókkal.
|
|
"""
|
|
user_point = ST_MakePoint(lon, lat)
|
|
|
|
# Alap lekérdezés joinolva az Organization-el a nevekért
|
|
stmt = select(ServiceProfile, Organization).join(
|
|
Organization, ServiceProfile.organization_id == Organization.id
|
|
).where(
|
|
func.ST_DWithin(ServiceProfile.location, user_point, radius_km * 1000)
|
|
)
|
|
|
|
# SZAKÉRTELEM SZŰRÉS (Logic Preserved)
|
|
if expertise_key:
|
|
stmt = stmt.join(ServiceProfile.expertises).join(ExpertiseTag).where(
|
|
ExpertiseTag.key == expertise_key
|
|
)
|
|
|
|
# RENDEZÉS TÁVOLSÁG SZERINT
|
|
stmt = stmt.order_by(ST_Distance(ServiceProfile.location, user_point))
|
|
|
|
result = await db.execute(stmt.limit(50))
|
|
rows = result.all()
|
|
|
|
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 (Logic Preserved: Premium előre, Trust Score csökkenő)
|
|
return sorted(results, key=lambda x: (not is_premium, -x['trust_score'])) |