Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.WebApi/Program.cs
glz 296d87b245 feat: 新增宠物进化分组接口、OSS图片搬运功能及配置更新
1. 新增皮肤按进化阶段分组的输出DTO
2. 新增宠物相关便捷查询接口并实现对应控制器
3. 新增OSS图片搬运辅助类,实现临时文件迁移逻辑
4. 为商品、宠物相关服务添加OSS图片自动迁移功能
5. 调整微信授权同步逻辑移除异步等待
6. 更新配置文件中的微信密钥和OSS存储信息
7. 注册SDK服务到DI容器
2026-06-09 18:02:26 +08:00

220 lines
7.6 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 Autofac;
using Autofac.Extensions.DependencyInjection;
using BCrypt.Net;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.OpenApi;
using Microsoft.OpenApi.Models;
using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.Common.Helpers;
using QYZH.InteractiveMagazine.Infrastructure.Autofacs;
using QYZH.InteractiveMagazine.Infrastructure.Context;
using QYZH.InteractiveMagazine.Infrastructure.Extensions;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.Infrastructure.Redis;
using QYZH.InteractiveMagazine.Infrastructure.SDK;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Models.Settings;
using QYZH.InteractiveMagazine.Repository;
using QYZH.InteractiveMagazine.Repository.Core;
using Serilog;
using SqlSugar.IOC;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System.Text.Json.Serialization;
using Yitter.IdGenerator;
var builder = WebApplication.CreateBuilder(args);
// 加载勋章规则独立配置文件
builder.Configuration.AddJsonFile("medal-rule-config.json", optional: false, reloadOnChange: true);
// 初始化雪花ID生成器
YitIdHelper.SetIdGenerator(new IdGeneratorOptions() { WorkerId = 1 });
// autofac注入 允许使用autofac作为DI容器
builder.UseAutofac();
builder.InitSqlSugarDb(new IocConfig()
{
ConfigId = 0,
DbType = IocDbType.MySql,
ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"),
IsAutoCloseConnection = true,
});
// 消除Error unprotecting the session cookie警告
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection"));
//redis
builder.Services.AddCSRedisCacheExtension(builder.Configuration.GetSection("RedisSettings"));
// 配置Serilog
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.Enrich.FromLogContext()
.CreateLogger();
builder.Host.UseSerilog();
builder.Services.AddControllers(options =>
{
options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;//Required 不作为必填
options.Filters.Add<ModelValidActionFilterAttribute>();//添加自定义模型验证
})
.AddJsonOptions(options =>
{
// 配置 JSON 不区分大小写(支持 camelCase 和 PascalCase
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
// 配置返回时间格式转换
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeConverter());
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
}).ConfigureApiBehaviorOptions(opt => opt.SuppressModelStateInvalidFilter = true);//关闭默认模型验证
builder.Services.AddEndpointsApiExplorer();
// 跨域配置
builder.Services.AddDataProtection().UseEphemeralDataProtectionProvider();
builder.AddCorsRegister();
//builder.Services.AddSession();
builder.Services.AddHttpClient();
// 注册 Swagger 文档
builder.Services.AddSwaggerGen(option =>
{
var xmlFile = $"{AppDomain.CurrentDomain.FriendlyName}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
var modelXml = Path.Combine(AppContext.BaseDirectory, $"QYZH.InteractiveMagazine.Models.xml");
Enum.GetValues<ApiVersionEnum>().ToList().ForEach(version =>
{
// 配置文档信息
option.SwaggerDoc(version.ToString(), new OpenApiInfo
{
Title = AppDomain.CurrentDomain.FriendlyName,
Version = "互动期刊接口文档",
Description = $"{version.GetDescription()}接口Last Modify Time{new FileInfo(xmlPath).LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")}"
});
});
// 配置接口路径排序
option.OrderActionsBy(o => o.RelativePath);
if (File.Exists(xmlPath))
option.IncludeXmlComments(xmlPath, true);
if (File.Exists(modelXml))
option.IncludeXmlComments(modelXml, true);
option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Description = "请输入 Token格式为 Bearer Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = "Bearer"
});
option.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
// 过滤文档/路径/方法筛选接口的响应结果
option.DocInclusionPredicate((docName, apiDesc) =>
{
// 方式 1将接口的 [ApiExplorerSettings(GroupName = "xxx")] 特性匹配
if (!apiDesc.TryGetMethodInfo(out var methodInfo)) return false;
var groupName = methodInfo.DeclaringType?
.GetCustomAttributes(true)
.OfType<ApiExplorerSettingsAttribute>()
.FirstOrDefault()?
.GroupName;
// 匹配当前文档(分组)则显示
return groupName == docName;
});
});
builder.Services.AddInfrastructureServices(builder.Configuration, builder.Environment);
//注册 HttpContextAccessor
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped(typeof(BaseRepository<>));
// 注册勋章规则配置
builder.Services.Configure<MedalRuleConfigSettings>(builder.Configuration.GetSection("MedalRuleConfig"));
// 添加CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
builder.Services.AddSDKService(builder.Configuration);
#region
// 1.首先配置压缩选项的Options>
builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = System.IO.Compression.CompressionLevel.Optimal;
});
builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
options.Level = System.IO.Compression.CompressionLevel.Fastest;
});
// 2.在服务容器中注册响应压缩服务
builder.Services.AddResponseCompression(options =>
{
// 可以在这里进行详细配置
options.EnableForHttps = true; // 启用对HTTPS响应的压缩请注意安全风险
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
//指定哪些类型的响应应该被压缩。默认列表包含常见的文本类类型,如 text/html, text/css, application/javascript, application/json, text/plain等
options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(["image/svg+xml", "application/json", "text/plain"]);
});
#endregion
var app = builder.Build();
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
// 根据版本名称倒序 遍历展示
Enum.GetValues<ApiVersionEnum>().OrderBy(e => e).ToList().ForEach(version =>
{
c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{version.GetDescription()}接口");
});
c.DocExpansion(DocExpansion.None); // ->修改界面打开时自动折叠
});
}
app.UseServiceContext();
app.UseHttpsRedirection();
app.UseCors("AllowAll");
app.UseMiddleware<GlobalExceptionMiddleware>();
app.UseMiddleware<OperationLogMiddleware>();
app.UseMiddleware<JwtAutoRefreshMiddleware>();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();