1. 新增数据库唯一约束和Message_Outbox表脚本 2. 新增雪花ID、Hangfire存储、MQ重试等配置实体 3. 重构各项目雪花ID生成逻辑,改为从配置读取WorkerId 4. 优化积分服务分页查询、用户背包更新逻辑 5. 新增JWT令牌Redis过期刷新逻辑 6. 完善RabbitMQ死信队列消息头信息 7. 新增可靠MQ消息发布服务和Outbox派发后台服务 8. 替换原有RabbitMQ直接发送为Outbox可靠发布 9. 优化签到服务逻辑,新增重复签到校验和补签卡扣减逻辑 10. 修复自动铺码消费逻辑,新增点阵页预占和释放机制
139 lines
4.3 KiB
C#
139 lines
4.3 KiB
C#
using Microsoft.AspNetCore.DataProtection;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.AspNetCore.ResponseCompression;
|
||
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.RabbitMQ;
|
||
using QYZH.InteractiveMagazine.Infrastructure.Redis;
|
||
using QYZH.InteractiveMagazine.Infrastructure.SDK;
|
||
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);
|
||
|
||
var snowflakeSettings = builder.Configuration.GetSection("SnowflakeSettings").Get<SnowflakeSettings>() ?? new SnowflakeSettings { WorkerId = 1 };
|
||
YitIdHelper.SetIdGenerator(new IdGeneratorOptions { WorkerId = snowflakeSettings.WorkerId });
|
||
|
||
builder.UseAutofac();
|
||
|
||
builder.InitSqlSugarDb(new IocConfig
|
||
{
|
||
ConfigId = 0,
|
||
DbType = IocDbType.MySql,
|
||
ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"),
|
||
IsAutoCloseConnection = true,
|
||
});
|
||
|
||
Log.Logger = new LoggerConfiguration()
|
||
.ReadFrom.Configuration(builder.Configuration)
|
||
.Enrich.FromLogContext()
|
||
.CreateLogger();
|
||
|
||
builder.Host.UseSerilog();
|
||
builder.AddInteractiveMagazineApiDefaults();
|
||
builder.Services.AddScoped(typeof(BaseRepository<>));
|
||
|
||
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");
|
||
var version = ApiVersionEnum.Wechat;
|
||
|
||
option.SwaggerDoc(version.ToString(), new OpenApiInfo
|
||
{
|
||
Title = AppDomain.CurrentDomain.FriendlyName,
|
||
Version = "互动期刊接口文档",
|
||
Description = $"{version.GetDescription()}接口,Last Modify Time:{new FileInfo(xmlPath).LastWriteTime: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"
|
||
}
|
||
},
|
||
[]
|
||
}
|
||
});
|
||
|
||
option.DocInclusionPredicate((docName, apiDesc) =>
|
||
{
|
||
if (!apiDesc.TryGetMethodInfo(out var methodInfo))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
var groupName = methodInfo.DeclaringType?
|
||
.GetCustomAttributes(true)
|
||
.OfType<ApiExplorerSettingsAttribute>()
|
||
.FirstOrDefault()?
|
||
.GroupName;
|
||
|
||
return groupName == docName;
|
||
});
|
||
});
|
||
|
||
var app = builder.Build();
|
||
|
||
app.UseSwagger();
|
||
app.UseSwaggerUI(c =>
|
||
{
|
||
var version = ApiVersionEnum.Wechat;
|
||
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();
|