support remove users

This commit is contained in:
DismissedLight
2022-06-22 11:16:34 +08:00
parent 98473af32f
commit 19ab4fef55
23 changed files with 173 additions and 205 deletions

View File

@@ -50,14 +50,13 @@ internal static partial class ServiceCollectionExtensions
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Snap.Hutao.SourceGeneration.DedendencyInjection.InjectionGenerator"","" 1.0.0.0"")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial IServiceCollection AddInjections(this IServiceCollection services)
{");
{
return services");
sourceCodeBuilder.Append("\r\n");
FillWithInjectionServices(receiver, sourceCodeBuilder);
sourceCodeBuilder.Append(@" return services;
sourceCodeBuilder.Append(@";
}
}");
sourceCodeBuilder.Append("\r\n");
context.AddSource("ServiceCollectionExtensions.g.cs", SourceText.From(sourceCodeBuilder.ToString(), Encoding.UTF8));
}
@@ -66,6 +65,8 @@ internal static partial class ServiceCollectionExtensions
{
foreach (INamedTypeSymbol classSymbol in receiver.Classes.OrderByDescending(symbol => symbol.ToDisplayString()))
{
sourceCodeBuilder.Append("\r\n");
AttributeData injectionInfo = classSymbol
.GetAttributes()
.Single(attr => attr.AttributeClass!.ToDisplayString() == InjectionSyntaxContextReceiver.AttributeName);
@@ -77,10 +78,10 @@ internal static partial class ServiceCollectionExtensions
switch (injectAsName)
{
case "Snap.Hutao.Core.DependencyInjection.InjectAs.Singleton":
sourceCodeBuilder.Append(@" services.AddSingleton(");
sourceCodeBuilder.Append(@" .AddSingleton(");
break;
case "Snap.Hutao.Core.DependencyInjection.InjectAs.Transient":
sourceCodeBuilder.Append(@" services.AddTransient(");
sourceCodeBuilder.Append(@" .AddTransient(");
break;
default:
throw new InvalidOperationException($"非法的InjectAs值: [{injectAsName}]。");
@@ -92,7 +93,7 @@ internal static partial class ServiceCollectionExtensions
sourceCodeBuilder.Append($"{interfaceType.ToCSharpString()}, ");
}
sourceCodeBuilder.Append($"typeof({classSymbol.ToDisplayString()}));\r\n");
sourceCodeBuilder.Append($"typeof({classSymbol.ToDisplayString()}))");
}
}
}

View File

@@ -3,12 +3,8 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
namespace Snap.Hutao.SourceGeneration.DedendencyInjection;
@@ -17,6 +13,9 @@ namespace Snap.Hutao.SourceGeneration.DedendencyInjection;
/// </summary>
public class InjectionSyntaxContextReceiver : ISyntaxContextReceiver
{
/// <summary>
/// 注入特性的名称
/// </summary>
public const string AttributeName = "Snap.Hutao.Core.DependencyInjection.Annotation.InjectionAttribute";
/// <summary>

View File

@@ -4,6 +4,7 @@
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using Snap.Hutao.Core.Logging;
namespace Snap.Hutao;
@@ -23,6 +24,8 @@ public partial class App : Application
// load app resource
InitializeComponent();
InitializeDependencyInjection();
UnhandledException += AppUnhandledException;
}
/// <summary>
@@ -44,15 +47,28 @@ public partial class App : Application
private static void InitializeDependencyInjection()
{
IServiceProvider services = new ServiceCollection()
// Microsoft extension
.AddLogging(builder => builder.AddDebug())
.AddSingleton<IMessenger>(WeakReferenceMessenger.Default)
.AddMemoryCache()
// Hutao extensions
.AddInjections()
.AddDatebase()
.AddHttpClients()
.AddDefaultJsonSerializerOptions()
.AddInjections()
// Discrete services
.AddSingleton<IMessenger>(WeakReferenceMessenger.Default)
.BuildServiceProvider();
Ioc.Default.ConfigureServices(services);
}
private void AppUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
{
ILogger<App> logger = Ioc.Default.GetRequiredService<ILogger<App>>();
logger.LogError(EventIds.UnhandledException, e.Exception, "未经处理的异常");
}
}

