diff --git a/README.en.md b/README.en.md index df4def8c7..a9565b37f 100644 --- a/README.en.md +++ b/README.en.md @@ -28,25 +28,26 @@ English | [简体中文](./README.md) ## 🖥 Operating Environment -- Windows 10 1607+ -- Windows 8.1 / Windows Server 2012 R2 -- Windows 7 SP1 [ESU](https://docs.microsoft.com/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq) - - Prerequisites - - KB3063858 [64 bit](https://www.microsoft.com/download/details.aspx?id=47442) / [32 bit](https://www.microsoft.com/download/details.aspx?id=47409) -- ~~macOS 10.13 High Sierra Or Higher~~ - +- Desktop + - Windows 10 1607+ + - Windows 8.1 / Windows Server 2012 R2 + - Windows 7 SP1 [ESU](https://docs.microsoft.com/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq) + - Prerequisites + - KB3063858 [64 bit](https://www.microsoft.com/download/details.aspx?id=47442) / [32 bit](https://www.microsoft.com/download/details.aspx?id=47409) + - macOS 10.13 High Sierra Or Higher + - Linux Distribution + - Alpine Linux 3.11+ + - CentOS 7+ + - Debian 9+ + - Fedora 32+ + - Linux Mint 18+ + - openSUSE 15+ + - Red Hat Enterprise Linux 7+ + - SUSE Enterprise Linux (SLES) 12 SP2+ + - Ubuntu 20.10, 20.04, 18.04, 16.04 +- Mobile + - Android 5.0+ + - iOS 10.0+ ## 🌎 Roadmap Read what we [milestones](https://github.com/SteamTools-Team/SteamTools/milestones), and feel free to ask questions. diff --git a/README.md b/README.md index 63973a62d..f65fb4b3b 100644 --- a/README.md +++ b/README.md @@ -38,25 +38,26 @@ ## 🖥 系统要求 -- Windows 10 1607+ -- Windows 8.1 / Windows Server 2012 R2 -- Windows 7 SP1 [ESU](https://docs.microsoft.com/zh-cn/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq) - - 先决条件 - - KB3063858 [64 位](https://www.microsoft.com/zh-cn/download/details.aspx?id=47442) / [32 位](https://www.microsoft.com/zh-cn/download/details.aspx?id=47409) -- ~~macOS 10.13 High Sierra 或更高版本~~ - +- 桌面端 + - Windows 10 1607+ + - Windows 8.1 / Windows Server 2012 R2 + - Windows 7 SP1 [ESU](https://docs.microsoft.com/zh-cn/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq) + - 先决条件 + - KB3063858 [64 位](https://www.microsoft.com/zh-cn/download/details.aspx?id=47442) / [32 位](https://www.microsoft.com/zh-cn/download/details.aspx?id=47409) + - macOS 10.13 High Sierra 或更高版本 + - Linux 发行版 + - Alpine Linux 3.11+ + - CentOS 7+ + - Debian 9+ + - Fedora 32+ + - Linux Mint 18+ + - openSUSE 15+ + - Red Hat Enterprise Linux 7+ + - SUSE Enterprise Linux (SLES) 12 SP2+ + - Ubuntu 20.10, 20.04, 18.04, 16.04 +- 移动端 + - Android 5.0+ + - iOS 10.0+ ## 🌎 路线图 查看这个 [milestones](https://github.com/SteamTools-Team/SteamTools/milestones) 来了解我们下一步的开发计划,并随时提出问题。 diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs index e6dd0cf11..0d40cd93e 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs @@ -3,6 +3,7 @@ using Avalonia.ReactiveUI; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using System.Application.Services.Implementation; using System.Application.UI.ViewModels; namespace System.Application.UI @@ -34,6 +35,7 @@ namespace System.Application.UI services.AddLogging(l => l.AddProvider(NullLoggerProvider.Instance)); services.AddDesktopPlatformService(); services.TryAddModelValidator(); + services.TryAddCloudServiceClient(); services.AddLocalizationService(); services.AddMainThreadPlatformService(); services.AddViewModelCollectionService(); diff --git a/System.Application.SteamTools.Client/Services/Implementation/CloudServiceClient.cs b/System.Application.SteamTools.Client/Services/Implementation/CloudServiceClient.cs index ae3d38694..514ea0a7a 100644 --- a/System.Application.SteamTools.Client/Services/Implementation/CloudServiceClient.cs +++ b/System.Application.SteamTools.Client/Services/Implementation/CloudServiceClient.cs @@ -3,23 +3,30 @@ using Microsoft.Extensions.Options; using System.Application.Columns; using System.Application.Models; using System.Application.Services.CloudService; +using System.Net.Http; using System.Threading.Tasks; namespace System.Application.Services.Implementation { - public abstract class CloudServiceClient : CloudServiceClientBase + public class CloudServiceClient : CloudServiceClientBase { - public const string TAG = "ServerApiClient"; - protected readonly IUserManager userManager; protected readonly IToast toast; public CloudServiceClient( ILoggerFactory loggerFactory, + IHttpClientFactory clientFactory, + IHttpPlatformHelper httpPlatformHelper, IUserManager userManager, IToast toast, IOptions options, - IModelValidator validator) : base(loggerFactory.CreateLogger(TAG), userManager, options, validator) + IModelValidator validator) : base( + loggerFactory.CreateLogger(ClientName_), + clientFactory, + httpPlatformHelper, + userManager, + options, + validator) { this.userManager = userManager; this.toast = toast; diff --git a/System.Application.SteamTools.Services.CloudService.Models/Models/AppVersionInfoDTO.cs b/System.Application.SteamTools.Services.CloudService.Models/Models/AppVersionInfoDTO.cs new file mode 100644 index 000000000..42ffeb781 --- /dev/null +++ b/System.Application.SteamTools.Services.CloudService.Models/Models/AppVersionInfoDTO.cs @@ -0,0 +1,44 @@ +using System.Application.Entities; +using MPKey = MessagePack.KeyAttribute; +using MPObject = MessagePack.MessagePackObjectAttribute; + +namespace System.Application.Models +{ + [MPObject] + public class AppVersionInfoDTO : IEntity, IExplicitHasValue + { + [MPKey(0)] + public Guid Id { get; set; } + + /// + /// 版本号 + /// + [MPKey(1)] + public string? Version { get; set; } + + /// + /// 哈希SHA256验证安装包,可选 + /// + [MPKey(2)] + public string? SHA256 { get; set; } + + /// + /// 本次更新描述 + /// + [MPKey(3)] + public string? Description { get; set; } + + /// + /// 下载链接 + /// + [MPKey(4)] + public string? DownloadLink { get; set; } + + bool IExplicitHasValue.ExplicitHasValue() + { + return !string.IsNullOrWhiteSpace(Version) && + !string.IsNullOrWhiteSpace(Description) && + !string.IsNullOrWhiteSpace(DownloadLink); + } + } +} \ No newline at end of file diff --git a/System.Application.SteamTools.Services.CloudService/Models/ICloudServiceSettings.cs b/System.Application.SteamTools.Services.CloudService/Models/ICloudServiceSettings.cs index 590a241f3..9d4272f41 100644 --- a/System.Application.SteamTools.Services.CloudService/Models/ICloudServiceSettings.cs +++ b/System.Application.SteamTools.Services.CloudService/Models/ICloudServiceSettings.cs @@ -1,4 +1,6 @@ -namespace System.Application.Models +using System.Application.Services.CloudService; + +namespace System.Application.Models { public interface ICloudServiceSettings { diff --git a/System.Application.SteamTools.Services.CloudService/ServiceCollectionExtensions.cs b/System.Application.SteamTools.Services.CloudService/ServiceCollectionExtensions.cs index 9c5b4e2e8..8bf92992e 100644 --- a/System.Application.SteamTools.Services.CloudService/ServiceCollectionExtensions.cs +++ b/System.Application.SteamTools.Services.CloudService/ServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection.Extensions; +using System; using System.Application.Services; using System.Application.Services.CloudService; @@ -16,6 +17,14 @@ namespace Microsoft.Extensions.DependencyInjection public static IServiceCollection TryAddCloudServiceClient(this IServiceCollection services) where T : CloudServiceClientBase { + services.TryAddHttpPlatformHelper(); + services.AddHttpClient(CloudServiceClientBase.ClientName_, (s, c) => + { + var sc = s.GetRequiredService(); + c.BaseAddress = new Uri(sc.ApiBaseUrl); + c.DefaultRequestHeaders.UserAgent.ParseAdd(sc.UserAgent); + c.DefaultRequestHeaders.Add(Constants.HeaderAppVersion, sc.Settings.AppVersion.ToStringN()); + }); services.TryAddSingleton(); services.TryAddSingleton(s => s.GetRequiredService()); services.TryAddSingleton(s => s.GetRequiredService()); diff --git a/System.Application.SteamTools.Services.CloudService/Services/CloudService/ApiConnection.cs b/System.Application.SteamTools.Services.CloudService/Services/CloudService/ApiConnection.cs index 6fb993c96..11ee1ce45 100644 --- a/System.Application.SteamTools.Services.CloudService/Services/CloudService/ApiConnection.cs +++ b/System.Application.SteamTools.Services.CloudService/Services/CloudService/ApiConnection.cs @@ -21,16 +21,20 @@ namespace System.Application.Services.CloudService internal sealed class ApiConnection : IApiConnection { readonly ILogger logger; - readonly HttpClient client; + readonly IHttpPlatformHelper httpPlatformHelper; readonly IApiConnectionPlatformHelper helper; readonly Lazy jsonSerializer = new Lazy(() => new JsonSerializer()); readonly IModelValidator validator; - public ApiConnection(ILogger logger, HttpClient client, IApiConnectionPlatformHelper helper, IModelValidator validator) + public ApiConnection( + ILogger logger, + IApiConnectionPlatformHelper helper, + IHttpPlatformHelper httpPlatformHelper, + IModelValidator validator) { this.logger = logger; - this.client = client; this.helper = helper; + this.httpPlatformHelper = httpPlatformHelper; this.validator = validator; } @@ -180,7 +184,7 @@ namespace System.Application.Services.CloudService } if (needHandle) { - var result = helper.TryHandleUploadFile(stream, uploadFile.UploadFileType); + var result = httpPlatformHelper.TryHandleUploadFile(stream); if (!result.HasValue) // 处理失败 { ThrowUnsupportedUploadFileMediaType(); @@ -402,6 +406,7 @@ namespace System.Application.Services.CloudService cancellationToken), }; await SetRequestHeaderAuthorization(request); + var client = helper.CreateClient(); using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken) @@ -489,6 +494,7 @@ namespace System.Application.Services.CloudService { using var request = new HttpRequestMessage(method, requestUri); await SetRequestHeaderAuthorization(request); + var client = helper.CreateClient(); using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken) diff --git a/System.Application.SteamTools.Services.CloudService/Services/CloudService/Clients/Abstractions/IVersionClient.cs b/System.Application.SteamTools.Services.CloudService/Services/CloudService/Clients/Abstractions/IVersionClient.cs new file mode 100644 index 000000000..9b61a609e --- /dev/null +++ b/System.Application.SteamTools.Services.CloudService/Services/CloudService/Clients/Abstractions/IVersionClient.cs @@ -0,0 +1,25 @@ +using System.Application.Models; +using System.Threading.Tasks; + +namespace System.Application.Services.CloudService.Clients.Abstractions +{ + public interface IVersionClient + { + /// + /// 检查更新 + /// + /// + /// + /// + /// + /// + /// + /// + Task> CheckUpdate(Guid id, + Platform platform, + DeviceIdiom deviceIdiom, + CPUABI.Value supportedAbis, + int major, + int minor); + } +} \ No newline at end of file diff --git a/System.Application.SteamTools.Services.CloudService/Services/CloudService/Clients/VersionClient.cs b/System.Application.SteamTools.Services.CloudService/Services/CloudService/Clients/VersionClient.cs new file mode 100644 index 000000000..d6cf9df5c --- /dev/null +++ b/System.Application.SteamTools.Services.CloudService/Services/CloudService/Clients/VersionClient.cs @@ -0,0 +1,31 @@ +using System.Application.Models; +using System.Application.Services.CloudService.Clients.Abstractions; +using System.Net.Http; +using System.Threading.Tasks; + +namespace System.Application.Services.CloudService.Clients +{ + internal sealed class VersionClient : ApiClient, IVersionClient + { + public VersionClient(IApiConnection conn) : base(conn) + { + } + + public Task> CheckUpdate( + Guid id, + Platform platform, + DeviceIdiom deviceIdiom, + CPUABI.Value supportedAbis, + int major, + int minor) + { + var url = + $"/version/{id}/{(int)platform}/{(int)deviceIdiom}/{(int)supportedAbis}/{major}/{minor}"; + return conn.SendAsync( + method: HttpMethod.Get, + requestUri: url, + cancellationToken: default, + responseContentMaybeNull: true); + } + } +} \ No newline at end of file diff --git a/System.Application.SteamTools.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs b/System.Application.SteamTools.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs index b86a98208..b6310d85e 100644 --- a/System.Application.SteamTools.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs +++ b/System.Application.SteamTools.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs @@ -4,61 +4,61 @@ using System.Application.Columns; using System.Application.Models; using System.Application.Services.CloudService.Clients; using System.Application.Services.CloudService.Clients.Abstractions; -using System.IO; using System.Net.Http; using System.Threading.Tasks; namespace System.Application.Services.CloudService { - public abstract class CloudServiceClientBase : ICloudServiceClient, IApiConnectionPlatformHelper + public abstract class CloudServiceClientBase : HttpService, ICloudServiceClient, IApiConnectionPlatformHelper { - //const string DefaultApiBaseUrl = Constants.Prefix_HTTPS + "api.待定.com"; - static string DefaultApiBaseUrl => throw new NotImplementedException(); + public const string ClientName_ = "CloudServiceClient"; + internal const string DefaultApiBaseUrl = Constants.Prefix_HTTPS + "api.steamtool.net"; #region Clients public IAccountClient Account { get; } public IAuthMessageClient AuthMessage { get; } + public IVersionClient Version { get; } #endregion - protected readonly ILogger logger; readonly ApiConnection connection; + protected readonly ICloudServiceSettings settings; protected readonly IAuthHelper authHelper; + protected readonly IHttpPlatformHelper httpPlatformHelper; public string ApiBaseUrl { get; } + internal ICloudServiceSettings Settings => settings; + + protected sealed override string? ClientName => ClientName_; + public CloudServiceClientBase( ILogger logger, + IHttpClientFactory clientFactory, + IHttpPlatformHelper httpPlatformHelper, IAuthHelper authHelper, IOptions options, - IModelValidator validator) + IModelValidator validator) : base(logger, clientFactory) { - this.logger = logger; this.authHelper = authHelper; - var client = CreateHttpClient(); - ApiBaseUrl = string.IsNullOrWhiteSpace(options.Value.ApiBaseUrl) ? DefaultApiBaseUrl : options.Value.ApiBaseUrl; - client.BaseAddress = new Uri(ApiBaseUrl); - client.DefaultRequestHeaders.UserAgent.ParseAdd(UserAgent); - client.DefaultRequestHeaders.Add(Constants.HeaderAppVersion, - options.Value.AppVersion.ToStringN()); - connection = new ApiConnection(logger, client, this, validator); + this.httpPlatformHelper = httpPlatformHelper; + settings = options.Value; + ApiBaseUrl = string.IsNullOrWhiteSpace(settings.ApiBaseUrl) + ? DefaultApiBaseUrl : settings.ApiBaseUrl; + connection = new ApiConnection(logger, this, httpPlatformHelper, validator); #region SetClients Account = new AccountClient(connection); AuthMessage = new AuthMessageClient(connection); + Version = new VersionClient(connection); #endregion } - protected virtual HttpClient CreateHttpClient() => new HttpClient(); - - /// - /// 用户代理 - /// https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/User-Agent - /// - protected virtual string UserAgent => Constants.DefaultUserAgent; + /// + internal string UserAgent => httpPlatformHelper.UserAgent; IAuthHelper IApiConnectionPlatformHelper.Auth => authHelper; @@ -68,6 +68,6 @@ namespace System.Application.Services.CloudService public abstract void ShowResponseErrorMessage(string message); - public abstract (string filePath, string mime)? TryHandleUploadFile(Stream imageFileStream, UploadFileType uploadFileType); + HttpClient IApiConnectionPlatformHelper.CreateClient() => CreateClient(); } } \ No newline at end of file diff --git a/System.Application.SteamTools.Services.CloudService/Services/CloudService/IApiConnectionPlatformHelper.cs b/System.Application.SteamTools.Services.CloudService/Services/CloudService/IApiConnectionPlatformHelper.cs index 2d43a9b55..b6242d930 100644 --- a/System.Application.SteamTools.Services.CloudService/Services/CloudService/IApiConnectionPlatformHelper.cs +++ b/System.Application.SteamTools.Services.CloudService/Services/CloudService/IApiConnectionPlatformHelper.cs @@ -1,6 +1,6 @@ using System.Application.Columns; using System.Application.Models; -using System.IO; +using System.Net.Http; using System.Threading.Tasks; namespace System.Application.Services.CloudService @@ -32,11 +32,6 @@ namespace System.Application.Services.CloudService /// void ShowResponseErrorMessage(string message); - /// - /// 尝试将需要[上传的文件流]处理(文件压缩,格式转换[heic->png],由客户端平台原生实现)保存到临时路径中并返回信息 - /// - /// - /// - (string filePath, string mime)? TryHandleUploadFile(Stream imageFileStream, UploadFileType uploadFileType); + HttpClient CreateClient(); } -} +} \ No newline at end of file diff --git a/System.Application.SteamTools.Services.CloudService/Services/ICloudServiceClient.cs b/System.Application.SteamTools.Services.CloudService/Services/ICloudServiceClient.cs index 21a94eadc..d4be445cf 100644 --- a/System.Application.SteamTools.Services.CloudService/Services/ICloudServiceClient.cs +++ b/System.Application.SteamTools.Services.CloudService/Services/ICloudServiceClient.cs @@ -7,5 +7,7 @@ namespace System.Application.Services IAccountClient Account { get; } IAuthMessageClient AuthMessage { get; } + + IVersionClient Version { get; } } } \ No newline at end of file diff --git a/System.Application.SteamTools/ReleaseType.cs b/System.Application.SteamTools/ReleaseType.cs index b0efff0c2..a0f23ba59 100644 --- a/System.Application.SteamTools/ReleaseType.cs +++ b/System.Application.SteamTools/ReleaseType.cs @@ -4,59 +4,61 @@ /// 发行版本类型 /// 枚举常量命名参考:https://dotnet.microsoft.com/download/dotnet/5.0 /// + [Flags] + [Obsolete] public enum ReleaseType { /// /// Windows 64 bit /// - Windows_x64, + Windows_x64 = 4, /// /// Windows 32 bit /// - Windows_x86, + Windows_x86 = 8, /// /// Windows平台下当用户不知道是否运行的64位系统时推荐使用此版本(不兼容),可通过后续更新到 或 /// - Windows_Any, + Windows_Any = Windows_x64 | Windows_x86, /// /// Windows ARM 64 bit /// 例如设备:Surface Pro X /// - Windows_Arm64, + Windows_Arm64 = 16, /// /// 使用 Intel 的 Mac 设备 /// - macOS_x64, + macOS_x64 = 32, /// /// 使用 Apple Silicon 的 Mac 设备 /// - macOS_Arm64, + macOS_Arm64 = 64, /// /// Linux 64 bit /// - Linux_x64, + Linux_x64 = 128, /// /// Apple (iPhone / iPad / iPod touch) /// - iOS, + iOS = 256, /// /// Android arm64-v8a /// 例如高通骁龙808,810等2015年后发布的Soc /// - Android_Arm64, + Android_Arm64 = 512, /// /// Android armeabi-v7a /// 安卓平台下当用户不知道是否运行的64位系统时推荐使用此版本,可通过后续更新到 /// - Android_Arm32, + Android_Arm32 = 1024, } } \ No newline at end of file diff --git a/System.Common.ClientLib.Droid/AndroidABI.cs b/System.Common.CoreLib/CPUABI.cs similarity index 90% rename from System.Common.ClientLib.Droid/AndroidABI.cs rename to System.Common.CoreLib/CPUABI.cs index 72f8ee701..eb7bf595f 100644 --- a/System.Common.ClientLib.Droid/AndroidABI.cs +++ b/System.Common.CoreLib/CPUABI.cs @@ -4,45 +4,46 @@ using System.Linq; namespace System { /// - /// 不同的 Android 设备使用不同的 CPU,而不同的 CPU 支持不同的指令集。 + /// CPU 构架,例如 x86、arm 等 + /// 例如不同的 Android 设备使用不同的 CPU,而不同的 CPU 支持不同的指令集。 /// CPU 与指令集的每种组合都有专属的应用二进制接口 (ABI)。 /// https://developer.android.google.cn/ndk/guides/abis.html /// 在比较版本支持的值与设备支持的值中的交集中,值越大的,优先选取。 /// - public static class AndroidABI + public static class CPUABI { - /// + /// [Flags] public enum Value { [Obsolete("Deprecated")] - ARM = 0x1, + ARM = 4, [Obsolete("Deprecated")] - MIPS = 0x2, + MIPS = 8, /// /// https://developer.android.google.cn/ndk/guides/abis.html#x86 /// - X86 = 0x4, + X86 = 16, /// /// https://developer.android.google.cn/ndk/guides/abis.html#v7a /// - ARM32 = 0x8, + ARM32 = 32, [Obsolete("Deprecated")] - MIPS64 = 0x10, + MIPS64 = 64, /// /// https://developer.android.google.cn/ndk/guides/abis.html#86-64 /// - X64 = 0x20, + X64 = 128, /// /// https://developer.android.google.cn/ndk/guides/abis.html#arm64-v8a /// - ARM64 = 0x40, + ARM64 = 256, } static readonly IReadOnlyDictionary mapping = new Dictionary diff --git a/System.Common.CoreLib/DeviceIdiom.cs b/System.Common.CoreLib/DeviceIdiom.cs index 7ec09e688..adf66d4d5 100644 --- a/System.Common.CoreLib/DeviceIdiom.cs +++ b/System.Common.CoreLib/DeviceIdiom.cs @@ -6,6 +6,7 @@ namespace System /// /// 设备种类,例如手机,平板,电视,手表 /// + [Flags] public enum DeviceIdiom { /// @@ -16,27 +17,27 @@ namespace System /// /// 手机 /// - Phone, + Phone = 4, /// /// 平板 /// - Tablet, + Tablet = 8, /// /// 桌面端 /// - Desktop, + Desktop = 16, /// /// 电视 /// - TV, + TV = 32, /// /// 手表 /// - Watch, + Watch = 64, } /// diff --git a/System.Common.CoreLib/Enum2.cs b/System.Common.CoreLib/Enum2.cs index b6a630929..3909750d7 100644 --- a/System.Common.CoreLib/Enum2.cs +++ b/System.Common.CoreLib/Enum2.cs @@ -1,4 +1,6 @@ -using System.Linq.Expressions; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; namespace System { @@ -11,6 +13,15 @@ namespace System /// public static TEnum[] GetAll() where TEnum : Enum => (TEnum[])Enum.GetValues(typeof(TEnum)); + /// + /// 将 Flags 枚举进行拆分 + /// + /// + /// + /// + public static IEnumerable FlagsSplit(TEnum resultant) where TEnum : Enum + => GetAll().Where(x => resultant.HasFlag(x)).ToArray(); + internal static TEnum ConvertToEnum(this TStruct value) { var parameter = Expression.Parameter(typeof(TStruct)); diff --git a/System.Common.CoreLib/Net/Http/HttpPlatformHelper.cs b/System.Common.CoreLib/Net/Http/HttpPlatformHelper.cs new file mode 100644 index 000000000..04b7614be --- /dev/null +++ b/System.Common.CoreLib/Net/Http/HttpPlatformHelper.cs @@ -0,0 +1,14 @@ +using System.IO; + +namespace System.Net.Http +{ + /// + public class HttpPlatformHelper : IHttpPlatformHelper + { + const string DefaultUserAgent = "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263"; + + public virtual string UserAgent => DefaultUserAgent; + + public (string filePath, string mime)? TryHandleUploadFile(Stream fileStream) => null; + } +} \ No newline at end of file diff --git a/System.Common.CoreLib/Net/Http/HttpService.cs b/System.Common.CoreLib/Net/Http/HttpService.cs new file mode 100644 index 000000000..bb5c16efb --- /dev/null +++ b/System.Common.CoreLib/Net/Http/HttpService.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.Logging; + +namespace System.Net.Http +{ + public abstract class HttpService + { + protected readonly ILogger logger; + readonly IHttpClientFactory _clientFactory; + + public HttpService( + ILogger logger, + IHttpClientFactory clientFactory) + { + this.logger = logger; + _clientFactory = clientFactory; + } + + /// + /// 用于 中传递的 name + /// 如果为 则调用 + /// 默认值为 + /// + protected virtual string? ClientName { get; } + + protected virtual HttpClient CreateClient() + { +#if DEBUG + logger.LogDebug("CreateClient, name: {0}", ClientName); +#endif + if (ClientName == null) + { + return _clientFactory.CreateClient(); + } + else + { + return _clientFactory.CreateClient(ClientName); + } + } + } +} \ No newline at end of file diff --git a/System.Common.CoreLib/Net/Http/IHttpPlatformHelper.cs b/System.Common.CoreLib/Net/Http/IHttpPlatformHelper.cs new file mode 100644 index 000000000..c57aebe6a --- /dev/null +++ b/System.Common.CoreLib/Net/Http/IHttpPlatformHelper.cs @@ -0,0 +1,26 @@ +using System.IO; + +namespace System.Net.Http +{ + /// + /// 由平台实现的HTTP工具助手 + /// + public interface IHttpPlatformHelper + { + /// + /// 用户代理 + /// https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/User-Agent + /// 通常可以从平台的WebView控件中调用js获取 + /// + string UserAgent { get; } + + /// + /// 尝试将需要上传的文件流[处理]后保存到临时路径中并返回信息 + /// [处理]由客户端平台原生实现 + /// 例如:文件压缩、格式转换(heic) + /// + /// + /// + (string filePath, string mime)? TryHandleUploadFile(Stream fileStream); + } +} \ No newline at end of file diff --git a/System.Common.CoreLib/Platform.cs b/System.Common.CoreLib/Platform.cs index d1c688398..11569fa7d 100644 --- a/System.Common.CoreLib/Platform.cs +++ b/System.Common.CoreLib/Platform.cs @@ -6,6 +6,7 @@ namespace System /// /// 平台 /// + [Flags] public enum Platform { /// @@ -16,22 +17,22 @@ namespace System /// /// Microsoft Windows / UWP(Universal Windows Platform) /// - Windows, + Windows = 4, /// /// Ubuntu / Debian / CentOS / Tizen /// - Linux, + Linux = 8, /// /// Android Phone / Android Pad / WearOS(Android Wear) / Android TV /// - Android, + Android = 16, /// /// iOS / iPadOS / watchOS / tvOS / macOS /// - Apple, + Apple = 32, } /// diff --git a/System.Common.CoreLib/ServiceCollectionExtensions.cs b/System.Common.CoreLib/ServiceCollectionExtensions.cs index 8a6ee7c05..eacbe9600 100644 --- a/System.Common.CoreLib/ServiceCollectionExtensions.cs +++ b/System.Common.CoreLib/ServiceCollectionExtensions.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using System.Application.Services; using System.Application.Services.Implementation; +using System.Net.Http; // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection @@ -17,5 +18,24 @@ namespace Microsoft.Extensions.DependencyInjection services.TryAddSingleton(); return services; } + + /// + /// 尝试添加 + /// + /// + /// + public static IServiceCollection TryAddHttpPlatformHelper(this IServiceCollection services) + { + services.TryAddSingleton(); + return services; + } + + //public static IServiceCollection AddHttpService(this IServiceCollection services, string name) + //{ + // // 此函数为添加HTTP服务模板 + // // https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0 + // services.AddHttpClient(name); + // services.AddSingleton(); + //} } } \ No newline at end of file diff --git a/System.Common.CoreLib/System.Common.CoreLib.csproj b/System.Common.CoreLib/System.Common.CoreLib.csproj index 0b2b008ac..1f64c54fd 100644 --- a/System.Common.CoreLib/System.Common.CoreLib.csproj +++ b/System.Common.CoreLib/System.Common.CoreLib.csproj @@ -7,6 +7,7 @@ + diff --git a/resources/screenshots.jpg b/resources/screenshots.jpg index 9cb41783b..ff640e2e4 100644 Binary files a/resources/screenshots.jpg and b/resources/screenshots.jpg differ