diff --git a/src/Snap.Hutao/Snap.Hutao/Extension/StringBuilderExtension.cs b/src/Snap.Hutao/Snap.Hutao/Extension/StringBuilderExtension.cs index 515666c7..f71001ec 100644 --- a/src/Snap.Hutao/Snap.Hutao/Extension/StringBuilderExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Extension/StringBuilderExtension.cs @@ -38,9 +38,23 @@ internal static class StringBuilderExtension return condition ? sb.Append(value) : sb; } + public static string ToStringTrimEnd(this StringBuilder builder) + { + if (builder.Length > 1 && char.IsWhiteSpace(builder[^1])) + { + return builder.ToString(0, builder.Length - 1); + } + + return builder.ToString(); + } + public static string ToStringTrimEndReturn(this StringBuilder builder) { - Must.Argument(builder.Length >= 1, "StringBuilder 的长度必须大于 0"); + if (builder.Length < 1) + { + return string.Empty; + } + int remove = 0; if (builder[^1] is '\n') { diff --git a/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs b/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs index 9129b6e7..81c6a057 100644 --- a/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs +++ b/src/Snap.Hutao/Snap.Hutao/Migrations/AppDbContextModelSnapshot.cs @@ -42,7 +42,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("ArchiveId"); - b.ToTable("achievements"); + b.ToTable("achievements", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b => @@ -60,7 +60,7 @@ namespace Snap.Hutao.Migrations b.HasKey("InnerId"); - b.ToTable("achievement_archives"); + b.ToTable("achievement_archives", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b => @@ -88,7 +88,7 @@ namespace Snap.Hutao.Migrations b.HasKey("InnerId"); - b.ToTable("avatar_infos"); + b.ToTable("avatar_infos", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b => @@ -110,7 +110,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("ProjectId"); - b.ToTable("cultivate_entries"); + b.ToTable("cultivate_entries", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntryLevelInformation", b => @@ -156,7 +156,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("EntryId"); - b.ToTable("cultivate_entry_level_informations"); + b.ToTable("cultivate_entry_level_informations", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b => @@ -181,7 +181,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("EntryId"); - b.ToTable("cultivate_items"); + b.ToTable("cultivate_items", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b => @@ -202,7 +202,7 @@ namespace Snap.Hutao.Migrations b.HasKey("InnerId"); - b.ToTable("cultivate_projects"); + b.ToTable("cultivate_projects", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b => @@ -258,7 +258,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("UserId"); - b.ToTable("daily_notes"); + b.ToTable("daily_notes", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b => @@ -276,7 +276,7 @@ namespace Snap.Hutao.Migrations b.HasKey("InnerId"); - b.ToTable("gacha_archives"); + b.ToTable("gacha_archives", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b => @@ -307,7 +307,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("ArchiveId"); - b.ToTable("gacha_items"); + b.ToTable("gacha_items", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b => @@ -332,7 +332,7 @@ namespace Snap.Hutao.Migrations b.HasKey("InnerId"); - b.ToTable("game_accounts"); + b.ToTable("game_accounts", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b => @@ -354,7 +354,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("ProjectId"); - b.ToTable("inventory_items"); + b.ToTable("inventory_items", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b => @@ -383,7 +383,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("ProjectId"); - b.ToTable("inventory_reliquaries"); + b.ToTable("inventory_reliquaries", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b => @@ -408,7 +408,7 @@ namespace Snap.Hutao.Migrations b.HasIndex("ProjectId"); - b.ToTable("inventory_weapons"); + b.ToTable("inventory_weapons", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b => @@ -424,7 +424,7 @@ namespace Snap.Hutao.Migrations b.HasKey("Key"); - b.ToTable("object_cache"); + b.ToTable("object_cache", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b => @@ -437,7 +437,7 @@ namespace Snap.Hutao.Migrations b.HasKey("Key"); - b.ToTable("settings"); + b.ToTable("settings", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.SpiralAbyssEntry", b => @@ -459,7 +459,7 @@ namespace Snap.Hutao.Migrations b.HasKey("InnerId"); - b.ToTable("spiral_abysses"); + b.ToTable("spiral_abysses", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b => @@ -502,7 +502,7 @@ namespace Snap.Hutao.Migrations b.HasKey("InnerId"); - b.ToTable("users"); + b.ToTable("users", (string)null); }); modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b => diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs index cd892254..348ffdd4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/CultivateEntry.cs @@ -33,6 +33,8 @@ internal sealed class CultivateEntry : IDbMappingForeignKeyFrom /// 养成类型 /// @@ -59,4 +61,10 @@ internal sealed class CultivateEntry : IDbMappingForeignKeyFrom +internal sealed class CultivateEntryLevelInformation : IMappingFrom { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -40,21 +41,29 @@ internal sealed class CultivateEntryLevelInformation : IMappingFrom new() + { + EntryId = entryId, + AvatarLevelFrom = source.AvatarLevelFrom, + AvatarLevelTo = source.AvatarLevelTo, + SkillALevelFrom = source.SkillALevelFrom, + SkillALevelTo = source.SkillALevelTo, + SkillELevelFrom = source.SkillELevelFrom, + SkillELevelTo = source.SkillELevelTo, + SkillQLevelFrom = source.SkillQLevelFrom, + SkillQLevelTo = source.SkillQLevelTo, + }, + CultivateType.Weapon => new() + { + EntryId = entryId, + WeaponLevelFrom = source.WeaponLevelFrom, + WeaponLevelTo = source.WeaponLevelTo, + }, + _ => throw Must.NeverHappen($"不支持的养成类型{type}"), }; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx index 8977675b..d97bc0c7 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx @@ -1406,6 +1406,9 @@ 请先前往养成计划页面创建计划并选中 + + 重新添加物品以查看养成描述 + 添加成功 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs index 77e4516d..8e9f18a5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationDbService.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Internal; using Snap.Hutao.Core.Database; using Snap.Hutao.Model.Entity; using Snap.Hutao.Model.Entity.Database; @@ -51,6 +52,20 @@ internal sealed partial class CultivationDbService : ICultivationDbService } } + public async ValueTask> GetCultivateEntryIncludeLevelInformationListByProjectIdAsync(Guid projectId) + { + using (IServiceScope scope = serviceProvider.CreateScope()) + { + AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); + return await appDbContext.CultivateEntries + .AsNoTracking() + .Where(e => e.ProjectId == projectId) + .Include(e => e.LevelInformation) + .ToListAsync() + .ConfigureAwait(false); + } + } + public async ValueTask> GetCultivateItemListByEntryIdAsync(Guid entryId) { using (IServiceScope scope = serviceProvider.CreateScope()) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index 5f429153..7491b43d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -54,19 +54,19 @@ internal sealed partial class CultivationService : ICultivationService { await taskContext.SwitchToBackgroundAsync(); List entries = await cultivationDbService - .GetCultivateEntryListByProjectIdAsync(cultivateProject.InnerId) + .GetCultivateEntryIncludeLevelInformationListByProjectIdAsync(cultivateProject.InnerId) .ConfigureAwait(false); List resultEntries = new(entries.Count); foreach (CultivateEntry entry in entries) { List entryItems = []; - foreach (CultivateItem item in await cultivationDbService.GetCultivateItemListByEntryIdAsync(entry.InnerId).ConfigureAwait(false)) + foreach (CultivateItem cultivateItem in await cultivationDbService.GetCultivateItemListByEntryIdAsync(entry.InnerId).ConfigureAwait(false)) { - entryItems.Add(new(item, context.GetMaterial(item.ItemId))); + entryItems.Add(new(cultivateItem, context.GetMaterial(cultivateItem.ItemId))); } - Item itemBase = entry.Type switch + Item item = entry.Type switch { CultivateType.AvatarAndSkill => context.GetAvatar(entry.Id).ToItem(), CultivateType.Weapon => context.GetWeapon(entry.Id).ToItem(), @@ -75,7 +75,7 @@ internal sealed partial class CultivationService : ICultivationService _ => default!, }; - resultEntries.Add(new(entry, itemBase, entryItems)); + resultEntries.Add(new(entry, item, entryItems)); } return resultEntries @@ -184,7 +184,7 @@ internal sealed partial class CultivationService : ICultivationService Guid entryId = entry.InnerId; await cultivationDbService.RemoveLevelInformationByEntryIdAsync(entryId).ConfigureAwait(false); - CultivateEntryLevelInformation entryLevelInformation = CultivateEntryLevelInformation.From(entryId, levelInformation); + CultivateEntryLevelInformation entryLevelInformation = CultivateEntryLevelInformation.From(entryId, type, levelInformation); await cultivationDbService.AddLevelInformationAsync(entryLevelInformation).ConfigureAwait(false); await cultivationDbService.RemoveCultivateItemRangeByEntryIdAsync(entryId).ConfigureAwait(false); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs index 5c1fca8c..45c90413 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationDbService.cs @@ -35,6 +35,10 @@ internal interface ICultivationDbService void UpdateCultivateItem(CultivateItem item); ValueTask UpdateCultivateItemAsync(CultivateItem item); + ValueTask RemoveLevelInformationByEntryIdAsync(Guid entryId); + ValueTask AddLevelInformationAsync(CultivateEntryLevelInformation levelInformation); + + ValueTask> GetCultivateEntryIncludeLevelInformationListByProjectIdAsync(Guid projectId); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml index 71055f38..09808809 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml @@ -74,7 +74,7 @@ Margin="0,8,0,0" Visibility="{x:Bind Avatar, Converter={StaticResource EmptyObjectToVisibilityConverter}}"> @@ -124,10 +124,10 @@ @@ -172,6 +172,6 @@ Value="{Binding LevelTarget, Mode=TwoWay}"/> - + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml index e275304f..2b0c2c38 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/CultivationPage.xaml @@ -130,11 +130,17 @@ Height="48" Icon="{Binding Icon}" Quality="{Binding Quality}"/> - + VerticalAlignment="Center"> + + + +