refactor: 枚举移入Models目录,命名空间更新为Rainbow.Entity.Models
大石头 authored at 2026-07-02 12:54:58
2.53 KiB
RainbowBridge
using Microsoft.Extensions.FileProviders;
using NewLife;
using NewLife.Cube.Extensions;

namespace Rainbow.Web;

/// <summary>Rainbow 服务注册与中间件扩展方法</summary>
/// <remarks>
/// 独立部署时:
///   services.AddRainbow()
///   app.UseRainbow()
/// </remarks>
public static class RainbowExtensions
{
    #region 服务注册

    /// <summary>注册 Rainbow 所需的额外服务(当前为空壳,预留扩展点)</summary>
    /// <param name="services">服务集合</param>
    /// <returns></returns>
    public static IServiceCollection AddRainbow(this IServiceCollection services)
    {
        // 预留:未来可在此注册 Rainbow 特有的服务

        return services;
    }

    #endregion

    #region 中间件配置

    /// <summary>配置 Rainbow 中间件:嵌入静态资源(React SPA 前端)与 SPA 路由回退</summary>
    /// <param name="app">应用构建器</param>
    /// <returns></returns>
    public static WebApplication UseRainbow(this WebApplication app)
    {
        var env = app.Environment;
        var assembly = typeof(RainbowExtensions).Assembly;
        var embeddedProvider = new CubeEmbeddedFileProvider(assembly, "Rainbow.Web.wwwroot");

        if (!String.IsNullOrEmpty(env.WebRootPath) && Directory.Exists(env.WebRootPath) && env.WebRootFileProvider != null)
        {
            // 磁盘 wwwroot 优先,再到嵌入资源作为后备;确保 pnpm build 后的新前端文件能立即生效
            env.WebRootFileProvider = new CompositeFileProvider(
                env.WebRootFileProvider,
                embeddedProvider);
        }
        else
        {
            env.WebRootFileProvider = embeddedProvider;
        }

        app.UseStaticFiles();

        // 仅对已知前端路由做 SPA 兜底,不干扰静态文件、API(/api/*)和 Cube 后台(/admin/*)
        app.MapFallbackToFile("/devices/{**path}", "index.html");
        app.MapFallbackToFile("/wan/{**path}", "index.html");
        app.MapFallbackToFile("/firewall/{**path}", "index.html");
        app.MapFallbackToFile("/pppoe/{**path}", "index.html");
        app.MapFallbackToFile("/dhcp/{**path}", "index.html");
        app.MapFallbackToFile("/dns/{**path}", "index.html");
        app.MapFallbackToFile("/settings/{**path}", "index.html");
        app.MapFallbackToFile("/members/{**path}", "index.html");
        app.MapFallbackToFile("/stats/{**path}", "index.html");
        // 根路径兜底(仪表盘首页)
        app.MapFallbackToFile("index.html");

        return app;
    }

    #endregion
}