Правка поиска, сортировка

This commit is contained in:
Халимов Рустам
2026-03-06 21:43:37 +03:00
parent 15c29fc296
commit 420a86b92f

View File

@@ -42,10 +42,19 @@ public static class SearchEndpoints
nearbyGeoQuery = nearbyGeoQuery.Where(x => x.Id != currentUserId.Value);
}
var nearbyGeo = await nearbyGeoQuery
var nearbyGeoRaw = await nearbyGeoQuery
.Select(x => new { x.Id, x.State, Latitude = x.Location.Coordinate.Y, Longitude = x.Location.Coordinate.X })
.ToListAsync(ct);
var nearbyGeo = nearbyGeoRaw.Select(x => new
{
x.Id,
x.State,
x.Latitude,
x.Longitude,
DistanceMeters = CalculateDistanceInMeters(lat, lon, x.Latitude, x.Longitude)
}).ToList();
var nearbyIds = nearbyGeo.Select(x => x.Id).ToList();
if (!nearbyIds.Any()) return Results.Ok(new List<object>());
@@ -62,10 +71,12 @@ public static class SearchEndpoints
(inDesc && o.Description != null && o.Description.ToLower().Contains(qLower)));
}
var matchedOffers = await offersQuery
var matchedOffersRaw = await offersQuery
.Select(o => new { o.Id, o.PerformerId, o.Title, Description = o.Description ?? "", o.Price.Amount, o.Price.Currency })
.ToListAsync(ct);
var matchedOffers = matchedOffersRaw.Select(o => new { o.Id, o.PerformerId, o.Title, o.Description, PriceAmount = o.Amount, PriceCurrency = "₽" }).ToList();
var performersWithOffers = matchedOffers.Select(o => o.PerformerId).Distinct().ToList();
// 3. Ищем пользователей, их расписание и компетенции (IdentityDbContext)
@@ -88,6 +99,14 @@ public static class SearchEndpoints
}
var profiles = await profilesQuery.ToListAsync(ct);
var profileIds = profiles.Select(p => p.Id).ToList();
var accountsRaw = await identityDb.Accounts
.Where(a => profileIds.Contains(a.Id))
.Select(a => new { a.Id, a.Roles })
.ToListAsync(ct);
var accountsDict = accountsRaw.ToDictionary(a => a.Id, a => a.Roles.Select(r => r.ToString()).ToList());
// 4. Сборка результата и логика "Умного статуса"
var currentDay = GetRussianDayOfWeek(DateTime.UtcNow.DayOfWeek);
@@ -110,6 +129,13 @@ public static class SearchEndpoints
? o.Select(x => (object)x).ToList()
: new List<object>();
var roles = accountsDict.TryGetValue(p.Id, out var r) ? r : new List<string>();
string roleName = "";
if (roles.Contains("Company")) roleName = "Компания";
else if (roles.Contains("Master")) roleName = "Мастер";
else if (roles.Contains("Candidate")) roleName = "Кандидат в мастера";
else roleName = "Пользователь";
return new
{
PerformerId = p.Id,
@@ -118,6 +144,8 @@ public static class SearchEndpoints
Latitude = g.Latitude,
Longitude = g.Longitude,
Status = finalStatus, // "Готов к заказу" или "Офлайн"
Distance = Math.Round(g.DistanceMeters),
Role = roleName,
MatchedCompetencies = p.Competencies
.Where(c => string.IsNullOrWhiteSpace(qLower) || !inComp || c.Name.ToLower().Contains(qLower))
.Select(c => c.Name).ToList(),
@@ -125,7 +153,7 @@ public static class SearchEndpoints
};
});
return Results.Ok(result.OrderByDescending(x => x.Status == "Готов к заказу").ThenBy(x => x.Name));
return Results.Ok(result.OrderByDescending(x => x.Status == "Готов к заказу").ThenBy(x => x.Distance));
})
.WithName("GlobalSearch")
.WithOpenApi(operation => new(operation)
@@ -175,4 +203,12 @@ public static class SearchEndpoints
DayOfWeek.Sunday => "Воскресенье",
_ => "Понедельник"
};
private static double CalculateDistanceInMeters(double lat1, double lon1, double lat2, double lon2)
{
var dLat = (lat2 - lat1) * Math.PI / 180.0;
var dLon = (lon2 - lon1) * Math.PI / 180.0;
var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(lat1 * Math.PI / 180.0) * Math.Cos(lat2 * Math.PI / 180.0) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
return 6371000.0 * 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
}
}