Compare commits
	
		
			9 Commits
		
	
	
		
			dv_onion
			...
			4e465563c4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4e465563c4 | |||
| 8bb4f18be3 | |||
| 2709816ccd | |||
| ea0d6d21f0 | |||
| 36759da784 | |||
| 26db968945 | |||
| dbde1486e2 | |||
| b545a603b0 | |||
| 6f2a1d1990 | 
| @ -1,7 +1,6 @@ | ||||
| FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base | ||||
| USER $APP_UID | ||||
| WORKDIR /app | ||||
| EXPOSE 8080 | ||||
| EXPOSE 8081 | ||||
|  | ||||
| FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build | ||||
| @ -9,15 +8,21 @@ ARG BUILD_CONFIGURATION=Release | ||||
| WORKDIR /src | ||||
| COPY ["NuGet.Config", "."] | ||||
| COPY ["applications/KonSoft.AuthServer/KonSoft.AuthServer.csproj", "applications/KonSoft.AuthServer/"] | ||||
| COPY ["shared/KonSoft.Shared.Hosting.Microservices/KonSoft.Shared.Hosting.Microservices.csproj", "shared/KonSoft.Shared.Hosting.Microservices/"] | ||||
| COPY ["shared/KonSoft.Shared.Hosting.AspNetCore/KonSoft.Shared.Hosting.AspNetCore.csproj", "shared/KonSoft.Shared.Hosting.AspNetCore/"] | ||||
| COPY ["shared/KonSoft.Shared.Hosting/KonSoft.Shared.Hosting.csproj", "shared/KonSoft.Shared.Hosting/"] | ||||
| COPY ["shared/KonSoft.Shared.Localization/KonSoft.Shared.Localization.csproj", "shared/KonSoft.Shared.Localization/"] | ||||
| RUN dotnet restore "./applications/KonSoft.AuthServer/KonSoft.AuthServer.csproj" | ||||
| COPY . . | ||||
| WORKDIR "/src/applications/KonSoft.AuthServer" | ||||
| RUN dotnet build "./KonSoft.AuthServer.csproj" -c $BUILD_CONFIGURATION -o /app/build | ||||
|  | ||||
| # 此阶段用于发布要复制到最终阶段的服务项目 | ||||
| FROM build AS publish | ||||
| ARG BUILD_CONFIGURATION=Release | ||||
| RUN dotnet publish "./KonSoft.AuthServer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false | ||||
|  | ||||
| # 此阶段在生产中使用,或在常规模式下从 VS 运行时使用(在不使用调试配置时为默认值) | ||||
| FROM base AS final | ||||
| WORKDIR /app | ||||
| COPY --from=publish /app/publish . | ||||
|  | ||||
| @ -39,22 +39,11 @@ | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.22.1" /> | ||||
|     <PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> | ||||
|     <PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.4" /> | ||||
|     <PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
| 		<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.22.1" /> | ||||
| 		<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" Version="8.3.4" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Volo.Abp.Autofac" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.DistributedLocking" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Account.Web.OpenIddict" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Account.Application" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Account.HttpApi" Version="8.3.4" /> | ||||
|  | ||||
| @ -1,38 +1,13 @@ | ||||
| { | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "profiles": { | ||||
|     "IIS Express": { | ||||
|       "commandName": "IISExpress", | ||||
|       "launchBrowser": true, | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "KonSoft.AuthServer": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
|       "launchBrowser": true, | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       }, | ||||
|       "applicationUrl": "https://localhost:44322" | ||||
|     }, | ||||
|     "Container (Dockerfile)": { | ||||
|       "commandName": "Docker", | ||||
|       "launchBrowser": true, | ||||
|       "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_HTTPS_PORTS": "8081", | ||||
|         "ASPNETCORE_HTTP_PORTS": "8080" | ||||
|       }, | ||||
|       "publishAllPorts": true, | ||||
|       "useSSL": true | ||||
|     } | ||||
|   }, | ||||
|   "iisSettings": { | ||||
|     "windowsAuthentication": false, | ||||
|     "anonymousAuthentication": true, | ||||
|     "iisExpress": { | ||||
|       "applicationUrl": "https://localhost:44322", | ||||
|       "sslPort": 44322 | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -1,13 +1,5 @@ | ||||
| { | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "iisSettings": { | ||||
|     "windowsAuthentication": false, | ||||
|     "anonymousAuthentication": true, | ||||
|     "iisExpress": { | ||||
|       "applicationUrl": "http://localhost:4773", | ||||
|       "sslPort": 44380 | ||||
|     } | ||||
|   }, | ||||
|   "profiles": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
| @ -18,24 +10,6 @@ | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "https": { | ||||
|       "commandName": "Project", | ||||
|       "dotnetRunMessages": true, | ||||
|       "launchBrowser": true, | ||||
|       "launchUrl": "swagger", | ||||
|       "applicationUrl": "https://localhost:7094;http://localhost:5243", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "IIS Express": { | ||||
|       "commandName": "IISExpress", | ||||
|       "launchBrowser": true, | ||||
|       "launchUrl": "swagger", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,13 +1,5 @@ | ||||
| { | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "iisSettings": { | ||||
|     "windowsAuthentication": false, | ||||
|     "anonymousAuthentication": true, | ||||
|     "iisExpress": { | ||||
|       "applicationUrl": "http://localhost:22937", | ||||
|       "sslPort": 44300 | ||||
|     } | ||||
|   }, | ||||
|   "profiles": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
| @ -18,24 +10,6 @@ | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "https": { | ||||
|       "commandName": "Project", | ||||
|       "dotnetRunMessages": true, | ||||
|       "launchBrowser": true, | ||||
|       "launchUrl": "swagger", | ||||
|       "applicationUrl": "https://localhost:7183;http://localhost:5074", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "IIS Express": { | ||||
|       "commandName": "IISExpress", | ||||
|       "launchBrowser": true, | ||||
|       "launchUrl": "swagger", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,14 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp.Data; | ||||
| using Volo.Abp.DependencyInjection; | ||||
|  | ||||
| namespace KonSoft.Admin.DbMigrations | ||||
| { | ||||
|     public class AdminDataSeeder : IDataSeedContributor, ITransientDependency | ||||
|     { | ||||
|         public Task SeedAsync(DataSeedContext context) | ||||
|         { | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| using System; | ||||
| using KonSoft.Admin.EntityFrameworkCore; | ||||
| using KonSoft.Shared.Hosting.Microservices.DbMigrations.EfCore; | ||||
| using Volo.Abp.DistributedLocking; | ||||
| using Volo.Abp.EventBus.Distributed; | ||||
| using Volo.Abp.MultiTenancy; | ||||
| using Volo.Abp.Uow; | ||||
|  | ||||
| namespace KonSoft.Admin.DbMigrations | ||||
| { | ||||
|     public class AdminPendingEfCoreMigrationsChecker : PendingEfCoreMigrationsChecker<AdminDbContext> | ||||
|     { | ||||
|         public AdminPendingEfCoreMigrationsChecker(IUnitOfWorkManager unitOfWorkManager, | ||||
|             IServiceProvider serviceProvider, | ||||
|             ICurrentTenant currentTenant, | ||||
|             IDistributedEventBus distributedEventBus, | ||||
|             IAbpDistributedLock abpDistributedLock) : base(unitOfWorkManager, | ||||
|             serviceProvider, | ||||
|             currentTenant, | ||||
|             distributedEventBus, | ||||
|             abpDistributedLock, | ||||
|             "Clean") | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -2,8 +2,9 @@ FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base | ||||
| USER $APP_UID | ||||
| WORKDIR /app | ||||
| EXPOSE 8080 | ||||
| EXPOSE 8081 | ||||
|  | ||||
|  | ||||
| # 此阶段用于生成服务项目 | ||||
| FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build | ||||
| ARG BUILD_CONFIGURATION=Release | ||||
| WORKDIR /src | ||||
| @ -15,6 +16,10 @@ COPY ["modules/admin/src/KonSoft.Admin.Domain.Shared/KonSoft.Admin.Domain.Shared | ||||
| COPY ["modules/admin/src/KonSoft.Admin.Application.Contracts/KonSoft.Admin.Application.Contracts.csproj", "modules/admin/src/KonSoft.Admin.Application.Contracts/"] | ||||
| COPY ["modules/admin/src/KonSoft.Admin.EntityFrameworkCore/KonSoft.Admin.EntityFrameworkCore.csproj", "modules/admin/src/KonSoft.Admin.EntityFrameworkCore/"] | ||||
| COPY ["modules/admin/src/KonSoft.Admin.HttpApi/KonSoft.Admin.HttpApi.csproj", "modules/admin/src/KonSoft.Admin.HttpApi/"] | ||||
| COPY ["shared/KonSoft.Shared.Hosting.Microservices/KonSoft.Shared.Hosting.Microservices.csproj", "shared/KonSoft.Shared.Hosting.Microservices/"] | ||||
| COPY ["shared/KonSoft.Shared.Hosting.AspNetCore/KonSoft.Shared.Hosting.AspNetCore.csproj", "shared/KonSoft.Shared.Hosting.AspNetCore/"] | ||||
| COPY ["shared/KonSoft.Shared.Hosting/KonSoft.Shared.Hosting.csproj", "shared/KonSoft.Shared.Hosting/"] | ||||
| COPY ["shared/KonSoft.Shared.Localization/KonSoft.Shared.Localization.csproj", "shared/KonSoft.Shared.Localization/"] | ||||
| RUN dotnet restore "./microservices/KonSoft.Admin.HttpApi.Host/KonSoft.Admin.HttpApi.Host.csproj" | ||||
| COPY . . | ||||
| WORKDIR "/src/microservices/KonSoft.Admin.HttpApi.Host" | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net8.0</TargetFramework> | ||||
|  | ||||
| @ -1,23 +1,13 @@ | ||||
| { | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "profiles": { | ||||
|     "KonSoft.Admin.HttpApi.Host": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
|       "launchBrowser": true, | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       }, | ||||
|       "applicationUrl": "https://localhost:44354" | ||||
|     }, | ||||
|     "Container (Dockerfile)": { | ||||
|       "commandName": "Docker", | ||||
|       "launchBrowser": true, | ||||
|       "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_HTTPS_PORTS": "8081", | ||||
|         "ASPNETCORE_HTTP_PORTS": "8080" | ||||
|       }, | ||||
|       "publishAllPorts": true, | ||||
|       "useSSL": true | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -1,179 +1,38 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using Medallion.Threading; | ||||
| using Medallion.Threading.Redis; | ||||
| using Microsoft.AspNetCore.Authentication.JwtBearer; | ||||
| using KonSoft.Dispatch.EntityFrameworkCore; | ||||
| using KonSoft.Shared.Hosting.AspNetCore; | ||||
| using KonSoft.Shared.Hosting.Microservices; | ||||
| using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Microsoft.AspNetCore.DataProtection; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Hosting; | ||||
| using KonSoft.Dispatch.EntityFrameworkCore; | ||||
| using KonSoft.Dispatch.MultiTenancy; | ||||
| using StackExchange.Redis; | ||||
| using Microsoft.OpenApi.Models; | ||||
| using Volo.Abp; | ||||
| using Volo.Abp.AspNetCore.Authentication.JwtBearer; | ||||
| using Volo.Abp.AspNetCore.Mvc; | ||||
| using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; | ||||
| using Volo.Abp.AspNetCore.Serilog; | ||||
| using Volo.Abp.Autofac; | ||||
| using Volo.Abp.Caching; | ||||
| using Volo.Abp.Caching.StackExchangeRedis; | ||||
| using Volo.Abp.DistributedLocking; | ||||
| using Volo.Abp.Identity; | ||||
| using Volo.Abp.Localization; | ||||
| using Volo.Abp.BackgroundJobs; | ||||
| using Volo.Abp.Modularity; | ||||
| using Volo.Abp.Security.Claims; | ||||
| using Volo.Abp.Swashbuckle; | ||||
| using Volo.Abp.VirtualFileSystem; | ||||
|  | ||||
| namespace KonSoft.Dispatch; | ||||
|  | ||||
| [DependsOn( | ||||
|     typeof(DispatchHttpApiModule), | ||||
|     typeof(AbpAutofacModule), | ||||
|     typeof(AbpCachingStackExchangeRedisModule), | ||||
|     typeof(AbpDistributedLockingModule), | ||||
|     typeof(AbpAspNetCoreMvcUiMultiTenancyModule), | ||||
|     typeof(AbpAspNetCoreAuthenticationJwtBearerModule), | ||||
|     typeof(DispatchApplicationModule), | ||||
|     typeof(DispatchEntityFrameworkCoreModule), | ||||
|     typeof(AbpAspNetCoreSerilogModule), | ||||
|     typeof(AbpSwashbuckleModule) | ||||
|     typeof(KonSoftSharedHostingMicroservicesModule) | ||||
| )] | ||||
| public class DispatchHttpApiHostModule : AbpModule | ||||
| { | ||||
|     public override void ConfigureServices(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var configuration = context.Services.GetConfiguration(); | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         ConfigureConventionalControllers(); | ||||
|         ConfigureAuthentication(context, configuration); | ||||
|         ConfigureCache(configuration); | ||||
|         ConfigureVirtualFileSystem(context); | ||||
|         ConfigureDataProtection(context, configuration, hostingEnvironment); | ||||
|         ConfigureDistributedLocking(context, configuration); | ||||
|         ConfigureCors(context, configuration); | ||||
|         ConfigureSwaggerServices(context, configuration); | ||||
|     } | ||||
|         SwaggerConfigurationHelper.ConfigureWithOidc( | ||||
|             context: context, | ||||
|             authority: configuration["AuthServer:Authority"]!, | ||||
|             scopes: ["DispatchService"], | ||||
|             discoveryEndpoint: configuration["AuthServer:MetadataAddress"], | ||||
|             apiTitle: "Dispatch Service API" | ||||
|         ); | ||||
|  | ||||
|     private void ConfigureCache(IConfiguration configuration) | ||||
|     { | ||||
|         Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "Dispatch:"; }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         if (hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             Configure<AbpVirtualFileSystemOptions>(options => | ||||
|             { | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<DispatchDomainSharedModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Dispatch.Domain.Shared")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<DispatchDomainModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Dispatch.Domain")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<DispatchApplicationContractsModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Dispatch.Application.Contracts")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<DispatchApplicationModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Dispatch.Application")); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureConventionalControllers() | ||||
|     { | ||||
|         Configure<AbpAspNetCoreMvcOptions>(options => | ||||
|         { | ||||
|             options.ConventionalControllers.Create(typeof(DispatchApplicationModule).Assembly); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | ||||
|             .AddAbpJwtBearer(options => | ||||
|             { | ||||
|                 options.Authority = configuration["AuthServer:Authority"]; | ||||
|                 options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"); | ||||
|                 options.Audience = "Dispatch"; | ||||
|             }); | ||||
|  | ||||
|         context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options => | ||||
|         { | ||||
|             options.IsDynamicClaimsEnabled = true; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAbpSwaggerGenWithOAuth( | ||||
|             configuration["AuthServer:Authority"]!, | ||||
|             new Dictionary<string, string> | ||||
|             { | ||||
|                     {"Dispatch", "Dispatch API"} | ||||
|             }, | ||||
|             options => | ||||
|             { | ||||
|                 options.SwaggerDoc("v1", new OpenApiInfo { Title = "Dispatch API", Version = "v1" }); | ||||
|                 options.DocInclusionPredicate((docName, description) => true); | ||||
|                 options.CustomSchemaIds(type => type.FullName); | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDataProtection( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration, | ||||
|         IWebHostEnvironment hostingEnvironment) | ||||
|     { | ||||
|         var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("Dispatch"); | ||||
|         if (!hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "Dispatch-Protection-Keys"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDistributedLocking( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddSingleton<IDistributedLockProvider>(sp => | ||||
|         { | ||||
|             var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddCors(options => | ||||
|         { | ||||
|             options.AddDefaultPolicy(builder => | ||||
|             { | ||||
|                 builder | ||||
|                     .WithOrigins(configuration["App:CorsOrigins"]? | ||||
|                         .Split(",", StringSplitOptions.RemoveEmptyEntries) | ||||
|                         .Select(o => o.RemovePostFix("/")) | ||||
|                         .ToArray() ?? []) | ||||
|                     .WithAbpExposedHeaders() | ||||
|                     .SetIsOriginAllowedToAllowWildcardSubdomains() | ||||
|                     .AllowAnyHeader() | ||||
|                     .AllowAnyMethod() | ||||
|                     .AllowCredentials(); | ||||
|             }); | ||||
|         }); | ||||
|         // ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD> | ||||
|         Configure<AbpBackgroundJobOptions>(options => options.IsJobExecutionEnabled = false); | ||||
|     } | ||||
|  | ||||
|     public override void OnApplicationInitialization(ApplicationInitializationContext context) | ||||
| @ -193,7 +52,7 @@ public class DispatchHttpApiHostModule : AbpModule | ||||
|         app.UseCors(); | ||||
|         app.UseAuthentication(); | ||||
|  | ||||
|         if (MultiTenancyConsts.IsEnabled) | ||||
|         if (KonSoftConsts.MultiTenancyEnabled) | ||||
|         { | ||||
|             app.UseMultiTenancy(); | ||||
|         } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net8.0</TargetFramework> | ||||
| @ -8,21 +8,6 @@ | ||||
|     <UserSecretsId>KonSoft.Dispatch-4681b4fd-151f-4221-84a4-929d86723e4c</UserSecretsId> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> | ||||
|     <PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.4" /> | ||||
|     <PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Autofac" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.DistributedLocking" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Swashbuckle" Version="8.3.4" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Compile Remove="Logs\**" /> | ||||
|     <Content Remove="Logs\**" /> | ||||
| @ -34,6 +19,7 @@ | ||||
|     <ProjectReference Include="..\..\modules\dispatch\src\KonSoft.Dispatch.Application\KonSoft.Dispatch.Application.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\dispatch\src\KonSoft.Dispatch.EntityFrameworkCore\KonSoft.Dispatch.EntityFrameworkCore.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\dispatch\src\KonSoft.Dispatch.HttpApi\KonSoft.Dispatch.HttpApi.csproj" /> | ||||
|     <ProjectReference Include="..\..\shared\KonSoft.Shared.Hosting.Microservices\KonSoft.Shared.Hosting.Microservices.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|  | ||||
| @ -1,27 +1,13 @@ | ||||
| { | ||||
|   "iisSettings": { | ||||
|     "windowsAuthentication": false,  | ||||
|     "anonymousAuthentication": true, | ||||
|     "iisExpress": { | ||||
|       "applicationUrl": "https://localhost:44331", | ||||
|       "sslPort": 44331 | ||||
|     } | ||||
|   }, | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "profiles": { | ||||
|     "IIS Express": { | ||||
|       "commandName": "IISExpress", | ||||
|       "launchBrowser": true, | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "KonSoft.Dispatch.HttpApi.Host": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
|       "launchBrowser": true, | ||||
|       "applicationUrl": "https://localhost:44331", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|       }, | ||||
|       "applicationUrl": "https://localhost:44331" | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -8,21 +8,6 @@ | ||||
|     <UserSecretsId>KonSoft.Payment-4681b4fd-151f-4221-84a4-929d86723e4c</UserSecretsId> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> | ||||
|     <PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.4" /> | ||||
|     <PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Autofac" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.DistributedLocking" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Swashbuckle" Version="8.3.4" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Compile Remove="Logs\**" /> | ||||
|     <Content Remove="Logs\**" /> | ||||
| @ -34,6 +19,7 @@ | ||||
|     <ProjectReference Include="..\..\modules\payment\src\KonSoft.Payment.Application\KonSoft.Payment.Application.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\payment\src\KonSoft.Payment.EntityFrameworkCore\KonSoft.Payment.EntityFrameworkCore.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\payment\src\KonSoft.Payment.HttpApi\KonSoft.Payment.HttpApi.csproj" /> | ||||
|     <ProjectReference Include="..\..\shared\KonSoft.Shared.Hosting.Microservices\KonSoft.Shared.Hosting.Microservices.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|  | ||||
| @ -1,179 +1,38 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using Medallion.Threading; | ||||
| using Medallion.Threading.Redis; | ||||
| using Microsoft.AspNetCore.Authentication.JwtBearer; | ||||
| using KonSoft.Payment.EntityFrameworkCore; | ||||
| using KonSoft.Shared.Hosting.AspNetCore; | ||||
| using KonSoft.Shared.Hosting.Microservices; | ||||
| using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Microsoft.AspNetCore.DataProtection; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Hosting; | ||||
| using KonSoft.Payment.EntityFrameworkCore; | ||||
| using KonSoft.Payment.MultiTenancy; | ||||
| using StackExchange.Redis; | ||||
| using Microsoft.OpenApi.Models; | ||||
| using Volo.Abp; | ||||
| using Volo.Abp.AspNetCore.Authentication.JwtBearer; | ||||
| using Volo.Abp.AspNetCore.Mvc; | ||||
| using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; | ||||
| using Volo.Abp.AspNetCore.Serilog; | ||||
| using Volo.Abp.Autofac; | ||||
| using Volo.Abp.Caching; | ||||
| using Volo.Abp.Caching.StackExchangeRedis; | ||||
| using Volo.Abp.DistributedLocking; | ||||
| using Volo.Abp.Identity; | ||||
| using Volo.Abp.Localization; | ||||
| using Volo.Abp.BackgroundJobs; | ||||
| using Volo.Abp.Modularity; | ||||
| using Volo.Abp.Security.Claims; | ||||
| using Volo.Abp.Swashbuckle; | ||||
| using Volo.Abp.VirtualFileSystem; | ||||
|  | ||||
| namespace KonSoft.Payment; | ||||
|  | ||||
| [DependsOn( | ||||
|     typeof(PaymentHttpApiModule), | ||||
|     typeof(AbpAutofacModule), | ||||
|     typeof(AbpCachingStackExchangeRedisModule), | ||||
|     typeof(AbpDistributedLockingModule), | ||||
|     typeof(AbpAspNetCoreMvcUiMultiTenancyModule), | ||||
|     typeof(AbpAspNetCoreAuthenticationJwtBearerModule), | ||||
|     typeof(PaymentApplicationModule), | ||||
|     typeof(PaymentEntityFrameworkCoreModule), | ||||
|     typeof(AbpAspNetCoreSerilogModule), | ||||
|     typeof(AbpSwashbuckleModule) | ||||
|     typeof(KonSoftSharedHostingMicroservicesModule) | ||||
| )] | ||||
| public class PaymentHttpApiHostModule : AbpModule | ||||
| { | ||||
|     public override void ConfigureServices(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var configuration = context.Services.GetConfiguration(); | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         ConfigureConventionalControllers(); | ||||
|         ConfigureAuthentication(context, configuration); | ||||
|         ConfigureCache(configuration); | ||||
|         ConfigureVirtualFileSystem(context); | ||||
|         ConfigureDataProtection(context, configuration, hostingEnvironment); | ||||
|         ConfigureDistributedLocking(context, configuration); | ||||
|         ConfigureCors(context, configuration); | ||||
|         ConfigureSwaggerServices(context, configuration); | ||||
|     } | ||||
|         SwaggerConfigurationHelper.ConfigureWithOidc( | ||||
|             context: context, | ||||
|             authority: configuration["AuthServer:Authority"]!, | ||||
|             scopes: ["PaymentService"], | ||||
|             discoveryEndpoint: configuration["AuthServer:MetadataAddress"], | ||||
|             apiTitle: "Payment Service API" | ||||
|         ); | ||||
|  | ||||
|     private void ConfigureCache(IConfiguration configuration) | ||||
|     { | ||||
|         Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "Payment:"; }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         if (hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             Configure<AbpVirtualFileSystemOptions>(options => | ||||
|             { | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<PaymentDomainSharedModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Payment.Domain.Shared")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<PaymentDomainModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Payment.Domain")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<PaymentApplicationContractsModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Payment.Application.Contracts")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<PaymentApplicationModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Payment.Application")); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureConventionalControllers() | ||||
|     { | ||||
|         Configure<AbpAspNetCoreMvcOptions>(options => | ||||
|         { | ||||
|             options.ConventionalControllers.Create(typeof(PaymentApplicationModule).Assembly); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | ||||
|             .AddAbpJwtBearer(options => | ||||
|             { | ||||
|                 options.Authority = configuration["AuthServer:Authority"]; | ||||
|                 options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"); | ||||
|                 options.Audience = "Payment"; | ||||
|             }); | ||||
|  | ||||
|         context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options => | ||||
|         { | ||||
|             options.IsDynamicClaimsEnabled = true; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAbpSwaggerGenWithOAuth( | ||||
|             configuration["AuthServer:Authority"]!, | ||||
|             new Dictionary<string, string> | ||||
|             { | ||||
|                     {"Payment", "Payment API"} | ||||
|             }, | ||||
|             options => | ||||
|             { | ||||
|                 options.SwaggerDoc("v1", new OpenApiInfo { Title = "Payment API", Version = "v1" }); | ||||
|                 options.DocInclusionPredicate((docName, description) => true); | ||||
|                 options.CustomSchemaIds(type => type.FullName); | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDataProtection( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration, | ||||
|         IWebHostEnvironment hostingEnvironment) | ||||
|     { | ||||
|         var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("Payment"); | ||||
|         if (!hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "Payment-Protection-Keys"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDistributedLocking( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddSingleton<IDistributedLockProvider>(sp => | ||||
|         { | ||||
|             var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddCors(options => | ||||
|         { | ||||
|             options.AddDefaultPolicy(builder => | ||||
|             { | ||||
|                 builder | ||||
|                     .WithOrigins(configuration["App:CorsOrigins"]? | ||||
|                         .Split(",", StringSplitOptions.RemoveEmptyEntries) | ||||
|                         .Select(o => o.RemovePostFix("/")) | ||||
|                         .ToArray() ?? []) | ||||
|                     .WithAbpExposedHeaders() | ||||
|                     .SetIsOriginAllowedToAllowWildcardSubdomains() | ||||
|                     .AllowAnyHeader() | ||||
|                     .AllowAnyMethod() | ||||
|                     .AllowCredentials(); | ||||
|             }); | ||||
|         }); | ||||
|         // ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD> | ||||
|         Configure<AbpBackgroundJobOptions>(options => options.IsJobExecutionEnabled = false); | ||||
|     } | ||||
|  | ||||
|     public override void OnApplicationInitialization(ApplicationInitializationContext context) | ||||
| @ -193,7 +52,7 @@ public class PaymentHttpApiHostModule : AbpModule | ||||
|         app.UseCors(); | ||||
|         app.UseAuthentication(); | ||||
|  | ||||
|         if (MultiTenancyConsts.IsEnabled) | ||||
|         if (KonSoftConsts.MultiTenancyEnabled) | ||||
|         { | ||||
|             app.UseMultiTenancy(); | ||||
|         } | ||||
|  | ||||
| @ -1,27 +1,13 @@ | ||||
| { | ||||
|   "iisSettings": { | ||||
|     "windowsAuthentication": false,  | ||||
|     "anonymousAuthentication": true, | ||||
|     "iisExpress": { | ||||
|       "applicationUrl": "https://localhost:44326", | ||||
|       "sslPort": 44326 | ||||
|     } | ||||
|   }, | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "profiles": { | ||||
|     "IIS Express": { | ||||
|       "commandName": "IISExpress", | ||||
|       "launchBrowser": true, | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "KonSoft.Payment.HttpApi.Host": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
|       "launchBrowser": true, | ||||
|       "applicationUrl": "https://localhost:44326", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|       }, | ||||
|       "applicationUrl": "https://localhost:44326" | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -8,21 +8,6 @@ | ||||
|     <UserSecretsId>KonSoft.Report-4681b4fd-151f-4221-84a4-929d86723e4c</UserSecretsId> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> | ||||
|     <PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.4" /> | ||||
|     <PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Autofac" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.DistributedLocking" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Swashbuckle" Version="8.3.4" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Compile Remove="Logs\**" /> | ||||
|     <Content Remove="Logs\**" /> | ||||
| @ -34,6 +19,7 @@ | ||||
|     <ProjectReference Include="..\..\modules\report\src\KonSoft.Report.Application\KonSoft.Report.Application.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\report\src\KonSoft.Report.EntityFrameworkCore\KonSoft.Report.EntityFrameworkCore.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\report\src\KonSoft.Report.HttpApi\KonSoft.Report.HttpApi.csproj" /> | ||||
|     <ProjectReference Include="..\..\shared\KonSoft.Shared.Hosting.Microservices\KonSoft.Shared.Hosting.Microservices.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|  | ||||
| @ -1,27 +1,13 @@ | ||||
| { | ||||
|   "iisSettings": { | ||||
|     "windowsAuthentication": false,  | ||||
|     "anonymousAuthentication": true, | ||||
|     "iisExpress": { | ||||
|       "applicationUrl": "https://localhost:44320", | ||||
|       "sslPort": 44320 | ||||
|     } | ||||
|   }, | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "profiles": { | ||||
|     "IIS Express": { | ||||
|       "commandName": "IISExpress", | ||||
|       "launchBrowser": true, | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "KonSoft.Report.HttpApi.Host": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
|       "launchBrowser": true, | ||||
|       "applicationUrl": "https://localhost:44320", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|       }, | ||||
|       "applicationUrl": "https://localhost:44320" | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -1,179 +1,38 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using Medallion.Threading; | ||||
| using Medallion.Threading.Redis; | ||||
| using Microsoft.AspNetCore.Authentication.JwtBearer; | ||||
| using KonSoft.Report.EntityFrameworkCore; | ||||
| using KonSoft.Shared.Hosting.AspNetCore; | ||||
| using KonSoft.Shared.Hosting.Microservices; | ||||
| using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Microsoft.AspNetCore.DataProtection; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Hosting; | ||||
| using KonSoft.Report.EntityFrameworkCore; | ||||
| using KonSoft.Report.MultiTenancy; | ||||
| using StackExchange.Redis; | ||||
| using Microsoft.OpenApi.Models; | ||||
| using Volo.Abp; | ||||
| using Volo.Abp.AspNetCore.Authentication.JwtBearer; | ||||
| using Volo.Abp.AspNetCore.Mvc; | ||||
| using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; | ||||
| using Volo.Abp.AspNetCore.Serilog; | ||||
| using Volo.Abp.Autofac; | ||||
| using Volo.Abp.Caching; | ||||
| using Volo.Abp.Caching.StackExchangeRedis; | ||||
| using Volo.Abp.DistributedLocking; | ||||
| using Volo.Abp.Identity; | ||||
| using Volo.Abp.Localization; | ||||
| using Volo.Abp.BackgroundJobs; | ||||
| using Volo.Abp.Modularity; | ||||
| using Volo.Abp.Security.Claims; | ||||
| using Volo.Abp.Swashbuckle; | ||||
| using Volo.Abp.VirtualFileSystem; | ||||
|  | ||||
| namespace KonSoft.Report; | ||||
|  | ||||
| [DependsOn( | ||||
|     typeof(ReportHttpApiModule), | ||||
|     typeof(AbpAutofacModule), | ||||
|     typeof(AbpCachingStackExchangeRedisModule), | ||||
|     typeof(AbpDistributedLockingModule), | ||||
|     typeof(AbpAspNetCoreMvcUiMultiTenancyModule), | ||||
|     typeof(AbpAspNetCoreAuthenticationJwtBearerModule), | ||||
|     typeof(ReportApplicationModule), | ||||
|     typeof(ReportEntityFrameworkCoreModule), | ||||
|     typeof(AbpAspNetCoreSerilogModule), | ||||
|     typeof(AbpSwashbuckleModule) | ||||
|     typeof(KonSoftSharedHostingMicroservicesModule) | ||||
| )] | ||||
| public class ReportHttpApiHostModule : AbpModule | ||||
| { | ||||
|     public override void ConfigureServices(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var configuration = context.Services.GetConfiguration(); | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         ConfigureConventionalControllers(); | ||||
|         ConfigureAuthentication(context, configuration); | ||||
|         ConfigureCache(configuration); | ||||
|         ConfigureVirtualFileSystem(context); | ||||
|         ConfigureDataProtection(context, configuration, hostingEnvironment); | ||||
|         ConfigureDistributedLocking(context, configuration); | ||||
|         ConfigureCors(context, configuration); | ||||
|         ConfigureSwaggerServices(context, configuration); | ||||
|     } | ||||
|         SwaggerConfigurationHelper.ConfigureWithOidc( | ||||
|             context: context, | ||||
|             authority: configuration["AuthServer:Authority"]!, | ||||
|             scopes: ["ReportService"], | ||||
|             discoveryEndpoint: configuration["AuthServer:MetadataAddress"], | ||||
|             apiTitle: "Report Service API" | ||||
|         ); | ||||
|  | ||||
|     private void ConfigureCache(IConfiguration configuration) | ||||
|     { | ||||
|         Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "Report:"; }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         if (hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             Configure<AbpVirtualFileSystemOptions>(options => | ||||
|             { | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<ReportDomainSharedModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Report.Domain.Shared")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<ReportDomainModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Report.Domain")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<ReportApplicationContractsModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Report.Application.Contracts")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<ReportApplicationModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.Report.Application")); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureConventionalControllers() | ||||
|     { | ||||
|         Configure<AbpAspNetCoreMvcOptions>(options => | ||||
|         { | ||||
|             options.ConventionalControllers.Create(typeof(ReportApplicationModule).Assembly); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | ||||
|             .AddAbpJwtBearer(options => | ||||
|             { | ||||
|                 options.Authority = configuration["AuthServer:Authority"]; | ||||
|                 options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"); | ||||
|                 options.Audience = "Report"; | ||||
|             }); | ||||
|  | ||||
|         context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options => | ||||
|         { | ||||
|             options.IsDynamicClaimsEnabled = true; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAbpSwaggerGenWithOAuth( | ||||
|             configuration["AuthServer:Authority"]!, | ||||
|             new Dictionary<string, string> | ||||
|             { | ||||
|                     {"Report", "Report API"} | ||||
|             }, | ||||
|             options => | ||||
|             { | ||||
|                 options.SwaggerDoc("v1", new OpenApiInfo { Title = "Report API", Version = "v1" }); | ||||
|                 options.DocInclusionPredicate((docName, description) => true); | ||||
|                 options.CustomSchemaIds(type => type.FullName); | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDataProtection( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration, | ||||
|         IWebHostEnvironment hostingEnvironment) | ||||
|     { | ||||
|         var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("Report"); | ||||
|         if (!hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "Report-Protection-Keys"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDistributedLocking( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddSingleton<IDistributedLockProvider>(sp => | ||||
|         { | ||||
|             var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddCors(options => | ||||
|         { | ||||
|             options.AddDefaultPolicy(builder => | ||||
|             { | ||||
|                 builder | ||||
|                     .WithOrigins(configuration["App:CorsOrigins"]? | ||||
|                         .Split(",", StringSplitOptions.RemoveEmptyEntries) | ||||
|                         .Select(o => o.RemovePostFix("/")) | ||||
|                         .ToArray() ?? []) | ||||
|                     .WithAbpExposedHeaders() | ||||
|                     .SetIsOriginAllowedToAllowWildcardSubdomains() | ||||
|                     .AllowAnyHeader() | ||||
|                     .AllowAnyMethod() | ||||
|                     .AllowCredentials(); | ||||
|             }); | ||||
|         }); | ||||
|         // ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD> | ||||
|         Configure<AbpBackgroundJobOptions>(options => options.IsJobExecutionEnabled = false); | ||||
|     } | ||||
|  | ||||
|     public override void OnApplicationInitialization(ApplicationInitializationContext context) | ||||
| @ -193,7 +52,7 @@ public class ReportHttpApiHostModule : AbpModule | ||||
|         app.UseCors(); | ||||
|         app.UseAuthentication(); | ||||
|  | ||||
|         if (MultiTenancyConsts.IsEnabled) | ||||
|         if (KonSoftConsts.MultiTenancyEnabled) | ||||
|         { | ||||
|             app.UseMultiTenancy(); | ||||
|         } | ||||
|  | ||||
| @ -8,21 +8,6 @@ | ||||
|     <UserSecretsId>KonSoft.TenantManagement-4681b4fd-151f-4221-84a4-929d86723e4c</UserSecretsId> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> | ||||
|     <PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.4" /> | ||||
|     <PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Autofac" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.DistributedLocking" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="8.3.4" /> | ||||
|     <PackageReference Include="Volo.Abp.Swashbuckle" Version="8.3.4" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Compile Remove="Logs\**" /> | ||||
|     <Content Remove="Logs\**" /> | ||||
| @ -34,6 +19,7 @@ | ||||
|     <ProjectReference Include="..\..\modules\tenant-management\src\KonSoft.TenantManagement.Application\KonSoft.TenantManagement.Application.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\tenant-management\src\KonSoft.TenantManagement.EntityFrameworkCore\KonSoft.TenantManagement.EntityFrameworkCore.csproj" /> | ||||
|     <ProjectReference Include="..\..\modules\tenant-management\src\KonSoft.TenantManagement.HttpApi\KonSoft.TenantManagement.HttpApi.csproj" /> | ||||
|     <ProjectReference Include="..\..\shared\KonSoft.Shared.Hosting.Microservices\KonSoft.Shared.Hosting.Microservices.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|  | ||||
| @ -1,27 +1,13 @@ | ||||
| { | ||||
|   "iisSettings": { | ||||
|     "windowsAuthentication": false,  | ||||
|     "anonymousAuthentication": true, | ||||
|     "iisExpress": { | ||||
|       "applicationUrl": "https://localhost:44348", | ||||
|       "sslPort": 44348 | ||||
|     } | ||||
|   }, | ||||
|   "$schema": "http://json.schemastore.org/launchsettings.json", | ||||
|   "profiles": { | ||||
|     "IIS Express": { | ||||
|       "commandName": "IISExpress", | ||||
|       "launchBrowser": true, | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|     }, | ||||
|     "KonSoft.TenantManagement.HttpApi.Host": { | ||||
|     "http": { | ||||
|       "commandName": "Project", | ||||
|       "launchBrowser": true, | ||||
|       "applicationUrl": "https://localhost:44348", | ||||
|       "environmentVariables": { | ||||
|         "ASPNETCORE_ENVIRONMENT": "Development" | ||||
|       } | ||||
|       }, | ||||
|       "applicationUrl": "https://localhost:44348" | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -1,179 +1,38 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using Medallion.Threading; | ||||
| using Medallion.Threading.Redis; | ||||
| using Microsoft.AspNetCore.Authentication.JwtBearer; | ||||
| using KonSoft.Shared.Hosting.AspNetCore; | ||||
| using KonSoft.Shared.Hosting.Microservices; | ||||
| using KonSoft.TenantManagement.EntityFrameworkCore; | ||||
| using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Microsoft.AspNetCore.DataProtection; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Hosting; | ||||
| using KonSoft.TenantManagement.EntityFrameworkCore; | ||||
| using KonSoft.TenantManagement.MultiTenancy; | ||||
| using StackExchange.Redis; | ||||
| using Microsoft.OpenApi.Models; | ||||
| using Volo.Abp; | ||||
| using Volo.Abp.AspNetCore.Authentication.JwtBearer; | ||||
| using Volo.Abp.AspNetCore.Mvc; | ||||
| using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; | ||||
| using Volo.Abp.AspNetCore.Serilog; | ||||
| using Volo.Abp.Autofac; | ||||
| using Volo.Abp.Caching; | ||||
| using Volo.Abp.Caching.StackExchangeRedis; | ||||
| using Volo.Abp.DistributedLocking; | ||||
| using Volo.Abp.Identity; | ||||
| using Volo.Abp.Localization; | ||||
| using Volo.Abp.BackgroundJobs; | ||||
| using Volo.Abp.Modularity; | ||||
| using Volo.Abp.Security.Claims; | ||||
| using Volo.Abp.Swashbuckle; | ||||
| using Volo.Abp.VirtualFileSystem; | ||||
|  | ||||
| namespace KonSoft.TenantManagement; | ||||
|  | ||||
| [DependsOn( | ||||
|     typeof(TenantManagementHttpApiModule), | ||||
|     typeof(AbpAutofacModule), | ||||
|     typeof(AbpCachingStackExchangeRedisModule), | ||||
|     typeof(AbpDistributedLockingModule), | ||||
|     typeof(AbpAspNetCoreMvcUiMultiTenancyModule), | ||||
|     typeof(AbpAspNetCoreAuthenticationJwtBearerModule), | ||||
|     typeof(TenantManagementApplicationModule), | ||||
|     typeof(TenantManagementEntityFrameworkCoreModule), | ||||
|     typeof(AbpAspNetCoreSerilogModule), | ||||
|     typeof(AbpSwashbuckleModule) | ||||
|     typeof(KonSoftSharedHostingMicroservicesModule) | ||||
| )] | ||||
| public class TenantManagementHttpApiHostModule : AbpModule | ||||
| { | ||||
|     public override void ConfigureServices(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var configuration = context.Services.GetConfiguration(); | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         ConfigureConventionalControllers(); | ||||
|         ConfigureAuthentication(context, configuration); | ||||
|         ConfigureCache(configuration); | ||||
|         ConfigureVirtualFileSystem(context); | ||||
|         ConfigureDataProtection(context, configuration, hostingEnvironment); | ||||
|         ConfigureDistributedLocking(context, configuration); | ||||
|         ConfigureCors(context, configuration); | ||||
|         ConfigureSwaggerServices(context, configuration); | ||||
|     } | ||||
|         SwaggerConfigurationHelper.ConfigureWithOidc( | ||||
|             context: context, | ||||
|             authority: configuration["AuthServer:Authority"]!, | ||||
|             scopes: ["TenantManagementService"], | ||||
|             discoveryEndpoint: configuration["AuthServer:MetadataAddress"], | ||||
|             apiTitle: "TenantManagement Service API" | ||||
|         ); | ||||
|  | ||||
|     private void ConfigureCache(IConfiguration configuration) | ||||
|     { | ||||
|         Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "TenantManagement:"; }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureVirtualFileSystem(ServiceConfigurationContext context) | ||||
|     { | ||||
|         var hostingEnvironment = context.Services.GetHostingEnvironment(); | ||||
|  | ||||
|         if (hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             Configure<AbpVirtualFileSystemOptions>(options => | ||||
|             { | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<TenantManagementDomainSharedModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.TenantManagement.Domain.Shared")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<TenantManagementDomainModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.TenantManagement.Domain")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<TenantManagementApplicationContractsModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.TenantManagement.Application.Contracts")); | ||||
|                 options.FileSets.ReplaceEmbeddedByPhysical<TenantManagementApplicationModule>( | ||||
|                     Path.Combine(hostingEnvironment.ContentRootPath, | ||||
|                         $"..{Path.DirectorySeparatorChar}KonSoft.TenantManagement.Application")); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureConventionalControllers() | ||||
|     { | ||||
|         Configure<AbpAspNetCoreMvcOptions>(options => | ||||
|         { | ||||
|             options.ConventionalControllers.Create(typeof(TenantManagementApplicationModule).Assembly); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) | ||||
|             .AddAbpJwtBearer(options => | ||||
|             { | ||||
|                 options.Authority = configuration["AuthServer:Authority"]; | ||||
|                 options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"); | ||||
|                 options.Audience = "TenantManagement"; | ||||
|             }); | ||||
|  | ||||
|         context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options => | ||||
|         { | ||||
|             options.IsDynamicClaimsEnabled = true; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddAbpSwaggerGenWithOAuth( | ||||
|             configuration["AuthServer:Authority"]!, | ||||
|             new Dictionary<string, string> | ||||
|             { | ||||
|                     {"TenantManagement", "TenantManagement API"} | ||||
|             }, | ||||
|             options => | ||||
|             { | ||||
|                 options.SwaggerDoc("v1", new OpenApiInfo { Title = "TenantManagement API", Version = "v1" }); | ||||
|                 options.DocInclusionPredicate((docName, description) => true); | ||||
|                 options.CustomSchemaIds(type => type.FullName); | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDataProtection( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration, | ||||
|         IWebHostEnvironment hostingEnvironment) | ||||
|     { | ||||
|         var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("TenantManagement"); | ||||
|         if (!hostingEnvironment.IsDevelopment()) | ||||
|         { | ||||
|             var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "TenantManagement-Protection-Keys"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ConfigureDistributedLocking( | ||||
|         ServiceConfigurationContext context, | ||||
|         IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddSingleton<IDistributedLockProvider>(sp => | ||||
|         { | ||||
|             var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); | ||||
|             return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) | ||||
|     { | ||||
|         context.Services.AddCors(options => | ||||
|         { | ||||
|             options.AddDefaultPolicy(builder => | ||||
|             { | ||||
|                 builder | ||||
|                     .WithOrigins(configuration["App:CorsOrigins"]? | ||||
|                         .Split(",", StringSplitOptions.RemoveEmptyEntries) | ||||
|                         .Select(o => o.RemovePostFix("/")) | ||||
|                         .ToArray() ?? []) | ||||
|                     .WithAbpExposedHeaders() | ||||
|                     .SetIsOriginAllowedToAllowWildcardSubdomains() | ||||
|                     .AllowAnyHeader() | ||||
|                     .AllowAnyMethod() | ||||
|                     .AllowCredentials(); | ||||
|             }); | ||||
|         }); | ||||
|         // ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD> | ||||
|         Configure<AbpBackgroundJobOptions>(options => options.IsJobExecutionEnabled = false); | ||||
|     } | ||||
|  | ||||
|     public override void OnApplicationInitialization(ApplicationInitializationContext context) | ||||
| @ -193,7 +52,7 @@ public class TenantManagementHttpApiHostModule : AbpModule | ||||
|         app.UseCors(); | ||||
|         app.UseAuthentication(); | ||||
|  | ||||
|         if (MultiTenancyConsts.IsEnabled) | ||||
|         if (KonSoftConsts.MultiTenancyEnabled) | ||||
|         { | ||||
|             app.UseMultiTenancy(); | ||||
|         } | ||||
|  | ||||
| @ -22,4 +22,10 @@ namespace KonSoft.Admin.Dtos | ||||
|         public AddressDto Address { get; set; } | ||||
|         public string Remark { get; set; } | ||||
|     } | ||||
|  | ||||
|     public class PageListInput | ||||
|     { | ||||
|         public int Index { get; set; } | ||||
|         public int PageSize { get; set; } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -7,19 +7,18 @@ using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp; | ||||
| using Volo.Abp.Application.Dtos; | ||||
| using Volo.Abp.Application.Services; | ||||
| using Volo.Abp.Domain.Repositories; | ||||
| using Volo.Abp.ObjectMapping; | ||||
|  | ||||
| namespace KonSoft.Admin.ApplicationServices | ||||
| { | ||||
|     public class OrderAppService : ApplicationService, IOrderAppService | ||||
|     public class OrderAppService(IOrderRepository orderRepository) : ApplicationService, IOrderAppService | ||||
|     { | ||||
|         private readonly IOrderRepository _orderRepository; | ||||
|         private readonly IOrderRepository _orderRepository = orderRepository; | ||||
|  | ||||
|         public OrderAppService(IOrderRepository orderRepository) | ||||
|         { | ||||
|             _orderRepository = orderRepository; | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// 分配师傅 | ||||
|         /// </summary> | ||||
| @ -27,7 +26,7 @@ namespace KonSoft.Admin.ApplicationServices | ||||
|         /// <param name="workerId"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public async Task  AssignAsync(Guid orderId, Guid workerId) | ||||
|         public async Task AssignAsync(Guid orderId, Guid workerId) | ||||
|         { | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.AssignWorker(workerId); | ||||
| @ -45,6 +44,7 @@ namespace KonSoft.Admin.ApplicationServices | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.Cancel(reason); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 完成订单 | ||||
|         /// </summary> | ||||
| @ -56,6 +56,7 @@ namespace KonSoft.Admin.ApplicationServices | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.CompleteService(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 确认订单 | ||||
|         /// </summary> | ||||
| @ -67,6 +68,7 @@ namespace KonSoft.Admin.ApplicationServices | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.ConfirmCompletion(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 创建订单 | ||||
|         /// </summary> | ||||
| @ -83,6 +85,34 @@ namespace KonSoft.Admin.ApplicationServices | ||||
|             await _orderRepository.InsertAsync(order); | ||||
|             return ObjectMapper.Map<Order, OrderDto>(order); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 根据订单ID删除订单 | ||||
|         /// </summary> | ||||
|         /// <param name="id">订单ID</param> | ||||
|         public async Task DeleteAsync(params Guid[] ids) | ||||
|         { | ||||
|             // 根据ID删除订单 | ||||
|             await _orderRepository.DeleteAsync(x => ids.Contains(x.Id)); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 修改订单信息 | ||||
|         /// </summary> | ||||
|         /// <param name="input">订单DTO对象</param>s | ||||
|         public async Task EditAsync(OrderDto input) | ||||
|         { | ||||
|             // 根据ID查询订单,如果不存在则抛出异常【修改前端必然看到了,数据若查不到提示自定义异常信息】 | ||||
|             var order = await _orderRepository.FindAsync(o => o.Id == input.Id) ?? | ||||
|                 throw new BusinessException("订单找不到").WithData("Id", input.Id); | ||||
|  | ||||
|             // 将输入的DTO字段映射到订单实体 | ||||
|             ObjectMapper.Map(input, order); | ||||
|  | ||||
|             // 更新订单 | ||||
|             await _orderRepository.UpdateAsync(order); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 支付 | ||||
|         /// </summary> | ||||
| @ -94,6 +124,7 @@ namespace KonSoft.Admin.ApplicationServices | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 开始订单 | ||||
|         /// </summary> | ||||
| @ -106,10 +137,32 @@ namespace KonSoft.Admin.ApplicationServices | ||||
|             order.StartService(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 根据订单ID获取单个订单 | ||||
|         /// </summary> | ||||
|         public async Task<OrderDto> GetAsync(Guid id) | ||||
|         { | ||||
|             // 根据ID从数据库查询订单 | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == id); | ||||
|  | ||||
|             // 转换为OrderDto返回 | ||||
|             return ObjectMapper.Map<Order, OrderDto>(order); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 获取所有订单列表 | ||||
|         /// </summary> | ||||
|         public async Task<PagedResultDto<OrderDto>> GetListAsync(PageListInput input) | ||||
|         { | ||||
|             var skipCount = (input.Index - 1) * input.PageSize; | ||||
|             // 查询所有订单 | ||||
|             var orders = await _orderRepository.GetPagedListAsync(skipCount, input.PageSize, "Id"); | ||||
|  | ||||
|             var totalCount = await _orderRepository.CountAsync(); | ||||
|  | ||||
|             var orderDtos = ObjectMapper.Map<List<Order>, List<OrderDto>>(orders); | ||||
|  | ||||
|             return new PagedResultDto<OrderDto>(totalCount, orderDtos); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @ -0,0 +1,109 @@ | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Serilog; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp; | ||||
| using Volo.Abp.Data; | ||||
| using Volo.Abp.DependencyInjection; | ||||
| using Volo.Abp.DistributedLocking; | ||||
| using Volo.Abp.EventBus.Distributed; | ||||
| using Volo.Abp.MultiTenancy; | ||||
| using Volo.Abp.Uow; | ||||
|  | ||||
| namespace KonSoft.Shared.Hosting.Microservices.DbMigrations.EfCore | ||||
| { | ||||
|     public abstract class PendingEfCoreMigrationsChecker<TDbContext> : ITransientDependency | ||||
|         where TDbContext : DbContext | ||||
|     { | ||||
|         protected IUnitOfWorkManager UnitOfWorkManager { get; } | ||||
|         protected IServiceProvider ServiceProvider { get; } | ||||
|         protected ICurrentTenant CurrentTenant { get; } | ||||
|         protected IDistributedEventBus DistributedEventBus { get; } | ||||
|         protected IAbpDistributedLock DistributedLockProvider { get; } | ||||
|         protected string DatabaseName { get; } | ||||
|  | ||||
|         protected PendingEfCoreMigrationsChecker( | ||||
|             IUnitOfWorkManager unitOfWorkManager, | ||||
|             IServiceProvider serviceProvider, | ||||
|             ICurrentTenant currentTenant, | ||||
|             IDistributedEventBus distributedEventBus, | ||||
|             IAbpDistributedLock abpDistributedLock, | ||||
|             string databaseName) | ||||
|         { | ||||
|             UnitOfWorkManager = unitOfWorkManager; | ||||
|             ServiceProvider = serviceProvider; | ||||
|             CurrentTenant = currentTenant; | ||||
|             DistributedEventBus = distributedEventBus; | ||||
|             DistributedLockProvider = abpDistributedLock; | ||||
|             DatabaseName = databaseName; | ||||
|         } | ||||
|  | ||||
|         public virtual async Task CheckAndApplyDatabaseMigrationsAsync() | ||||
|         { | ||||
|             await TryAsync(LockAndApplyDatabaseMigrationsAsync); | ||||
|         } | ||||
|  | ||||
|         protected async Task TryAsync(Func<Task> task, int retryCount = 3) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await task(); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 retryCount--; | ||||
|  | ||||
|                 if (retryCount <= 0) | ||||
|                 { | ||||
|                     throw; | ||||
|                 } | ||||
|  | ||||
|                 Log.Warning($"{ex.GetType().Name} has been thrown. The operation will be tried {retryCount} times more. Exception:\n{ex.Message}"); | ||||
|  | ||||
|                 await Task.Delay(RandomHelper.GetRandom(5000, 15000)); | ||||
|  | ||||
|                 await TryAsync(task, retryCount); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         protected virtual async Task LockAndApplyDatabaseMigrationsAsync() | ||||
|         { | ||||
|             await using (var handle = await DistributedLockProvider.TryAcquireAsync("Migration_" + DatabaseName)) | ||||
|             { | ||||
|                 Log.Information($"Lock is acquired for db migration and seeding on database named: {DatabaseName}..."); | ||||
|  | ||||
|                 if (handle is null) | ||||
|                 { | ||||
|                     Log.Information($"Handle is null because of the locking for : {DatabaseName}"); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 using (CurrentTenant.Change(null)) | ||||
|                 { | ||||
|                     // Create database tables if needed | ||||
|                     using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false)) | ||||
|                     { | ||||
|                         var dbContext = ServiceProvider.GetRequiredService<TDbContext>(); | ||||
|  | ||||
|                         var pendingMigrations = await dbContext | ||||
|                             .Database | ||||
|                             .GetPendingMigrationsAsync(); | ||||
|  | ||||
|                         if (pendingMigrations.Any()) | ||||
|                         { | ||||
|                             await dbContext.Database.MigrateAsync(); | ||||
|                         } | ||||
|  | ||||
|                         await uow.CompleteAsync(); | ||||
|                     } | ||||
|  | ||||
|                     await ServiceProvider.GetRequiredService<IDataSeeder>() | ||||
|                         .SeedAsync(); | ||||
|                 } | ||||
|                 Log.Information($"Lock is released for db migration and seeding on database named: {DatabaseName}..."); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -11,7 +11,7 @@ | ||||
|   </ItemGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.20" /> | ||||
| 		<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.4" /> | ||||
| 		<PackageReference Include="DistributedLock.Redis" Version="1.1.0" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| @ -22,6 +22,7 @@ | ||||
| 		<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="8.3.4" /> | ||||
| 		<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="8.3.4" /> | ||||
| 		<PackageReference Include="Volo.Abp.DistributedLocking" Version="8.3.4" /> | ||||
| 		<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="8.3.4" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|  | ||||
| @ -2,14 +2,15 @@ | ||||
| using Medallion.Threading; | ||||
| using Medallion.Threading.Redis; | ||||
| using Microsoft.AspNetCore.Authentication.JwtBearer; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Microsoft.AspNetCore.DataProtection; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using StackExchange.Redis; | ||||
| using System; | ||||
| using System.Linq; | ||||
| using Microsoft.AspNetCore.Cors; | ||||
| using Volo.Abp.AspNetCore.Authentication.JwtBearer; | ||||
| using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; | ||||
| using Volo.Abp.BackgroundJobs.RabbitMQ; | ||||
| using Volo.Abp.Caching; | ||||
| using Volo.Abp.Caching.StackExchangeRedis; | ||||
| @ -18,6 +19,7 @@ using Volo.Abp.EntityFrameworkCore; | ||||
| using Volo.Abp.EventBus.RabbitMq; | ||||
| using Volo.Abp.Modularity; | ||||
| using Volo.Abp.Security.Claims; | ||||
| using Volo.Abp.Swashbuckle; | ||||
|  | ||||
| namespace KonSoft.Shared.Hosting.Microservices | ||||
| { | ||||
| @ -28,7 +30,9 @@ namespace KonSoft.Shared.Hosting.Microservices | ||||
|         typeof(AbpEventBusRabbitMqModule), | ||||
|         typeof(AbpCachingStackExchangeRedisModule), | ||||
|         typeof(AbpDistributedLockingModule), | ||||
|         typeof(AbpEntityFrameworkCoreModule) | ||||
|         typeof(AbpAspNetCoreMvcUiMultiTenancyModule), | ||||
|         typeof(AbpEntityFrameworkCoreModule), | ||||
|         typeof(AbpSwashbuckleModule) | ||||
|     )] | ||||
|     public class KonSoftSharedHostingMicroservicesModule : AbpModule | ||||
|     { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user