Program.cs 4.42 KB
using Rcs.Api;
using Rcs.Api.BackgroundServices;
using Rcs.Api.Hubs;
using Rcs.Infrastructure.Installs;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
// 添加 CORS 策略,允许跨域访问(根据需要修改策略)
builder.Services.AddCors(options =>
{
    options.AddPolicy("DefaultCorsPolicy", policy =>
    {
        policy.SetIsOriginAllowed(_ => true)
              .AllowAnyMethod()
              .AllowAnyHeader()
              .AllowCredentials();
    });
});

// 添加 SignalR
builder.Services.AddSignalR();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
    {
        Title = "HaHRCS API",
        Version = "v1",
        Description = "长沙华恒机器人控制系统 API"
    });
});

// 安装应用配置
builder.InstallApplicationSettings();

// 安装Entity Framework
builder.InstallEntityFramework();

// 安装依赖注入
builder.InstallDependencyInjection();

// 安装 AutoMapper
builder.Services.InstallAutoMapper();

// 安装 Redis
builder.InstallRedis();
// 安装 Mqtt
builder.InstallMqtt();
// 安装过滤器
builder.InstallFilters();

// 安装消息总线 (MassTransit + RabbitMQ)
builder.InstallMessageBus();
// 安装 LanYin 服务
builder.Services.InstallLanYinService();
builder.Services.InstallHttpClient();

// 添加机器人状态推送后台服务
builder.Services.AddHostedService<RobotStatusPushService>();

var app = builder.Build();

// 自动运行数据库迁移
using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    try
    {
        app.Logger.LogInformation("开始初始化数据库...");
        var dbContext = services.GetRequiredService<Rcs.Infrastructure.DB.MsSql.AppDbContext>();
        EntityFrameworkInstaller.SeedDatabase(dbContext);
        app.Logger.LogInformation("✓ 数据库初始化成功完成");
    }
    catch (Exception ex)
    {
        app.Logger.LogError(ex, "✗ 数据库初始化失败");
        throw;
    }
}

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

// 使用 CORS 策略
app.UseCors("DefaultCorsPolicy");

// 配置静态文件服务,允许访问上传的文件
app.UseStaticFiles();
// 配置上传文件的静态访问路径(使用内容根目录确保 Debug 和 Release 模式一致)
var uploadsPath = Path.Combine(app.Environment.ContentRootPath, "uploads");
if (!Directory.Exists(uploadsPath))
{
    Directory.CreateDirectory(uploadsPath);
}
app.Logger.LogInformation("静态文件路径: {UploadsPath}", uploadsPath);
app.UseStaticFiles(new Microsoft.AspNetCore.Builder.StaticFileOptions
{
    FileProvider = new Microsoft.Extensions.FileProviders.PhysicalFileProvider(uploadsPath),
    RequestPath = "/uploads",
    OnPrepareResponse = ctx =>
    {
        // 禁用缓存,确保每次都获取最新文件
        ctx.Context.Response.Headers.Append("Cache-Control", "no-cache, no-store, must-revalidate");
        ctx.Context.Response.Headers.Append("Pragma", "no-cache");
        ctx.Context.Response.Headers.Append("Expires", "0");
        // 添加 CORS 头,允许 SVG 图片跨域访问
        ctx.Context.Response.Headers.Append("Access-Control-Allow-Origin", "*");
        ctx.Context.Response.Headers.Append("Access-Control-Allow-Methods", "GET, OPTIONS");
        ctx.Context.Response.Headers.Append("Access-Control-Allow-Headers", "*");
    }
});

app.MapControllers();

// 映射 SignalR Hub
app.MapHub<RobotStatusHub>("/hubs/robotstatus");

var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () =>
{
    var forecast =  Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();

app.Run();

namespace Rcs.Api
{
    record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
    {
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}