View File

@@ -6,8 +6,14 @@ using Snap.Hutao.Context.FileSystem;
namespace Snap.Hutao.Context.Database;
/// <summary>
/// 此类只用于在生成迁移时提供数据库上下文
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public class AppDbContextDesignTimeFactory : IDesignTimeDbContextFactory<AppDbContext>
{
/// <inheritdoc/>
[EditorBrowsable(EditorBrowsableState.Never)]
public AppDbContext CreateDbContext(string[] args)
{
MyDocumentContext myDocument = new(new());

View File

@@ -11,5 +11,10 @@ internal static class EventIds
/// <summary>
/// 导航失败
/// </summary>
public static readonly EventId NavigationFailed = new(100000, "NavigationFailed");
public static readonly EventId NavigationFailed = new(100000, nameof(NavigationFailed));
/// <summary>
/// 未处理的异常
/// </summary>
public static readonly EventId UnhandledException = new(100000, nameof(UnhandledException));
}

View File

@@ -50,17 +50,15 @@ internal static class IocConfiguration
// temporarily create a context
using (AppDbContext context = AppDbContext.CreateFrom(sqlConnectionString))
{
Debug.WriteLine("Migrate started");
if (context.Database.GetPendingMigrations().Any())
{
Debug.WriteLine("Migrate started");
context.Database.Migrate();
Debug.WriteLine("Migrate completed");
}
Debug.WriteLine("Migrate completed");
}
// LocalSetting.Set(SettingKeys.LastAppVersion, CoreEnvironment.Version.ToString());
return services
.AddDbContextPool<AppDbContext>(builder => builder.UseSqlite(sqlConnectionString));
}
}
}

View File

@@ -25,12 +25,12 @@ internal static class IocHttpClientConfiguration
/// <returns>可继续操作的集合</returns>
public static IServiceCollection AddHttpClients(this IServiceCollection services)
{
services.AddHttpClient<HutaoClient>().ConfigureHttpClient(DefaultConfiguration);
services.AddHttpClient<AnnouncementClient>().ConfigureHttpClient(DefaultConfiguration);
services.AddHttpClient<UserGameRoleClient>().ConfigureHttpClient(DefaultConfiguration);
services.AddHttpClient<HutaoClient>(DefaultConfiguration);
services.AddHttpClient<AnnouncementClient>(DefaultConfiguration);
services.AddHttpClient<UserGameRoleClient>(DefaultConfiguration);
services.AddHttpClient<GameRecordClient>().ConfigureHttpClient(XRpcConfiguration);
services.AddHttpClient<UserClient>().ConfigureHttpClient(XRpcConfiguration);
services.AddHttpClient<GameRecordClient>(XRpcConfiguration);
services.AddHttpClient<UserClient>(XRpcConfiguration);
return services;
}

View File

@@ -1,9 +1,15 @@
using Microsoft.EntityFrameworkCore.Migrations;
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Snap.Hutao.Migrations
{
[SuppressMessage("", "SA1413")]
[SuppressMessage("", "SA1600")]
[SuppressMessage("", "SA1601")]
public partial class SettingAndUser : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)

View File

@@ -1,8 +1,6 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Snap.Hutao.Context.Database;
#nullable disable

View File

