-
Notifications
You must be signed in to change notification settings - Fork 80
Лаб. 3 6412 Яковлев Радик #284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ada8f21
d5f5239
f76f3c4
b370ceb
c9b8bae
f7e7b93
6e9534e
90b42f5
0b6b109
fe2b488
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| name: Run .NET Tests | ||
|
|
||
| on: | ||
| push: | ||
| pull_request: | ||
|
|
||
| jobs: | ||
| build-and-test: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup .NET | ||
| uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: "8.0.x" | ||
|
|
||
| - name: Restore dependencies | ||
| run: dotnet restore Library/Library.sln | ||
|
|
||
| - name: Build | ||
| run: dotnet build Library/Library.sln --configuration Release --no-restore | ||
|
|
||
| - name: Run tests | ||
| run: dotnet test Library/Library.sln --configuration Release --no-build | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| using Library.Application.Contracts; | ||
| using Library.Application.Contracts.Analytics; | ||
| using Library.Application.Contracts.Books; | ||
| using Library.Application.Contracts.Readers; | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace Library.Api.Host.Controllers; | ||
|
|
||
| /// <summary> | ||
| /// Контроллер для выполнения аналитических запросов по библиотеке | ||
| /// </summary> | ||
| [Route("api/[controller]")] | ||
| [ApiController] | ||
| public class AnalyticsController( | ||
| IAnalyticsService analyticsService, | ||
| ILogger<AnalyticsController> logger) : ControllerBase | ||
| { | ||
| /// <summary> | ||
| /// Возвращает информацию о выданных книгах, упорядоченных по названию | ||
| /// </summary> | ||
| /// <returns>Список DTO для получения книг</returns> | ||
| [HttpGet("issued-books")] | ||
| [ProducesResponseType(200)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<IList<BookDto>>> GetIssuedBooksOrderedByTitle() | ||
| { | ||
| logger.LogInformation("{method} method of {controller} is called", nameof(GetIssuedBooksOrderedByTitle), GetType().Name); | ||
| try | ||
| { | ||
| var res = await analyticsService.GetIssuedBooksOrderedByTitle(); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetIssuedBooksOrderedByTitle), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetIssuedBooksOrderedByTitle), GetType().Name, ex); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Здесь и далее по коду - у |
||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Возвращает информацию о топ 5 читателей, прочитавших больше всего книг за заданный период | ||
| /// </summary> | ||
| /// <param name="periodStart">Начало периода в UTC</param> | ||
| /// <param name="periodEnd">Конец периода в UTC</param> | ||
| /// <returns>Список DTO для получения статистики по читателям</returns> | ||
| [HttpGet("top-readers")] | ||
| [ProducesResponseType(200)] | ||
| [ProducesResponseType(400)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<IList<ReaderIssuesStatDto>>> GetTop5ReadersByIssuesCount([FromQuery] DateTime periodStart, [FromQuery] DateTime periodEnd) | ||
| { | ||
| logger.LogInformation( | ||
| "{method} method of {controller} is called with {start},{end} parameters", | ||
| nameof(GetTop5ReadersByIssuesCount), GetType().Name, periodStart, periodEnd); | ||
|
|
||
| if (periodEnd < periodStart) | ||
| return BadRequest("periodEnd cannot be less than PeriodStart"); | ||
|
|
||
| try | ||
| { | ||
| var res = await analyticsService.GetTop5ReadersByIssuesCount(periodStart, periodEnd); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetTop5ReadersByIssuesCount), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetTop5ReadersByIssuesCount), GetType().Name, ex); | ||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Возвращает информацию о читателях, бравших книги на наибольший период времени, упорядоченных по ФИО | ||
| /// </summary> | ||
| /// <returns>Список DTO для получения читателей</returns> | ||
| [HttpGet("readers-max-loan-days")] | ||
| [ProducesResponseType(200)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<IList<ReaderDto>>> GetReadersByMaxLoanDaysOrderedByFullName() | ||
| { | ||
| logger.LogInformation("{method} method of {controller} is called", nameof(GetReadersByMaxLoanDaysOrderedByFullName), GetType().Name); | ||
| try | ||
| { | ||
| var res = await analyticsService.GetReadersByMaxLoanDaysOrderedByFullName(); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetReadersByMaxLoanDaysOrderedByFullName), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetReadersByMaxLoanDaysOrderedByFullName), GetType().Name, ex); | ||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Возвращает топ 5 наиболее популярных издательств за последний год | ||
| /// </summary> | ||
| /// <returns>Список DTO для получения статистики по издательствам</returns> | ||
| [HttpGet("top-publishers-last-year")] | ||
| [ProducesResponseType(200)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<IList<PublisherIssuesStatDto>>> GetTop5PublishersByIssuesCountLastYear() | ||
| { | ||
| logger.LogInformation("{method} method of {controller} is called", nameof(GetTop5PublishersByIssuesCountLastYear), GetType().Name); | ||
| try | ||
| { | ||
| var res = await analyticsService.GetTop5PublishersByIssuesCountLastYear(DateTime.UtcNow); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetTop5PublishersByIssuesCountLastYear), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetTop5PublishersByIssuesCountLastYear), GetType().Name, ex); | ||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Возвращает топ 5 наименее популярных книг за последний год | ||
| /// </summary> | ||
| /// <returns>Список DTO для получения статистики по книгам</returns> | ||
| [HttpGet("bottom-books-last-year")] | ||
| [ProducesResponseType(200)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<IList<BookIssuesStatDto>>> GetBottom5BooksByIssuesCountLastYear() | ||
| { | ||
| logger.LogInformation("{method} method of {controller} is called", nameof(GetBottom5BooksByIssuesCountLastYear), GetType().Name); | ||
| try | ||
| { | ||
| var res = await analyticsService.GetBottom5BooksByIssuesCountLastYear(DateTime.UtcNow); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetBottom5BooksByIssuesCountLastYear), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetBottom5BooksByIssuesCountLastYear), GetType().Name, ex); | ||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| using Library.Application.Contracts.Books; | ||
| using Library.Application.Contracts.BookIssues; | ||
| using Library.Application.Contracts.EditionTypes; | ||
| using Library.Application.Contracts.Publishers; | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace Library.Api.Host.Controllers; | ||
|
|
||
| /// <summary> | ||
| /// Контроллер для работы с книгами | ||
| /// </summary> | ||
|
Comment on lines
+9
to
+11
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Здесь и далее по коду - в саммари служб отсутствует описание параметров |
||
| [Route("api/[controller]")] | ||
| [ApiController] | ||
| public class BookController( | ||
| IBookService bookService, | ||
| ILogger<BookController> logger) | ||
| : CrudControllerBase<BookDto, BookCreateUpdateDto, int>(bookService, logger) | ||
| { | ||
| /// <summary> | ||
| /// Возвращает записи о выдачах книги | ||
| /// </summary> | ||
| /// <param name="id">Идентификатор книги</param> | ||
| /// <returns>Список DTO для получения выдач книг</returns> | ||
| [HttpGet("{id}/Issues")] | ||
| [ProducesResponseType(typeof(IList<BookIssueDto>), 200)] | ||
| [ProducesResponseType(404)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<IList<BookIssueDto>>> GetIssues(int id) | ||
| { | ||
| logger.LogInformation("{method} method of {controller} is called with {id} parameter", nameof(GetIssues), GetType().Name, id); | ||
| try | ||
| { | ||
| var res = await bookService.GetIssues(id); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetIssues), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (KeyNotFoundException ex) | ||
| { | ||
| logger.LogWarning("A not found exception happened during {method} method of {controller}: {@exception}", nameof(GetIssues), GetType().Name, ex); | ||
| return NotFound(ex.Message); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetIssues), GetType().Name, ex); | ||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Возвращает вид издания книги | ||
| /// </summary> | ||
| /// <param name="id">Идентификатор книги</param> | ||
| /// <returns>DTO для получения вида издания</returns> | ||
| [HttpGet("{id}/EditionType")] | ||
| [ProducesResponseType(typeof(EditionTypeDto), 200)] | ||
| [ProducesResponseType(404)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<EditionTypeDto>> GetEditionType(int id) | ||
| { | ||
| logger.LogInformation("{method} method of {controller} is called with {id} parameter", nameof(GetEditionType), GetType().Name, id); | ||
| try | ||
| { | ||
| var res = await bookService.GetEditionType(id); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetEditionType), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (KeyNotFoundException ex) | ||
| { | ||
| logger.LogWarning("A not found exception happened during {method} method of {controller}: {@exception}", nameof(GetEditionType), GetType().Name, ex); | ||
| return NotFound(ex.Message); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetEditionType), GetType().Name, ex); | ||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Возвращает издательство книги | ||
| /// </summary> | ||
| /// <param name="id">Идентификатор книги</param> | ||
| /// <returns>DTO для получения издательства</returns> | ||
| [HttpGet("{id}/Publisher")] | ||
| [ProducesResponseType(typeof(PublisherDto), 200)] | ||
| [ProducesResponseType(404)] | ||
| [ProducesResponseType(500)] | ||
| public async Task<ActionResult<PublisherDto>> GetPublisher(int id) | ||
| { | ||
| logger.LogInformation("{method} method of {controller} is called with {id} parameter", nameof(GetPublisher), GetType().Name, id); | ||
| try | ||
| { | ||
| var res = await bookService.GetPublisher(id); | ||
| logger.LogInformation("{method} method of {controller} executed successfully", nameof(GetPublisher), GetType().Name); | ||
| return Ok(res); | ||
| } | ||
| catch (KeyNotFoundException ex) | ||
| { | ||
| logger.LogWarning("A not found exception happened during {method} method of {controller}: {@exception}", nameof(GetPublisher), GetType().Name, ex); | ||
| return NotFound(ex.Message); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| logger.LogError("An exception happened during {method} method of {controller}: {@exception}", nameof(GetPublisher), GetType().Name, ex); | ||
| return StatusCode(500, $"{ex.Message}\n\r{ex.InnerException?.Message}"); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| using Library.Application.Contracts; | ||
| using Library.Application.Contracts.BookIssues; | ||
| using Microsoft.AspNetCore.Mvc; | ||
|
|
||
| namespace Library.Api.Host.Controllers; | ||
|
|
||
| /// <summary> | ||
| /// Контроллер для работы с выдачами книг | ||
| /// </summary> | ||
| [Route("api/[controller]")] | ||
| [ApiController] | ||
| public class BookIssueController( | ||
| IApplicationService<BookIssueDto, BookIssueCreateUpdateDto, int> appService, | ||
| ILogger<BookIssueController> logger) | ||
| : CrudControllerBase<BookIssueDto, BookIssueCreateUpdateDto, int>(appService, logger); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Настолько часто запускать ашон нет смысла