diff --git a/Hcs.WebApp/Components/Dialogs/StartParsing.razor b/Hcs.WebApp/Components/Dialogs/StartParsing.razor index 37864de..85a8f1e 100644 --- a/Hcs.WebApp/Components/Dialogs/StartParsing.razor +++ b/Hcs.WebApp/Components/Dialogs/StartParsing.razor @@ -22,7 +22,7 @@ @errorMessage - + @@ -44,6 +44,10 @@ int progress; bool hasError; string errorMessage; + int? fileToParseId; + + [Parameter] + public required string UploaderId { get; set; } void Upload() { @@ -55,7 +59,7 @@ void Close() { - DialogService.Close(true); + DialogService.Close(fileToParseId); } void OnProgress(UploadProgressArgs args) @@ -67,7 +71,13 @@ { try { - // TODO + var root = args.JsonResponse.RootElement; + var fileToParse = await FileToParseService.AddFileToParseAsync( + root.GetProperty("Path").GetString(), + root.GetProperty("FileName").GetString(), + UploaderId, + DateTime.Now); + fileToParseId = fileToParse.Id; } catch (Exception e) { diff --git a/Hcs.WebApp/Components/Shared/SyncedPageBase.cs b/Hcs.WebApp/Components/Shared/SyncedPageBase.cs index 0365d47..b9d042c 100644 --- a/Hcs.WebApp/Components/Shared/SyncedPageBase.cs +++ b/Hcs.WebApp/Components/Shared/SyncedPageBase.cs @@ -1,6 +1,7 @@ using Hcs.WebApp.BackgroundServices; using Hcs.WebApp.Components.Dialogs; using Hcs.WebApp.Data.Hcs; +using Hcs.WebApp.Data.Hcs.CampaignArgs; using Hcs.WebApp.Services; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; @@ -74,7 +75,7 @@ namespace Hcs.WebApp.Components.Shared if (await HeadquartersService.HasActiveCampaignAsync(CampaignType)) { - ChangeState(SyncedPageState.Idle); + ChangeState(SyncedPageState.SyncWaiting); } else { @@ -88,17 +89,19 @@ namespace Hcs.WebApp.Components.Shared { if (state == SyncedPageState.SyncWaiting) return; - ChangeState(SyncedPageState.SyncWaiting); - if (await HeadquartersService.HasActiveCampaignAsync(CampaignType)) { - ChangeState(SyncedPageState.Idle); + ChangeState(SyncedPageState.SyncWaiting); } else { - await DialogService.OpenAsync( + var dialogResult = await DialogService.OpenAsync( "Отправка файла", - null, + new Dictionary() + { + // TODO: Use user id + { nameof(StartParsing.UploaderId), "" } + }, new DialogOptions() { Width = "600px", @@ -107,9 +110,18 @@ namespace Hcs.WebApp.Components.Shared ShowClose = false }); - //// TODO: Use user id - //var campaign = await HeadquartersService.InitiateCampaignAsync(CampaignType, ""); - //CampaignManagementState.EnqueueCampaign(campaign); + var fileToParseId = -1; + if (dialogResult != null && int.TryParse(dialogResult, out fileToParseId)) + { + // TODO: Use user id + var campaign = await HeadquartersService.InitiateCampaignAsync(CampaignType, "", new CampaignParseArgs() + { + FileToParseId = fileToParseId + }); + CampaignManagementState.EnqueueCampaign(campaign); + + ChangeState(SyncedPageState.SyncWaiting); + } } } diff --git a/Hcs.WebApp/Controllers/UploadController.cs b/Hcs.WebApp/Controllers/UploadController.cs new file mode 100644 index 0000000..7e7a7d8 --- /dev/null +++ b/Hcs.WebApp/Controllers/UploadController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Hcs.WebApp.Controllers +{ + [Authorize] + [DisableRequestSizeLimit] + public class UploadController(IWebHostEnvironment environment) : Controller + { + private readonly IWebHostEnvironment environment = environment; + + [HttpPost("upload/parsing")] + public IActionResult Single(IFormFile file) + { + try + { + var fileName = $"{DateTime.Today:dd-MM-yyyy}-{Guid.NewGuid()}{Path.GetExtension(file.FileName)}"; + using var stream = new FileStream(Path.Combine(environment.WebRootPath, fileName), FileMode.Create); + file.CopyTo(stream); + + return Ok(new + { + Path = Url.Content($"~/{fileName}"), + FileName = file.FileName + }); + } + catch (Exception e) + { + return StatusCode(500, e.Message); + } + } + } +} diff --git a/Hcs.WebApp/Data/Hcs/Campaign.cs b/Hcs.WebApp/Data/Hcs/Campaign.cs index 846d3bc..9f45cdd 100644 --- a/Hcs.WebApp/Data/Hcs/Campaign.cs +++ b/Hcs.WebApp/Data/Hcs/Campaign.cs @@ -1,4 +1,6 @@ -using System.ComponentModel.DataAnnotations; +using Hcs.WebApp.Data.Hcs.CampaignArgs; +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Hcs.WebApp.Data.Hcs @@ -35,9 +37,29 @@ namespace Hcs.WebApp.Data.Hcs public string? FailureReason { get; set; } + public string? Args { get; set; } + public virtual ICollection? Operations { get; set; } = null; [NotMapped] public bool Completed => EndedAt.HasValue; + + public ICampaignArgs? DeserializeArgs() + { + if (Args == null) return null; + + return JsonConvert.DeserializeObject(Args, new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.Auto + }); + } + + public void SerializeArgs(ICampaignArgs args) + { + Args = JsonConvert.SerializeObject(args, Formatting.None, new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.Auto + }); + } } } diff --git a/Hcs.WebApp/Data/Hcs/CampaignArgs/CampaignParseArgs.cs b/Hcs.WebApp/Data/Hcs/CampaignArgs/CampaignParseArgs.cs new file mode 100644 index 0000000..59087d0 --- /dev/null +++ b/Hcs.WebApp/Data/Hcs/CampaignArgs/CampaignParseArgs.cs @@ -0,0 +1,7 @@ +namespace Hcs.WebApp.Data.Hcs.CampaignArgs +{ + public class CampaignParseArgs : ICampaignArgs + { + public int FileToParseId; + } +} diff --git a/Hcs.WebApp/Data/Hcs/CampaignArgs/ICampaignArgs.cs b/Hcs.WebApp/Data/Hcs/CampaignArgs/ICampaignArgs.cs new file mode 100644 index 0000000..085355b --- /dev/null +++ b/Hcs.WebApp/Data/Hcs/CampaignArgs/ICampaignArgs.cs @@ -0,0 +1,5 @@ +namespace Hcs.WebApp.Data.Hcs.CampaignArgs +{ + // Маркер + public interface ICampaignArgs { } +} diff --git a/Hcs.WebApp/Data/Hcs/FileToParse.cs b/Hcs.WebApp/Data/Hcs/FileToParse.cs index f629e13..b90cfe6 100644 --- a/Hcs.WebApp/Data/Hcs/FileToParse.cs +++ b/Hcs.WebApp/Data/Hcs/FileToParse.cs @@ -8,9 +8,9 @@ public string FileName { get; set; } - public int UploaderId { get; set; } + public string UploaderId { get; set; } - public DateTime? UploadedAt { get; set; } + public DateTime UploadedAt { get; set; } public DateTime? ParsedAt { get; set; } diff --git a/Hcs.WebApp/Services/FileToParseService.cs b/Hcs.WebApp/Services/FileToParseService.cs index 61c4479..2b5533e 100644 --- a/Hcs.WebApp/Services/FileToParseService.cs +++ b/Hcs.WebApp/Services/FileToParseService.cs @@ -10,5 +10,21 @@ namespace Hcs.WebApp.Services using var context = GetNewContext(); return await context.FilesToParse.ToListAsync(); } + + public async Task AddFileToParseAsync(string path, string fileName, string uploaderId, DateTime uploadedAt) + { + using var context = GetNewContext(); + var fileToParse = new FileToParse() + { + Path = path, + FileName = fileName, + UploaderId = uploaderId, + UploadedAt = uploadedAt + }; + + await context.FilesToParse.AddAsync(fileToParse); + await context.SaveChangesAsync(); + return fileToParse; + } } } diff --git a/Hcs.WebApp/Services/HeadquartersService.cs b/Hcs.WebApp/Services/HeadquartersService.cs index 11e9d6c..110ba24 100644 --- a/Hcs.WebApp/Services/HeadquartersService.cs +++ b/Hcs.WebApp/Services/HeadquartersService.cs @@ -1,4 +1,5 @@ using Hcs.WebApp.Data.Hcs; +using Hcs.WebApp.Data.Hcs.CampaignArgs; using Microsoft.EntityFrameworkCore; namespace Hcs.WebApp.Services @@ -69,7 +70,7 @@ namespace Hcs.WebApp.Services select operation).ToListAsync(); } - public async Task InitiateCampaignAsync(Campaign.CampaignType type, string initiatorId) + public async Task InitiateCampaignAsync(Campaign.CampaignType type, string initiatorId, ICampaignArgs? args = null) { using var context = GetNewContext(); var campaign = new Campaign() @@ -78,6 +79,12 @@ namespace Hcs.WebApp.Services InitiatorId = initiatorId, CreatedAt = DateTime.UtcNow }; + + if (args != null) + { + campaign.SerializeArgs(args); + } + await context.Campaigns.AddAsync(campaign); await context.SaveChangesAsync(); return campaign;