From 486c6eb30831988b676a804b968913aabccce095 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Tue, 16 Apr 2024 10:13:35 +0800 Subject: [PATCH] achievement service --- src/Snap.Hutao/Snap.Hutao/App.xaml.cs | 2 - .../Control/Layout/UniformStaggeredLayout.cs | 1 - .../Snap.Hutao/Control/Panel/UniformPanel.cs | 2 - .../Core/Database/DbSetExtension.cs | 76 +++---------------- .../Core/ExceptionService/HutaoException.cs | 6 ++ .../ExceptionService/HutaoExceptionKind.cs | 1 + .../Resource/Localization/SH.en.resx | 34 ++++----- .../Resource/Localization/SH.id.resx | 34 ++++----- .../Resource/Localization/SH.ja.resx | 34 ++++----- .../Resource/Localization/SH.ko.resx | 34 ++++----- .../Resource/Localization/SH.pt.resx | 34 ++++----- .../Snap.Hutao/Resource/Localization/SH.resx | 2 +- .../Resource/Localization/SH.ru.resx | 34 ++++----- .../Resource/Localization/SH.zh-Hant.resx | 34 ++++----- .../AppDbServiceAppDbEntityExtension.cs | 4 +- .../Abstraction/AppDbServiceExtension.cs | 52 ++++++++++--- .../Achievement/AchievementDbService.cs | 44 +++++------ .../Achievement/IAchievementDbService.cs | 12 +-- .../Announcement/AnnouncementService.cs | 11 +-- .../Service/Hutao/IHutaoAsAService.cs | 3 +- .../Snap.Hutao/View/Card/AchievementCard.xaml | 6 +- 21 files changed, 221 insertions(+), 239 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs index d7f33573..c1d79aa1 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs @@ -10,8 +10,6 @@ using Snap.Hutao.Core.LifeCycle.InterProcess; using Snap.Hutao.Core.Logging; using Snap.Hutao.Core.Shell; using System.Diagnostics; -using System.Text; -using static Snap.Hutao.Core.Logging.ConsoleVirtualTerminalSequences; namespace Snap.Hutao; diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Layout/UniformStaggeredLayout.cs b/src/Snap.Hutao/Snap.Hutao/Control/Layout/UniformStaggeredLayout.cs index 1258fc42..6817858d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Layout/UniformStaggeredLayout.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Layout/UniformStaggeredLayout.cs @@ -4,7 +4,6 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using System.Collections.Specialized; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Windows.Foundation; diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Panel/UniformPanel.cs b/src/Snap.Hutao/Snap.Hutao/Control/Panel/UniformPanel.cs index d41b8881..8adea268 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Panel/UniformPanel.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Panel/UniformPanel.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; using Windows.Foundation; namespace Snap.Hutao.Control.Panel; diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Database/DbSetExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/Database/DbSetExtension.cs index 10787b35..2d5a2da6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Database/DbSetExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Database/DbSetExtension.cs @@ -13,13 +13,6 @@ namespace Snap.Hutao.Core.Database; [HighQuality] internal static class DbSetExtension { - /// - /// 添加并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 public static int AddAndSave(this DbSet dbSet, TEntity entity) where TEntity : class { @@ -27,27 +20,13 @@ internal static class DbSetExtension return dbSet.SaveChangesAndClearChangeTracker(); } - /// - /// 异步添加并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 - public static ValueTask AddAndSaveAsync(this DbSet dbSet, TEntity entity) + public static ValueTask AddAndSaveAsync(this DbSet dbSet, TEntity entity, CancellationToken token = default) where TEntity : class { dbSet.Add(entity); - return dbSet.SaveChangesAndClearChangeTrackerAsync(); + return dbSet.SaveChangesAndClearChangeTrackerAsync(token); } - /// - /// 添加列表并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 public static int AddRangeAndSave(this DbSet dbSet, IEnumerable entities) where TEntity : class { @@ -55,27 +34,13 @@ internal static class DbSetExtension return dbSet.SaveChangesAndClearChangeTracker(); } - /// - /// 异步添加列表并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 - public static ValueTask AddRangeAndSaveAsync(this DbSet dbSet, IEnumerable entities) + public static ValueTask AddRangeAndSaveAsync(this DbSet dbSet, IEnumerable entities, CancellationToken token = default) where TEntity : class { dbSet.AddRange(entities); - return dbSet.SaveChangesAndClearChangeTrackerAsync(); + return dbSet.SaveChangesAndClearChangeTrackerAsync(token); } - /// - /// 移除并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 public static int RemoveAndSave(this DbSet dbSet, TEntity entity) where TEntity : class { @@ -83,27 +48,13 @@ internal static class DbSetExtension return dbSet.SaveChangesAndClearChangeTracker(); } - /// - /// 异步移除并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 - public static ValueTask RemoveAndSaveAsync(this DbSet dbSet, TEntity entity) + public static ValueTask RemoveAndSaveAsync(this DbSet dbSet, TEntity entity, CancellationToken token = default) where TEntity : class { dbSet.Remove(entity); - return dbSet.SaveChangesAndClearChangeTrackerAsync(); + return dbSet.SaveChangesAndClearChangeTrackerAsync(token); } - /// - /// 更新并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 public static int UpdateAndSave(this DbSet dbSet, TEntity entity) where TEntity : class { @@ -111,18 +62,11 @@ internal static class DbSetExtension return dbSet.SaveChangesAndClearChangeTracker(); } - /// - /// 异步更新并保存 - /// - /// 实体类型 - /// 数据库集 - /// 实体 - /// 影响条数 - public static ValueTask UpdateAndSaveAsync(this DbSet dbSet, TEntity entity) + public static ValueTask UpdateAndSaveAsync(this DbSet dbSet, TEntity entity, CancellationToken token = default) where TEntity : class { dbSet.Update(entity); - return dbSet.SaveChangesAndClearChangeTrackerAsync(); + return dbSet.SaveChangesAndClearChangeTrackerAsync(token); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -136,11 +80,11 @@ internal static class DbSetExtension } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static async ValueTask SaveChangesAndClearChangeTrackerAsync(this DbSet dbSet) + private static async ValueTask SaveChangesAndClearChangeTrackerAsync(this DbSet dbSet, CancellationToken token = default) where TEntity : class { DbContext dbContext = dbSet.Context(); - int count = await dbContext.SaveChangesAsync().ConfigureAwait(false); + int count = await dbContext.SaveChangesAsync(token).ConfigureAwait(false); dbContext.ChangeTracker.Clear(); return count; } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs index b204de5f..460e5b3c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoException.cs @@ -47,6 +47,12 @@ internal sealed class HutaoException : Exception throw new HutaoException(HutaoExceptionKind.GachaStatisticsInvalidItemId, message, innerException); } + [DoesNotReturn] + public static HutaoException UserdataCorrupted(string message, Exception? innerException = default) + { + throw new HutaoException(HutaoExceptionKind.UserdataCorrupted, message, innerException); + } + [DoesNotReturn] public static InvalidCastException InvalidCast(string name, Exception? innerException = default) { diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs index c7e3c6d4..2ea398e6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/HutaoExceptionKind.cs @@ -10,6 +10,7 @@ internal enum HutaoExceptionKind // Foundation ImageCacheInvalidUri, DatabaseCorrupted, + UserdataCorrupted, // IO FileSystemCreateFileInsufficientPermissions, diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.en.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.en.resx index 2179dd45..1f7ec92f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.en.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.en.resx @@ -60,45 +60,45 @@ : and then encoded with base64 encoding. --> - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -653,7 +653,7 @@ Open UIAF Json File - + Multiple identical achievement IDs found in a single achievement archive diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.id.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.id.resx index c6b5b748..e80e0912 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.id.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.id.resx @@ -60,45 +60,45 @@ : and then encoded with base64 encoding. --> - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -653,7 +653,7 @@ Buka berkas UIAF Json - + Terdapat beberapa ID pencapaian yang identik dalam satu arsip pencapaian diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ja.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ja.resx index 0402200b..75a9737e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ja.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ja.resx @@ -60,45 +60,45 @@ : and then encoded with base64 encoding. --> - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -653,7 +653,7 @@ UIAF Json ファイルを開く - + 複数の同一アチーブメント Idがアーカイブに混在しています diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ko.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ko.resx index d71ac43b..a902c876 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ko.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ko.resx @@ -60,45 +60,45 @@ : and then encoded with base64 encoding. --> - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -653,7 +653,7 @@ 打开 UIAF Json 文件 - + 한 업적 아카이브에서 Id 동일한 업적 발견됨 diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.pt.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.pt.resx index 89a6ee8e..8ea53d63 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.pt.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.pt.resx @@ -60,45 +60,45 @@ : and then encoded with base64 encoding. --> - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -653,7 +653,7 @@ Abrir arquivo Json UIAF - + Várias IDs de conquistas idênticas encontradas em um único arquivo de conquistas diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx index 794e650c..34f52421 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx @@ -653,7 +653,7 @@ 打开 UIAF Json 文件 - + 单个成就存档内发现多个相同的成就 Id diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ru.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ru.resx index 57b4679d..a28ab4ff 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ru.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.ru.resx @@ -60,45 +60,45 @@ : and then encoded with base64 encoding. --> - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -653,7 +653,7 @@ Открыть UIAF Json файл - + В одном архиве достижений обнаружено несколько одинаковых идентификаторов достижений diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.zh-Hant.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.zh-Hant.resx index 48f1949c..b4a9a3fb 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.zh-Hant.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.zh-Hant.resx @@ -60,45 +60,45 @@ : and then encoded with base64 encoding. --> - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -653,7 +653,7 @@ 打開 UIAF Json 文件 - + 單個成就存檔內發現多個相同的成就 Id diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceAppDbEntityExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceAppDbEntityExtension.cs index c412fc0b..2dfb7a1a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceAppDbEntityExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceAppDbEntityExtension.cs @@ -14,9 +14,9 @@ internal static class AppDbServiceAppDbEntityExtension return service.Execute(dbset => dbset.ExecuteDeleteWhere(e => e.InnerId == entity.InnerId)); } - public static ValueTask DeleteByInnerIdAsync(this IAppDbService service, TEntity entity) + public static ValueTask DeleteByInnerIdAsync(this IAppDbService service, TEntity entity, CancellationToken token = default) where TEntity : class, IAppDbEntity { - return service.ExecuteAsync(dbset => dbset.ExecuteDeleteWhereAsync(e => e.InnerId == entity.InnerId)); + return service.ExecuteAsync((dbset, token) => dbset.ExecuteDeleteWhereAsync(e => e.InnerId == entity.InnerId, token), token); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceExtension.cs b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceExtension.cs index 6eef72e4..fdf0d8a1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/AppDbServiceExtension.cs @@ -30,6 +30,16 @@ internal static class AppDbServiceExtension } } + public static async ValueTask ExecuteAsync(this IAppDbService service, Func, CancellationToken, ValueTask> asyncFunc, CancellationToken token) + where TEntity : class + { + using (IServiceScope scope = service.ServiceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.GetAppDbContext(); + return await asyncFunc(appDbContext.Set(), token).ConfigureAwait(false); + } + } + public static async ValueTask ExecuteAsync(this IAppDbService service, Func, Task> asyncFunc) where TEntity : class { @@ -40,16 +50,26 @@ internal static class AppDbServiceExtension } } + public static async ValueTask ExecuteAsync(this IAppDbService service, Func, CancellationToken, Task> asyncFunc, CancellationToken token) + where TEntity : class + { + using (IServiceScope scope = service.ServiceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.GetAppDbContext(); + return await asyncFunc(appDbContext.Set(), token).ConfigureAwait(false); + } + } + public static int Add(this IAppDbService service, TEntity entity) where TEntity : class { return service.Execute(dbset => dbset.AddAndSave(entity)); } - public static ValueTask AddAsync(this IAppDbService service, TEntity entity) + public static ValueTask AddAsync(this IAppDbService service, TEntity entity, CancellationToken token = default) where TEntity : class { - return service.ExecuteAsync(dbset => dbset.AddAndSaveAsync(entity)); + return service.ExecuteAsync((dbset, token) => dbset.AddAndSaveAsync(entity, token), token); } public static int AddRange(this IAppDbService service, IEnumerable entities) @@ -58,10 +78,10 @@ internal static class AppDbServiceExtension return service.Execute(dbset => dbset.AddRangeAndSave(entities)); } - public static ValueTask AddRangeAsync(this IAppDbService service, IEnumerable entities) + public static ValueTask AddRangeAsync(this IAppDbService service, IEnumerable entities, CancellationToken token = default) where TEntity : class { - return service.ExecuteAsync(dbset => dbset.AddRangeAndSaveAsync(entities)); + return service.ExecuteAsync((dbset, token) => dbset.AddRangeAndSaveAsync(entities, token), token); } public static TEntity Single(this IAppDbService service, Expression> predicate) @@ -70,10 +90,10 @@ internal static class AppDbServiceExtension return service.Execute(dbset => dbset.AsNoTracking().Single(predicate)); } - public static ValueTask SingleAsync(this IAppDbService service, Expression> predicate) + public static ValueTask SingleAsync(this IAppDbService service, Expression> predicate, CancellationToken token = default) where TEntity : class { - return service.ExecuteAsync(dbset => dbset.AsNoTracking().SingleAsync(predicate, default)); + return service.ExecuteAsync((dbset, token) => dbset.AsNoTracking().SingleAsync(predicate, token), token); } public static TResult Query(this IAppDbService service, Func, TResult> func) @@ -88,22 +108,34 @@ internal static class AppDbServiceExtension return service.ExecuteAsync(dbset => func(dbset.AsNoTracking())); } + public static ValueTask QueryAsync(this IAppDbService service, Func, CancellationToken, ValueTask> func, CancellationToken token = default) + where TEntity : class + { + return service.ExecuteAsync((dbset, token) => func(dbset.AsNoTracking(), token), token); + } + public static ValueTask QueryAsync(this IAppDbService service, Func, Task> func) where TEntity : class { return service.ExecuteAsync(dbset => func(dbset.AsNoTracking())); } + public static ValueTask QueryAsync(this IAppDbService service, Func, CancellationToken, Task> func, CancellationToken token = default) + where TEntity : class + { + return service.ExecuteAsync((dbset, token) => func(dbset.AsNoTracking(), token), token); + } + public static int Update(this IAppDbService service, TEntity entity) where TEntity : class { return service.Execute(dbset => dbset.UpdateAndSave(entity)); } - public static ValueTask UpdateAsync(this IAppDbService service, TEntity entity) + public static ValueTask UpdateAsync(this IAppDbService service, TEntity entity, CancellationToken token = default) where TEntity : class { - return service.ExecuteAsync(dbset => dbset.UpdateAndSaveAsync(entity)); + return service.ExecuteAsync((dbset, token) => dbset.UpdateAndSaveAsync(entity, token), token); } public static int Delete(this IAppDbService service, TEntity entity) @@ -112,9 +144,9 @@ internal static class AppDbServiceExtension return service.Execute(dbset => dbset.RemoveAndSave(entity)); } - public static ValueTask DeleteAsync(this IAppDbService service, TEntity entity) + public static ValueTask DeleteAsync(this IAppDbService service, TEntity entity, CancellationToken token = default) where TEntity : class { - return service.ExecuteAsync(dbset => dbset.RemoveAndSaveAsync(entity)); + return service.ExecuteAsync((dbset, token) => dbset.RemoveAndSaveAsync(entity, token), token); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs index bdfab117..1bed7625 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/AchievementDbService.cs @@ -2,13 +2,10 @@ // Licensed under the MIT license. using Microsoft.EntityFrameworkCore; -using Snap.Hutao.Core.Database; using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Model.Entity; -using Snap.Hutao.Model.Entity.Database; using Snap.Hutao.Model.Primitive; using Snap.Hutao.Service.Abstraction; -using Snap.Hutao.Web.Request.Builder; using System.Collections.ObjectModel; using EntityAchievement = Snap.Hutao.Model.Entity.Achievement; @@ -35,29 +32,31 @@ internal sealed partial class AchievementDbService : IAchievementDbService } catch (ArgumentException ex) { - throw HutaoException.Throw(HutaoExceptionKind.DatabaseCorrupted, SH.ServiceAchievementUserdataCorruptedInnerIdNotUnique, ex); + throw HutaoException.UserdataCorrupted(SH.ServiceAchievementUserdataCorruptedAchievementIdNotUnique, ex); } } - public async ValueTask GetFinishedAchievementCountByArchiveIdAsync(Guid archiveId) + public ValueTask GetFinishedAchievementCountByArchiveIdAsync(Guid archiveId, CancellationToken token = default) { - return await this.QueryAsync(query => query + return this.QueryAsync( + (query, token) => query .Where(a => a.ArchiveId == archiveId) .Where(a => a.Status >= Model.Intrinsic.AchievementStatus.STATUS_FINISHED) - .CountAsync()) - .ConfigureAwait(false); + .CountAsync(token), + token); } [SuppressMessage("", "CA1305")] - public async ValueTask> GetLatestFinishedAchievementListByArchiveIdAsync(Guid archiveId, int take) + public ValueTask> GetLatestFinishedAchievementListByArchiveIdAsync(Guid archiveId, int take, CancellationToken token = default) { - return await this.QueryAsync>(query => query + return this.QueryAsync>( + (query, token) => query .Where(a => a.ArchiveId == archiveId) .Where(a => a.Status >= Model.Intrinsic.AchievementStatus.STATUS_FINISHED) .OrderByDescending(a => a.Time.ToString()) .Take(take) - .ToListAsync()) - .ConfigureAwait(false); + .ToListAsync(token), + token); } public void OverwriteAchievement(EntityAchievement achievement) @@ -69,12 +68,12 @@ internal sealed partial class AchievementDbService : IAchievementDbService } } - public async ValueTask OverwriteAchievementAsync(EntityAchievement achievement) + public async ValueTask OverwriteAchievementAsync(EntityAchievement achievement, CancellationToken token = default) { - await this.DeleteByInnerIdAsync(achievement).ConfigureAwait(false); + await this.DeleteByInnerIdAsync(achievement, token).ConfigureAwait(false); if (achievement.Status >= Model.Intrinsic.AchievementStatus.STATUS_FINISHED) { - await this.AddAsync(achievement).ConfigureAwait(false); + await this.AddAsync(achievement, token).ConfigureAwait(false); } } @@ -83,10 +82,10 @@ internal sealed partial class AchievementDbService : IAchievementDbService return this.Query>(query => query.ToObservableCollection()); } - public async ValueTask RemoveAchievementArchiveAsync(AchievementArchive archive) + public async ValueTask RemoveAchievementArchiveAsync(AchievementArchive archive, CancellationToken token = default) { // It will cascade deleted the achievements. - await this.DeleteAsync(archive).ConfigureAwait(false); + await this.DeleteAsync(archive, token).ConfigureAwait(false); } public List GetAchievementListByArchiveId(Guid archiveId) @@ -94,12 +93,13 @@ internal sealed partial class AchievementDbService : IAchievementDbService return this.Query>(query => [.. query.Where(a => a.ArchiveId == archiveId)]); } - public async ValueTask> GetAchievementListByArchiveIdAsync(Guid archiveId) + public ValueTask> GetAchievementListByArchiveIdAsync(Guid archiveId, CancellationToken token = default) { - return await this.QueryAsync>(query => query + return this.QueryAsync>( + (query, token) => query .Where(a => a.ArchiveId == archiveId) - .ToListAsync()) - .ConfigureAwait(false); + .ToListAsync(token), + token); } public List GetAchievementArchiveList() @@ -107,7 +107,7 @@ internal sealed partial class AchievementDbService : IAchievementDbService return this.Query>(query => [.. query]); } - public async ValueTask> GetAchievementArchiveListAsync() + public async ValueTask> GetAchievementArchiveListAsync(CancellationToken token = default) { return await this.QueryAsync>(query => query.ToListAsync()).ConfigureAwait(false); } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs index 6e33e94a..45755d9d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Achievement/IAchievementDbService.cs @@ -10,25 +10,25 @@ namespace Snap.Hutao.Service.Achievement; internal interface IAchievementDbService : IAppDbService, IAppDbService { - ValueTask RemoveAchievementArchiveAsync(Model.Entity.AchievementArchive archive); + ValueTask RemoveAchievementArchiveAsync(Model.Entity.AchievementArchive archive, CancellationToken token = default); ObservableCollection GetAchievementArchiveCollection(); List GetAchievementArchiveList(); - ValueTask> GetAchievementArchiveListAsync(); + ValueTask> GetAchievementArchiveListAsync(CancellationToken token = default); List GetAchievementListByArchiveId(Guid archiveId); - ValueTask> GetAchievementListByArchiveIdAsync(Guid archiveId); + ValueTask> GetAchievementListByArchiveIdAsync(Guid archiveId, CancellationToken token = default); Dictionary GetAchievementMapByArchiveId(Guid archiveId); - ValueTask GetFinishedAchievementCountByArchiveIdAsync(Guid archiveId); + ValueTask GetFinishedAchievementCountByArchiveIdAsync(Guid archiveId, CancellationToken token = default); - ValueTask> GetLatestFinishedAchievementListByArchiveIdAsync(Guid archiveId, int take); + ValueTask> GetLatestFinishedAchievementListByArchiveIdAsync(Guid archiveId, int take, CancellationToken token = default); void OverwriteAchievement(EntityAchievement achievement); - ValueTask OverwriteAchievementAsync(EntityAchievement achievement); + ValueTask OverwriteAchievementAsync(EntityAchievement achievement, CancellationToken token = default); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Announcement/AnnouncementService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Announcement/AnnouncementService.cs index dab0fa50..cfcc4cd3 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Announcement/AnnouncementService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Announcement/AnnouncementService.cs @@ -10,6 +10,7 @@ using Snap.Hutao.Web.Response; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; +using WebAnnouncement = Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement.Announcement; namespace Snap.Hutao.Service; @@ -72,7 +73,7 @@ internal sealed partial class AnnouncementService : IAnnouncementService // 将公告内容联入公告列表 foreach (ref readonly AnnouncementListWrapper listWrapper in CollectionsMarshal.AsSpan(announcementListWrappers)) { - foreach (ref readonly Announcement item in CollectionsMarshal.AsSpan(listWrapper.List)) + foreach (ref readonly WebAnnouncement item in CollectionsMarshal.AsSpan(listWrapper.List)) { contentMap.TryGetValue(item.AnnId, out string? rawContent); item.Content = rawContent ?? string.Empty; @@ -83,7 +84,7 @@ internal sealed partial class AnnouncementService : IAnnouncementService foreach (ref readonly AnnouncementListWrapper listWrapper in CollectionsMarshal.AsSpan(announcementListWrappers)) { - foreach (ref readonly Announcement item in CollectionsMarshal.AsSpan(listWrapper.List)) + foreach (ref readonly WebAnnouncement item in CollectionsMarshal.AsSpan(listWrapper.List)) { item.Subtitle = new StringBuilder(item.Subtitle) .Replace("\r
", string.Empty) @@ -99,12 +100,12 @@ internal sealed partial class AnnouncementService : IAnnouncementService private static void AdjustAnnouncementTime(List announcementListWrappers, in TimeSpan offset) { // 活动公告 - List activities = announcementListWrappers + List activities = announcementListWrappers .Single(wrapper => wrapper.TypeId == 1) .List; // 更新公告 - Announcement versionUpdate = announcementListWrappers + WebAnnouncement versionUpdate = announcementListWrappers .Single(wrapper => wrapper.TypeId == 2) .List .Single(ann => AnnouncementRegex.VersionUpdateTitleRegex.IsMatch(ann.Title)); @@ -116,7 +117,7 @@ internal sealed partial class AnnouncementService : IAnnouncementService DateTimeOffset versionUpdateTime = UnsafeDateTimeOffset.ParseDateTime(versionMatch.Groups[1].ValueSpan, offset); - foreach (ref readonly Announcement announcement in CollectionsMarshal.AsSpan(activities)) + foreach (ref readonly WebAnnouncement announcement in CollectionsMarshal.AsSpan(activities)) { if (AnnouncementRegex.PermanentActivityAfterUpdateTimeRegex.Match(announcement.Content) is { Success: true } permanent) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHutaoAsAService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHutaoAsAService.cs index cde526e1..5a18da78 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHutaoAsAService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Hutao/IHutaoAsAService.cs @@ -1,12 +1,11 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. -using Snap.Hutao.Web.Hutao.HutaoAsAService; using System.Collections.ObjectModel; namespace Snap.Hutao.Service.Hutao; internal interface IHutaoAsAService { - ValueTask> GetHutaoAnnouncementCollectionAsync(CancellationToken token = default); + ValueTask> GetHutaoAnnouncementCollectionAsync(CancellationToken token = default); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml b/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml index 1f624454..2a696ffa 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Card/AchievementCard.xaml @@ -52,9 +52,13 @@ Grid.Row="0" HorizontalAlignment="Right" Text="{Binding DisplayName}"/> - +