You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

420 lines
16 KiB

using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using AuthServer.Host;
using BaseService;
using Hangfire;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerUI;
using Volo.Abp;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundJobs.Hangfire;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.BlobStoring.Minio;
using Volo.Abp.Caching;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore.SqlServer;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Threading;
using Win.Sfs.Shared.Constant;
using Win.Utils;
namespace Win.Sfs.SettleAccount
{
[DependsOn(
typeof(AbpAutofacModule),
typeof(AuthServerHostModule),
typeof(BaseServiceHostModule),
typeof(SettleAccountApplicationModule),
typeof(SettleAccountEntityFrameworkCoreModule),
typeof(SettleAccountHttpApiModule),
//typeof(AbpAspNetCoreMvcUiMultiTenancyModule),
//typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpBlobStoringModule),
typeof(AbpBlobStoringFileSystemModule),
typeof(AbpBackgroundJobsHangfireModule)
//typeof(AbpEventBusRabbitMqModule)
//typeof(AbpHangfireModule)
//typeof(AbpSwashbuckleModule)
)]
public class SettleAccountHttpApiHostModule : AbpModule
{
private const string DefaultCorsPolicyName = "Default";
public override void ConfigureServices(ServiceConfigurationContext context)
{
// System.AbpStringExtensions.ToCamelCase(System.String, Boolean)'
var configuration = context.Services.GetConfiguration();
//文件上传大小限制
ConfigureBodyLengthLimit(context);
//配置多租户
ConfigureMultiTenancy();
//配置认证
ConfigureAuthentication(context, configuration);
//配置本地化
ConfigureLocalization();
//配置缓存
ConfigureCache(configuration);
//配置虚拟文件系统
// ConfigureVirtualFileSystem(context);
//配置Redis
ConfigureRedis(context, configuration);
//配置跨域资源共享
//ConfigureCors(context, configuration);
//配置Swagger
ConfigureSwaggerServices(context, configuration);
//null: DTO的属性首字母保持大写
ConfigureJson(context);
//应用服务自动转换为控制器
ConfigureConventionalControllers();
//配置异常处理
ConfigureException();
//注册BOLB容器
ConfigureBLOBServices(configuration);
//注册大众的二配实际输出文件的容器
//ConfigureBLOBSecSummaryServices(configuration);
//注册奔腾的二配实际输出文件的容器
//ConfigureBLOBTSecSummaryServices(configuration);
ConfigureHangfire(context, configuration);
//context.Services.Configure<AbpExceptionHttpStatusCodeOptions>(options =>
//{
// options.Map("Volo.Qa:010002", System.Net.HttpStatusCode.Conflict);
//});
//context.Services.Configure<AbpExceptionHandlingOptions>(options =>
//{
// options.SendExceptionsDetailsToClients = false;
//});
/*
Configure<AbpRabbitMqOptions>(options =>
{
options.Connections.Default.UserName = "user1";
options.Connections.Default.Password = "123123";
options.Connections.Default.HostName = "192.168.0.203";
options.Connections.Default.Port = 5672;
});
*/
//Configure<AbpRabbitMqEventBusOptions>(options =>
//{
// options.ClientName = "SettleAccount";
// options.ExchangeName = "TestMessages";
//});
//Configure<AbpBackgroundJobWorkerOptions>(options =>
//{
// options.DefaultTimeout = 864000; //10 days (as seconds)
//});
context.Services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = int.MaxValue;
x.MemoryBufferThreshold = int.MaxValue;
});
}
private void ConfigureBodyLengthLimit(ServiceConfigurationContext context)
{
context.Services.Configure<FormOptions>(options =>
{
options.ValueLengthLimit = int.MaxValue;
options.MultipartBodyLengthLimit = int.MaxValue;
options.MultipartHeadersLengthLimit = int.MaxValue;
});
}
/// <summary>
/// 上传文件的容器
/// </summary>
/// <param name="context"></param>
private void ConfigureBLOBServices(IConfiguration cfg)
{
//Configure<AbpBlobStoringOptions>(options =>
//{
// options.Containers.Configure<MyFileContainer>(configuration =>
// {
// configuration.UseFileSystem(fileSystem =>
// {
// var filestreampath = Environment.CurrentDirectory + @"\wwwroot\files";
// if (!Directory.Exists(filestreampath))
// {
// Directory.CreateDirectory(filestreampath);
// }
// fileSystem.BasePath = filestreampath;
// });
// });
//});
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(container =>
{
container.UseMinio(minio =>
{
minio.EndPoint = cfg.GetValue("MinIO:EndPoint", "localhost:10684");
minio.AccessKey = cfg.GetValue("MinIO:AccessKey", "g0GKnhRGEQHI0uiGBYre");
minio.SecretKey = cfg.GetValue("MinIO:SecretKey", "iKGlLz6UBzci3xrERw5Zz1gI77enT5u9agFemHPv");
minio.BucketName = cfg.GetValue("MinIO:BucketName", "default");
minio.WithSSL = false;
});
});
});
}
private static void ConfigureJson(ServiceConfigurationContext context)
{
//null: DTO的属性首字母保持大写
//JsonNamingPolicy.CamelCase; : DTO的属性首字母改为小写
context.Services.Configure<JsonOptions>(opt =>
{
opt.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
//opt.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
});
}
private void ConfigureException()
{
//将错误明细发送给客户端
Configure<AbpExceptionHandlingOptions>(options => { options.SendExceptionsDetailsToClients = true; });
Configure<MvcOptions>(options =>
{
var index = options.Filters.ToList().FindIndex(filter => filter is ServiceFilterAttribute attr && attr.ServiceType.Equals(typeof(AbpExceptionFilter)));
if (index > -1)
{
options.Filters.RemoveAt(index);
}
options.Filters.Add(typeof(CustomExceptionFilter));
});
}
private void ConfigureMultiTenancy()
{
Configure<AbpMultiTenancyOptions>(options =>
{
options.IsEnabled = true;
});
}
private void ConfigureConventionalControllers()
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options
.ConventionalControllers
.Create(typeof(SettleAccountApplicationModule).Assembly, opts
=>
{ opts.RootPath = "settleaccount"; });
});
}
private void ConfigureCache(IConfiguration configuration)
{
Configure<AbpDistributedCacheOptions>(options =>
{
options.KeyPrefix = "SettleAccount:";
});
}
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
var isAlwaysAllowAuthorization = configuration.GetValue<bool>("AuthServer:AlwaysAllowAuthorization");
if (isAlwaysAllowAuthorization)
{
//绕过授权服务,用于测试
context.Services.AddAlwaysAllowAuthorization();
}
else
{
//context.Services.AddAuthentication("Bearer")
// .AddIdentityServerAuthentication(options =>
// {
// options.Authority = configuration["AuthServer:Authority"];
// options.RequireHttpsMetadata = false;
// options.ApiName = "SettleAccount";
// });
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = false;
options.Audience = "SettleAccount";
});
}
}
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
{
var defaultBranchId = configuration["DefaultBranchId"];
context.Services.AddSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Settle Account Service API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
//解决相同方法名冲突
options.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
options.OperationFilter<BranchHeaderParameter>(defaultBranchId);
var xmlapppath = Path.Combine(AppContext.BaseDirectory, "SettleAccount.Application.xml");
if (File.Exists(xmlapppath))
{
options.IncludeXmlComments(xmlapppath, true);
}
xmlapppath = Path.Combine(AppContext.BaseDirectory, "SettleAccount.Application.Contracts.xml");
if (File.Exists(xmlapppath))
{
options.IncludeXmlComments(xmlapppath, true);
}
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "请输入 JWT Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference {Type = ReferenceType.SecurityScheme, Id = "Bearer"}
},
Array.Empty<string>()
}
});
});
}
private void ConfigureLocalization()
{
Configure<AbpLocalizationOptions>(options =>
{
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
});
}
private void ConfigureRedis(
ServiceConfigurationContext context,
IConfiguration configuration)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
//context.Services.AddStackExchangeRedisCache(options =>
//{
// options.Configuration = configuration["Redis:Configuration"];
//});
//if (!hostingEnvironment.IsDevelopment())
//{
// var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
// context.Services
// .AddDataProtection()
// .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
//}
}
private void ConfigureHangfire(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddHangfire(config =>
{
config.UseSqlServerStorage(configuration.GetConnectionString("SettleAccountService"), new Hangfire.SqlServer.SqlServerStorageOptions
{
PrepareSchemaIfNecessary = true
});
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseCorrelationId();
//app.UseVirtualFiles();
app.UseRouting();
app.UseCors(DefaultCorsPolicyName);
app.UseAuthentication();
app.UseAuthorization();
app.UseAbpClaimsMap();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseAbpRequestLocalization();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Settle Account Service API");
options.DocExpansion(DocExpansion.None); //->修改界面打开时自动折叠
});
new BackgroundJobServerOptions() { WorkerCount = 12, ServerTimeout = TimeSpan.FromSeconds(1200) };
app.UseHangfireServer();
app.UseHangfireDashboard();
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
AsyncHelper.RunSync(async () =>
{
using (var scope = context.ServiceProvider.CreateScope())
{
await scope.ServiceProvider
.GetRequiredService<IDataSeeder>()
.SeedAsync().ConfigureAwait(false);
}
});
}
}
public class CustomExceptionFilter : IExceptionFilter
{
private readonly ILogger<CustomExceptionFilter> logger;
public CustomExceptionFilter(ILogger<CustomExceptionFilter> logger)
{
this.logger = logger;
}
public void OnException(ExceptionContext context)
{
logger.LogError(new EventId(context.Exception.HResult), context.Exception, context.Exception.Message);
var message = context.Exception.InnerException?.InnerException?.Message ?? context.Exception.Message;
context.Result = new JsonResult(new { code = 400, message });
context.ExceptionHandled = true;
}
}
}