Files
EmailBill/WebApi/Program.cs
SunCheng 704f58b1a1
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 24s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 3s
fix
2026-01-30 10:41:19 +08:00

159 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using FreeSql;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.IdentityModel.Tokens;
using Scalar.AspNetCore;
using Serilog;
using Service.AppSettingModel;
using WebApi;
using WebApi.Middleware;
using Yitter.IdGenerator;
// 初始化雪花算法ID生成器
var options = new IdGeneratorOptions(1); // WorkerId 为 1可根据实际部署情况调整
YitIdHelper.SetIdGenerator(options);
var builder = WebApplication.CreateBuilder(args);
// 配置 Serilog
builder.Host.UseSerilog((context, loggerConfig) =>
{
loggerConfig.ReadFrom.Configuration(context.Configuration);
});
// Add services to the container.
builder.Services.AddControllers(mvcOptions =>
{
var policy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
mvcOptions.Filters.Add(new AuthorizeFilter(policy));
});
builder.Services.AddOpenApi();
builder.Services.AddHttpClient();
// 配置 CORS
builder.Services.AddCors(corsOptions =>
{
corsOptions.AddDefaultPolicy(policy =>
{
policy.WithOrigins("http://localhost:5173")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
// 绑定配置
builder.Services.Configure<EmailSettings>(builder.Configuration.GetSection("EmailSettings"));
builder.Services.Configure<AiSettings>(builder.Configuration.GetSection("OpenAI"));
builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("JwtSettings"));
builder.Services.Configure<AuthSettings>(builder.Configuration.GetSection("AuthSettings"));
// 配置JWT认证
var jwtSettings = builder.Configuration.GetSection("JwtSettings");
var secretKey = jwtSettings["SecretKey"]!;
var key = Encoding.UTF8.GetBytes(secretKey);
builder.Services.AddAuthentication(authenticationOptions =>
{
authenticationOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
authenticationOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtBearerOptions =>
{
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(key),
ClockSkew = TimeSpan.Zero
};
jwtBearerOptions.Events = new JwtBearerEvents
{
OnChallenge = async context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(BaseResponse.Fail("未登录"));
},
OnForbidden = async context =>
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(BaseResponse.Fail("权限不足"));
}
};
});
builder.Services.AddAuthorization();
// 配置 FreeSql + SQLite
var dbPath = Path.Combine(AppContext.BaseDirectory, "database");
if (!Directory.Exists(dbPath))
{
Directory.CreateDirectory(dbPath);
}
// 使用绝对路径作为数据库文件路径
var dbFilePath = Path.Combine(dbPath, "EmailBill.db");
var connectionString = $"Data Source={dbFilePath}";
Log.Information("数据库路径: {DbPath}", dbFilePath);
var fsql = new FreeSqlBuilder()
.UseConnectionString(DataType.Sqlite, connectionString)
.UseAutoSyncStructure(true)
.UseLazyLoading(true)
.UseMonitorCommand(
cmd =>
{
Log.Verbose("执行SQL: {Sql}", cmd.CommandText);
}
)
.Build();
fsql.UseJsonMap();
builder.Services.AddSingleton(fsql);
// 自动扫描注册服务和仓储
builder.Services.AddServices();
// 配置 Quartz.NET 定时任务
builder.AddScheduler();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference();
}
// 启用静态文件服务
app.UseDefaultFiles();
app.UseStaticFiles();
// 启用 CORS
app.UseCors();
// 启用请求ID跟踪
app.UseRequestId();
// 启用认证和授权
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
// 添加 SPA 回退路由(用于前端路由)
app.MapFallbackToFile("index.html");
app.Run();