迁移到 Ant Design 并优化 DNS 接口

将项目从 Fluent UI 迁移到 Ant Design Blazor:
- 替换 UI 组件,更新样式和脚本。
- 移除 Fluent UI 相关依赖,添加 Ant Design 依赖。

优化 DNS 解析接口:
- 将解析接口从 POST 改为 GET,简化参数结构。
- 更新 `DnsResponse` 和配置文件结构。

数据库模型优化:
- 为 JSON 数据存储添加 `JArray` 映射支持。

初始化逻辑重构:
- 简化 `AutoInit` 初始化逻辑,提升代码可读性。

其他改动:
- 升级依赖包版本。
- 移除无用命名空间和属性。
This commit is contained in:
Megghy
2025-09-25 17:15:57 +08:00
parent 5863336e20
commit b2c648c3e6
14 changed files with 256 additions and 324 deletions

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="zh-cn">
<head>
@@ -7,17 +7,17 @@
<base href="/" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["MegghysAPI.styles.css"]" />
<link rel="stylesheet" href="_content/AntDesign/css/ant-design-blazor.css" />
<ImportMap />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<HeadOutlet />
<script src="_content/Microsoft.FluentUI.AspNetCore.Components/js/loading-theme.js" type="text/javascript"></script>
<loading-theme storage-name="theme"></loading-theme>
</head>
<body>
<Routes />
<FluentDesignTheme StorageName="theme" />
<ConfigProvider>
<Routes />
</ConfigProvider>
<script src="_content/AntDesign/js/ant-design-blazor.js"></script>
<script src="_framework/blazor.web.js"></script>
</body>

View File

@@ -1,26 +1,43 @@
@inherits LayoutComponentBase
@inherits LayoutComponentBase
<FluentLayout>
<FluentHeader>
MegghysAPI
</FluentHeader>
<FluentStack Class="main" Orientation="Orientation.Horizontal" Width="100%">
<NavMenu />
<FluentBodyContent Class="body-content">
<div class="content">
@Body
</div>
</FluentBodyContent>
</FluentStack>
<FluentFooter>
<a href="https://www.fluentui-blazor.net" target="_blank">Documentation and demos</a>
<FluentSpacer />
<a href="https://learn.microsoft.com/en-us/aspnet/core/blazor" target="_blank">About Blazor</a>
</FluentFooter>
</FluentLayout>
<Layout class="app-layout">
<Header class="app-header">
<div class="app-header-title">MegghysAPI</div>
</Header>
<Layout>
<Sider Collapsible="true"
Collapsed="@collapsed"
OnCollapse="HandleCollapse"
Width="220"
Class="app-sider">
<NavMenu InlineCollapsed="@collapsed" />
</Sider>
<Layout>
<Content class="app-content">
<div class="content">
@Body
</div>
</Content>
<Footer class="app-footer">
<a href="https://antblazor.com" target="_blank">Ant Design Blazor 文档</a>
<span class="footer-spacer"></span>
<a href="https://learn.microsoft.com/aspnet/core/blazor" target="_blank">About Blazor</a>
</Footer>
</Layout>
</Layout>
</Layout>
<div id="blazor-error-ui" data-nosnippet>
An unhandled error has occurred.
<a href="." class="reload">Reload</a>
<span class="dismiss">🗙</span>
</div>
@code {
private bool collapsed;
private void HandleCollapse(bool isCollapsed)
{
collapsed = isCollapsed;
}
}

View File

@@ -1,20 +1,80 @@
@rendermode InteractiveServer
@rendermode InteractiveServer
@implements IDisposable
<div class="navmenu">
<input type="checkbox" title="Menu expand/collapse toggle" id="navmenu-toggle" class="navmenu-icon" />
<label for="navmenu-toggle" class="navmenu-icon"><FluentIcon Value="@(new Icons.Regular.Size20.Navigation())" Color="Color.Fill" /></label>
<nav class="sitenav" aria-labelledby="main-menu">
<FluentNavMenu Id="main-menu" Collapsible="true" Width="250" Title="Navigation menu" @bind-Expanded="expanded" CustomToggle="true">
<FluentNavLink Href="/" Match="NavLinkMatch.All" Icon="@(new Icons.Regular.Size20.Home())" IconColor="Color.Accent">Home</FluentNavLink>
<FluentNavLink Href="pixiv" Icon="@(new Icons.Regular.Size20.NumberSymbolSquare())" IconColor="Color.Accent">Pixiv</FluentNavLink>
<FluentNavLink Href="weather" Icon="@(new Icons.Regular.Size20.WeatherPartlyCloudyDay())" IconColor="Color.Accent">Weather</FluentNavLink>
</FluentNavMenu>
</nav>
<FluentDesignTheme @bind-Mode="@Mode" @bind-OfficeColor="@OfficeColor" StorageName="theme" />
</div>
<Menu Mode="MenuMode.Inline"
Theme="MenuTheme.Dark"
InlineCollapsed="@InlineCollapsed"
SelectedKeys="@selectedKeys"
OnMenuItemClicked="HandleMenuClick"
Class="app-menu">
<MenuItem Key="/">
<Icon Type="IconType.OutlineHome" />
<span>Home</span>
</MenuItem>
<MenuItem Key="pixiv">
<Icon Type="IconType.OutlinePicture" />
<span>Pixiv</span>
</MenuItem>
<MenuItem Key="weather">
<Icon Type="IconType.OutlineCloud" />
<span>Weather</span>
</MenuItem>
</Menu>
@code {
private bool expanded = true;
public DesignThemeModes Mode { get; set; }
public OfficeColor? OfficeColor { get; set; }
[Parameter]
public bool InlineCollapsed { get; set; }
private string[] selectedKeys = ["/"];
[Inject]
private NavigationManager NavigationManager { get; set; } = default!;
protected override void OnParametersSet()
{
UpdateSelectedKeys(NavigationManager.Uri);
}
protected override void OnInitialized()
{
UpdateSelectedKeys(NavigationManager.Uri);
NavigationManager.LocationChanged += HandleLocationChanged;
}
private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
{
UpdateSelectedKeys(e.Location);
StateHasChanged();
}
private void UpdateSelectedKeys(string uri)
{
var relative = NavigationManager.ToBaseRelativePath(uri);
if (string.IsNullOrEmpty(relative))
{
selectedKeys = ["/"];
}
else
{
var key = relative.Split('/', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ?? string.Empty;
selectedKeys = [key];
}
}
private void HandleMenuClick(MenuItem menuItem)
{
if (menuItem.Key is null)
{
return;
}
selectedKeys = [menuItem.Key];
var target = menuItem.Key == "/" ? "/" : $"/{menuItem.Key}";
NavigationManager.NavigateTo(target);
}
public void Dispose()
{
NavigationManager.LocationChanged -= HandleLocationChanged;
}
}

View File

@@ -1,21 +0,0 @@
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<div role="status" style="padding-bottom: 1em;">
Current count: <FluentBadge Appearance="Appearance.Neutral">@currentCount</FluentBadge>
</div>
<FluentButton Appearance="Appearance.Accent" @onclick="IncrementCount">Click me</FluentButton>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}

View File

@@ -1,14 +1,13 @@
@page "/pixiv"
@page "/pixiv"
@rendermode InteractiveServer
<h3>Pixiv</h3>
<FluentButton OnClick="RandomGet">
随机获取
</FluentButton>
<FluentDivider />
<br/>
<FluentStack Orientation="Orientation.Vertical" HorizontalAlignment="HorizontalAlignment.Center">
<Space Direction="SpaceDirection.Horizontal" Size="@("16")" Align="SpaceAlign.Center">
<Button Type="ButtonType.Primary" OnClick="RandomGet">随机获取</Button>
</Space>
<Divider />
<Space Direction="SpaceDirection.Vertical" Size="@("16")" Align="SpaceAlign.Center">
@foreach (var (index, img) in CurrentImgs.S3URL.Index())
{
@if(index == 0)
@@ -20,7 +19,7 @@
<img src="@img.Large" loading="lazy" referrerpolicy="no-referrer" />
}
}
</FluentStack>
</Space>
@code {
public Modules.PixivFavoriteDownloader.Pixiv.PixivImgInfo CurrentImgs;

View File

@@ -1,43 +0,0 @@
@page "/weather"
@attribute [StreamRendering]
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
<!-- This page is rendered in SSR mode, so the FluentDataGrid component does not offer any interactivity (like sorting). -->
<FluentDataGrid Id="weathergrid" Items="@forecasts" GridTemplateColumns="1fr 1fr 1fr 2fr" Loading="@(forecasts == null)" Style="height:204px;" TGridItem="WeatherForecast">
<PropertyColumn Title="Date" Property="@(c => c!.Date)" Align="Align.Start"/>
<PropertyColumn Title="Temp. (C)" Property="@(c => c!.TemperatureC)" Align="Align.Center"/>
<PropertyColumn Title="Temp. (F)" Property="@(c => c!.TemperatureF)" Align="Align.Center"/>
<PropertyColumn Title="Summary" Property="@(c => c!.Summary)" Align="Align.End"/>
</FluentDataGrid>
@code {
private IQueryable<WeatherForecast>? forecasts;
protected override async Task OnInitializedAsync()
{
// Simulate asynchronous loading to demonstrate streaming rendering
await Task.Delay(500);
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).AsQueryable();
}
private class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}

View File

@@ -1,12 +1,11 @@
@using System.Net.Http
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.FluentUI.AspNetCore.Components
@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons
@using AntDesign
@using Microsoft.JSInterop
@using MegghysAPI
@using MegghysAPI.Components