From eb4380b6d5ab565969b24d04cc3f6871ddf1b02e Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Thu, 23 Feb 2023 00:35:59 +0800 Subject: [PATCH] Add Play Records page and apis, finish migration (except for online matching) --- Application/Api/GetSongPlayRecordsQuery.cs | 125 ++++++++++++++++++ Domain/Domain.csproj | 2 +- Domain/Entities/CardDetail.cs | 2 +- Domain/Enums/ClearState.cs | 14 ++ Domain/Enums/Difficulty.cs | 12 ++ .../Migrations/20230208132952_Initial.cs | 2 +- Infrastructure/Persistence/CardDbContext.cs | 2 +- MainServer/Configurations/database.json | 2 +- .../Controllers/API/ProfilesController.cs | 10 +- MainServer/Database/card.db3-shm | Bin 32768 -> 0 bytes MainServer/Database/card.db3-wal | Bin 16512 -> 0 bytes Shared/Models/SongPlayRecord.cs | 18 +++ Shared/Models/StagePlayRecord.cs | 18 +++ WebUI/GlobalUsings.cs | 5 +- WebUI/Pages/Cards.razor | 2 +- WebUI/Pages/Cards.razor.cs | 5 +- WebUI/Pages/Dialogs/ChangeAvatarDialog.razor | 5 +- .../Pages/Dialogs/ChangeNavigatorDialog.razor | 5 +- .../Dialogs/ChangePlayerNameDialog.razor | 1 - WebUI/Pages/Dialogs/ChangeTitleDialog.razor | 5 +- WebUI/Pages/Dialogs/FavoriteDialog.razor | 61 +++++++++ WebUI/Pages/Option.razor.cs | 5 +- WebUI/Pages/PlayRecords.razor | 84 ++++++++++++ WebUI/Pages/PlayRecords.razor.cs | 85 ++++++++++++ WebUI/Pages/TotalResult.razor | 1 + WebUI/Pages/TotalResult.razor.cs | 5 +- WebUI/Services/DataService.cs | 19 +-- WebUI/_Imports.razor | 5 +- 28 files changed, 450 insertions(+), 50 deletions(-) create mode 100644 Application/Api/GetSongPlayRecordsQuery.cs create mode 100644 Domain/Enums/ClearState.cs create mode 100644 Domain/Enums/Difficulty.cs delete mode 100644 MainServer/Database/card.db3-shm delete mode 100644 MainServer/Database/card.db3-wal create mode 100644 Shared/Models/SongPlayRecord.cs create mode 100644 Shared/Models/StagePlayRecord.cs create mode 100644 WebUI/Pages/Dialogs/FavoriteDialog.razor create mode 100644 WebUI/Pages/PlayRecords.razor create mode 100644 WebUI/Pages/PlayRecords.razor.cs diff --git a/Application/Api/GetSongPlayRecordsQuery.cs b/Application/Api/GetSongPlayRecordsQuery.cs new file mode 100644 index 0000000..8bc5d6e --- /dev/null +++ b/Application/Api/GetSongPlayRecordsQuery.cs @@ -0,0 +1,125 @@ +using System.Diagnostics.CodeAnalysis; +using Domain.Entities; +using Domain.Enums; + +namespace Application.Api; + +public record GetSongPlayRecordsQuery(long cardId) : IRequestWrapper>; + +public class GetSongPlayRecordsQueryHandler : RequestHandlerBase> +{ + public GetSongPlayRecordsQueryHandler(ICardDependencyAggregate aggregate) : base(aggregate) + { + } + + [SuppressMessage("ReSharper.DPA", "DPA0007: Large number of DB records")] + public override async Task>> Handle(GetSongPlayRecordsQuery request, + CancellationToken cancellationToken) + { + var exists = await CardDbContext.CardDetails.AnyAsync(detail => detail.CardId == request.cardId); + if (!exists) + { + return ServiceResult.Failed>(ServiceError.CustomMessage("No play record")); + } + var results = new List(); + + var musics = await MusicDbContext.MusicUnlocks.ToDictionaryAsync(unlock => unlock.MusicId, cancellationToken); + + var playCounts = await CardDbContext.CardDetails + .Where(detail => detail.CardId == request.cardId && + detail.Pcol1 == 20) + .Select(detail => new + { + MusicId = detail.Pcol2, + Difficulty = (Difficulty)detail.Pcol3, + Detail = detail + }) + .ToDictionaryAsync(arg => new { arg.MusicId, arg.Difficulty }, cancellationToken: cancellationToken); + + var stageDetails = await CardDbContext.CardDetails + .Where(detail => detail.CardId == request.cardId && + detail.Pcol1 == 21) + .Select(detail => new + { + MusicId = detail.Pcol2, + Difficulty = (Difficulty)detail.Pcol3, + Score = detail.ScoreUi1, + MaxChain = detail.ScoreUi3, + }) + .ToDictionaryAsync(arg => new { arg.MusicId, arg.Difficulty }, cancellationToken); + + var favorites = await CardDbContext.CardDetails + .Where(detail => detail.CardId == request.cardId && + detail.Pcol1 == 10) + .Select(detail => new { MusicId = detail.Pcol2, IsFavorite = detail.Fcol1 == 1 }) + .ToListAsync(cancellationToken); + + foreach (var song in favorites) + { + var musicId = song.MusicId; + var music = musics.GetValueOrDefault(musicId); + var songPlayRecord = new SongPlayRecord + { + MusicId = (int)musicId, + Title = music?.Title ?? string.Empty, + Artist = music?.Artist ?? string.Empty, + IsFavorite = song.IsFavorite + }; + foreach (var difficulty in DifficultyExtensions.GetValues()) + { + var key = new { MusicId = musicId, Difficulty = difficulty }; + if (!playCounts.ContainsKey(key) || !stageDetails.ContainsKey(key)) continue; + var playCountDetail = playCounts[key].Detail; + var playCount = playCountDetail.ScoreUi1; + var stageDetail = stageDetails[key]; + var score = stageDetail.Score; + var maxChain = stageDetail.MaxChain; + var clearState = GetClearState(playCountDetail); + var stagePlayRecord = new StagePlayRecord + { + Difficulty = difficulty, + ClearState = clearState, + PlayCount = (int)playCount, + Score = (int)score, + MaxChain = (int)maxChain, + LastPlayTime = playCountDetail?.LastPlayTime ?? DateTime.MinValue + }; + songPlayRecord.StagePlayRecords.Add(stagePlayRecord); + } + + songPlayRecord.TotalPlayCount = songPlayRecord.StagePlayRecords.Sum(record => record.PlayCount); + if (songPlayRecord.StagePlayRecords.Count > 0) + { + results.Add(songPlayRecord); + } + } + + return new ServiceResult>(results); + } + + private static ClearState GetClearState(CardDetail detail) + { + var result = ClearState.Failed; + if (detail.ScoreUi2 > 0) + { + result = ClearState.Clear; + } + + if (detail.ScoreUi3 > 0) + { + result = ClearState.NoMiss; + } + + if (detail.ScoreUi4 > 0) + { + result = ClearState.FullChain; + } + + if (detail.ScoreUi6 > 0) + { + result = ClearState.Perfect; + } + + return result; + } +} \ No newline at end of file diff --git a/Domain/Domain.csproj b/Domain/Domain.csproj index d21f3bd..2c82047 100644 --- a/Domain/Domain.csproj +++ b/Domain/Domain.csproj @@ -7,7 +7,7 @@ - + diff --git a/Domain/Entities/CardDetail.cs b/Domain/Entities/CardDetail.cs index b31db01..5310e0d 100644 --- a/Domain/Entities/CardDetail.cs +++ b/Domain/Entities/CardDetail.cs @@ -34,5 +34,5 @@ public partial class CardDetail public long Fcol3 { get; set; } - public DateTime LastPlayTime { get; set; } + public DateTime? LastPlayTime { get; set; } } diff --git a/Domain/Enums/ClearState.cs b/Domain/Enums/ClearState.cs new file mode 100644 index 0000000..70fd3f7 --- /dev/null +++ b/Domain/Enums/ClearState.cs @@ -0,0 +1,14 @@ +using NetEscapades.EnumGenerators; + +namespace Domain.Enums; + +[EnumExtensions] +public enum ClearState +{ + NotPlayed = 0, + Failed, + Clear, + NoMiss, + FullChain, + Perfect +} \ No newline at end of file diff --git a/Domain/Enums/Difficulty.cs b/Domain/Enums/Difficulty.cs new file mode 100644 index 0000000..67547be --- /dev/null +++ b/Domain/Enums/Difficulty.cs @@ -0,0 +1,12 @@ +using NetEscapades.EnumGenerators; + +namespace Domain.Enums; + +[EnumExtensions] +public enum Difficulty +{ + Simple = 0, + Normal = 1, + Hard = 2, + Extra = 3 +} \ No newline at end of file diff --git a/Infrastructure/Migrations/20230208132952_Initial.cs b/Infrastructure/Migrations/20230208132952_Initial.cs index 1af7824..967d43b 100644 --- a/Infrastructure/Migrations/20230208132952_Initial.cs +++ b/Infrastructure/Migrations/20230208132952_Initial.cs @@ -48,7 +48,7 @@ namespace Infrastructure.Migrations fcol1 = table.Column(type: "INTEGER", nullable: false), fcol2 = table.Column(type: "INTEGER", nullable: false), fcol3 = table.Column(type: "INTEGER", nullable: false), - lastplaytime = table.Column(name: "last_play_time", type: "INTEGER", nullable: false) + lastplaytime = table.Column(name: "last_play_time", type: "INTEGER", nullable: true) }, constraints: table => { diff --git a/Infrastructure/Persistence/CardDbContext.cs b/Infrastructure/Persistence/CardDbContext.cs index 5cbb1fa..bcf63c4 100644 --- a/Infrastructure/Persistence/CardDbContext.cs +++ b/Infrastructure/Persistence/CardDbContext.cs @@ -76,7 +76,7 @@ public partial class CardDbContext : DbContext, ICardDbContext entity.Property(e => e.Fcol3).HasColumnName("fcol3"); entity.Property(e => e.LastPlayTenpoId).HasColumnName("last_play_tenpo_id").IsRequired(false); entity.Property(e => e.LastPlayTime).HasColumnName("last_play_time") - .HasConversion(); + .HasConversion().IsRequired(false); entity.Property(e => e.ScoreBi1).HasColumnName("score_bi1"); entity.Property(e => e.ScoreI1).HasColumnName("score_i1"); entity.Property(e => e.ScoreUi1).HasColumnName("score_ui1"); diff --git a/MainServer/Configurations/database.json b/MainServer/Configurations/database.json index 3c9ff35..4b2f10b 100644 --- a/MainServer/Configurations/database.json +++ b/MainServer/Configurations/database.json @@ -1,4 +1,4 @@ { - "CardDbName": "card.db3", + "CardDbName": "card.full.db3", "MusicDbName": "music471omni.db3" } \ No newline at end of file diff --git a/MainServer/Controllers/API/ProfilesController.cs b/MainServer/Controllers/API/ProfilesController.cs index eed548c..b7b7a66 100644 --- a/MainServer/Controllers/API/ProfilesController.cs +++ b/MainServer/Controllers/API/ProfilesController.cs @@ -23,7 +23,15 @@ public class ProfilesController : BaseController return result; } - [HttpPost("Favorite")] + [HttpGet("SongPlayRecords/{cardId:long}")] + public async Task>> GetSongPlayRecords(long cardId) + { + var result = await Mediator.Send(new GetSongPlayRecordsQuery(cardId)); + + return result; + } + + [HttpPost("SetFavorite")] public async Task> SetFavoriteMusic(MusicFavoriteDto favorite) { var result = await Mediator.Send(new SetFavoriteMusicCommand(favorite)); diff --git a/MainServer/Database/card.db3-shm b/MainServer/Database/card.db3-shm deleted file mode 100644 index 73e920c963f99d05dcab460cc50d8effe143db30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI)y$J#_7zW^+T3K0GM0d~?T;m21>>R-ZC2IrI1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!89K1d93}t0vsk9SQte zApfx@1PBlyK!5-N0t5&UAV7dXy9GM!e!kZeAV7cs0RjXF5FkK+009C72oNAZfB*pk R1PBlyK!5-N0tEh2;0bnvDt7N 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 StagePlayRecords { get; set; } = new(); +} \ No newline at end of file diff --git a/Shared/Models/StagePlayRecord.cs b/Shared/Models/StagePlayRecord.cs new file mode 100644 index 0000000..e9eba54 --- /dev/null +++ b/Shared/Models/StagePlayRecord.cs @@ -0,0 +1,18 @@ +using Domain.Enums; + +namespace Shared.Models; + +public class StagePlayRecord +{ + public int Score { get; set; } + + public int PlayCount { get; set; } + + public int MaxChain { get; set; } + + public Difficulty Difficulty { get; set; } + + public ClearState ClearState { get; set; } + + public DateTime LastPlayTime { get; set; } +} \ No newline at end of file diff --git a/WebUI/GlobalUsings.cs b/WebUI/GlobalUsings.cs index 099b2c7..5a3bacf 100644 --- a/WebUI/GlobalUsings.cs +++ b/WebUI/GlobalUsings.cs @@ -1,3 +1,6 @@ // Global using directives -global using MudBlazor; \ No newline at end of file +global using System.Net.Http.Json; +global using Microsoft.AspNetCore.Components; +global using MudBlazor; +global using Shared.Models; \ No newline at end of file diff --git a/WebUI/Pages/Cards.razor b/WebUI/Pages/Cards.razor index 9a2b66b..81283ef 100644 --- a/WebUI/Pages/Cards.razor +++ b/WebUI/Pages/Cards.razor @@ -73,7 +73,7 @@ AnchorOrigin="Origin.BottomCenter" TransformOrigin="Origin.TopCenter"> Total Result - Song Play Results + Song Play Results diff --git a/WebUI/Pages/Cards.razor.cs b/WebUI/Pages/Cards.razor.cs index ae20ddb..b5a0659 100644 --- a/WebUI/Pages/Cards.razor.cs +++ b/WebUI/Pages/Cards.razor.cs @@ -1,7 +1,4 @@ -using System.Net.Http.Json; -using Microsoft.AspNetCore.Components; -using Shared.Dto.Api; -using Shared.Models; +using Shared.Dto.Api; using Throw; using WebUI.Pages.Dialogs; diff --git a/WebUI/Pages/Dialogs/ChangeAvatarDialog.razor b/WebUI/Pages/Dialogs/ChangeAvatarDialog.razor index 69dcd49..bd838b4 100644 --- a/WebUI/Pages/Dialogs/ChangeAvatarDialog.razor +++ b/WebUI/Pages/Dialogs/ChangeAvatarDialog.razor @@ -1,7 +1,4 @@ -@using WebUI.Services -@using Shared.Models -@using WebUI.Common.Models -@inject IDataService DataService +@inject IDataService DataService diff --git a/WebUI/Pages/Dialogs/ChangeNavigatorDialog.razor b/WebUI/Pages/Dialogs/ChangeNavigatorDialog.razor index 014a11a..6a7c9a3 100644 --- a/WebUI/Pages/Dialogs/ChangeNavigatorDialog.razor +++ b/WebUI/Pages/Dialogs/ChangeNavigatorDialog.razor @@ -1,7 +1,4 @@ -@using WebUI.Services -@using Shared.Models -@using WebUI.Common.Models -@inject IDataService DataService +@inject IDataService DataService diff --git a/WebUI/Pages/Dialogs/ChangePlayerNameDialog.razor b/WebUI/Pages/Dialogs/ChangePlayerNameDialog.razor index ab17b50..58f427f 100644 --- a/WebUI/Pages/Dialogs/ChangePlayerNameDialog.razor +++ b/WebUI/Pages/Dialogs/ChangePlayerNameDialog.razor @@ -1,6 +1,5 @@ @using System.Text.RegularExpressions @using Shared.Dto.Api -@using Shared.Models @using Throw @inject HttpClient Client @inject ILogger Logger diff --git a/WebUI/Pages/Dialogs/ChangeTitleDialog.razor b/WebUI/Pages/Dialogs/ChangeTitleDialog.razor index 1cb19cc..f41eda0 100644 --- a/WebUI/Pages/Dialogs/ChangeTitleDialog.razor +++ b/WebUI/Pages/Dialogs/ChangeTitleDialog.razor @@ -1,7 +1,4 @@ -@using WebUI.Services -@using Shared.Models -@using WebUI.Common.Models -@inject IDataService DataService +@inject IDataService DataService diff --git a/WebUI/Pages/Dialogs/FavoriteDialog.razor b/WebUI/Pages/Dialogs/FavoriteDialog.razor new file mode 100644 index 0000000..dce7bd3 --- /dev/null +++ b/WebUI/Pages/Dialogs/FavoriteDialog.razor @@ -0,0 +1,61 @@ +@using Shared.Dto.Api +@using Throw +@inject HttpClient Client + + + + @if (!Data.IsFavorite) + { + + + Add to favorite? + + } + else + { + + + Remove from favorite? + + } + + + + + + + Cancel + Confirm + + + +@code{ + + [CascadingParameter] + public required MudDialogInstance MudDialog { get; set; } + + [Parameter] + public required SongPlayRecord Data { get; set; } + + [Parameter] + public long CardId { get; set; } + + private async Task Submit() + { + var favoriteData = new MusicFavoriteDto + { + CardId = CardId, + IsFavorite = !Data.IsFavorite, + MusicId = Data.MusicId + }; + + var response = await Client.PostAsJsonAsync("api/Profiles/SetFavorite", favoriteData); + var result = await response.Content.ReadFromJsonAsync>(); + result.ThrowIfNull(); + + MudDialog.Close(DialogResult.Ok(result)); + } + + private void Cancel() => MudDialog.Cancel(); + +} \ No newline at end of file diff --git a/WebUI/Pages/Option.razor.cs b/WebUI/Pages/Option.razor.cs index 7d5cefa..b47adb2 100644 --- a/WebUI/Pages/Option.razor.cs +++ b/WebUI/Pages/Option.razor.cs @@ -1,7 +1,4 @@ -using System.Net.Http.Json; -using Microsoft.AspNetCore.Components; -using Shared.Models; -using Throw; +using Throw; using WebUI.Pages.Dialogs; using WebUI.Services; diff --git a/WebUI/Pages/PlayRecords.razor b/WebUI/Pages/PlayRecords.razor new file mode 100644 index 0000000..967652a --- /dev/null +++ b/WebUI/Pages/PlayRecords.razor @@ -0,0 +1,84 @@ +@page "/Cards/PlayRecords/{cardId:long}" + + + +Song Play Records +

