Initial commit - Migrated to Dev environment
This commit is contained in:
72
backend/app/api/v1/endpoints/search.py
Executable file
72
backend/app/api/v1/endpoints/search.py
Executable file
@@ -0,0 +1,72 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import text
|
||||
from app.db.session import get_db
|
||||
from app.api.deps import get_current_user
|
||||
from app.services.matching_service import matching_service
|
||||
from app.services.config_service import config
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/match")
|
||||
async def match_service(
|
||||
lat: float,
|
||||
lng: float,
|
||||
radius: int = 20,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user = Depends(get_current_user)
|
||||
):
|
||||
# 1. SQL lekérdezés: Haversine-formula a távolság számításhoz
|
||||
# 6371 a Föld sugara km-ben
|
||||
query = text("""
|
||||
SELECT
|
||||
o.id,
|
||||
o.name,
|
||||
ol.latitude,
|
||||
ol.longitude,
|
||||
ol.label as location_name,
|
||||
(6371 * 2 * ASIN(SQRT(
|
||||
POWER(SIN((RADIANS(ol.latitude) - RADIANS(:lat)) / 2), 2) +
|
||||
COS(RADIANS(:lat)) * COS(RADIANS(ol.latitude)) *
|
||||
POWER(SIN((RADIANS(ol.longitude) - RADIANS(:lng)) / 2), 2)
|
||||
))) AS distance
|
||||
FROM data.organizations o
|
||||
JOIN data.organization_locations ol ON o.id = ol.organization_id
|
||||
WHERE o.org_type = 'SERVICE'
|
||||
AND o.is_active = True
|
||||
HAVING
|
||||
(6371 * 2 * ASIN(SQRT(
|
||||
POWER(SIN((RADIANS(ol.latitude) - RADIANS(:lat)) / 2), 2) +
|
||||
COS(RADIANS(:lat)) * COS(RADIANS(ol.latitude)) *
|
||||
POWER(SIN((RADIANS(ol.longitude) - RADIANS(:lng)) / 2), 2)
|
||||
))) <= :radius
|
||||
ORDER BY distance ASC
|
||||
""")
|
||||
|
||||
result = await db.execute(query, {"lat": lat, "lng": lng, "radius": radius})
|
||||
|
||||
# Adatok átalakítása a MatchingService számára (mock rating-et adunk hozzá, amíg nincs review tábla)
|
||||
services_to_rank = []
|
||||
for row in result.all():
|
||||
services_to_rank.append({
|
||||
"id": row.id,
|
||||
"name": row.name,
|
||||
"distance": row.distance,
|
||||
"rating": 4.5, # Alapértelmezett, amíg nincs kész az értékelési rendszer
|
||||
"tier": "gold" if row.id == 1 else "free" # Példa logika
|
||||
})
|
||||
|
||||
if not services_to_rank:
|
||||
return {"status": "no_results", "message": "Nem található szerviz a megadott körzetben."}
|
||||
|
||||
# 2. Limit lekérése a beállításokból
|
||||
limit = await config.get_setting('match_limit_default', default=5)
|
||||
|
||||
# 3. Okos rangsorolás (Admin súlyozás alapján)
|
||||
ranked_results = await matching_service.rank_services(services_to_rank)
|
||||
|
||||
return {
|
||||
"user_location": {"lat": lat, "lng": lng},
|
||||
"radius_km": radius,
|
||||
"results": ranked_results[:limit]
|
||||
}
|
||||
Reference in New Issue
Block a user