@@ -62,6 +62,12 @@ public class User : Observable
private set => Set(ref selectedUserGameRole, value);
}
/// <summary>
/// 移除命令
/// </summary>
[NotMapped]
public ICommand? RemoveCommand { get; set; }
/// <summary>
/// 判断用户是否为空用户
/// </summary>
@@ -91,6 +97,7 @@ public class User : Observable
/// <summary>
/// 初始化此用户
/// 初始化前必须设置 <see cref="RemoveCommand"/> 属性
/// </summary>
/// <param name="userClient">用户客户端</param>
/// <param name="userGameRoleClient">角色客户端</param>
@@ -103,6 +110,8 @@ public class User : Observable
return false;
}
Must.NotNull(RemoveCommand!);
UserInfo = await userClient
.GetUserFullInfoAsync(this, token)
.ConfigureAwait(false);
@@ -111,9 +120,9 @@ public class User : Observable
.GetUserGameRolesAsync(this, token)
.ConfigureAwait(false);
SelectedUserGameRole = UserGameRoles.FirstOrDefault(role => role.IsChosen) ?? UserGameRoles.FirstOrDefault();
SelectedUserGameRole = UserGameRoles.FirstOrFirstOrDefault(role => role.IsChosen);
return UserInfo != null && UserGameRoles != null;
return UserInfo != null && UserGameRoles.Any();
}
/// <summary>

View File

@@ -9,7 +9,7 @@
<Identity
Name="7f0db578-026f-4e0b-a75b-d5d06bb0a74d"
Publisher="CN=DGP Studio"
Version="1.0.3.0" />
Version="1.0.4.0" />
<Properties>
<DisplayName>胡桃</DisplayName>

View File

