diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs index d3a3c6cf..cccc6a22 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/DailyNoteEntry.cs @@ -52,6 +52,8 @@ internal sealed class DailyNoteEntry : ObservableObject, IMappingFrom public DailyNote? DailyNote { get; set; } + // TODO: Add RefreshTime + /// /// 树脂提醒阈值 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs index ae47a60f..fdb248b6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbBulkOperation.cs @@ -217,7 +217,7 @@ internal sealed partial class AvatarInfoDbBulkOperation // This means that there are duplicate items. if (distinctCount < dbInfos.Count) { - avatarInfoDbService.DeleteAvatarInfoByUid(uid); + avatarInfoDbService.DeleteAvatarInfoRangeByUid(uid); dbInfos = new(); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbService.cs index c0337e81..029e21b9 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/AvatarInfoDbService.cs @@ -37,7 +37,7 @@ internal sealed partial class AvatarInfoDbService : IAvatarInfoDbService } } - public void DeleteAvatarInfoByUid(string uid) + public void DeleteAvatarInfoRangeByUid(string uid) { using (IServiceScope scope = serviceProvider.CreateScope()) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/IAvatarInfoDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/IAvatarInfoDbService.cs index 0b4d9508..3fa3f867 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/IAvatarInfoDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/IAvatarInfoDbService.cs @@ -8,7 +8,7 @@ namespace Snap.Hutao.Service.AvatarInfo; internal interface IAvatarInfoDbService { - void DeleteAvatarInfoByUid(string uid); + void DeleteAvatarInfoRangeByUid(string uid); List GetAvatarInfoInfoListByUid(string uid); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs index 8c68caaa..a0016390 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs @@ -93,4 +93,64 @@ internal sealed partial class CultivationDbService : ICultivationDbService appDbContext.CultivateItems.UpdateAndSave(item); } } + + public async ValueTask GetCultivateEntryByProjectIdAndItemIdAsync(Guid projectId, uint itemId) + { + using (IServiceScope scope = serviceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); + return await appDbContext.CultivateEntries + .SingleOrDefaultAsync(e => e.ProjectId == projectId && e.Id == itemId) + .ConfigureAwait(false); + } + } + + public async ValueTask InsertCultivateEntryAsync(CultivateEntry entry) + { + using (IServiceScope scope = serviceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); + await appDbContext.CultivateEntries.AddAndSaveAsync(entry).ConfigureAwait(false); + } + } + + public async ValueTask DeleteCultivateItemRangeByEntryIdAsync(Guid entryId) + { + using (IServiceScope scope = serviceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); + await appDbContext.CultivateItems + .ExecuteDeleteWhereAsync(i => i.EntryId == entryId) + .ConfigureAwait(false); + } + } + + public async ValueTask InsertCultivateItemRangeAsync(IEnumerable toAdd) + { + using (IServiceScope scope = serviceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); + await appDbContext.CultivateItems.AddRangeAndSaveAsync(toAdd).ConfigureAwait(false); + } + } + + public async ValueTask AddCultivateProjectAsync(CultivateProject project) + { + using (IServiceScope scope = serviceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); + await appDbContext.CultivateProjects.AddAndSaveAsync(project).ConfigureAwait(false); + } + } + + public async ValueTask DeleteCultivateProjectByIdAsync(Guid projectId) + { + using (IServiceScope scope = serviceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); + await appDbContext.CultivateProjects + .ExecuteDeleteWhereAsync(p => p.InnerId == projectId) + .ConfigureAwait(false); + } + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.Collection.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.Collection.cs index 6a1cdd00..a0ddb11e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.Collection.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.Collection.cs @@ -50,44 +50,36 @@ internal sealed partial class CultivationService return ProjectAddResult.InvalidName; } - if (projects!.SingleOrDefault(a => a.Name == project.Name) != null) + ArgumentNullException.ThrowIfNull(projects); + + if (projects.Any(a => a.Name == project.Name)) { return ProjectAddResult.AlreadyExists; } - else - { - // Sync cache - await taskContext.SwitchToMainThreadAsync(); - projects!.Add(project); - // Sync database - await taskContext.SwitchToBackgroundAsync(); - using (IServiceScope scope = serviceProvider.CreateScope()) - { - AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); - await appDbContext.CultivateProjects.AddAndSaveAsync(project).ConfigureAwait(false); - } + // Sync cache + await taskContext.SwitchToMainThreadAsync(); + projects.Add(project); - return ProjectAddResult.Added; - } + // Sync database + await taskContext.SwitchToBackgroundAsync(); + await cultivationDbService.AddCultivateProjectAsync(project).ConfigureAwait(false); + + return ProjectAddResult.Added; } /// public async Task RemoveProjectAsync(CultivateProject project) { + ArgumentNullException.ThrowIfNull(projects); + // Sync cache // Keep this on main thread. await taskContext.SwitchToMainThreadAsync(); - projects!.Remove(project); + projects.Remove(project); // Sync database await taskContext.SwitchToBackgroundAsync(); - using (IServiceScope scope = serviceProvider.CreateScope()) - { - AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); - await appDbContext.CultivateProjects - .ExecuteDeleteWhereAsync(p => p.InnerId == project.InnerId) - .ConfigureAwait(false); - } + await cultivationDbService.DeleteCultivateProjectByIdAsync(project.InnerId).ConfigureAwait(false); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index 380ca61c..78ec27cf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -167,42 +167,28 @@ internal sealed partial class CultivationService : ICultivationService } await taskContext.SwitchToBackgroundAsync(); - using (IServiceScope scope = serviceProvider.CreateScope()) + + if (Current is null) { - AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); - - try - { - Current ??= appDbContext.CultivateProjects.SelectedOrDefault(); - } - catch (InvalidOperationException ex) - { - ThrowHelper.UserdataCorrupted(SH.ServiceCultivationProjectCurrentUserdataCourrpted2, ex); - } - - if (Current == null) - { - return false; - } - - Guid projectId = Current!.InnerId; - CultivateEntry? entry = await appDbContext.CultivateEntries - .SingleOrDefaultAsync(e => e.ProjectId == projectId && e.Id == itemId) - .ConfigureAwait(false); - - if (entry == null) - { - entry = CultivateEntry.From(projectId, type, itemId); - await appDbContext.CultivateEntries.AddAndSaveAsync(entry).ConfigureAwait(false); - } - - Guid entryId = entry.InnerId; - await appDbContext.CultivateItems.ExecuteDeleteWhereAsync(i => i.EntryId == entryId).ConfigureAwait(false); - - IEnumerable toAdd = items.Select(item => CultivateItem.From(entryId, item)); - await appDbContext.CultivateItems.AddRangeAndSaveAsync(toAdd).ConfigureAwait(false); + return false; } + CultivateEntry? entry = await cultivationDbService + .GetCultivateEntryByProjectIdAndItemIdAsync(Current.InnerId, itemId) + .ConfigureAwait(false); + + if (entry == null) + { + entry = CultivateEntry.From(Current.InnerId, type, itemId); + await cultivationDbService.InsertCultivateEntryAsync(entry).ConfigureAwait(false); + } + + Guid entryId = entry.InnerId; + await cultivationDbService.DeleteCultivateItemRangeByEntryIdAsync(entryId).ConfigureAwait(false); + + IEnumerable toAdd = items.Select(item => CultivateItem.From(entryId, item)); + await cultivationDbService.InsertCultivateItemRangeAsync(toAdd).ConfigureAwait(false); + return true; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs index a527463f..8717142c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs @@ -7,8 +7,14 @@ namespace Snap.Hutao.Service.Cultivation; internal interface ICultivationDbService { + ValueTask AddCultivateProjectAsync(CultivateProject project); + ValueTask DeleteCultivateEntryByIdAsync(Guid entryId); + ValueTask DeleteCultivateItemRangeByEntryIdAsync(Guid entryId); + ValueTask DeleteCultivateProjectByIdAsync(Guid projectId); + ValueTask GetCultivateEntryByProjectIdAndItemIdAsync(Guid projectId, uint itemId); + ValueTask> GetCultivateEntryListByProjectIdAsync(Guid projectId); ValueTask> GetCultivateItemListByEntryIdAsync(Guid entryId); @@ -17,6 +23,10 @@ internal interface ICultivationDbService ValueTask> GetInventoryItemListByProjectIdAsync(Guid projectId); + ValueTask InsertCultivateEntryAsync(CultivateEntry entry); + + ValueTask InsertCultivateItemRangeAsync(IEnumerable toAdd); + void UpdateCultivateItem(CultivateItem item); void UpdateInventoryItem(InventoryItem item);