1
0
mirror of https://github.com/wangdage12/Snap.Hutao.git synced 2026-07-31 04:10:25 +08:00

修正机器人审查的一些项

This commit is contained in:
mfkvfhpdx
2026-05-04 17:34:21 +08:00
parent a02d7e533f
commit f66d712a1b
8 changed files with 92 additions and 65 deletions
@@ -19,7 +19,8 @@ namespace Snap.Hutao.Migrations
table: "cultivate_entries", table: "cultivate_entries",
column: "RelatedEntryId", column: "RelatedEntryId",
principalTable: "cultivate_entries", principalTable: "cultivate_entries",
principalColumn: "InnerId"); principalColumn: "InnerId",
onDelete: ReferentialAction.SetNull);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -108,8 +108,10 @@ internal sealed partial class AvatarPropertyBatchCultivateService : IAvatarPrope
if (baseline.SyncInventoryItems) if (baseline.SyncInventoryItems)
{ {
CultivateProject? project = await cultivationService.GetCurrentProjectAsync().ConfigureAwait(false); Snap.Hutao.Core.Database.IAdvancedDbCollectionView<CultivateProject> projects = await cultivationService.GetProjectCollectionAsync().ConfigureAwait(false);
if (project is not null) await cultivationService.EnsureCurrentProjectAsync(projects).ConfigureAwait(false);
if (projects.CurrentItem is { } project)
{ {
IMetadataService metadataService = serviceProvider.GetRequiredService<IMetadataService>(); IMetadataService metadataService = serviceProvider.GetRequiredService<IMetadataService>();
ICultivationMetadataContext cultivationContext = await metadataService ICultivationMetadataContext cultivationContext = await metadataService
@@ -153,6 +155,7 @@ internal sealed partial class AvatarPropertyBatchCultivateService : IAvatarPrope
if (!await SaveCultivationAsync(consumption, new CultivatePromotionDeltaOptions(delta, baseline.Strategy)).ConfigureAwait(false)) if (!await SaveCultivationAsync(consumption, new CultivatePromotionDeltaOptions(delta, baseline.Strategy)).ConfigureAwait(false))
{ {
result.StopReason = BatchCultivateStopReason.NoProject;
break; break;
} }
@@ -7,4 +7,11 @@ internal struct BatchCultivateResult
{ {
public int SucceedCount; public int SucceedCount;
public int SkippedCount; public int SkippedCount;
public BatchCultivateStopReason StopReason;
}
internal enum BatchCultivateStopReason
{
None = 0,
NoProject = 1,
} }
@@ -54,22 +54,17 @@ internal sealed partial class CultivationRepository : ICultivationRepository
public Guid? TryGetAvatarCultivateEntryInnerId(Guid projectId, uint avatarId) public Guid? TryGetAvatarCultivateEntryInnerId(Guid projectId, uint avatarId)
{ {
ImmutableArray<CultivateEntry> entries = GetCultivateEntryImmutableArrayByProjectIdAndItemId(projectId, avatarId); // NOTE: InnerId(Guid) 的大小不代表插入顺序;这里使用 SQLite 的 rowid 选择最新插入的一条。
Guid? last = null; using (IServiceScope scope = ServiceProvider.CreateScope())
foreach (ref readonly CultivateEntry entry in entries.AsSpan())
{ {
if (entry.Type != CultivateType.AvatarAndSkill) AppDbContext db = scope.GetAppDbContext();
{ return db.Set<CultivateEntry>()
continue; .AsNoTracking()
} .Where(e => e.ProjectId == projectId && e.Id == avatarId && e.Type == CultivateType.AvatarAndSkill)
.OrderByDescending(e => EF.Property<long>(e, "rowid"))
if (last is null || entry.InnerId.CompareTo(last.Value) > 0) .Select(e => (Guid?)e.InnerId)
{ .FirstOrDefault();
last = entry.InnerId;
}
} }
return last;
} }
public void AddCultivateEntry(CultivateEntry entry) public void AddCultivateEntry(CultivateEntry entry)
@@ -47,7 +47,7 @@ internal interface ICultivationRepository : IRepository<CultivateEntryLevelInfor
/// <summary> /// <summary>
/// 解析当前计划中指定角色的养成条目(类型为 CultivateType.AvatarAndSkill)。 /// 解析当前计划中指定角色的养成条目(类型为 CultivateType.AvatarAndSkill)。
/// 若存在多条历史记录,取条目主键 InnerId(Guid)较大的一条 /// 若存在多条历史记录,取最近插入数据库的一条(按 SQLite rowid 倒序)
/// </summary> /// </summary>
Guid? TryGetAvatarCultivateEntryInnerId(Guid projectId, uint avatarId); Guid? TryGetAvatarCultivateEntryInnerId(Guid projectId, uint avatarId);
@@ -232,65 +232,69 @@
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="StatisticsItemTemplate" x:DataType="shvcu:StatisticsCultivateItem"> <DataTemplate x:Key="StatisticsItemTemplate" x:DataType="shvcu:StatisticsCultivateItem">
<Border Background="Transparent" IsRightTapEnabled="True"> <Border Background="Transparent">
<Border.ContextFlyout> <shuxcc:HorizontalCard
<Flyout FlyoutPresenterStyle="{ThemeResource FlyoutPresenterPadding0Style}"> Background="{Binding IsToday, Converter={ThemeResource BoolToStatisticsBrushSelector}}"
<ScrollViewer MaxHeight="320" MinWidth="220" Padding="12,10"> IsRightTapEnabled="True"
<ItemsControl ItemsSource="{Binding StatisticsConsumerMenuLines, Mode=OneWay}"> IsTabStop="True"
<ItemsControl.ItemTemplate> UseSystemFocusVisuals="True">
<DataTemplate x:DataType="shvcu:StatisticsConsumerMenuLine"> <FrameworkElement.ContextFlyout>
<Grid Margin="0,3"> <Flyout FlyoutPresenterStyle="{ThemeResource FlyoutPresenterPadding0Style}">
<TextBlock <ScrollViewer MaxHeight="320" MinWidth="220" Padding="12,10">
Style="{ThemeResource BodyTextBlockStyle}" <ItemsControl ItemsSource="{Binding StatisticsConsumerMenuLines, Mode=OneWay}">
Text="{x:Bind PlainMessage, Mode=OneWay}" <ItemsControl.ItemTemplate>
TextWrapping="WrapWholeWords" <DataTemplate x:DataType="shvcu:StatisticsConsumerMenuLine">
Visibility="{x:Bind IsPlainMessage, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"/> <Grid Margin="0,3">
<StackPanel
Orientation="Horizontal"
Spacing="4"
VerticalAlignment="Center"
Visibility="{x:Bind ShowRichRow, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<shuxc:ItemIcon
Width="28"
Height="28"
Icon="{x:Bind LeadingIcon, Mode=OneWay}"
Quality="{x:Bind LeadingQuality, Mode=OneWay}"/>
<TextBlock <TextBlock
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}" Style="{ThemeResource BodyTextBlockStyle}"
Text="{x:Bind FirstName, Mode=OneWay}"/> Text="{x:Bind PlainMessage, Mode=OneWay}"
TextWrapping="WrapWholeWords"
Visibility="{x:Bind IsPlainMessage, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"/>
<StackPanel <StackPanel
Orientation="Horizontal" Orientation="Horizontal"
Spacing="4" Spacing="4"
VerticalAlignment="Center" VerticalAlignment="Center"
Visibility="{x:Bind HasSecondIcon, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"> Visibility="{x:Bind ShowRichRow, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="{x:Bind BetweenSeparator, Mode=OneWay}"/>
<shuxc:ItemIcon <shuxc:ItemIcon
Width="28" Width="28"
Height="28" Height="28"
Icon="{x:Bind SecondIcon, Mode=OneWay}" Icon="{x:Bind LeadingIcon, Mode=OneWay}"
Quality="{x:Bind SecondQuality, Mode=OneWay}"/> Quality="{x:Bind LeadingQuality, Mode=OneWay}"/>
<TextBlock <TextBlock
VerticalAlignment="Center" VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}" Style="{ThemeResource BodyTextBlockStyle}"
Text="{x:Bind SecondName, Mode=OneWay}"/> Text="{x:Bind FirstName, Mode=OneWay}"/>
<StackPanel
Orientation="Horizontal"
Spacing="4"
VerticalAlignment="Center"
Visibility="{x:Bind HasSecondIcon, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="{x:Bind BetweenSeparator, Mode=OneWay}"/>
<shuxc:ItemIcon
Width="28"
Height="28"
Icon="{x:Bind SecondIcon, Mode=OneWay}"
Quality="{x:Bind SecondQuality, Mode=OneWay}"/>
<TextBlock
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="{x:Bind SecondName, Mode=OneWay}"/>
</StackPanel>
<TextBlock
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="{x:Bind CountSuffix, Mode=OneWay}"/>
</StackPanel> </StackPanel>
<TextBlock </Grid>
VerticalAlignment="Center" </DataTemplate>
Style="{ThemeResource BodyTextBlockStyle}" </ItemsControl.ItemTemplate>
Text="{x:Bind CountSuffix, Mode=OneWay}"/> </ItemsControl>
</StackPanel> </ScrollViewer>
</Grid> </Flyout>
</DataTemplate> </FrameworkElement.ContextFlyout>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Flyout>
</Border.ContextFlyout>
<shuxcc:HorizontalCard Background="{Binding IsToday, Converter={ThemeResource BoolToStatisticsBrushSelector}}">
<shuxcc:HorizontalCard.Left> <shuxcc:HorizontalCard.Left>
<Grid Grid.Column="0"> <Grid Grid.Column="0">
<shuxc:ItemIcon <shuxc:ItemIcon
@@ -281,6 +281,12 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
return; return;
} }
if (result.StopReason is not BatchCultivateStopReason.None)
{
scopeContext.Messenger.Send(InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning));
return;
}
scopeContext.Messenger.Send(CultivationProjectEntriesChangedMessage.Empty); scopeContext.Messenger.Send(CultivationProjectEntriesChangedMessage.Empty);
InfoBarMessage message = result.SkippedCount > 0 InfoBarMessage message = result.SkippedCount > 0
@@ -149,7 +149,12 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel, IRec
LocalSetting.Set(SettingKeys.CultivationRefreshInventoryByCalculatorToAllProjects, value); LocalSetting.Set(SettingKeys.CultivationRefreshInventoryByCalculatorToAllProjects, value);
} }
public async void Receive(CultivationProjectEntriesChangedMessage message) public void Receive(CultivationProjectEntriesChangedMessage _)
{
ReceiveProjectEntriesChangedAsync().SafeForget();
}
private async ValueTask ReceiveProjectEntriesChangedAsync()
{ {
await taskContext.SwitchToMainThreadAsync(); await taskContext.SwitchToMainThreadAsync();
if (Projects?.CurrentItem is null) if (Projects?.CurrentItem is null)
@@ -382,6 +387,12 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel, IRec
return; return;
} }
if (result.StopReason is not BatchCultivateStopReason.None)
{
messenger.Send(InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning));
return;
}
messenger.Send(CultivationProjectEntriesChangedMessage.Empty); messenger.Send(CultivationProjectEntriesChangedMessage.Empty);
InfoBarMessage message = result.SkippedCount > 0 InfoBarMessage message = result.SkippedCount > 0