Program.cs
4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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);
}
}