@@ -22,7 +22,7 @@ public static class Program
XamlCheckProcessRequirements();
ComWrappersSupport.InitializeComWrappers();
Application.Start((p) =>
Application.Start(p =>
{
DispatcherQueueSynchronizationContext context = new(DispatcherQueue.GetForCurrentThread());
SynchronizationContext.SetSynchronizationContext(context);

View File

@@ -28,17 +28,17 @@ public interface IInfoBarService
/// <summary>
/// 显示错误消息
/// </summary>
/// <param name="ex">异常</param>
/// <param name="exception">异常</param>
/// <param name="delay">关闭延迟</param>
void Error(Exception ex, int delay = 0);
void Error(Exception exception, int delay = 0);
/// <summary>
/// 显示错误消息
/// </summary>
/// <param name="ex">异常</param>
/// <param name="exception">异常</param>
/// <param name="title">标题</param>
/// <param name="delay">关闭延迟</param>
void Error(Exception ex, string title, int delay = 0);
void Error(Exception exception, string title, int delay = 0);
/// <summary>
/// 显示提示信息

View File

@@ -22,9 +22,9 @@ public interface IUserService
/// 每个用户信息都应准备完成
/// 此操作不能取消
/// </summary>
/// <param name="token">取消令牌</param>
/// <param name="removeCommand">移除用户命令</param>
/// <returns>准备完成的用户信息枚举</returns>
Task<ObservableCollection<User>> GetInitializedUsersAsync();
Task<ObservableCollection<User>> GetInitializedUsersAsync(ICommand removeCommand);
/// <summary>
/// 异步添加用户

View File

@@ -107,7 +107,7 @@ internal class InfoBarService : IInfoBarService
};
infoBar.Closed += OnInfoBarClosed;
Must.NotNull(infoBarStack!)!.Children.Add(infoBar);
Must.NotNull(infoBarStack!).Children.Add(infoBar);
if (delay > 0)
{

View File

@@ -3,6 +3,7 @@
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Core.Logging;
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.Abstraction.Navigation;
using Snap.Hutao.View.Helper;
using Snap.Hutao.View.Page;
@@ -16,6 +17,7 @@ namespace Snap.Hutao.Service;
[Injection(InjectAs.Singleton, typeof(INavigationService))]
internal class NavigationService : INavigationService
{
private readonly IInfoBarService infoBarService;
private readonly ILogger<INavigationService> logger;
private NavigationView? navigationView;
@@ -23,9 +25,11 @@ internal class NavigationService : INavigationService
/// <summary>
/// 构造一个新的导航服务
/// </summary>
/// <param name="infobarService">信息条服务</param>
/// <param name="logger">日志器</param>
public NavigationService(ILogger<INavigationService> logger)
public NavigationService(IInfoBarService infobarService, ILogger<INavigationService> logger)
{
this.infoBarService = infobarService;
this.logger = logger;
}
@@ -108,6 +112,7 @@ internal class NavigationService : INavigationService
catch (Exception ex)
{
logger.LogError(EventIds.NavigationFailed, ex, "导航到指定页面时发生了错误");
infoBarService.Error(ex);
}
logger.LogInformation("Navigate to {pageType}:{result}", pageType, navigated ? "succeed" : "failed");

View File

@@ -45,15 +45,21 @@ internal class UserService : IUserService
get => currentUser;
set
{
if (!User.IsNone(currentUser))
{
User.SetSelectionState(currentUser, false);
appDbContext.Users.Update(currentUser);
}
// only update when not processing a deletion
if (!User.IsNone(value))
{
currentUser = value;
if (!User.IsNone(currentUser))
{
User.SetSelectionState(currentUser, false);
appDbContext.Users.Update(currentUser);
}
}
// 当删除到无用户时也能正常反应状态
currentUser = value;
if (!User.IsNone(currentUser))
{
User.SetSelectionState(currentUser, true);
appDbContext.Users.Update(currentUser);
}
@@ -79,7 +85,7 @@ internal class UserService : IUserService
}
/// <inheritdoc/>
public async Task<ObservableCollection<User>> GetInitializedUsersAsync()
public async Task<ObservableCollection<User>> GetInitializedUsersAsync(ICommand removeCommand)
{
if (cachedUser == null)
{
@@ -88,6 +94,7 @@ internal class UserService : IUserService
foreach (User user in cachedUser)
{
user.RemoveCommand = removeCommand;
await user.InitializeAsync(userClient, userGameRoleClient);
}

View File

@@ -1,41 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI.Xaml.Markup;
namespace Snap.Hutao.View.Converter;
/// <summary>
/// Static class used to provide internal tools
/// </summary>
internal static class ConvertHelper
{
/// <summary>
/// Helper method to safely cast an object to a boolean
/// </summary>
/// <param name="parameter">Parameter to cast to a boolean</param>
/// <returns>Bool value or false if cast failed</returns>
internal static bool TryParseBool(object parameter)
{
bool parsed = false;
if (parameter != null)
{
_ = bool.TryParse(parameter.ToString(), out parsed);
}
return parsed;
}
/// <summary>
/// Helper method to convert a value from a source type to a target type.
/// </summary>
/// <param name="value">The value to convert</param>
/// <param name="targetType">The target type</param>
/// <returns>The converted value</returns>
internal static object Convert(object value, Type targetType)
{
return targetType.IsInstanceOfType(value)
? value
: XamlBindingHelper.ConvertValue(targetType, value);
}
}

View File

@@ -1,49 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data;
using Snap.Hutao.Core;
namespace Snap.Hutao.View.Converter;
/// <summary>
/// 百分比转换高度
/// </summary>
public sealed class PercentageToHeightConverter : DependencyObject, IValueConverter
{
private static readonly DependencyProperty TargetWidthProperty = Property<PercentageToHeightConverter>.Depend(nameof(TargetWidth), 1080D);
private static readonly DependencyProperty TargetHeightProperty = Property<PercentageToHeightConverter>.Depend(nameof(TargetHeight), 390D);
/// <summary>
/// 目标宽度
/// </summary>
public double TargetWidth
{
get => (double)GetValue(TargetWidthProperty);
set => SetValue(TargetWidthProperty, value);
}
/// <summary>
/// 目标高度
/// </summary>
public double TargetHeight
{
get => (double)GetValue(TargetHeightProperty);
set => SetValue(TargetHeightProperty, value);
}
/// <inheritdoc/>
public object Convert(object value, Type targetType, object parameter, string culture)
{
return (double)value * (TargetHeight / TargetWidth);
}
/// <inheritdoc/>
public object ConvertBack(object value, Type targetType, object parameter, string culture)
{
throw Must.NeverHappen();
}
}

View File

@@ -1,49 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data;
using Snap.Hutao.Core;
namespace Snap.Hutao.View.Converter;
/// <summary>
/// 百分比转宽度
/// </summary>
public sealed class PercentageToWidthConverter : DependencyObject, IValueConverter
{
private static readonly DependencyProperty TargetWidthProperty = Property<PercentageToWidthConverter>.Depend(nameof(TargetWidth), 1080D);
private static readonly DependencyProperty TargetHeightProperty = Property<PercentageToWidthConverter>.Depend(nameof(TargetHeight), 390D);
/// <summary>
/// 目标宽度
/// </summary>
public double TargetWidth
{
get => (double)GetValue(TargetWidthProperty);
set => SetValue(TargetWidthProperty, value);
}
/// <summary>
/// 目标高度
/// </summary>
public double TargetHeight
{
get => (double)GetValue(TargetHeightProperty);
set => SetValue(TargetHeightProperty, value);
}
/// <inheritdoc/>
public object Convert(object value, Type targetType, object parameter, string culture)
{
return (double)value * (TargetWidth / TargetHeight);
}
/// <inheritdoc/>
public object ConvertBack(object value, Type targetType, object parameter, string culture)
{
throw Must.NeverHappen();
}
}

View File

@@ -7,6 +7,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
xmlns:mxim="using:Microsoft.Xaml.Interactions.Media"
mc:Ignorable="d">
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="Loaded">
@@ -25,11 +26,6 @@
HorizontalAlignment="Left"
Margin="4,0,4,0"
Height="40"/>
<!--<PersonPicture
ProfilePicture="{Binding SelectedUser.UserInfo.Pendant,FallbackValue={x:Null},Mode=OneWay}"
HorizontalAlignment="Left"
Margin="4,0,4,0"
Height="40"/>-->
<TextBlock
VerticalAlignment="Center"
Margin="0,0,0,2"
@@ -87,21 +83,72 @@
SelectedItem="{Binding SelectedUser,Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Padding="0,12">
<Grid Padding="0,12" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<PersonPicture
ProfilePicture="{Binding UserInfo.AvatarUrl,Mode=OneWay}"
HorizontalAlignment="Left"
Margin="4,0"
Margin="0,0"
Height="32"/>
<TextBlock
Margin="12,0,0,0"
Grid.Column="1"
VerticalAlignment="Center"
Text="{Binding UserInfo.Nickname}"/>
<Button
x:Name="RemoveUserButton"
Content="&#xE74D;"
FontFamily="{StaticResource SymbolThemeFontFamily}"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Grid.Column="2"
Background="Transparent"
BorderThickness="0"
BorderBrush="{x:Null}"
Margin="12,0,0,0"
Visibility="Collapsed"
Command="{Binding RemoveCommand}"
CommandParameter="{Binding}"/>
<Grid.Resources>
<Storyboard x:Name="RemoveUserButtonVisibleStoryboard">
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="RemoveUserButton"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="RemoveUserButtonCollapsedStoryboard">
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="RemoveUserButton"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="PointerEntered">
<mxim:ControlStoryboardAction Storyboard="{StaticResource RemoveUserButtonVisibleStoryboard}"/>
</mxic:EventTriggerBehavior>
<mxic:EventTriggerBehavior EventName="PointerExited">
<mxim:ControlStoryboardAction Storyboard="{StaticResource RemoveUserButtonCollapsedStoryboard}"/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
</Grid>
</DataTemplate>

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Core.Threading;
using Snap.Hutao.Factory.Abstraction;
@@ -23,6 +24,8 @@ internal class UserViewModel : ObservableObject
private readonly IUserService userService;
private readonly IInfoBarService infoBarService;
private ICommand removeUserCommand;
private User? selectedUser;
private ObservableCollection<User>? userInfos;
@@ -39,6 +42,8 @@ internal class UserViewModel : ObservableObject
OpenUICommand = asyncRelayCommandFactory.Create(OpenUIAsync);
AddUserCommand = asyncRelayCommandFactory.Create<Flyout>(AddUserAsync);
removeUserCommand = new RelayCommand<User>(RemoveUser);
}
/// <summary>
@@ -110,8 +115,8 @@ internal class UserViewModel : ObservableObject
private async Task OpenUIAsync()
{
Users = await userService.GetInitializedUsersAsync();
SelectedUser = Users.FirstOrDefault();
Users = await userService.GetInitializedUsersAsync(removeUserCommand);
SelectedUser = userService.CurrentUser;
}
private async Task AddUserAsync(Flyout? flyout)
@@ -129,7 +134,11 @@ internal class UserViewModel : ObservableObject
if (TryValidateCookie(map, out SortedDictionary<string, string>? filteredCookie))
{
string simplifiedCookie = string.Join(';', filteredCookie.Select(kvp => $"{kvp.Key}={kvp.Value}"));
User user = new() { Cookie = simplifiedCookie };
User user = new()
{
Cookie = simplifiedCookie,
RemoveCommand = removeUserCommand,
};
if (!await userService.TryAddUserAsync(user))
{
@@ -138,4 +147,12 @@ internal class UserViewModel : ObservableObject
}
}
}
private void RemoveUser(User? user)
{
if (!User.IsNone(user))
{
userService.RemoveUser(user);
}
}
}

View File

@@ -4,8 +4,6 @@
using Snap.Hutao.Core.Abstraction;
using Snap.Hutao.Extension;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Web.Hoyolab.Takumi;
using Snap.Hutao.Web.Hoyolab.Takumi.Binding;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Avatar;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.SpiralAbyss;
@@ -31,7 +29,6 @@ internal class HutaoClient : ISupportAsyncInitialization
private readonly HttpClient httpClient;
private readonly GameRecordClient gameRecordClient;
private readonly UserGameRoleClient userGameRoleClient;
private readonly JsonSerializerOptions jsonSerializerOptions;
private bool isInitialized = false;
@@ -41,17 +38,14 @@ internal class HutaoClient : ISupportAsyncInitialization
/// </summary>
/// <param name="httpClient">http客户端</param>
/// <param name="gameRecordClient">游戏记录客户端</param>
/// <param name="userGameRoleClient">用户游戏角色客户端</param>
/// <param name="jsonSerializerOptions">json序列化选项</param>
public HutaoClient(
HttpClient httpClient,
GameRecordClient gameRecordClient,
UserGameRoleClient userGameRoleClient,
JsonSerializerOptions jsonSerializerOptions)
{
this.httpClient = httpClient;
this.gameRecordClient = gameRecordClient;
this.userGameRoleClient = userGameRoleClient;
this.jsonSerializerOptions = jsonSerializerOptions;
}
@@ -64,13 +58,12 @@ internal class HutaoClient : ISupportAsyncInitialization
Auth auth = new(
"08d9e212-0cb3-4d71-8ed7-003606da7b20",
"7ueWgZGn53dDhrm8L5ZRw+YWfOeSWtgQmJWquRgaygw=");
JsonSerializerOptions? option = Ioc.Default.GetService<JsonSerializerOptions>();
HttpResponseMessage response = await httpClient
.PostAsJsonAsync($"{AuthAPIHost}/Auth/Login", auth, option, token)
.PostAsJsonAsync($"{AuthAPIHost}/Auth/Login", auth, jsonSerializerOptions, token)
.ConfigureAwait(false);
Response<Token>? resp = await response.Content
.ReadFromJsonAsync<Response<Token>>(option, token)
.ReadFromJsonAsync<Response<Token>>(jsonSerializerOptions, token)
.ConfigureAwait(false);
httpClient.DefaultRequestHeaders.Authorization = new("Bearer", Must.NotNull(resp?.Data?.AccessToken!));