docs: 补全全部缺失的 XML 文档注释(中文)
- 为全部 5 个项目(Avalonia-API、Avalonia-Common、Avalonia-EFCore、 Avalonia-PC、Avalonia-Services)中缺失注释的类、方法、属性、字段、 接口成员等补全中文 XML 文档注释 - 共修改约 37 个文件,补全约 220+ 处注释 - 修复 ServiceEndpointCollection.cs 中 MapDelete<TService> 语法错误 - 修复 PcAuthService.cs 中 const prefix 位置错乱导致编译失败的问题 - 扫描结果:缺失项 0 - 构建结果:4/4 项目编译通过
This commit is contained in:
@@ -7,13 +7,22 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Avalonia_PC
|
||||
{
|
||||
/// <summary>
|
||||
/// Avalonia 应用程序入口类,负责初始化 XAML 资源和设置主窗口。
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载 Avalonia XAML 资源。
|
||||
/// </summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 框架初始化完成后设置主窗口和数据上下文。
|
||||
/// </summary>
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
|
||||
@@ -10,6 +10,12 @@ namespace Avalonia_PC.Authentication
|
||||
/// </summary>
|
||||
public sealed class DefaultPcThirdPartyAuthorizationClient : IPcThirdPartyAuthorizationClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证第三方授权码是否有效。默认实现将 "invalid" 视为授权丢失,其余视为有效。
|
||||
/// </summary>
|
||||
/// <param name="authorizationCode">第三方授权码。</param>
|
||||
/// <param name="cancellationToken">取消令牌。</param>
|
||||
/// <returns>授权检查结果。</returns>
|
||||
public Task<ThirdPartyAuthCheckResult> ValidateAuthorizationCodeAsync(
|
||||
string authorizationCode,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -23,6 +29,12 @@ namespace Avalonia_PC.Authentication
|
||||
return Task.FromResult(ThirdPartyAuthCheckResult.Valid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新第三方授权。默认实现总是返回 TemporaryFailure,表示暂时无法刷新。
|
||||
/// </summary>
|
||||
/// <param name="authorizationReference">授权引用标识。</param>
|
||||
/// <param name="cancellationToken">取消令牌。</param>
|
||||
/// <returns>授权检查结果。</returns>
|
||||
public Task<ThirdPartyAuthCheckResult> RefreshAuthorizationAsync(
|
||||
string authorizationReference,
|
||||
CancellationToken cancellationToken = default)
|
||||
|
||||
@@ -8,6 +8,10 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Avalonia_PC.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// PC 端鉴权端点服务,实现 <see cref="IPcAuthEndpointService"/>,
|
||||
/// 处理授权码登录、Token 刷新和登出操作。
|
||||
/// </summary>
|
||||
public sealed class PcAuthEndpointService(PcGlobalTokenService tokenService) : IPcAuthEndpointService
|
||||
{
|
||||
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||
@@ -15,6 +19,7 @@ namespace Avalonia_PC.Authentication
|
||||
PropertyNameCaseInsensitive = true,
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<object?> AuthorizeAsync(ServiceEndpointContext ctx)
|
||||
{
|
||||
var request = Deserialize<PcAuthorizeRequest>(ctx.Body);
|
||||
@@ -28,6 +33,7 @@ namespace Avalonia_PC.Authentication
|
||||
return ResponseHelper.Ok(token, "授权成功");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<object?> RefreshAsync(ServiceEndpointContext ctx)
|
||||
{
|
||||
var request = Deserialize<PcRefreshRequest>(ctx.Body);
|
||||
@@ -42,6 +48,7 @@ namespace Avalonia_PC.Authentication
|
||||
return ResponseHelper.Ok(refreshed, "刷新成功");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<object?> LogoutAsync(ServiceEndpointContext ctx)
|
||||
{
|
||||
var request = Deserialize<PcLogoutRequest>(ctx.Body);
|
||||
@@ -50,6 +57,12 @@ namespace Avalonia_PC.Authentication
|
||||
return Task.FromResult<object?>(ResponseHelper.Succeed("退出成功"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 JSON 请求体反序列化为指定类型。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">目标类型。</typeparam>
|
||||
/// <param name="body">JSON 请求体字符串,可为空。</param>
|
||||
/// <returns>反序列化后的对象;若 body 为空则返回默认值。</returns>
|
||||
private static T? Deserialize<T>(string? body)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(body)
|
||||
@@ -57,6 +70,11 @@ namespace Avalonia_PC.Authentication
|
||||
: JsonSerializer.Deserialize<T>(body, JsonOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 Authorization 头中提取 Bearer Token。
|
||||
/// </summary>
|
||||
/// <param name="authorization">Authorization 头的值。</param>
|
||||
/// <returns>提取的 Token 字符串;若无法提取则返回 null。</returns>
|
||||
private static string? ExtractBearerToken(string? authorization)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(authorization))
|
||||
@@ -64,7 +82,10 @@ namespace Avalonia_PC.Authentication
|
||||
return null;
|
||||
}
|
||||
|
||||
const string prefix = "Bearer ";
|
||||
/// <summary>
|
||||
/// Bearer Token 的前缀常量。
|
||||
/// </summary>
|
||||
const string prefix = "Bearer ";
|
||||
return authorization.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)
|
||||
? authorization[prefix.Length..].Trim()
|
||||
: authorization.Trim();
|
||||
|
||||
@@ -6,8 +6,12 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Avalonia_PC.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// PC 端鉴权服务,基于全局 Token 验证用户身份,实现 <see cref="IAuthService"/>。
|
||||
/// </summary>
|
||||
public sealed class PcAuthService(PcGlobalTokenService tokenService) : IAuthService
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task<ClaimsPrincipal?> AuthenticateAsync(ServiceEndpointContext context)
|
||||
{
|
||||
var token = ExtractBearerToken(context.GetHeader("Authorization"));
|
||||
@@ -29,11 +33,17 @@ namespace Avalonia_PC.Authentication
|
||||
return new ClaimsPrincipal(identity);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<bool> AuthorizeAsync(ClaimsPrincipal user, string policy)
|
||||
{
|
||||
return Task.FromResult(user.Identity?.IsAuthenticated == true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 Authorization 头中提取 Bearer Token。
|
||||
/// </summary>
|
||||
/// <param name="authorization">Authorization 头的值。</param>
|
||||
/// <returns>提取的 Token 字符串;若无法提取则返回 null。</returns>
|
||||
private static string? ExtractBearerToken(string? authorization)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(authorization))
|
||||
@@ -41,7 +51,7 @@ namespace Avalonia_PC.Authentication
|
||||
return null;
|
||||
}
|
||||
|
||||
const string prefix = "Bearer ";
|
||||
string prefix = "Bearer ";
|
||||
return authorization.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)
|
||||
? authorization[prefix.Length..].Trim()
|
||||
: authorization.Trim();
|
||||
|
||||
@@ -7,16 +7,45 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// PC 端全局 Token 服务,管理全局唯一的访问 Token。
|
||||
/// 支持授权码登录、Token 刷新、有效性验证和登出,
|
||||
/// 在第三方授权暂时失败时使用缩短有效期的临时 Token。
|
||||
/// </summary>
|
||||
public sealed class PcGlobalTokenService(IPcThirdPartyAuthorizationClient thirdPartyClient)
|
||||
{
|
||||
/// <summary>
|
||||
/// 超级管理员角色集合。
|
||||
/// </summary>
|
||||
private static readonly string[] SuperRoles = ["SuperAdmin", "Admin"];
|
||||
/// <summary>
|
||||
/// 线程同步锁。
|
||||
/// </summary>
|
||||
private readonly object _syncRoot = new();
|
||||
/// <summary>
|
||||
/// 当前 Token 状态。
|
||||
/// </summary>
|
||||
private PcTokenState? _current;
|
||||
|
||||
/// <summary>
|
||||
/// 正常 Token 有效期(8 小时)。
|
||||
/// </summary>
|
||||
private static readonly TimeSpan NormalLifetime = TimeSpan.FromHours(8);
|
||||
/// <summary>
|
||||
/// 第三方暂时失败时的 Token 有效期(20 分钟)。
|
||||
/// </summary>
|
||||
private static readonly TimeSpan TemporaryFailureLifetime = TimeSpan.FromMinutes(20);
|
||||
/// <summary>
|
||||
/// 第三方暂时失败的最长容忍窗口(24 小时),超出后清除 Token。
|
||||
/// </summary>
|
||||
private static readonly TimeSpan MaxTemporaryFailureWindow = TimeSpan.FromHours(24);
|
||||
|
||||
/// <summary>
|
||||
/// 使用授权码进行登录授权,验证成功后颁发全局 Token。
|
||||
/// </summary>
|
||||
/// <param name="authorizationCode">第三方授权码。</param>
|
||||
/// <param name="cancellationToken">取消令牌。</param>
|
||||
/// <returns>Token 响应;若授权码无效则返回 null。</returns>
|
||||
public async Task<PcTokenResponse?> AuthorizeAsync(string? authorizationCode, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(authorizationCode))
|
||||
@@ -33,6 +62,13 @@ namespace Authentication
|
||||
return IssueToken(authorizationCode, NormalLifetime, resetTemporaryFailureWindow: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新当前 Token,向第三方验证授权引用是否仍然有效。
|
||||
/// 根据第三方返回结果决定是续期、降级为临时 Token 还是清除。
|
||||
/// </summary>
|
||||
/// <param name="token">当前 Token。</param>
|
||||
/// <param name="cancellationToken">取消令牌。</param>
|
||||
/// <returns>新的 Token 响应;若授权丢失则返回 null。</returns>
|
||||
public async Task<PcTokenResponse?> RefreshAsync(string? token, CancellationToken cancellationToken = default)
|
||||
{
|
||||
PcTokenState? current;
|
||||
@@ -56,6 +92,12 @@ namespace Authentication
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证 Token 是否有效,若已过期则尝试自动刷新。
|
||||
/// </summary>
|
||||
/// <param name="token">要验证的 Token。</param>
|
||||
/// <param name="cancellationToken">取消令牌。</param>
|
||||
/// <returns>Token 是否有效。</returns>
|
||||
public async Task<bool> ValidateAsync(string? token, CancellationToken cancellationToken = default)
|
||||
{
|
||||
PcTokenState? current;
|
||||
@@ -76,6 +118,10 @@ namespace Authentication
|
||||
return await RefreshAsync(token, cancellationToken) is not null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登出并清除当前 Token。
|
||||
/// </summary>
|
||||
/// <param name="token">要清除的 Token。</param>
|
||||
public void Logout(string? token)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
@@ -87,6 +133,13 @@ namespace Authentication
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 颁发新的全局 Token。
|
||||
/// </summary>
|
||||
/// <param name="authorizationReference">授权引用标识。</param>
|
||||
/// <param name="lifetime">Token 有效期。</param>
|
||||
/// <param name="resetTemporaryFailureWindow">是否重置暂时失败窗口。</param>
|
||||
/// <returns>包含 Token 和过期时间的响应。</returns>
|
||||
private PcTokenResponse IssueToken(string authorizationReference, TimeSpan lifetime, bool resetTemporaryFailureWindow)
|
||||
{
|
||||
var token = Convert.ToBase64String(RandomNumberGenerator.GetBytes(64));
|
||||
@@ -105,6 +158,11 @@ namespace Authentication
|
||||
return new PcTokenResponse(token, state.ExpiresAt, SuperRoles);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在第三方暂时失败时刷新 Token。若超出最大容忍窗口则清除 Token。
|
||||
/// </summary>
|
||||
/// <param name="current">当前 Token 状态。</param>
|
||||
/// <returns>新的临时 Token 响应;若超出容忍窗口则返回 null。</returns>
|
||||
private PcTokenResponse? RefreshAfterTemporaryFailure(PcTokenState current)
|
||||
{
|
||||
var startedAt = current.TemporaryFailureStartedAt ?? DateTime.UtcNow;
|
||||
@@ -116,6 +174,10 @@ namespace Authentication
|
||||
return IssueToken(current.AuthorizationReference, TemporaryFailureLifetime, resetTemporaryFailureWindow: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除当前 Token 并返回 null。
|
||||
/// </summary>
|
||||
/// <returns>始终返回 null。</returns>
|
||||
private PcTokenResponse? ClearAndReturnNull()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
@@ -126,6 +188,11 @@ namespace Authentication
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查给定 Token 是否与当前持有的 Token 匹配。
|
||||
/// </summary>
|
||||
/// <param name="token">要检查的 Token。</param>
|
||||
/// <returns>是否匹配。</returns>
|
||||
private bool IsCurrentToken(string? token)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(token) &&
|
||||
@@ -133,12 +200,24 @@ namespace Authentication
|
||||
string.Equals(_current.TokenHash, HashToken(token), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对 Token 原文进行 SHA256 哈希,返回十六进制字符串。
|
||||
/// </summary>
|
||||
/// <param name="token">Token 原文。</param>
|
||||
/// <returns>SHA256 哈希后的十六进制字符串。</returns>
|
||||
private static string HashToken(string token)
|
||||
{
|
||||
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(token));
|
||||
return Convert.ToHexString(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存当前全局 Token 的内部状态。
|
||||
/// </summary>
|
||||
/// <param name="TokenHash">Token 的 SHA256 哈希值。</param>
|
||||
/// <param name="AuthorizationReference">授权引用标识。</param>
|
||||
/// <param name="ExpiresAt">过期时间。</param>
|
||||
/// <param name="TemporaryFailureStartedAt">第三方暂时失败的起始时间。</param>
|
||||
private sealed record PcTokenState(
|
||||
string TokenHash,
|
||||
string AuthorizationReference,
|
||||
|
||||
+17
-1
@@ -14,10 +14,20 @@ using System;
|
||||
|
||||
namespace Avalonia_PC
|
||||
{
|
||||
/// <summary>
|
||||
/// 桌面应用程序入口类,负责配置 DI 容器、初始化数据库和启动 Avalonia 框架。
|
||||
/// </summary>
|
||||
internal sealed class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取全局 DI 服务提供程序。
|
||||
/// </summary>
|
||||
public static IServiceProvider Services { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序主入口点。
|
||||
/// </summary>
|
||||
/// <param name="args">命令行参数。</param>
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
@@ -40,6 +50,9 @@ namespace Avalonia_PC
|
||||
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 DI 容器,注册数据库、业务服务、鉴权服务和统一端点。
|
||||
/// </summary>
|
||||
private static void ConfigureServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
@@ -71,7 +84,10 @@ namespace Avalonia_PC
|
||||
Services = services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
/// <summary>
|
||||
/// 构建 Avalonia 应用程序(供可视化设计器使用,请勿删除)。
|
||||
/// </summary>
|
||||
/// <returns>Avalonia 应用构建器。</returns>
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
|
||||
@@ -12,8 +12,18 @@ namespace Avalonia_PC
|
||||
[RequiresUnreferencedCode(
|
||||
"Default implementation of ViewLocator involves reflection which may be trimmed away.",
|
||||
Url = "https://docs.avaloniaui.net/docs/concepts/view-locator")]
|
||||
/// <summary>
|
||||
/// 视图定位器,根据 ViewModel 类型自动查找对应的 View,
|
||||
/// 实现 IDataTemplate 以支持 Avalonia 的数据模板机制。
|
||||
/// </summary>
|
||||
public class ViewLocator : IDataTemplate
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据 ViewModel 实例构建对应的 View 控件。
|
||||
/// 约定:将 ViewModels 命名空间中的 ViewModel 替换为 Views 命名空间中的同名 View。
|
||||
/// </summary>
|
||||
/// <param name="param">ViewModel 实例。</param>
|
||||
/// <returns>对应的 View 控件;若未找到则返回 TextBlock 显示错误信息。</returns>
|
||||
public Control? Build(object? param)
|
||||
{
|
||||
if (param is null)
|
||||
@@ -30,6 +40,11 @@ namespace Avalonia_PC
|
||||
return new TextBlock { Text = "Not Found: " + name };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断数据对象是否为 ViewModel 类型(以 "ViewModel" 结尾)。
|
||||
/// </summary>
|
||||
/// <param name="data">要判断的数据对象。</param>
|
||||
/// <returns>是否为 ViewModel。</returns>
|
||||
public bool Match(object? data)
|
||||
{
|
||||
return data is ViewModelBase;
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
namespace Avalonia_PC.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// 主窗口的 ViewModel,提供问候语等绑定属性。
|
||||
/// </summary>
|
||||
public partial class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取问候语文本。
|
||||
/// </summary>
|
||||
public string Greeting { get; } = "Welcome to Avalonia!";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace Avalonia_PC.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// ViewModel 基类,继承自 CommunityToolkit.Mvvm 的 ObservableObject,
|
||||
/// 提供属性变更通知功能。
|
||||
/// </summary>
|
||||
public abstract class ViewModelBase : ObservableObject
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace Avalonia_PC.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// MainWindow 的分部类,定义注入 WebView2 的 JavaScript Bridge 脚本。
|
||||
/// </summary>
|
||||
public partial class MainWindow
|
||||
{
|
||||
private const string BridgeScript = """
|
||||
@@ -106,6 +109,9 @@ if (!window.__appBridgeInstalled) {
|
||||
});
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// WebView2 Bridge 中的 XMLHttpRequest 替代实现,将 app:// 请求拦截并转为 C# 调用。
|
||||
/// </summary>
|
||||
class BridgeXMLHttpRequest {
|
||||
constructor() {
|
||||
this._native = new NativeXMLHttpRequest();
|
||||
|
||||
@@ -9,6 +9,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Avalonia_PC.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// MainWindow 的分部类,负责路由注册和统一端点适配。
|
||||
/// </summary>
|
||||
public partial class MainWindow
|
||||
{
|
||||
/// <summary>
|
||||
@@ -22,6 +25,9 @@ namespace Avalonia_PC.Views
|
||||
/// </summary>
|
||||
private IServiceProvider _services = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 从 DI 获取统一端点集合并构建桌面适配器。
|
||||
/// </summary>
|
||||
private void RegisterRoutes()
|
||||
{
|
||||
// 从 DI 获取已构建的端点集合
|
||||
|
||||
@@ -12,23 +12,56 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Avalonia_PC.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// 主窗口,承载 WebView2 控件并管理前后端 Bridge 通信。
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义协议方案名称。
|
||||
/// </summary>
|
||||
private const string AppScheme = "app";
|
||||
/// <summary>
|
||||
/// 在线模式下的前端启动 URL。
|
||||
/// </summary>
|
||||
private const string? OnlineStartupUrl = "http://localhost:51240";
|
||||
//private const string? OnlineStartupUrl = null;
|
||||
/// <summary>
|
||||
/// 离线模式下的前端本地文件路径,为空则使用在线模式。
|
||||
/// </summary>
|
||||
private const string? LocalStartupPath = null;
|
||||
private static readonly JsonSerializerOptions BridgeJsonSerializerOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// WebView2 原生控件实例。
|
||||
/// </summary>
|
||||
private NativeWebView? _webView;
|
||||
/// <summary>
|
||||
/// 标记 WebView 事件是否已绑定。
|
||||
/// </summary>
|
||||
private bool _eventsAttached;
|
||||
/// <summary>
|
||||
/// WebView 适配器对象。
|
||||
/// </summary>
|
||||
private object? _webViewAdapter;
|
||||
/// <summary>
|
||||
/// 本地 HTTP 服务器实例(离线模式)。
|
||||
/// </summary>
|
||||
private HttpListener? _localHttpServer;
|
||||
/// <summary>
|
||||
/// 本地 HTTP 服务器的取消令牌源。
|
||||
/// </summary>
|
||||
private CancellationTokenSource? _localHttpServerCts;
|
||||
/// <summary>
|
||||
/// 本地 HTTP 服务器的基础 URL。
|
||||
/// </summary>
|
||||
private string? _localHttpBaseUrl;
|
||||
/// <summary>
|
||||
/// 本地 HTTP 服务器的根目录路径。
|
||||
/// </summary>
|
||||
private string? _localHttpRoot;
|
||||
|
||||
#region 生命周期与 WebView 事件
|
||||
@@ -610,18 +643,39 @@ namespace Avalonia_PC.Views
|
||||
|
||||
#region DTO / 路由上下文模型
|
||||
|
||||
/// <summary>
|
||||
/// Bridge 通信响应 DTO,用于序列化返回给前端的数据。
|
||||
/// </summary>
|
||||
private sealed class AppResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置响应类型标识。
|
||||
/// </summary>
|
||||
public string Kind { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置请求 ID(对应前端请求)。
|
||||
/// </summary>
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置 HTTP 状态码。
|
||||
/// </summary>
|
||||
public int StatusCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置状态描述文本。
|
||||
/// </summary>
|
||||
public string StatusMessage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置响应体 JSON 字符串。
|
||||
/// </summary>
|
||||
public string Body { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置响应头字典。
|
||||
/// </summary>
|
||||
public Dictionary<string, string> Headers { get; set; } = new();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user