add gachalogserviceexpiredat in hutaocloudservice

This commit is contained in:
Lightczx
2023-07-07 11:13:47 +08:00
parent 4d526bb363
commit 5020621c46
10 changed files with 128 additions and 23 deletions

View File

@@ -1473,6 +1473,15 @@ namespace Snap.Hutao.Resource.Localization {
} }
} }
/// <summary>
/// 查找类似 祈愿记录上传服务将于 {0:yyyy-MM-dd HH:mm:ss} 到期 的本地化字符串。
/// </summary>
internal static string ServiceHutaoUserGachaLogExpiredAt {
get {
return ResourceManager.GetString("ServiceHutaoUserGachaLogExpiredAt", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 无法找到缓存的元数据文件 的本地化字符串。 /// 查找类似 无法找到缓存的元数据文件 的本地化字符串。
/// </summary> /// </summary>
@@ -3426,6 +3435,15 @@ namespace Snap.Hutao.Resource.Localization {
} }
} }
/// <summary>
/// 查找类似 已注册为开发者,即使服务过期依旧能使用 的本地化字符串。
/// </summary>
internal static string ViewPageGachaLogHutaoCloudDeveloperHint {
get {
return ResourceManager.GetString("ViewPageGachaLogHutaoCloudDeveloperHint", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 胡桃云服务时长不足 的本地化字符串。 /// 查找类似 胡桃云服务时长不足 的本地化字符串。
/// </summary> /// </summary>

View File

@@ -2037,4 +2037,10 @@
<data name="WebDailyNoteResinRecoveryCompleted" xml:space="preserve"> <data name="WebDailyNoteResinRecoveryCompleted" xml:space="preserve">
<value>原粹树脂已完全恢复</value> <value>原粹树脂已完全恢复</value>
</data> </data>
<data name="ServiceHutaoUserGachaLogExpiredAt" xml:space="preserve">
<value>祈愿记录上传服务将于 {0:yyyy-MM-dd HH:mm:ss} 到期</value>
</data>
<data name="ViewPageGachaLogHutaoCloudDeveloperHint" xml:space="preserve">
<value>已注册为开发者,即使服务过期依旧能使用</value>
</data>
</root> </root>

View File

@@ -3,6 +3,7 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Snap.Hutao.Web.Hutao.Model;
namespace Snap.Hutao.Service.Hutao; namespace Snap.Hutao.Service.Hutao;
@@ -16,6 +17,8 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions<HutaoUserOpt
private string? token; private string? token;
private bool isLoggedIn; private bool isLoggedIn;
private bool isHutaoCloudServiceAllowed; private bool isHutaoCloudServiceAllowed;
private bool isLicensedDeveloper;
private string? gachaLogExpireAt;
/// <summary> /// <summary>
/// 用户名 /// 用户名
@@ -42,6 +45,16 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions<HutaoUserOpt
/// </summary> /// </summary>
public bool IsCloudServiceAllowed { get => isHutaoCloudServiceAllowed; set => SetProperty(ref isHutaoCloudServiceAllowed, value); } public bool IsCloudServiceAllowed { get => isHutaoCloudServiceAllowed; set => SetProperty(ref isHutaoCloudServiceAllowed, value); }
/// <summary>
/// 是否为开发者
/// </summary>
public bool IsLicensedDeveloper { get => isLicensedDeveloper; set => SetProperty(ref isLicensedDeveloper, value); }
/// <summary>
/// 祈愿记录服务到期时间
/// </summary>
public string? GachaLogExpireAt { get => gachaLogExpireAt; set => SetProperty(ref gachaLogExpireAt, value); }
/// <inheritdoc/> /// <inheritdoc/>
public HutaoUserOptions Value { get => this; } public HutaoUserOptions Value { get => this; }
@@ -64,4 +77,14 @@ internal sealed class HutaoUserOptions : ObservableObject, IOptions<HutaoUserOpt
{ {
UserName = SH.ViewServiceHutaoUserLoginFailHint; UserName = SH.ViewServiceHutaoUserLoginFailHint;
} }
/// <summary>
/// 刷新用户信息
/// </summary>
/// <param name="userInfo">用户信息</param>
public void UpdateUserInfo(UserInfo userInfo)
{
IsLicensedDeveloper = userInfo.IsLicensedDeveloper;
GachaLogExpireAt = string.Format(SH.ServiceHutaoUserGachaLogExpiredAt, userInfo.GachaLogExpireAt);
}
} }

View File

@@ -3,6 +3,7 @@
using Snap.Hutao.Core.Setting; using Snap.Hutao.Core.Setting;
using Snap.Hutao.Web.Hutao; using Snap.Hutao.Web.Hutao;
using Snap.Hutao.Web.Hutao.Model;
namespace Snap.Hutao.Service.Hutao; namespace Snap.Hutao.Service.Hutao;
@@ -41,8 +42,16 @@ internal sealed partial class HutaoUserService : IHutaoUserService, IHutaoUserSe
{ {
await taskContext.SwitchToMainThreadAsync(); await taskContext.SwitchToMainThreadAsync();
options.LoginSucceed(userName, response.Data); options.LoginSucceed(userName, response.Data);
await taskContext.SwitchToBackgroundAsync();
Web.Response.Response<UserInfo> userInfoResponse = await passportClient.GetUserInfoAsync(response.Data).ConfigureAwait(false);
if (userInfoResponse.IsOk())
{
await taskContext.SwitchToMainThreadAsync();
options.UpdateUserInfo(userInfoResponse.Data);
isInitialized = true; isInitialized = true;
} }
}
else else
{ {
await taskContext.SwitchToMainThreadAsync(); await taskContext.SwitchToMainThreadAsync();

View File

@@ -240,7 +240,7 @@
<ItemGroup> <ItemGroup>
<!-- https://pkgs.dev.azure.com/dotnet/CommunityToolkit/_packaging/CommunityToolkit-Labs/nuget/v3/index.json --> <!-- https://pkgs.dev.azure.com/dotnet/CommunityToolkit/_packaging/CommunityToolkit-Labs/nuget/v3/index.json -->
<PackageReference Include="CommunityToolkit.Labs.WinUI.SettingsControls" Version="0.0.18" /> <PackageReference Include="CommunityToolkit.Labs.WinUI.SettingsControls" Version="0.0.18" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" /> <PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
<PackageReference Include="CommunityToolkit.WinUI.UI.Behaviors" Version="7.1.2" /> <PackageReference Include="CommunityToolkit.WinUI.UI.Behaviors" Version="7.1.2" />
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" /> <PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
@@ -256,7 +256,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="17.6.11" /> <PackageReference Include="Microsoft.VisualStudio.Validation" Version="17.6.11" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.14-beta"> <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.18-beta">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View File

@@ -83,18 +83,26 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ScrollViewer <Grid Grid.Row="0">
Grid.Row="0" <StackPanel Margin="0,0,0,12">
MaxWidth="480" <TextBlock HorizontalTextAlignment="Center" Text="{Binding HutaoCloudViewModel.Options.GachaLogExpireAt}"/>
Margin="0,0,0,8"> <TextBlock
Margin="0,6,0,0"
HorizontalTextAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudDeveloperHint}"/>
</StackPanel>
</Grid>
<ScrollViewer Grid.Row="1" Margin="0,0,0,8">
<ItemsControl ItemsSource="{Binding HutaoCloudViewModel.Uids}"> <ItemsControl ItemsSource="{Binding HutaoCloudViewModel.Uids}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<Grid Margin="0,0,0,8"> <Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition/> <ColumnDefinition/>
<ColumnDefinition/> <ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock <TextBlock
Grid.Column="0" Grid.Column="0"
@@ -133,7 +141,7 @@
</ItemsControl> </ItemsControl>
</ScrollViewer> </ScrollViewer>
<Button <Button
Grid.Row="1" Grid.Row="2"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Command="{Binding HutaoCloudViewModel.UploadCommand}" Command="{Binding HutaoCloudViewModel.UploadCommand}"
CommandParameter="{Binding SelectedArchive}" CommandParameter="{Binding SelectedArchive}"

View File

@@ -35,6 +35,8 @@ internal sealed class HomaGachaLogClient
httpClient.DefaultRequestHeaders.Authorization = new("Bearer", hutaoUserOptions.Token); httpClient.DefaultRequestHeaders.Authorization = new("Bearer", hutaoUserOptions.Token);
} }
/// <summary> /// <summary>
/// 异步获取 Uid 列表 /// 异步获取 Uid 列表
/// </summary> /// </summary>

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Web.Hutao.Model;
using Snap.Hutao.Web.Response; using Snap.Hutao.Web.Response;
using System.Net.Http; using System.Net.Http;
using System.Security.Cryptography; using System.Security.Cryptography;
@@ -14,7 +15,8 @@ namespace Snap.Hutao.Web.Hutao;
/// </summary> /// </summary>
[HighQuality] [HighQuality]
[HttpClient(HttpClientConfiguration.Default)] [HttpClient(HttpClientConfiguration.Default)]
internal sealed class HomaPassportClient [ConstructorGenerated(ResolveHttpClient = true)]
internal sealed partial class HomaPassportClient
{ {
/// <summary> /// <summary>
/// 通行证请求公钥 /// 通行证请求公钥
@@ -32,15 +34,8 @@ internal sealed class HomaPassportClient
"""; """;
private readonly HttpClient httpClient; private readonly HttpClient httpClient;
private readonly JsonSerializerOptions options;
/// <summary> private readonly ILogger<HomaPassportClient> logger;
/// 构造一个新的胡桃通行证客户端
/// </summary>
/// <param name="httpClient">Http客户端</param>
public HomaPassportClient(HttpClient httpClient)
{
this.httpClient = httpClient;
}
/// <summary> /// <summary>
/// 异步获取验证码 /// 异步获取验证码
@@ -58,7 +53,7 @@ internal sealed class HomaPassportClient
}; };
Response.Response? resp = await httpClient Response.Response? resp = await httpClient
.TryCatchPostAsJsonAsync<Dictionary<string, object>, Response.Response>(HutaoEndpoints.PassportVerify, data, token) .TryCatchPostAsJsonAsync<Dictionary<string, object>, Response.Response>(HutaoEndpoints.PassportVerify, data, options, logger, token)
.ConfigureAwait(false); .ConfigureAwait(false);
return Response.Response.DefaultIfNull(resp); return Response.Response.DefaultIfNull(resp);
@@ -82,7 +77,7 @@ internal sealed class HomaPassportClient
}; };
Response<string>? resp = await httpClient Response<string>? resp = await httpClient
.TryCatchPostAsJsonAsync<Dictionary<string, string>, Response<string>>(HutaoEndpoints.PassportRegister, data, token) .TryCatchPostAsJsonAsync<Dictionary<string, string>, Response<string>>(HutaoEndpoints.PassportRegister, data, options, logger, token)
.ConfigureAwait(false); .ConfigureAwait(false);
return Response.Response.DefaultIfNull(resp); return Response.Response.DefaultIfNull(resp);
@@ -106,7 +101,7 @@ internal sealed class HomaPassportClient
}; };
Response<string>? resp = await httpClient Response<string>? resp = await httpClient
.TryCatchPostAsJsonAsync<Dictionary<string, string>, Response<string>>(HutaoEndpoints.PassportResetPassword, data, token) .TryCatchPostAsJsonAsync<Dictionary<string, string>, Response<string>>(HutaoEndpoints.PassportResetPassword, data, options, logger, token)
.ConfigureAwait(false); .ConfigureAwait(false);
return Response.Response.DefaultIfNull(resp); return Response.Response.DefaultIfNull(resp);
@@ -128,12 +123,31 @@ internal sealed class HomaPassportClient
}; };
Response<string>? resp = await httpClient Response<string>? resp = await httpClient
.TryCatchPostAsJsonAsync<Dictionary<string, string>, Response<string>>(HutaoEndpoints.PassportLogin, data, token) .TryCatchPostAsJsonAsync<Dictionary<string, string>, Response<string>>(HutaoEndpoints.PassportLogin, data, options, logger, token)
.ConfigureAwait(false); .ConfigureAwait(false);
return Response.Response.DefaultIfNull(resp); return Response.Response.DefaultIfNull(resp);
} }
/// <summary>
/// 获取用户信息
/// </summary>
/// <param name="authToken">验证令牌</param>
/// <param name="token">取消令牌</param>
/// <returns>用户信息</returns>
public async Task<Response<UserInfo>> GetUserInfoAsync(string authToken, CancellationToken token = default)
{
httpClient.DefaultRequestHeaders.Authorization = new("Bearer", authToken);
Response<UserInfo>? resp = await httpClient
.TryCatchGetFromJsonAsync<Response<UserInfo>>(HutaoEndpoints.PassportUserInfo, options, logger, token)
.ConfigureAwait(false);
httpClient.DefaultRequestHeaders.Authorization = default;
return Response.Response.DefaultIfNull(resp);
}
private static string Encrypt(string text) private static string Encrypt(string text)
{ {
byte[] plaintextBytes = Encoding.UTF8.GetBytes(text); byte[] plaintextBytes = Encoding.UTF8.GetBytes(text);

View File

@@ -0,0 +1,20 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Web.Hutao.Model;
/// <summary>
/// 用户信息
/// </summary>
internal sealed class UserInfo
{
/// <summary>
/// 是否为开发者
/// </summary>
public bool IsLicensedDeveloper { get; set; }
/// <summary>
/// 祈愿记录服务到期时间
/// </summary>
public DateTimeOffset GachaLogExpireAt { get; set; }
}

View File

@@ -75,6 +75,11 @@ internal static class HutaoEndpoints
/// 登录 /// 登录
/// </summary> /// </summary>
public const string PassportLogin = $"{HomaSnapGenshinApi}/Passport/Login"; public const string PassportLogin = $"{HomaSnapGenshinApi}/Passport/Login";
/// <summary>
/// 用户信息
/// </summary>
public const string PassportUserInfo = $"{HomaSnapGenshinApi}/Passport/UserInfo";
#endregion #endregion
#region HutaoAPI #region HutaoAPI