diff --git a/AsbCloudApp/Data/ClusterDto.cs b/AsbCloudApp/Data/ClusterDto.cs index 8751807a..895d3501 100644 --- a/AsbCloudApp/Data/ClusterDto.cs +++ b/AsbCloudApp/Data/ClusterDto.cs @@ -8,7 +8,8 @@ namespace AsbCloudApp.Data public string Caption { get; set; } public double? Latitude { get; set; } public double? Longitude { get; set; } - + public int? IdDeposit { get; set; } + public DepositBaseDto Deposit { get; set; } public IEnumerable Wells { get; set; } } } diff --git a/AsbCloudApp/Data/DepositDto.cs b/AsbCloudApp/Data/DepositDto.cs index dfc3d580..71d59f9c 100644 --- a/AsbCloudApp/Data/DepositDto.cs +++ b/AsbCloudApp/Data/DepositDto.cs @@ -2,13 +2,16 @@ namespace AsbCloudApp.Data { - public class DepositDto : IMapPoint, IId + public class DepositBaseDto : IMapPoint, IId { public int Id { get; set; } public string Caption { get; set; } public double? Latitude { get; set; } public double? Longitude { get; set; } + } + public class DepositDto : DepositBaseDto + { public IEnumerable Clusters { get; set; } } } diff --git a/AsbCloudApp/Data/TelemetryDto.cs b/AsbCloudApp/Data/TelemetryDto.cs index 94ff740e..221e10dd 100644 --- a/AsbCloudApp/Data/TelemetryDto.cs +++ b/AsbCloudApp/Data/TelemetryDto.cs @@ -1,10 +1,13 @@ -namespace AsbCloudApp.Data +using System.Text.Json.Serialization; + +namespace AsbCloudApp.Data { public class TelemetryDto : IId { public int Id { get; set; } public string RemoteUid { get; set; } public TelemetryInfoDto Info { get; set; } - public WellDto Well { get; set; } + public int? IdWell { get; set; } + public WellInfoDto Well { get; set; } } } diff --git a/AsbCloudApp/Data/WellDto.cs b/AsbCloudApp/Data/WellDto.cs index 7d2bef82..a7a235cf 100644 --- a/AsbCloudApp/Data/WellDto.cs +++ b/AsbCloudApp/Data/WellDto.cs @@ -1,16 +1,15 @@ using System; +using System.Collections.Generic; namespace AsbCloudApp.Data { - public class WellDto : WellInfoDto, IMapPoint, IId { public int Id { get; set; } public double? Latitude { get; set; } public double? Longitude { get; set; } public string WellType { get; set; } - public int IdWellType { get; set; } - + public int IdWellType { get; set; } public int? IdCluster { get; set; } /// @@ -22,5 +21,6 @@ namespace AsbCloudApp.Data public DateTime LastTelemetryDate { get; set; } public int? IdTelemetry { get; set; } public TelemetryDto Telemetry { get; set; } + public IEnumerable Companies { get; set; } } } diff --git a/AsbCloudApp/Data/WellParamsDto.cs b/AsbCloudApp/Data/WellParamsDto.cs deleted file mode 100644 index 36fe5418..00000000 --- a/AsbCloudApp/Data/WellParamsDto.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace AsbCloudApp.Data -{ - public class WellParamsDto - { - public string Caption { get; set; } - public double? Latitude { get; set; } - public double? Longitude { get; set; } - public int IdWellType { get; set; } - public int IdState { get; set; } - } -} \ No newline at end of file diff --git a/AsbCloudApp/Services/ICachedCrudService.cs b/AsbCloudApp/Services/ICachedCrudService.cs deleted file mode 100644 index 26751519..00000000 --- a/AsbCloudApp/Services/ICachedCrudService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using AsbCloudApp.Data; - -namespace AsbCloudApp.Services -{ - public interface ICachedCrudService where Tdto : IId - { - } -} \ No newline at end of file diff --git a/AsbCloudApp/Services/IWellService.cs b/AsbCloudApp/Services/IWellService.cs index 10c9512e..b8206976 100644 --- a/AsbCloudApp/Services/IWellService.cs +++ b/AsbCloudApp/Services/IWellService.cs @@ -6,15 +6,13 @@ using System.Threading.Tasks; namespace AsbCloudApp.Services { - public interface IWellService + public interface IWellService: ICrudService { Task> GetWellsByCompanyAsync(int idCompany, CancellationToken token); - Task UpdateWellAsync(int idWell, WellParamsDto dto, CancellationToken token = default); - Task> GetTransmittingWellsAsync(int idCompany, CancellationToken token); Task IsCompanyInvolvedInWellAsync(int idCompany, int idWell, CancellationToken token); Task GetWellCaptionByIdAsync(int idWell, CancellationToken token); - Task> GetCompaniesAsync(int idWell, CancellationToken token); - Task GetAsync(int idWell, CancellationToken token); + //TODO: remove that + Task> GetCompaniesAsync(int idWell, CancellationToken token); bool IsCompanyInvolvedInWell(int idCompany, int idWell); string GetStateText(int state); DateTime GetLastTelemetryDate(int idWell); diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index 2fbebbbe..a77c2cdf 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -50,7 +50,6 @@ namespace AsbCloudDb.Model DbSet Set() where TEntity : class; - IQueryable GetWellsForCompany(int idCompany); Task<(DateTime From, DateTime To)> GetDatesRangeAsync(int idTelemetry, CancellationToken token) where T : class, ITelemetryData; Task> GetDepthToIntervalAsync(int telemetryId, int intervalHoursTimestamp, int workStartTimestamp, double timezoneOffset, CancellationToken token); diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index f16b4a7d..7eef6f57 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -63,7 +63,6 @@ namespace AsbCloudInfrastructure services.AddTransient(); // admin crud services: - services.AddTransient, CrudServiceBase>(); services.AddTransient, CrudServiceBase>(); services.AddTransient, DrillParamsService>(); services.AddTransient, CrudServiceBase>(); diff --git a/AsbCloudInfrastructure/Services/Cache/CacheDb.cs b/AsbCloudInfrastructure/Services/Cache/CacheDb.cs index bff205ad..e4c8cf8f 100644 --- a/AsbCloudInfrastructure/Services/Cache/CacheDb.cs +++ b/AsbCloudInfrastructure/Services/Cache/CacheDb.cs @@ -11,6 +11,11 @@ namespace AsbCloudInfrastructure.Services.Cache private readonly ConcurrentDictionary cache = new ConcurrentDictionary(); + + public CacheTable GetCachedTable(DbContext context, params string[] includes) + where TEntity : class + => GetCachedTable(context, includes); + public CacheTable GetCachedTable(DbContext context, IEnumerable includes = null) where TEntity : class { diff --git a/AsbCloudInfrastructure/Services/CrudCacheServiceBase.cs b/AsbCloudInfrastructure/Services/CrudCacheServiceBase.cs index 207cb69d..6a04a50f 100644 --- a/AsbCloudInfrastructure/Services/CrudCacheServiceBase.cs +++ b/AsbCloudInfrastructure/Services/CrudCacheServiceBase.cs @@ -20,7 +20,7 @@ namespace AsbCloudInfrastructure.Services public List Includes { get; } = new (); - private CacheTable Cache { + protected CacheTable Cache { get { if(cache is null) cache = cacheDb.GetCachedTable((AsbCloudDbContext)db, Includes); @@ -103,13 +103,13 @@ namespace AsbCloudInfrastructure.Services return affected; } - private TModel Convert(TDto src) + protected virtual TModel Convert(TDto src) { var entity = src.Adapt(); return entity; } - private TDto Convert(TModel src) + protected virtual TDto Convert(TModel src) { var dto = src.Adapt(); return dto; diff --git a/AsbCloudInfrastructure/Services/CrudServiceBase.cs b/AsbCloudInfrastructure/Services/CrudServiceBase.cs index a8cbacf3..45375aef 100644 --- a/AsbCloudInfrastructure/Services/CrudServiceBase.cs +++ b/AsbCloudInfrastructure/Services/CrudServiceBase.cs @@ -68,7 +68,7 @@ namespace AsbCloudInfrastructure.Services var entities = await query .OrderBy(e => e.Id) .ToListAsync(token).ConfigureAwait(false); - var dto = entities.Select(entity => Convert(entity)); + var dto = entities.Select(Convert).ToList(); return dto; } diff --git a/AsbCloudInfrastructure/Services/UserService.cs b/AsbCloudInfrastructure/Services/UserService.cs index d4438fdd..ea379d55 100644 --- a/AsbCloudInfrastructure/Services/UserService.cs +++ b/AsbCloudInfrastructure/Services/UserService.cs @@ -104,7 +104,13 @@ namespace AsbCloudInfrastructure.Services public IEnumerable GetNestedPermissions(int idUser) { var roles = GetRolesByIdUser(idUser); - return roles.SelectMany(r => r.Permissions); + if(roles?.Any() != true) + return null; + var permissions = roles + .Where(r => r.Permissions is not null) + .SelectMany(r => r.Permissions); + + return permissions; } private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable newRoleNames, CancellationToken token) diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index fce123ee..c8a03bb2 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -12,24 +12,21 @@ using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { - public class WellService : IWellService - { - private readonly IAsbCloudDbContext db; + public class WellService : CrudCacheServiceBase, IWellService + { private readonly ITelemetryService telemetryService; private readonly CacheTable cacheRelationCompaniesWells; - private readonly CacheTable cacheWells; - public WellService(IAsbCloudDbContext db, ITelemetryService telemetryService, CacheDb cacheDb) + public WellService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService) + :base(db, cacheDb) { - this.db = db; this.telemetryService = telemetryService; - cacheRelationCompaniesWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); - cacheWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); + cacheRelationCompaniesWells = cacheDb.GetCachedTable((AsbCloudDbContext)db, nameof(RelationCompanyWell.Company), nameof(RelationCompanyWell.Well)); } public DateTime GetLastTelemetryDate(int idWell) { - var well = cacheWells.FirstOrDefault(w => w.Id == idWell); + var well = Cache.FirstOrDefault(w => w.Id == idWell); if (well?.IdTelemetry is null) return DateTime.MinValue; @@ -38,30 +35,27 @@ namespace AsbCloudInfrastructure.Services return lastTelemetryDate; } - public async Task> GetTransmittingWellsAsync(int idCompany, - CancellationToken token) - { - var activeTelemetryIds = telemetryService.GetTransmittingTelemetries() - .Select(t => t.Id); - - var wells = await (from w in db.GetWellsForCompany(idCompany) - where w.IdTelemetry != null && - activeTelemetryIds.Contains((int)w.IdTelemetry) - select w) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - return wells.Select(Convert); - } - public async Task> GetWellsByCompanyAsync(int idCompany, CancellationToken token) { - var wells = await db.GetWellsForCompany(idCompany).ToListAsync(token); - return wells.Select(Convert); + var relations = await cacheRelationCompaniesWells + .WhereAsync(r => r.IdCompany == idCompany, token); + var dtos = relations.Select(r => Convert(r.Well)); + return dtos; } - - public async Task UpdateWellAsync(int idWell, WellParamsDto dto, + + public override Task InsertAsync(WellDto newItem, CancellationToken token = default) + { + throw new NotImplementedException(); + implement this + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } + + public override Task InsertRangeAsync(IEnumerable dtos, CancellationToken token) + { + throw new NotImplementedException(); + } + + public override async Task UpdateAsync(int idWell, WellDto dto, CancellationToken token = default) { if (dto.IdWellType is < 1 or > 2) @@ -69,23 +63,16 @@ namespace AsbCloudInfrastructure.Services if (dto.IdState is < 0 or > 2) throw new ArgumentException("Текущее состояние работы скважины указано неправильно.", nameof(dto)); + + if(dto.Id != idWell) + throw new ArgumentException($"Нельзя поменять id для скважины: {idWell} => {dto.Id}.", nameof(dto)); - var entity = await db.Wells - .FirstOrDefaultAsync(w => w.Id == idWell, token) - .ConfigureAwait(false); + var entity = Convert(dto); - if (entity is null) - throw new ArgumentException("Тип секции указан неправильно.", nameof(idWell)); + var oldRelations = await cacheRelationCompaniesWells.FirstOrDefaultAsync(w => w.Id == idWell, token); - entity.Caption = dto.Caption; - entity.Latitude = dto.Latitude; - entity.Longitude = dto.Longitude; - entity.IdWellType = dto.IdWellType; - entity.IdState = dto.IdState; - - db.Wells.Update(entity); - - return await db.SaveChangesAsync(token); + var result = await Cache.UpsertAsync(entity, token); + return result; } public bool IsCompanyInvolvedInWell(int idCompany, int idWell) @@ -95,38 +82,25 @@ namespace AsbCloudInfrastructure.Services => await cacheRelationCompaniesWells.ContainsAsync(r => r.IdWell == idWell && r.IdCompany == idCompany, token).ConfigureAwait(false); - public async Task GetAsync(int idWell, CancellationToken token) - { - var entity = await db.Wells - .Include(w => w.Cluster) - .ThenInclude(c => c.Deposit) - .FirstOrDefaultAsync(w => w.Id == idWell, token) - .ConfigureAwait(false); - - if (entity is null) - return null; - - var dto = Convert(entity); - - return dto; - } - public async Task GetWellCaptionByIdAsync(int idWell, CancellationToken token) { - var entity = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token).ConfigureAwait(false); + var entity = await Cache.FirstOrDefaultAsync(w => w.Id == idWell, token).ConfigureAwait(false); var dto = Convert(entity); return dto.Caption; } public async Task> GetCompaniesAsync(int idWell, CancellationToken token) { - var well = await db.Wells - .Include(w => w.RelationCompaniesWells) - .ThenInclude(r => r.Company) - .FirstOrDefaultAsync(w => w.Id == idWell, token) - .ConfigureAwait(false); - var companies = well.RelationCompaniesWells.Select(r => r.Company); - return companies.Adapt(); + var relations = await cacheRelationCompaniesWells.WhereAsync(r => r.IdWell == idWell, token); + var dtos = relations.Select(r => Convert(r.Company)); + return dtos; + } + + private IEnumerable GetCompanies(int idWell) + { + var relations = cacheRelationCompaniesWells.Where(r => r.IdWell == idWell); + var dtos = relations.Select(r => Convert(r.Company)); + return dtos; } public string GetStateText(int state) @@ -141,33 +115,32 @@ namespace AsbCloudInfrastructure.Services public async Task> GetClusterWellsIdsAsync(int idWell, CancellationToken token) { - var well = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token) + var well = await Cache.FirstOrDefaultAsync(w => w.Id == idWell, token) .ConfigureAwait(false); if (well is null) return null; - var clusterWells = await cacheWells.WhereAsync(w => w.IdCluster == well.IdCluster, token) + var clusterWells = await Cache.WhereAsync(w => w.IdCluster == well.IdCluster, token) .ConfigureAwait(false); return clusterWells.Select(w => w.Id); } - private WellDto Convert(Well well) + protected override WellDto Convert(Well entity) { - return new WellDto - { - Id = well.Id, - Caption = well.Caption, - IdCluster = well.IdCluster, - Cluster = well.Cluster?.Caption, - Deposit = well.Cluster?.Deposit?.Caption, - LastTelemetryDate = GetLastTelemetryDate(well.Id), - IdWellType = well.IdWellType ?? default, - IdState = well.IdState, - Latitude = well.Latitude, - Longitude = well.Longitude, - }; + var dto = base.Convert(entity); + dto.Cluster = entity.Cluster?.Caption; + dto.Deposit = entity.Cluster?.Deposit?.Caption; + dto.LastTelemetryDate = GetLastTelemetryDate(entity.Id); + dto.Companies = GetCompanies(entity.Id); + return dto; + } + + private CompanyDto Convert(Company entity) + { + var dto = entity.Adapt(); + return dto; } } } diff --git a/AsbCloudWebApi/Controllers/AdminClusterController.cs b/AsbCloudWebApi/Controllers/AdminClusterController.cs index c285a33d..60cbe2b6 100644 --- a/AsbCloudWebApi/Controllers/AdminClusterController.cs +++ b/AsbCloudWebApi/Controllers/AdminClusterController.cs @@ -13,7 +13,8 @@ namespace AsbCloudWebApi.Controllers public AdminClusterController(ICrudService service) :base(service) { - service.Includes.Add("Wells"); + service.Includes.Add(nameof(ClusterDto.Wells)); + service.Includes.Add(nameof(ClusterDto.Deposit)); } } } diff --git a/AsbCloudWebApi/Controllers/AdminWellController.cs b/AsbCloudWebApi/Controllers/AdminWellController.cs index 5e593d62..94a5739b 100644 --- a/AsbCloudWebApi/Controllers/AdminWellController.cs +++ b/AsbCloudWebApi/Controllers/AdminWellController.cs @@ -10,10 +10,11 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class AdminWellController : CrudController> { - public AdminWellController(ICrudService service) + public AdminWellController(IWellService service) :base(service) { service.Includes.Add("Telemetry"); } + } } diff --git a/AsbCloudWebApi/Controllers/WellController.cs b/AsbCloudWebApi/Controllers/WellController.cs index 85ffea8d..8f2bd24b 100644 --- a/AsbCloudWebApi/Controllers/WellController.cs +++ b/AsbCloudWebApi/Controllers/WellController.cs @@ -67,30 +67,6 @@ namespace AsbCloudWebApi.Controllers return Ok(well); } - /// - /// Возвращает список скважин, передающих телеметрию в данный момент - /// - /// Токен отмены задачи - /// Список скважин - [HttpGet("transmittingWells")] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetTransmittingWellsAsync(CancellationToken token = default) - { - var idCompany = User.GetCompanyId(); - - if (idCompany is null) - return NoContent(); - - var transmittingWells = await wellService.GetTransmittingWellsAsync((int)idCompany, - token).ConfigureAwait(false); - - if (transmittingWells is null || !transmittingWells.Any()) - return NoContent(); - - return Ok(transmittingWells); - - } - /// /// Редактирует указанные поля скважины /// @@ -102,7 +78,7 @@ namespace AsbCloudWebApi.Controllers /// [HttpPut] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task UpdateWellAsync(int idWell, WellParamsDto dto, + public async Task UpdateWellAsync(int idWell, WellDto dto, CancellationToken token = default) { var idCompany = User.GetCompanyId(); @@ -111,7 +87,7 @@ namespace AsbCloudWebApi.Controllers idWell, token).ConfigureAwait(false)) return Forbid(); - var result = await wellService.UpdateWellAsync(idWell, dto, token) + var result = await wellService.UpdateAsync(idWell, dto, token) .ConfigureAwait(false); return Ok(result);