feat: Asset Catalog system, PostGIS integration and RobotScout V1
This commit is contained in:
61
backend/app/services/search_service.py
Normal file
61
backend/app/services/search_service.py
Normal file
@@ -0,0 +1,61 @@
|
||||
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']))
|
||||
Reference in New Issue
Block a user