Files
EmailBill/WebApi/Program.cs

159 lines
4.5 KiB
C#
Raw Normal View History

2025-12-25 11:20:56 +08:00
using FreeSql;
2025-12-25 13:27:23 +08:00
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
2025-12-25 13:27:23 +08:00
using Microsoft.IdentityModel.Tokens;
2025-12-25 11:20:56 +08:00
using Scalar.AspNetCore;
using Serilog;
using Service.AppSettingModel;
2025-12-29 15:20:32 +08:00
using WebApi;
using WebApi.Middleware;
2025-12-25 11:20:56 +08:00
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.
2026-01-18 22:25:59 +08:00
builder.Services.AddControllers(mvcOptions =>
{
var policy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
2026-01-18 22:25:59 +08:00
mvcOptions.Filters.Add(new AuthorizeFilter(policy));
});
2025-12-25 11:20:56 +08:00
builder.Services.AddOpenApi();
builder.Services.AddHttpClient();
// 配置 CORS
2026-01-18 22:25:59 +08:00
builder.Services.AddCors(corsOptions =>
2025-12-25 11:20:56 +08:00
{
2026-01-18 22:25:59 +08:00
corsOptions.AddDefaultPolicy(policy =>
2025-12-25 11:20:56 +08:00
{
policy.WithOrigins("http://localhost:5173")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
// 绑定配置
builder.Services.Configure<EmailSettings>(builder.Configuration.GetSection("EmailSettings"));
2026-01-18 22:04:56 +08:00
builder.Services.Configure<AiSettings>(builder.Configuration.GetSection("OpenAI"));
2025-12-25 13:27:23 +08:00
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);
2026-01-18 22:25:59 +08:00
builder.Services.AddAuthentication(authenticationOptions =>
2025-12-25 13:27:23 +08:00
{
2026-01-18 22:25:59 +08:00
authenticationOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
authenticationOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
2025-12-25 13:27:23 +08:00
})
2026-01-18 22:25:59 +08:00
.AddJwtBearer(jwtBearerOptions =>
2025-12-25 13:27:23 +08:00
{
2026-01-18 22:25:59 +08:00
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
2025-12-25 13:27:23 +08:00
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(key),
ClockSkew = TimeSpan.Zero
};
2026-01-18 22:25:59 +08:00
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("权限不足"));
}
};
2025-12-25 13:27:23 +08:00
});
builder.Services.AddAuthorization();
2025-12-25 11:20:56 +08:00
// 配置 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(
2026-01-30 10:41:19 +08:00
cmd =>
2025-12-25 11:20:56 +08:00
{
2026-01-12 16:58:51 +08:00
Log.Verbose("执行SQL: {Sql}", cmd.CommandText);
2025-12-25 11:20:56 +08:00
}
)
.Build();
fsql.UseJsonMap();
2025-12-25 11:20:56 +08:00
builder.Services.AddSingleton(fsql);
// 自动扫描注册服务和仓储
builder.Services.AddServices();
2025-12-29 15:20:32 +08:00
// 配置 Quartz.NET 定时任务
builder.AddScheduler();
2025-12-25 11:20:56 +08:00
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();
2025-12-25 13:27:23 +08:00
// 启用认证和授权
app.UseAuthentication();
app.UseAuthorization();
2025-12-25 11:20:56 +08:00
app.MapControllers();
// 添加 SPA 回退路由(用于前端路由)
app.MapFallbackToFile("index.html");
app.Run();