feat: add city search autocompletion and suggestion

This commit is contained in:
cuqmbr 2023-05-23 16:08:35 +03:00
parent e9af067dfa
commit 55bef31a2e
64 changed files with 170 additions and 71 deletions

View File

@ -1,6 +1,6 @@
using AutoMapper;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using Route = Server.Models.Route;
namespace Server.Configurations;

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters.Objects;
namespace Server.Controllers;

View File

@ -3,7 +3,7 @@ using Server.Services;
namespace Server.Controllers;
[Route("api/search")]
[Route("api/")]
[ApiController]
public class VehicleEnrollmentSearchController : ControllerBase
{
@ -14,10 +14,10 @@ public class VehicleEnrollmentSearchController : ControllerBase
_vehicleEnrollmentSearchService = vehicleEnrollmentSearchService;
}
[HttpGet]
public async Task<IActionResult> GetRoute(int from, int to, DateTime date)
[HttpGet("search")]
public async Task<IActionResult> GetEnrollments(int fromCityId, int toCityId, DateTime date)
{
var result = await _vehicleEnrollmentSearchService.GetRoute(from, to, date);
var result = await _vehicleEnrollmentSearchService.GetEnrollments(fromCityId, toCityId, date);
if (!result.isSucceed)
{
@ -26,5 +26,30 @@ public class VehicleEnrollmentSearchController : ControllerBase
return Ok(result.result);
}
}
[HttpGet("autocomplete")]
public async Task<IActionResult> AutocompleteCityName([FromQuery] string type, [FromQuery] string query, [FromQuery] int limit)
{
var result = await _vehicleEnrollmentSearchService.GetPopularCityNames(type, query, limit);
if (!result.isSucceed)
{
return result.actionResult;
}
return new OkObjectResult(result.cities);
}
[HttpGet("popular")]
public async Task<IActionResult> GetPopularCityNames([FromQuery] string type, [FromQuery] int limit)
{
var result = await _vehicleEnrollmentSearchService.GetPopularCityNames(type, limit);
if (!result.isSucceed)
{
return result.actionResult;
}
return new OkObjectResult(result.cities);
}
}

View File

@ -12,7 +12,7 @@ using Server.Data;
using Server.Helpers;
using Server.Models;
using Server.Services;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using Utils;
var builder = WebApplication.CreateBuilder(args);

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;
using Utils;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -1,6 +1,6 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;
using Utils;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;
using Route = Server.Models.Route;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Statistics;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;
using Utils;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;
using Utils;

View File

@ -1,9 +1,9 @@
using System.Dynamic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Services;
using SharedModels.Responses;
namespace Server.Services;
@ -17,8 +17,8 @@ public class VehicleEnrollmentSearchService
_dbContext = dbContext;
}
public async Task<(bool isSucceed, IActionResult? actionResult, IList<EnrollmentGroup> result)>
GetRoute(int fromCityId, int toCityId, DateTime date)
public async Task<(bool isSucceed, IActionResult actionResult, IList<EnrollmentGroup> result)>
GetEnrollments(int fromCityId, int toCityId, DateTime date)
{
var dbEnrollments = await _dbContext.VehicleEnrollments
.Include(ve => ve.Tickets)
@ -247,7 +247,7 @@ public class VehicleEnrollmentSearchService
return (false, new NotFoundResult(), null!);
}
return (true, null, result.EnrollmentGroups);
return (true, null!, result.EnrollmentGroups);
DateTime GetDepartureTime(VehicleEnrollment enrollment)
{
@ -315,4 +315,67 @@ public class VehicleEnrollmentSearchService
return result;
}
}
public async Task<(bool isSucceed, IActionResult actionResult, IList<AutocompleteCityDto> cities)>
GetPopularCityNames(string type, string name, int limit)
{
var dbCities = await _dbContext.Cities.Include(c => c.State).ThenInclude(s => s.Country)
.Where(c => EF.Functions.ILike(c.Name, $"%{name}%")).ToArrayAsync();
var dbTicketGroups = await _dbContext.TicketGroups.Include(tg => tg.Tickets)
.ThenInclude(t => t.VehicleEnrollment).ThenInclude(ve => ve.Route).ThenInclude(r => r.RouteAddresses)
.ThenInclude(ra => ra.Address).ThenInclude(a => a.City)
.Where(tg => tg.PurchaseDateTimeUtc >= DateTime.UtcNow.AddDays(-60))
.ToArrayAsync();
var cityFrequency = dbCities.ToDictionary(key => key, value => 0);
foreach (var tg in dbTicketGroups)
{
var departureCity = tg.GetDepartureAddress().City;
var arrivalCity = tg.GetArrivalAddress().City;
if ((type == "from" || type == "any") && cityFrequency.ContainsKey(departureCity))
{
cityFrequency[departureCity]++;
}
if ((type == "to" || type == "any") && cityFrequency.ContainsKey(arrivalCity))
{
cityFrequency[arrivalCity]++;
}
}
var orderedCityFrequency = cityFrequency.OrderByDescending(kvp => kvp.Value);
int order = 1;
var popularCitiesDto = new List<AutocompleteCityDto>();
foreach (var city in orderedCityFrequency.Take(limit).Select(kvp => kvp.Key))
{
popularCitiesDto.Add(new AutocompleteCityDto
{
Id = city.Id,
Name = city.Name,
StateName = city.State.Name,
CountryName = city.State.Country.Name,
FullName = city.GetFullName(),
Order = order
});
order++;
}
return (true, null!, popularCitiesDto);
}
public async Task<(bool isSucceed, IActionResult actionResult, IList<AutocompleteCityDto> cities)>
GetPopularCityNames(string type, int limit)
{
return await GetPopularCityNames(type, "", limit);
}
public async Task<(bool isSucceed, IActionResult actionResult, IList<AutocompleteCityDto> cities)>
GetPopularCityNames(int limit)
{
return await GetPopularCityNames("any", "", limit);
}
}

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Server.Data;
using Server.Helpers;
using Server.Models;
using SharedModels.DataTransferObjects;
using SharedModels.DataTransferObjects.Model;
using SharedModels.QueryParameters;
using SharedModels.QueryParameters.Objects;
using Utils;

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class AddressDto : CreateAddressDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class CityDto : CreateCityDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class CompanyDto : CreateCompanyDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class CountryDto : CreateCountryDto
{

View File

@ -1,4 +1,4 @@
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class DriverDto : UserDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class PaymentDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class ReviewDto : CreateReviewDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class RouteAddressDetailsDto : CreateRouteAddressDetailsDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class RouteAddressDto : CreateRouteAddressDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class RouteDto : CreateRouteDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class StateDto : CreateStateDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class TicketDto : CreateTicketDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class TicketGroupDto : CreateTicketGroupDto
{

View File

@ -1,7 +1,7 @@
using System.ComponentModel.DataAnnotations;
using Utils;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class UserDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class VehicleDto : CreateVehicleDto
{

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace SharedModels.DataTransferObjects;
namespace SharedModels.DataTransferObjects.Model;
public class VehicleEnrollmentDto : CreateVehicleEnrollmentDto
{

View File

@ -0,0 +1,11 @@
namespace SharedModels.DataTransferObjects.Services;
public class AutocompleteCityDto
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public string StateName { get; set; } = null!;
public string CountryName { get; set; } = null!;
public string FullName { get; set; } = null!;
public int Order { get; set; }
}