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}"/>
-
+