| | | 1 | | using Microsoft.AspNetCore.Authorization; |
| | | 2 | | using Microsoft.AspNetCore.Mvc; |
| | | 3 | | using Microsoft.EntityFrameworkCore; |
| | | 4 | | using OzonDomains.Models.Authorization.Enums; |
| | | 5 | | using OzonOrdersWeb.Authorization; |
| | | 6 | | using OzonOrdersWeb.WebServices.Grid; |
| | | 7 | | using OzonOrdersWeb.WebServices.Journals; |
| | | 8 | | using OzonRepositories.Context; |
| | | 9 | | |
| | | 10 | | namespace OzonOrdersWeb.Areas.Studio2.Controllers; |
| | | 11 | | |
| | | 12 | | /// <summary> |
| | | 13 | | /// Журнал вызовов API-поставщиков: каркас страницы, серверный грид (сотни тысяч строк) и запрос/ответ одной записи. |
| | | 14 | | /// </summary> |
| | | 15 | | [Area("Studio2")] |
| | | 16 | | [Authorize(Roles = "User,Admin")] |
| | | 17 | | [Route("Studio2/ApiSupplierRequestAudit")] |
| | | 18 | | public sealed class ApiSupplierRequestAuditController : Controller |
| | | 19 | | { |
| | | 20 | | private const string PageCode = "Studio2.ApiSupplierRequestAudit.Index"; |
| | | 21 | | private readonly ApplicationDbContext _db; |
| | | 22 | | |
| | 0 | 23 | | public ApiSupplierRequestAuditController(ApplicationDbContext db) => _db = db; |
| | | 24 | | |
| | | 25 | | [HttpGet("")] |
| | 0 | 26 | | public IActionResult Index() => View(); |
| | | 27 | | |
| | | 28 | | [HttpPost("grid")] |
| | | 29 | | [ValidateAntiForgeryToken] |
| | | 30 | | [PageAuthorize(PageCode, AccessType.View)] |
| | | 31 | | public async Task<IActionResult> GridRows([FromBody] ServerGridRequest? request, CancellationToken cancellationToken |
| | | 32 | | { |
| | 0 | 33 | | var error = ServerGridQuery.Validate(request); |
| | 0 | 34 | | if (error != null) return BadRequest(new { success = false, error }); |
| | | 35 | | |
| | 0 | 36 | | var def = JournalGridDefinitions.ApiSupplierAudit; |
| | 0 | 37 | | var filtered = ServerGridQuery.ApplyFilters(_db.ApiSupplierRequestAuditEntries.AsNoTracking(), def, request!); |
| | 0 | 38 | | var total = await filtered.CountAsync(cancellationToken); |
| | 0 | 39 | | var start = Math.Max(0, request!.StartRow); |
| | 0 | 40 | | var take = Math.Clamp(request.EndRow - start, 1, ServerGridQuery.MaxBlockSize); |
| | 0 | 41 | | var rows = start >= total |
| | 0 | 42 | | ? [] |
| | 0 | 43 | | : await ServerGridQuery.ApplySort(filtered, def, request.SortModel).Skip(start).Take(take) |
| | 0 | 44 | | .Select(x => new |
| | 0 | 45 | | { |
| | 0 | 46 | | x.Id, x.OccurredAtUtc, x.ProviderKey, x.IsSuccess, x.StatusCode, x.Method, x.Endpoint, x.Source, x.A |
| | 0 | 47 | | x.DurationMs |
| | 0 | 48 | | }) |
| | 0 | 49 | | .ToListAsync(cancellationToken); |
| | 0 | 50 | | var lastRow = start + rows.Count >= total ? total : -1; |
| | 0 | 51 | | return Ok(new { success = true, rows, totalCount = total, lastRow }); |
| | 0 | 52 | | } |
| | | 53 | | |
| | | 54 | | [HttpPost("grid/facets")] |
| | | 55 | | [ValidateAntiForgeryToken] |
| | | 56 | | [PageAuthorize(PageCode, AccessType.View)] |
| | | 57 | | public async Task<IActionResult> GridFacets([FromBody] ServerGridRequest? request, CancellationToken cancellationTok |
| | | 58 | | { |
| | 0 | 59 | | if (request is null || string.IsNullOrWhiteSpace(request.ColId)) return BadRequest(new { success = false, error |
| | 0 | 60 | | request.StartRow = 0; |
| | 0 | 61 | | request.EndRow = 1; |
| | 0 | 62 | | var error = ServerGridQuery.Validate(request); |
| | 0 | 63 | | if (error != null) return BadRequest(new { success = false, error }); |
| | 0 | 64 | | var values = await ServerGridQuery.FacetsAsync(_db.ApiSupplierRequestAuditEntries.AsNoTracking(), |
| | 0 | 65 | | JournalGridDefinitions.ApiSupplierAudit, request, cancellationToken); |
| | 0 | 66 | | return Ok(new { success = true, values }); |
| | 0 | 67 | | } |
| | | 68 | | |
| | | 69 | | /// <summary>Запрос и ответ вызова (longtext) — по кнопке «Открыть», в строки грида не входят.</summary> |
| | | 70 | | [HttpGet("{id:long}")] |
| | | 71 | | [PageAuthorize(PageCode, AccessType.View)] |
| | | 72 | | public async Task<IActionResult> Details(long id, CancellationToken cancellationToken) |
| | | 73 | | { |
| | 0 | 74 | | var entry = await _db.ApiSupplierRequestAuditEntries.AsNoTracking() |
| | 0 | 75 | | .Where(x => x.Id == id) |
| | 0 | 76 | | .Select(x => new { x.Id, x.Method, x.Endpoint, x.Request, x.Response }) |
| | 0 | 77 | | .FirstOrDefaultAsync(cancellationToken); |
| | 0 | 78 | | return entry == null ? NotFound() : Ok(entry); |
| | 0 | 79 | | } |
| | | 80 | | } |