diff --git a/AsbCloudApp/Data/WellOperationCategoryDto.cs b/AsbCloudApp/Data/WellOperationCategoryDto.cs new file mode 100644 index 00000000..04a8fcd0 --- /dev/null +++ b/AsbCloudApp/Data/WellOperationCategoryDto.cs @@ -0,0 +1,11 @@ +namespace AsbCloudApp.Data +{ + public class WellOperationCategoryDto + { + public int Id { get; set; } + + public string Name { get; set; } + + public int Code { get; set; } + } +} diff --git a/AsbCloudApp/Data/WellOperationDto.cs b/AsbCloudApp/Data/WellOperationDto.cs index 5428a204..6b8e2d27 100644 --- a/AsbCloudApp/Data/WellOperationDto.cs +++ b/AsbCloudApp/Data/WellOperationDto.cs @@ -6,21 +6,25 @@ namespace AsbCloudApp.Data { public int Id { get; set; } - public int IdSection { get; set; } + public int IdWell { get; set; } - public int IdCategory { get; set; } + public int IdWellSectionType { get; set; } + + public string WellSectionTypeName { get; set; } + + public int IdOperationCategory { get; set; } public string CategoryName { get; set; } public string Type { get; set; } - public string WellDepth { get; set; } + public double WellDepth { get; set; } public DateTime StartDate { get; set; } - public double Duration { get; set; } + public double DurationHours { get; set; } - public string Data { get; set; } + public string Info { get; set; } public string Comment { get; set; } } diff --git a/AsbCloudApp/Services/IWellOperationService.cs b/AsbCloudApp/Services/IWellOperationService.cs index fe90fdce..8dca0e31 100644 --- a/AsbCloudApp/Services/IWellOperationService.cs +++ b/AsbCloudApp/Services/IWellOperationService.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; @@ -7,7 +8,22 @@ namespace AsbCloudApp.Services { public interface IWellOperationService { + IEnumerable GetTypes(); + Task> GetAllByWellIdAsync(int idWell, int skip = 0, int take = 32, CancellationToken token = default); + + Task GetAsync(int id, CancellationToken token); + + Task InsertAsync(WellOperationDto wellOperationDto, + int idWell, CancellationToken token); + + Task InsertRangeAsync(int idWell, + IEnumerable wellOperationDtos, CancellationToken token); + + Task UpdateAsync(int idWell, int idSection, WellOperationDto item, + CancellationToken token); + + Task DeleteAsync(IEnumerable ids, CancellationToken token); } } diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index 412ac241..8e9934d3 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -27,7 +27,7 @@ namespace AsbCloudDb.Model public virtual DbSet TelemetryEvents { get; set; } public virtual DbSet TelemetryMessages { get; set; } public virtual DbSet TelemetryUsers { get; set; } - public virtual DbSet TelemetryOperations { get; set; } + public virtual DbSet TelemetryOperations { get; set; } public virtual DbSet TelemetryAnalysis { get; set; } public virtual DbSet WellSections { get; set; } public virtual DbSet WellSectionTypes { get; set; } @@ -204,26 +204,26 @@ namespace AsbCloudDb.Model }); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { - entity.HasData(new List { - new OperationCategory {Id = 1, OperationType = 0, Name = "Невозможно определить операцию"}, - new OperationCategory {Id = 2, OperationType = 0, Name = "Роторное бурение" }, - new OperationCategory {Id = 3, OperationType = 0, Name = "Слайдирование" }, - new OperationCategory {Id = 4, OperationType = 0, Name = "Подъем с проработкой" }, - new OperationCategory {Id = 5, OperationType = 0, Name = "Спуск с проработкой" }, - new OperationCategory {Id = 6, OperationType = 0, Name = "Подъем с промывкой" }, - new OperationCategory {Id = 7, OperationType = 0, Name = "Спуск с промывкой" }, - new OperationCategory {Id = 8, OperationType = 0, Name = "Спуск в скважину" }, - new OperationCategory {Id = 9, OperationType = 0, Name = "Спуск с вращением" }, - new OperationCategory {Id = 10, OperationType = 0, Name = "Подъем из скважины" }, - new OperationCategory {Id = 11, OperationType = 0, Name = "Подъем с вращением" }, - new OperationCategory {Id = 12, OperationType = 0, Name = "Промывка в покое" }, - new OperationCategory {Id = 13, OperationType = 0, Name = "Промывка с вращением" }, - new OperationCategory {Id = 14, OperationType = 0, Name = "Удержание в клиньях" }, - new OperationCategory {Id = 15, OperationType = 0, Name = "Неподвижное состояние" }, - new OperationCategory {Id = 16, OperationType = 0, Name = "Вращение без циркуляции" }, - new OperationCategory {Id = 17, OperationType = 0, Name = "На поверхности" } + entity.HasData(new List { + new WellOperationCategory {Id = 1, Name = "Невозможно определить операцию", Code = 0}, + new WellOperationCategory {Id = 2, Name = "Роторное бурение", Code = 0 }, + new WellOperationCategory {Id = 3, Name = "Слайдирование", Code = 0 }, + new WellOperationCategory {Id = 4, Name = "Подъем с проработкой", Code = 0 }, + new WellOperationCategory {Id = 5, Name = "Спуск с проработкой", Code = 0 }, + new WellOperationCategory {Id = 6, Name = "Подъем с промывкой", Code = 0 }, + new WellOperationCategory {Id = 7, Name = "Спуск с промывкой", Code = 0 }, + new WellOperationCategory {Id = 8, Name = "Спуск в скважину", Code = 0 }, + new WellOperationCategory {Id = 9, Name = "Спуск с вращением", Code = 0 }, + new WellOperationCategory {Id = 10, Name = "Подъем из скважины", Code = 0 }, + new WellOperationCategory {Id = 11, Name = "Подъем с вращением", Code = 0 }, + new WellOperationCategory {Id = 12, Name = "Промывка в покое", Code = 0 }, + new WellOperationCategory {Id = 13, Name = "Промывка с вращением", Code = 0 }, + new WellOperationCategory {Id = 14, Name = "Удержание в клиньях", Code = 0 }, + new WellOperationCategory {Id = 15, Name = "Неподвижное состояние", Code = 0 }, + new WellOperationCategory {Id = 16, Name = "Вращение без циркуляции", Code = 0 }, + new WellOperationCategory {Id = 17, Name = "На поверхности", Code = 0 } }); }); diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index d906e035..0d3b2f45 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -22,7 +22,7 @@ namespace AsbCloudDb.Model DbSet FileCategories { get; set; } DbSet Telemetries { get; set; } DbSet TelemetryUsers { get; set; } - DbSet TelemetryOperations { get; set; } + DbSet TelemetryOperations { get; set; } DbSet TelemetryAnalysis { get; set; } DbSet Wells { get; set; } DbSet WellSections { get; set; } diff --git a/AsbCloudDb/Model/TelemetryAnalysis.cs b/AsbCloudDb/Model/TelemetryAnalysis.cs index 30346d6c..d4c509ba 100644 --- a/AsbCloudDb/Model/TelemetryAnalysis.cs +++ b/AsbCloudDb/Model/TelemetryAnalysis.cs @@ -28,8 +28,8 @@ namespace AsbCloudDb.Model [JsonIgnore] [ForeignKey(nameof(IdOperation))] - [InverseProperty(nameof(Model.OperationCategory.Analysis))] - public virtual OperationCategory Operation { get; set; } + [InverseProperty(nameof(Model.WellOperationCategory.Analysis))] + public virtual WellOperationCategory Operation { get; set; } [Column("unix_date", TypeName = "bigint"), Comment("Unix timestamp для Linq запросов с вычислением дат")] diff --git a/AsbCloudDb/Model/WellOperation.cs b/AsbCloudDb/Model/WellOperation.cs index d2ca33ac..1b70704c 100644 --- a/AsbCloudDb/Model/WellOperation.cs +++ b/AsbCloudDb/Model/WellOperation.cs @@ -20,7 +20,7 @@ namespace AsbCloudDb.Model public int IdWellSectionType { get; set; } [Column("id_category"), Comment("Id категории операции")] - public int IdCategory { get; set; } + public int IdOperationCategory { get; set; } [Column("type"), Comment("План или Факт")] public string Type { get; set; } @@ -49,7 +49,7 @@ namespace AsbCloudDb.Model public virtual WellSectionType WellSectionType { get; set; } [JsonIgnore] - [ForeignKey(nameof(IdCategory))] - public virtual OperationCategory OperationCategory { get; set; } + [ForeignKey(nameof(IdOperationCategory))] + public virtual WellOperationCategory OperationCategory { get; set; } } } diff --git a/AsbCloudDb/Model/OperationCategory.cs b/AsbCloudDb/Model/WellOperationCategory.cs similarity index 72% rename from AsbCloudDb/Model/OperationCategory.cs rename to AsbCloudDb/Model/WellOperationCategory.cs index 38516bbe..25434aff 100644 --- a/AsbCloudDb/Model/OperationCategory.cs +++ b/AsbCloudDb/Model/WellOperationCategory.cs @@ -6,16 +6,13 @@ using System.ComponentModel.DataAnnotations.Schema; namespace AsbCloudDb.Model { [Table("t_operation"), Comment("Справочник операций на скважине")] - public class OperationCategory + public class WellOperationCategory { [Key] [Column("id")] public int Id { get; set; } - [Column("type"), Comment("Тип операции (авто/ручной ввод)")] - public int OperationType { get; set; } - - [Column("name"), Comment("Название операции")] + [Column("name"), Comment("Название категории операции")] public string Name { get; set; } [Column("code"), Comment("Код операции")] diff --git a/AsbCloudInfrastructure/Services/TelemetryAnalyticsService.cs b/AsbCloudInfrastructure/Services/TelemetryAnalyticsService.cs index fcb604d3..29a7363f 100644 --- a/AsbCloudInfrastructure/Services/TelemetryAnalyticsService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryAnalyticsService.cs @@ -17,9 +17,9 @@ namespace AsbCloudInfrastructure.Services private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; private readonly ISaubDataCache saubDataCache; - private readonly CacheTable cacheOperations; + private readonly CacheTable cacheOperations; private readonly TelemetryOperationDetectorService operationDetectorService; - private readonly IEnumerable operations; + private readonly IEnumerable operations; public TelemetryAnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService, ISaubDataCache saubDataCache, CacheDb cacheDb) @@ -27,8 +27,8 @@ namespace AsbCloudInfrastructure.Services this.db = db; this.telemetryService = telemetryService; this.saubDataCache = saubDataCache; - cacheOperations = cacheDb.GetCachedTable((AsbCloudDbContext)db); - operations = cacheOperations.Where(c => true); + cacheOperations = cacheDb.GetCachedTable((AsbCloudDbContext)db); + operations = cacheOperations.Where(); operationDetectorService = new TelemetryOperationDetectorService(operations); } diff --git a/AsbCloudInfrastructure/Services/TelemetryOperationDetector.cs b/AsbCloudInfrastructure/Services/TelemetryOperationDetector.cs index bd99f812..c618b0f1 100644 --- a/AsbCloudInfrastructure/Services/TelemetryOperationDetector.cs +++ b/AsbCloudInfrastructure/Services/TelemetryOperationDetector.cs @@ -7,7 +7,7 @@ namespace AsbCloudInfrastructure.Services public class TelemetryOperationDetector { public int Order { get; set; } - public OperationCategory Operation { get; set; } + public WellOperationCategory Operation { get; set; } public Func Detect { get; set; } } } diff --git a/AsbCloudInfrastructure/Services/TelemetryOperationDetectorService.cs b/AsbCloudInfrastructure/Services/TelemetryOperationDetectorService.cs index 66c0b4ae..c48d21b7 100644 --- a/AsbCloudInfrastructure/Services/TelemetryOperationDetectorService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryOperationDetectorService.cs @@ -9,7 +9,7 @@ namespace AsbCloudInfrastructure.Services { private readonly IEnumerable detectors; - public TelemetryOperationDetectorService(IEnumerable operations) + public TelemetryOperationDetectorService(IEnumerable operations) { detectors = new List() { @@ -180,8 +180,8 @@ namespace AsbCloudInfrastructure.Services }; } - public OperationCategory DetectOperation(TelemetryAnalysisDto data) => + public WellOperationCategory DetectOperation(TelemetryAnalysisDto data) => detectors.OrderBy(d => d.Order).First(o => o.Detect(data)).Operation - ?? new OperationCategory { Id = 1, Name = "Невозможно определить операцию" }; + ?? new WellOperationCategory { Id = 1, Name = "Невозможно определить операцию" }; } } diff --git a/AsbCloudInfrastructure/Services/WellOperationService.cs b/AsbCloudInfrastructure/Services/WellOperationService.cs index e8bf9227..efe2db83 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; @@ -13,21 +14,34 @@ namespace AsbCloudInfrastructure.Services public class WellOperationService : IWellOperationService { private readonly IAsbCloudDbContext context; - private readonly DbSet dbSet; - private readonly CacheTable cachedOperationTypes; + private readonly CacheTable cachedOperationTypes; public WellOperationService(IAsbCloudDbContext context, Cache.CacheDb cache) { this.context = context; - dbSet = context.Set(); - cachedOperationTypes = cache.GetCachedTable((DbContext)context); + cachedOperationTypes = cache.GetCachedTable((DbContext)context); + } + + public IEnumerable GetTypes() + { + var operationTypes = cachedOperationTypes.Where().Distinct(); + var result = new List(); + + foreach(var op in operationTypes) + { + var dto = op.Adapt(); + result.Add(dto); + } + + return result; } public async Task> GetAllByWellIdAsync(int idWell, int skip = 0, int take = 32, CancellationToken token = default) { - var query = dbSet + var query = context.WellOperations .Include(s => s.WellSectionType) + .Include(s => s.OperationCategory) .Where(s => s.IdWell == idWell) .AsNoTracking(); @@ -46,16 +60,77 @@ namespace AsbCloudInfrastructure.Services query = query.Take(take); - var entities = await query.Take(take).ToListAsync(token).ConfigureAwait(false); + var entities = await query.Take(take) + .ToListAsync(token).ConfigureAwait(false); foreach (var item in entities) { var dto = item.Adapt(); - //dto.SectionType = item.WellSectionType.Caption; + dto.WellSectionTypeName = item.WellSectionType.Caption; + dto.CategoryName = item.OperationCategory.Name; result.Items.Add(dto); } return result; } + + public async Task GetAsync(int id, + CancellationToken token = default) + { + var entity = await context.WellOperations + .Include(s => s.WellSectionType) + .Include(s => s.OperationCategory) + .FirstOrDefaultAsync(e => e.Id == id, token) + .ConfigureAwait(false); + + if (entity is null) + return null; + + var dto = entity.Adapt(); + dto.WellSectionTypeName = entity.WellSectionType.Caption; + dto.CategoryName = entity.OperationCategory.Name; + return dto; + } + + public async Task InsertAsync(WellOperationDto wellOperationDto, + int idWell, CancellationToken token = default) + { + var entity = wellOperationDto.Adapt(); + context.WellOperations.Add(entity); + return await context.SaveChangesAsync(token) + .ConfigureAwait(false); + } + + public async Task InsertRangeAsync(int idWell, + IEnumerable wellOperationDtos, + CancellationToken token = default) + { + foreach(var operationDto in wellOperationDtos) + { + var entity = operationDto.Adapt(); + context.WellOperations.Add(entity); + } + + return await context.SaveChangesAsync(token) + .ConfigureAwait(false); + } + + public async Task UpdateAsync(int idWell, int idSection, + WellOperationDto item, CancellationToken token = default) + { + var entity = item.Adapt(); + context.WellOperations.Update(entity); + return await context.SaveChangesAsync(token) + .ConfigureAwait(false); + } + + public async Task DeleteAsync(IEnumerable ids, + CancellationToken token = default) + { + var entities = context.WellOperations.Where(e => ids.Contains(e.Id)); + context.WellOperations.RemoveRange(entities); + return await context.SaveChangesAsync(token) + .ConfigureAwait(false); + } } } diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index 6ca3fe4a..05316b88 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Services; @@ -8,9 +9,9 @@ using Microsoft.AspNetCore.Authorization; namespace AsbCloudWebApi.Controllers { /// - /// Контроллер операций на скважине + /// Контроллер вручную внесенных операций на скважине /// - [Route("api/wellOperation")] + [Route("api/wellOperations")] [ApiController] [Authorize] public class WellOperationController : ControllerBase @@ -24,8 +25,29 @@ namespace AsbCloudWebApi.Controllers this.wellService = wellService; } + /// + /// Возвращает список имен типов операций на скважине + /// + /// [HttpGet] - [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] + [Route("types")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetTypesAsync() + { + var result = operationService.GetTypes(); + return Ok(result); + } + + /// + /// Возвращает весь список операций на скважине + /// + /// id скважины + /// Для пагинации кол-во записей пропустить + /// Для пагинации кол-во записей + /// Токен отмены задачи + /// Список операций на скважине + [HttpGet] + [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] public async Task GetAllAsync(int idWell, int skip = 0, int take = 32, CancellationToken token = default) { @@ -36,6 +58,88 @@ namespace AsbCloudWebApi.Controllers return Ok(result); } + /// + /// Возвращает нужную операцию на скважине + /// + /// id скважины + /// id нужной операции + /// Токен отмены задачи + /// Нужную операцию на скважине + [HttpGet] + [Route("{idOperation}")] + [ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)] + public async Task GetAsync(int idWell, int idOperation, + CancellationToken token = default) + { + if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) + return Forbid(); + + var result = await operationService.GetAsync(idOperation, token).ConfigureAwait(false); + return Ok(result); + } + + /// + /// Добавляет новые операции на скважине + /// + /// id скважины + /// Данные о добавляемых операциях + /// Токен отмены задачи + /// Количество добавленых в БД строк + [HttpPost] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task InsertRangeAsync(int idWell, [FromBody] IEnumerable values, + CancellationToken token = default) + { + if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) + return Forbid(); + + var result = await operationService.InsertRangeAsync(idWell, values, token) + .ConfigureAwait(false); + return Ok(result); + } + + /// + /// Обновляет выбранную операцию на скважине + /// + /// id скважины + /// id выбраной операции + /// Новые данные для выбраной операции + /// Токен отмены задачи + /// Количество обновленных в БД строк + [HttpPut("{idOperation}")] + [ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)] + public async Task UpdateAsync(int idWell, int idOperation, + [FromBody] WellOperationDto value, CancellationToken token = default) + { + if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) + return Forbid(); + + var result = await operationService.UpdateAsync(idWell, idOperation, value, token) + .ConfigureAwait(false); + return Ok(result); + } + + /// + /// Удаляет выбраную операцию на скважине + /// + /// id скважины + /// id выбраной операции + /// Токен отмены задачи + /// Количество удаленных из БД строк + [HttpDelete("{idOperation}")] + [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] + public async Task DeleteAsync(int idWell, int idOperation, CancellationToken token = default) + { + if (!await CanUserAccessToWellAsync(idWell, + token).ConfigureAwait(false)) + return Forbid(); + + var result = await operationService.DeleteAsync(new int[] { idOperation }, token) + .ConfigureAwait(false); + + return Ok(result); + } + private async Task CanUserAccessToWellAsync(int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId();