feat: 新增文件库功能,支持局域网文件浏览与媒体播放

后端:
- 新增 ManagedLibraryRoot / ManagedFileRecord 数据模型及 SQLite 迁移
- 新增文件库服务、端点服务及定时扫描后台任务
- 新增 REST API: drives、directories、roots CRUD、files 分页搜索、文本预览
- 新增文件流端点支持视频/音频流式传输
- 数据库切换为 SQLite,Kestrel 绑定 0.0.0.0 支持局域网访问

前端:
- 管理端:磁盘浏览、目录选择、根目录添加/启用/删除/扫描
- 客户端:根目录选择、文件搜索/筛选/分页、音视频播放、文本预览
- 全新响应式 UI(桌面+移动端),CSS 变量设计系统
- HTTP 客户端支持 Vite 开发代理与生产同源自动切换
- 移除 HTTPS 强制重定向以提升移动端视频流兼容性
This commit is contained in:
2026-05-21 16:45:56 +08:00
parent e3fe965f10
commit a68bb6c4b3
31 changed files with 3162 additions and 85 deletions
@@ -3,6 +3,7 @@ using Avalonia_EFCore.Database;
using Avalonia_EFCore.Models;
using Avalonia_Services.Core;
using Avalonia_Services.Services;
using Avalonia_Services.Services.FileLibrary;
using Microsoft.EntityFrameworkCore;
namespace Avalonia_Services.Endpoints
@@ -47,6 +48,46 @@ namespace Avalonia_Services.Endpoints
endpoints.MapPost("api/processData", ProcessDataAsync)
.WithName("ProcessData");
endpoints.MapGet<IFileLibraryEndpointService>("api/library/drives", (service, ctx) => service.GetDrivesAsync(ctx))
.WithOpenApi("FileLibrary", "查询服务器磁盘。")
.WithName("GetLibraryDrives");
endpoints.MapGet<IFileLibraryEndpointService>("api/library/directories", (service, ctx) => service.GetDirectoriesAsync(ctx))
.WithOpenApi("FileLibrary", "查询服务器目录。")
.WithName("GetLibraryDirectories");
endpoints.MapGet<IFileLibraryEndpointService>("api/library/roots", (service, ctx) => service.GetRootsAsync(ctx))
.WithOpenApi("FileLibrary", "查询文件库目录。")
.WithName("GetLibraryRoots");
endpoints.MapPost<IFileLibraryEndpointService>("api/library/roots", (service, ctx) => service.AddRootAsync(ctx))
.WithOpenApi("FileLibrary", "添加文件库目录。")
.WithName("AddLibraryRoot");
endpoints.MapPost<IFileLibraryEndpointService>("api/library/roots/enabled", (service, ctx) => service.SetRootEnabledAsync(ctx))
.WithOpenApi("FileLibrary", "启用或禁用文件库目录。")
.WithName("SetLibraryRootEnabled");
endpoints.MapPost<IFileLibraryEndpointService>("api/library/roots/delete", (service, ctx) => service.DeleteRootAsync(ctx))
.WithOpenApi("FileLibrary", "删除文件库目录。")
.WithName("DeleteLibraryRoot");
endpoints.MapPost<IFileLibraryEndpointService>("api/library/roots/scan", (service, ctx) => service.ScanRootAsync(ctx))
.WithOpenApi("FileLibrary", "立即扫描文件库目录。")
.WithName("ScanLibraryRoot");
endpoints.MapGet<IFileLibraryEndpointService>("api/files", (service, ctx) => service.SearchFilesAsync(ctx))
.WithOpenApi("FileLibrary", "分页查询已扫描文件。")
.WithName("SearchFiles");
endpoints.MapGet<IFileLibraryEndpointService>("api/files/detail", (service, ctx) => service.GetFileAsync(ctx))
.WithOpenApi("FileLibrary", "查询文件详情。")
.WithName("GetFileDetail");
endpoints.MapGet<IFileLibraryEndpointService>("api/files/text", (service, ctx) => service.GetTextPreviewAsync(ctx))
.WithOpenApi("FileLibrary", "预览文本文件。")
.WithName("GetTextPreview");
// ---- 需要鉴权的端点示例 ----
// endpoints.MapGet("api/admin/dashboard", AdminDashboardAsync)
// .WithName("AdminDashboard")