1.更换软件协议为AGPL

2.切换项目名称为Hua.Todo
This commit is contained in:
ShaoHua
2026-04-06 22:06:30 +08:00
parent 40a91e39b6
commit 758f6772c6
147 changed files with 1203 additions and 644 deletions
@@ -0,0 +1,137 @@
#if WINDOWS
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using System.Text.Json;
using Hua.Todo.Application;
using Hua.Todo.Application.DynamicApi;
using Hua.Todo.Maui.Models;
using AppSettings = Hua.Todo.Maui.Models.AppSettings;
namespace Hua.Todo.Maui.Services;
public class EmbeddedWebServerService : IEmbeddedWebServerService
{
private WebApplication? _webApp;
private readonly AppSettings _appSettings;
public bool IsRunning => _webApp != null;
public string BaseUrl => _appSettings.WebServer.HostUrl;
public EmbeddedWebServerService(AppSettings appSettings)
{
_appSettings = appSettings;
}
public async Task StartAsync()
{
if (_webApp != null) return;
var builder = WebApplication.CreateBuilder();
builder.WebHost.UseUrls(_appSettings.WebServer.HostUrl);
builder.Services.AddControllers()
.AddApplicationPart(typeof(Hua.Todo.Application.ServiceCollectionExtensions).Assembly)
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddApplicationServices(_appSettings.WebServer.ConnectionString);
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
var app = builder.Build();
if (_appSettings.WebServer.IsUsingStatic)
{
ServeStaticFiles(app);
}
app.UseCors("AllowAll");
app.UseAuthorization();
app.UseDynamicApi();
app.MapControllers();
_webApp = app;
await _webApp.StartAsync();
}
private void ServeStaticFiles(WebApplication app)
{
try
{
var wwwrootPath = Path.Combine(AppContext.BaseDirectory, "wwwroot");
if (!Directory.Exists(wwwrootPath))
{
Console.WriteLine("[EmbeddedWebServer] wwwroot directory not found. Static file serving disabled.");
return;
}
var fileProvider = new PhysicalFileProvider(wwwrootPath);
var defaultFilesOptions = new DefaultFilesOptions { FileProvider = fileProvider, RequestPath = "" };
app.UseDefaultFiles(defaultFilesOptions);
var staticFileOptions = new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = "",
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
ctx.Context.Response.Headers["Pragma"] = "no-cache";
ctx.Context.Response.Headers["Expires"] = "0";
}
};
app.UseStaticFiles(staticFileOptions);
app.Use(async (context, next) =>
{
if (context.Request.Path.HasValue)
{
var path = context.Request.Path.Value;
if (path != "/" && !path.StartsWith("/assets", StringComparison.OrdinalIgnoreCase) && !path.StartsWith("/api", StringComparison.OrdinalIgnoreCase))
{
var ext = Path.GetExtension(path);
if (string.IsNullOrEmpty(ext))
{
context.Request.Path = "/index.html";
}
}
}
await next();
});
Console.WriteLine($"[EmbeddedWebServer] Serving static files from: {wwwrootPath}");
}
catch (Exception ex)
{
Console.WriteLine($"[EmbeddedWebServer] Failed to serve static files: {ex.Message}");
}
}
public async Task StopAsync()
{
if (_webApp == null) return;
await _webApp.StopAsync();
await _webApp.DisposeAsync();
_webApp = null;
}
}
#endif