From 81ab77cdfc8f7ffa4587b5e197e8b9ac8c1cb496 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Fri, 21 Apr 2023 11:22:39 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D1=82?= =?UTF-8?q?=D0=B0=D0=BC=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/FaqDto.cs | 13 +--- AsbCloudApp/Repositories/IFaqRepository.cs | 22 ++++-- AsbCloudApp/Requests/FaqRequest.cs | 29 +------ AsbCloudDb/Model/AsbCloudDbContext.cs | 2 +- AsbCloudDb/Model/Faq.cs | 16 +--- AsbCloudDb/Model/IAsbCloudDbContext.cs | 2 +- .../Repository/FaqRepository.cs | 75 +++++++++---------- AsbCloudWebApi/Controllers/FaqController.cs | 71 +++++++----------- 8 files changed, 82 insertions(+), 148 deletions(-) diff --git a/AsbCloudApp/Data/FaqDto.cs b/AsbCloudApp/Data/FaqDto.cs index 9dd9527e..13f17c29 100644 --- a/AsbCloudApp/Data/FaqDto.cs +++ b/AsbCloudApp/Data/FaqDto.cs @@ -2,7 +2,6 @@ namespace AsbCloudApp.Data { -#nullable enable /// /// DTO для faq-вопроса /// @@ -13,11 +12,6 @@ namespace AsbCloudApp.Data /// public int Id { get; set; } - /// - /// ключ скважины - /// - public int? IdWell { get; set; } - /// /// ключ автора вопроса /// @@ -47,17 +41,16 @@ namespace AsbCloudApp.Data /// /// статус вопроса /// - public int? State { get; set; } = 0!; + public int State { get; set; } = 0; /// /// Счетчик повторений вопроса /// - public int? CounterQuestion { get; set; } = 0!; + public int CounterQuestion { get; set; } = 1; /// /// Частый вопрос /// - public bool? IsFrequently { get; set; } = false!; + public bool IsFrequently { get; set; } = false; } -#nullable disable } diff --git a/AsbCloudApp/Repositories/IFaqRepository.cs b/AsbCloudApp/Repositories/IFaqRepository.cs index 1ad81885..7931b506 100644 --- a/AsbCloudApp/Repositories/IFaqRepository.cs +++ b/AsbCloudApp/Repositories/IFaqRepository.cs @@ -7,7 +7,6 @@ using AsbCloudApp.Services; namespace AsbCloudApp.Repositories { -#nullable enable /// /// репозиторий по работе с faq-вопросами /// @@ -19,7 +18,7 @@ namespace AsbCloudApp.Repositories /// /// /// - Task> GetAllAsync(FaqRequest request, CancellationToken token); + Task> GetFilteredAsync(FaqRequest request, CancellationToken token); /// /// Добавить вопрос @@ -40,20 +39,27 @@ namespace AsbCloudApp.Repositories /// /// Объединить 2 вопроса в 1 /// - /// Ключи вопросов, подлежащих объединению - /// Флаг, объединять текст вопросов или нет + /// ключ первого вопроса, подлежащего объединению + /// ключ второго вопроса, подлежащего объединению + /// Флаг, объединять текст вопросов или нет /// /// - Task MergeAsync(IEnumerable sourceIds, bool mergeTexts, CancellationToken token); + Task MergeAsync(int sourceId1, int sourceId2, bool mergeQuestions, CancellationToken token); /// /// Пометить вопрос по id как удаленный /// - /// /// /// /// - Task MarkAsDeletedAsync(int idWell, int id, CancellationToken token); + Task MarkAsDeletedAsync(int id, CancellationToken token); + + /// + /// Удалить вопрос по ключу + /// + /// + /// + /// + Task DeleteAsync(int id, CancellationToken token); } -#nullable disable } diff --git a/AsbCloudApp/Requests/FaqRequest.cs b/AsbCloudApp/Requests/FaqRequest.cs index b5a56b53..c52631fa 100644 --- a/AsbCloudApp/Requests/FaqRequest.cs +++ b/AsbCloudApp/Requests/FaqRequest.cs @@ -7,11 +7,10 @@ using System.Threading.Tasks; namespace AsbCloudApp.Requests { -#nullable enable /// /// Параметры запроса для фильтрации faq-вопросов /// - public class FaqRequestBase : RequestBase + public class FaqRequest { /// /// Есть ли ответ на вопрос @@ -28,30 +27,4 @@ namespace AsbCloudApp.Requests /// public bool IncludeDeleted { get; set; } = false; } - - /// - /// Параметры запроса для фильтрации faq-вопросов (с id скважины) - /// - public class FaqRequest : FaqRequestBase - { - /// - /// копирующий конструктор - /// - /// - /// - public FaqRequest(FaqRequestBase request, int idWell) - { - IdWell = idWell; - this.IncludeDeleted = request.IncludeDeleted; - this.HasAnswer = request.HasAnswer; - this.IsFrequently = request.IsFrequently; - } - - /// - /// id скважины - /// - public int IdWell { get; set; } - - } -#nullable disable } diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index 4682c958..472d788a 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -72,7 +72,7 @@ namespace AsbCloudDb.Model private static int referenceCount; public static int ReferenceCount => referenceCount; - public DbSet FAQs => Set(); + public DbSet Faqs => Set(); public AsbCloudDbContext() : base() { diff --git a/AsbCloudDb/Model/Faq.cs b/AsbCloudDb/Model/Faq.cs index e592e632..c02bd793 100644 --- a/AsbCloudDb/Model/Faq.cs +++ b/AsbCloudDb/Model/Faq.cs @@ -6,7 +6,6 @@ using System.Text.Json.Serialization; namespace AsbCloudDb.Model { -#nullable enable [Table("t_faq"), Comment("вопросы пользователей")] public class Faq : IId { @@ -17,16 +16,6 @@ namespace AsbCloudDb.Model [Column("id"), Comment("Идентификатор")] public int Id { get; set; } - /// - /// ключ скважины, к которой пивязан вопрос - /// - [Column("id_well"), Comment("id скважины")] - public int IdWell { get; set; } - - [JsonIgnore] - [ForeignKey(nameof(IdWell))] - public virtual Well Well { get; set; } = null!; - /// /// автор вопроса /// @@ -45,7 +34,7 @@ namespace AsbCloudDb.Model [JsonIgnore] [ForeignKey(nameof(IdAuthorAnswer))] - public virtual User AuthorAnswer { get; set; } = null!; + public virtual User? AuthorAnswer { get; set; } /// /// дата создания вопроса @@ -87,7 +76,7 @@ namespace AsbCloudDb.Model /// Счетчик повторений вопроса /// [Column("counter_question"), Comment("Счетчик повторений вопроса")] - public int CounterQuestion { get; set; } + public int CounterQuestion { get; set; } = 1; /// /// Ключ заменяющего вопроса @@ -102,5 +91,4 @@ namespace AsbCloudDb.Model public bool IsFrequently { get; set; } = false; } -#nullable disable } diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index 41003ac3..c4a5c157 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -57,7 +57,7 @@ namespace AsbCloudDb.Model DbSet WellFinalDocuments { get; } DbSet LimitingParameter { get; } DbSet TelemetryWirelineRunOut { get; } - DbSet FAQs { get; } + DbSet Faqs { get; } DbSet Record1 { get; } DbSet Record7 { get; } diff --git a/AsbCloudInfrastructure/Repository/FaqRepository.cs b/AsbCloudInfrastructure/Repository/FaqRepository.cs index 72d95c2f..50e0f383 100644 --- a/AsbCloudInfrastructure/Repository/FaqRepository.cs +++ b/AsbCloudInfrastructure/Repository/FaqRepository.cs @@ -15,7 +15,6 @@ using System.Threading.Tasks; namespace AsbCloudInfrastructure.Repository { -#nullable enable /// /// сервис по работе с faq-вопросами /// @@ -30,10 +29,9 @@ namespace AsbCloudInfrastructure.Repository this.wellService = wellService; } - public async Task> GetAllAsync(FaqRequest request, CancellationToken token) + public async Task> GetFilteredAsync(FaqRequest request, CancellationToken token) { - var query = db.FAQs - .Where(o => o.IdWell == request.IdWell); + var query = db.Faqs.AsNoTracking(); if (request.IsFrequently) { @@ -48,26 +46,19 @@ namespace AsbCloudInfrastructure.Repository query = query.Where(o => o.State != Faq.StateDeleted); } - var entities = query.Select(o => new FaqDto() - { - Id = o.Id, - Question = o.Question, - Answer = o.Answer, - CounterQuestion = o.CounterQuestion, - IsFrequently = o.IsFrequently, - State = o.State, - DateCreatedQuestion = o.DateCreatedQuestion, - }); + var entities = query + .OrderByDescending(e => e.DateCreatedQuestion) + .Select(o => new FaqDto() + { + Id = o.Id, + Question = o.Question, + Answer = o.Answer, + CounterQuestion = o.CounterQuestion, + IsFrequently = o.IsFrequently, + State = o.State, + DateCreatedQuestion = o.DateCreatedQuestion, + }); - if (request.SortFields?.Any() == true) - { - entities = entities.SortBy(request.SortFields); - } - else - { - entities = entities.OrderByDescending(e => e.DateCreatedQuestion); - - }; var result = await entities.AsNoTracking() .ToArrayAsync(token) @@ -81,22 +72,20 @@ namespace AsbCloudInfrastructure.Repository { var entity = faqDto.Adapt(); entity.DateCreatedQuestion = entity.DateLastEditedQuestion = DateTimeOffset.UtcNow; - entity.CounterQuestion = 0; + entity.CounterQuestion = 1; entity.State = Faq.StateOpened; - db.FAQs.Add(entity); + db.Faqs.Add(entity); await db.SaveChangesAsync(token).ConfigureAwait(false); return entity.Id; } - public async Task MergeAsync(IEnumerable sourceIds, bool mergeTexts, CancellationToken token) + public async Task MergeAsync(int sourceId1, int sourceId2, bool mergeQuestions, CancellationToken token) { - var sourceFaqs = db.FAQs.Where(e => sourceIds.Contains(e.Id)).ToArray(); + var sourceFaqs = db.Faqs.Where(e => e.Id == sourceId1 || e.Id == sourceId2).ToArray(); if (sourceFaqs.Count() < 2) - throw new ArgumentInvalidException("Questions with target ids don't exist", nameof(sourceIds)); - if (sourceFaqs.Select(e => e.IdWell).Distinct().Count() > 1) - throw new ArgumentInvalidException("Questions with different idWell are not merged", nameof(sourceIds)); + throw new ArgumentInvalidException("Questions with target ids don't exist", nameof(sourceFaqs)); var newFaq = new Faq() { @@ -106,16 +95,15 @@ namespace AsbCloudInfrastructure.Repository IdAuthorQuestion = sourceFaqs.Last().IdAuthorQuestion, DateCreatedQuestion = DateTimeOffset.UtcNow, DateLastEditedQuestion = DateTimeOffset.UtcNow, - IdWell = sourceFaqs.Last().IdWell, - Answer = mergeTexts == true + Answer = mergeQuestions == true ? string.Join(Environment.NewLine, sourceFaqs.Select(e => e.Answer)) : sourceFaqs.Last().Answer, - Question = mergeTexts == true + Question = mergeQuestions == true ? string.Join(Environment.NewLine, sourceFaqs.Select(e => e.Question)) : sourceFaqs.Last().Question, }; - db.FAQs.Add(newFaq); + db.Faqs.Add(newFaq); await db.SaveChangesAsync(token).ConfigureAwait(false); if (newFaq.Id == 0) @@ -135,18 +123,16 @@ namespace AsbCloudInfrastructure.Repository { var entity = dto.Adapt(); entity.DateLastEditedQuestion = DateTimeOffset.UtcNow; - db.FAQs.Update(entity); + db.Faqs.Update(entity); return await db.SaveChangesAsync(token) .ConfigureAwait(false); } - public async Task MarkAsDeletedAsync(int idWell, int id, CancellationToken token) + public async Task MarkAsDeletedAsync(int id, CancellationToken token) { - var entity = db.FAQs.FirstOrDefault(e => e.Id == id); + var entity = db.Faqs.FirstOrDefault(e => e.Id == id); if (entity is null) throw new ArgumentInvalidException("Question doesn't exist", nameof(id)); - if (entity.IdWell != idWell) - throw new ArgumentInvalidException("Question's well and idWell don't match", nameof(idWell)); entity.State = Faq.StateDeleted; entity.DateLastEditedQuestion = DateTimeOffset.UtcNow; @@ -154,6 +140,15 @@ namespace AsbCloudInfrastructure.Repository return await db.SaveChangesAsync(token) .ConfigureAwait(false); } + + public async Task DeleteAsync(int id, CancellationToken token) + { + var faq = db.Faqs.FirstOrDefault(f => f.Id == id); + if (faq is null) + throw new ArgumentInvalidException("Question doesn't exist", nameof(id)); + + db.Faqs.Remove(faq); + return await db.SaveChangesAsync(token); + } } -#nullable disable } diff --git a/AsbCloudWebApi/Controllers/FaqController.cs b/AsbCloudWebApi/Controllers/FaqController.cs index 17ac2a41..5561d81f 100644 --- a/AsbCloudWebApi/Controllers/FaqController.cs +++ b/AsbCloudWebApi/Controllers/FaqController.cs @@ -14,7 +14,6 @@ using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers { -#nullable enable /// /// контроллер по работе с faq-вопросами /// @@ -35,34 +34,23 @@ namespace AsbCloudWebApi.Controllers /// /// получение списка faq-вопросов /// - /// /// /// /// [HttpGet] [Permission] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetAllAsync( - [FromRoute] int idWell, - [FromQuery] FaqRequestBase request, + public async Task GetFilteredAsync( + [FromQuery] FaqRequest request, CancellationToken token) { - if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) - return Forbid(); - - var requestToRepository = new FaqRequest(request, idWell); - - var result = await faqRepository.GetAllAsync( - requestToRepository, - token) - .ConfigureAwait(false); + var result = await faqRepository.GetFilteredAsync(request, token).ConfigureAwait(false); return Ok(result); } /// /// добавление нового вопроса /// - /// ключ скважины /// вопрос /// /// @@ -70,14 +58,9 @@ namespace AsbCloudWebApi.Controllers [Permission] [ProducesResponseType(typeof(FaqDto), (int)System.Net.HttpStatusCode.OK)] public async Task InsertAsync( - [Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")] int idWell, [FromBody] FaqDto faqDto, CancellationToken token) { - if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) - return Forbid(); - - faqDto.IdWell = idWell; faqDto.IdAuthorQuestion = User.GetUserId()!.Value; var result = await faqRepository.InsertAsync(faqDto, token) @@ -88,11 +71,8 @@ namespace AsbCloudWebApi.Controllers [HttpPut] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task UpdateAsync(int idWell, [FromBody] FaqDto faqDto, CancellationToken token) + public async Task UpdateAsync([FromBody] FaqDto faqDto, CancellationToken token) { - if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) - return Forbid(); - faqDto.IdAuthorAnswer = User.GetUserId()!.Value; var result = await faqRepository.UpdateAsync(faqDto, token) @@ -103,8 +83,8 @@ namespace AsbCloudWebApi.Controllers /// /// Объединение 2 вопросов в один /// - /// ключ скважины - /// ключи вопросов, подлежащих объединению + /// + /// /// настройка, объединять ли текст 2-х вопросов в один или нет /// /// @@ -112,17 +92,12 @@ namespace AsbCloudWebApi.Controllers [HttpGet("merge")] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task MergeAsync( - int idWell, - [FromQuery] IEnumerable sourceIds, + [FromQuery] int sourceId1, + [FromQuery] int sourceId2, [FromQuery] bool mergeTexts, CancellationToken token) { - if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) - return Forbid(); - if (sourceIds.Count() < 2) - throw new ArgumentInvalidException("Count of questions must be more than 1", nameof(sourceIds)); - - var result = await faqRepository.MergeAsync(sourceIds, mergeTexts, token) + var result = await faqRepository.MergeAsync(sourceId1, sourceId2, mergeTexts, token) .ConfigureAwait(false); return Ok(result); } @@ -130,31 +105,35 @@ namespace AsbCloudWebApi.Controllers /// /// Помечает вопрос как удаленный /// - /// id скважины /// id вопроса /// Токен отмены задачи /// Количество удаленных из БД строк [HttpPut("{id}")] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task MarkAsDeletedAsync(int idWell, int id, CancellationToken token) + public async Task MarkAsDeletedAsync(int id, CancellationToken token) { - if (!await CanUserAccessToWellAsync(idWell, - token).ConfigureAwait(false)) - return Forbid(); - - var result = await faqRepository.MarkAsDeletedAsync(idWell, id, token) + var result = await faqRepository.MarkAsDeletedAsync(id, token) .ConfigureAwait(false); return Ok(result); } - private async Task CanUserAccessToWellAsync(int idWell, CancellationToken token) + /// + /// Удаление вопроса + /// + /// id вопроса + /// Токен отмены задачи + /// Количество удаленных из БД строк + [HttpDelete("{id}")] + [Permission] + [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] + public async Task DeleteAsync(int id, CancellationToken token) { - int? idCompany = User.GetCompanyId(); - return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false); + var result = await faqRepository.DeleteAsync(id, token) + .ConfigureAwait(false); + + return Ok(result); } } -#nullable disable }