This commit implements a complete WeChat mini program mall and related features: 1. Add pet skin entity and backpack item type support 2. Add make-up check-in and missed date query functions 3. Implement mall product browsing, exchange and record query 4. Add backpack management and item usage (make-up card) 5. Add pet skin equipping function 6. Fix UserBag ItemId type from int to long 7. Adjust Dockerfile exposed port to 8080 8. Fix session cookie unprotect warning
205 lines
7.1 KiB
C#
205 lines
7.1 KiB
C#
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.Models.Entity;
|
||
using QYZH.InteractiveMagazine.Models.Enum;
|
||
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);
|
||
|
||
// 初始化雪花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"));
|
||
|
||
// 配置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<>));
|
||
|
||
// 添加CORS
|
||
builder.Services.AddCors(options =>
|
||
{
|
||
options.AddPolicy("AllowAll", policy =>
|
||
{
|
||
policy.AllowAnyOrigin()
|
||
.AllowAnyMethod()
|
||
.AllowAnyHeader();
|
||
});
|
||
});
|
||
#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();
|
||
|