Song Play Records

+@if (errorMessage is not null) +{ + @errorMessage + return; +} + +@if (songPlayRecords is null) +{ + + + + + + + + + return; +} + + + + Played Songs + + + + + + + + + + + + + + + + + Song Play Details + + + + + + Difficulty + Play Count + Clear State + Score + Rating + Max Chain + Last Play Time + + + @stage.Difficulty + @stage.PlayCount + @stage.ClearState + @stage.Score + @GetRating(stage.Score) + @stage.MaxChain + @stage.LastPlayTime + + + + + + + + + \ No newline at end of file diff --git a/WebUI/Pages/PlayRecords.razor.cs b/WebUI/Pages/PlayRecords.razor.cs new file mode 100644 index 0000000..1949277 --- /dev/null +++ b/WebUI/Pages/PlayRecords.razor.cs @@ -0,0 +1,85 @@ +using Throw; +using WebUI.Pages.Dialogs; + +namespace WebUI.Pages; + +public partial class PlayRecords +{ + private readonly List breadcrumbs = new() + { + new BreadcrumbItem("Cards", href: "/Cards") + }; + + [Parameter] + public long CardId { get; set; } + + [Inject] + public required HttpClient Client { get; set; } + + [Inject] + public required IDialogService DialogService { get; set; } + + private string? errorMessage; + + private List? songPlayRecords; + + protected async override Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + breadcrumbs.Add(new BreadcrumbItem($"Card: {CardId}", href:null, disabled:true)); + breadcrumbs.Add(new BreadcrumbItem("TotalResult", href: $"/Cards/PlayRecords/{CardId}", disabled: false)); + + var result = await Client.GetFromJsonAsync>>($"api/Profiles/SongPlayRecords/{CardId}"); + result.ThrowIfNull(); + + if (!result.Succeeded) + { + errorMessage = result.Error!.Message; + return; + } + + songPlayRecords = result.Data; + } + + private static string GetRating(int score) => score switch + { + > 990000 => "S++", + > 950000 => "S+", + > 900000 => "S", + > 800000 => "A", + > 700000 => "B", + > 500000 => "C", + > 300000 => "D", + _ => "E" + }; + + private async Task OnFavoriteToggled(SongPlayRecord data) + { + var options = new DialogOptions + { + CloseOnEscapeKey = false, + DisableBackdropClick = true, + FullWidth = true + }; + + var parameters = new DialogParameters + { + { "Data", data }, + {"CardId", CardId} + }; + var dialog = await DialogService.ShowAsync("Favorite", parameters, options); + var result = await dialog.Result; + + if (result.Canceled) + { + return; + } + + if (result.Data is ServiceResult serviceResult && serviceResult.Data) + { + data.IsFavorite = !data.IsFavorite; + } + } + +} \ No newline at end of file diff --git a/WebUI/Pages/TotalResult.razor b/WebUI/Pages/TotalResult.razor index 92102e5..ce868c6 100644 --- a/WebUI/Pages/TotalResult.razor +++ b/WebUI/Pages/TotalResult.razor @@ -35,6 +35,7 @@ Player Name: @totalResultData.PlayerName Total Score: @totalResultData.PlayerData.TotalScore + Rank: @totalResultData.PlayerData.Rank Average Score: @totalResultData.PlayerData.AverageScore Played Song Count: @totalResultData.PlayerData.PlayedSongCount / @totalResultData.PlayerData.TotalSongCount Cleared Stage Count: @totalResultData.StageCountData.Cleared / @totalResultData.StageCountData.Total diff --git a/WebUI/Pages/TotalResult.razor.cs b/WebUI/Pages/TotalResult.razor.cs index 71ee5fc..4d20a0d 100644 --- a/WebUI/Pages/TotalResult.razor.cs +++ b/WebUI/Pages/TotalResult.razor.cs @@ -1,7 +1,4 @@ -using System.Net.Http.Json; -using Microsoft.AspNetCore.Components; -using Shared.Models; -using Throw; +using Throw; namespace WebUI.Pages; diff --git a/WebUI/Services/DataService.cs b/WebUI/Services/DataService.cs index 80ab2ec..a8a075b 100644 --- a/WebUI/Services/DataService.cs +++ b/WebUI/Services/DataService.cs @@ -1,7 +1,4 @@ -using System.Collections.ObjectModel; -using System.Net.Http.Json; -using System.Text.Json.Serialization; -using Throw; + using Throw; using WebUI.Common.Models; namespace WebUI.Services; @@ -29,17 +26,17 @@ public class DataService : IDataService public async Task InitializeAsync() { - var avatarList = await client.GetFromJsonAsync("data/Avatars.json", SourceGenerationContext.Default.ListAvatar); + var avatarList = await client.GetFromJsonAsync>("data/Avatars.json"); avatarList.ThrowIfNull(); avatars = avatarList.ToDictionary(avatar => avatar.AvatarId); sortedAvatarList = avatarList.OrderBy(avatar => avatar.AvatarId).ToList(); - var navigatorList = await client.GetFromJsonAsync("data/Navigators.json", SourceGenerationContext.Default.ListNavigator); + var navigatorList = await client.GetFromJsonAsync>("data/Navigators.json"); navigatorList.ThrowIfNull(); navigators = navigatorList.ToDictionary(navigator => navigator.Id); sortedNavigatorList = navigatorList.OrderBy(navigator => navigator.Id).ToList(); - var titleList = await client.GetFromJsonAsync("data/Titles.json", SourceGenerationContext.Default.ListTitle); + var titleList = await client.GetFromJsonAsync>("data/Titles.json"); titleList.ThrowIfNull(); titles = titleList.ToDictionary(title => title.Id); sortedTitleList = titleList.OrderBy(title => title.Id).ToList(); @@ -74,12 +71,4 @@ public class DataService : IDataService { return navigators.GetValueOrDefault(id); } -} - -[JsonSerializable(typeof(List))] -[JsonSerializable(typeof(List))] -[JsonSerializable(typeof(List))] -internal partial class SourceGenerationContext : JsonSerializerContext -{ - } \ No newline at end of file diff --git a/WebUI/_Imports.razor b/WebUI/_Imports.razor index 1199b20..3564498 100644 --- a/WebUI/_Imports.razor +++ b/WebUI/_Imports.razor @@ -1,5 +1,4 @@ @using System.Net.Http -@using System.Net.Http.Json @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @@ -8,4 +7,6 @@ @using Microsoft.JSInterop @using MudBlazor @using WebUI -@using WebUI.Common \ No newline at end of file +@using WebUI.Common +@using WebUI.Services +@using WebUI.Common.Models \ No newline at end of file