Browse Source

add book-store

master
wwwk 3 years ago
parent
commit
658f89aa60
  1. 10
      Sanhe.Abp.Framework.sln
  2. 2
      modules/common/Sanhe.Abp.Wrapper/Sanhe/Abp/Wrapper/WrapResult.cs
  3. 2
      modules/common/Sanhe.Abp.Wrapper/Sanhe/Abp/Wrapper/WrapResult`T.cs
  4. 99
      services/book-store/BookStore.csproj
  5. 345
      services/book-store/BookStoreModule.cs
  6. 12
      services/book-store/Controllers/HomeController.cs
  7. 46
      services/book-store/Controllers/WrapController.cs
  8. 36
      services/book-store/Data/BookStoreDbContext.cs
  9. 203
      services/book-store/Data/BookStoreDbMigrationService.cs
  10. 29
      services/book-store/Data/BookStoreEFCoreDbSchemaMigrator.cs
  11. 271
      services/book-store/Data/IdentityServerDataSeedContributor.cs
  12. 0
      services/book-store/Entities/.gitkeep
  13. 8
      services/book-store/Localization/BookStore/ar.json
  14. 8
      services/book-store/Localization/BookStore/cs.json
  15. 8
      services/book-store/Localization/BookStore/de-DE.json
  16. 8
      services/book-store/Localization/BookStore/en-GB.json
  17. 8
      services/book-store/Localization/BookStore/en.json
  18. 8
      services/book-store/Localization/BookStore/es.json
  19. 8
      services/book-store/Localization/BookStore/fi.json
  20. 8
      services/book-store/Localization/BookStore/fr.json
  21. 8
      services/book-store/Localization/BookStore/hi.json
  22. 8
      services/book-store/Localization/BookStore/hu.json
  23. 8
      services/book-store/Localization/BookStore/is.json
  24. 8
      services/book-store/Localization/BookStore/it.json
  25. 8
      services/book-store/Localization/BookStore/nl.json
  26. 8
      services/book-store/Localization/BookStore/pl-PL.json
  27. 8
      services/book-store/Localization/BookStore/pt-BR.json
  28. 8
      services/book-store/Localization/BookStore/ro-RO.json
  29. 8
      services/book-store/Localization/BookStore/ru.json
  30. 8
      services/book-store/Localization/BookStore/sk.json
  31. 8
      services/book-store/Localization/BookStore/sl.json
  32. 8
      services/book-store/Localization/BookStore/tr.json
  33. 8
      services/book-store/Localization/BookStore/vi.json
  34. 8
      services/book-store/Localization/BookStore/zh-Hans.json
  35. 8
      services/book-store/Localization/BookStore/zh-Hant.json
  36. 9
      services/book-store/Localization/BookStoreResource.cs
  37. 11
      services/book-store/ObjectMapping/BookStoreAutoMapperProfile.cs
  38. 77
      services/book-store/Program.cs
  39. 20
      services/book-store/Properties/launchSettings.json
  40. 0
      services/book-store/Services/Dtos/.gitkeep
  41. 37
      services/book-store/appsettings.json
  42. 2
      services/book-store/appsettings.secrets.json
  43. 8
      services/book-store/package.json
  44. 1
      services/book-store/tempkey.jwk
  45. 1
      services/book-store/wwwroot/global-styles.css

10
Sanhe.Abp.Framework.sln

@ -17,6 +17,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.AspNetCore.Mvc.Wr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Wrapper", "modules\common\Sanhe.Abp.Wrapper\Sanhe.Abp.Wrapper.csproj", "{FDC1A6FC-DDAC-4119-9AF3-005F26030B94}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "book-store", "book-store", "{928FDD8C-1EE8-455E-952F-11039B52FE03}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookStore", "services\book-store\BookStore.csproj", "{64178F61-A488-4182-A409-C32AE51E33A1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -31,6 +35,10 @@ Global
{FDC1A6FC-DDAC-4119-9AF3-005F26030B94}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FDC1A6FC-DDAC-4119-9AF3-005F26030B94}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FDC1A6FC-DDAC-4119-9AF3-005F26030B94}.Release|Any CPU.Build.0 = Release|Any CPU
{64178F61-A488-4182-A409-C32AE51E33A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64178F61-A488-4182-A409-C32AE51E33A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64178F61-A488-4182-A409-C32AE51E33A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64178F61-A488-4182-A409-C32AE51E33A1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -41,6 +49,8 @@ Global
{21B8099B-881D-40AE-888E-FC94E66D90C0} = {F5F5D604-531B-4B57-A88E-C9C5CEEC55D7}
{06F1C7AC-3A43-4210-8126-8DA0089A39EE} = {21B8099B-881D-40AE-888E-FC94E66D90C0}
{FDC1A6FC-DDAC-4119-9AF3-005F26030B94} = {2A768109-31B7-4C52-928C-3023DAB9F254}
{928FDD8C-1EE8-455E-952F-11039B52FE03} = {BBE3B270-DF4F-47F5-9705-89FCFDE2779F}
{64178F61-A488-4182-A409-C32AE51E33A1} = {928FDD8C-1EE8-455E-952F-11039B52FE03}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB69BFDE-9DDB-4D16-8CB8-72472C0319CD}

2
modules/common/Sanhe.Abp.Wrapper/Sanhe/Abp/Wrapper/WrapResult.cs

@ -20,7 +20,7 @@ public class WrapResult : WrapResult<object>
public WrapResult(
string code,
object result,
string message = "OK") : base(code, result, message)
string message = "ok") : base(code, result, message)
{
}
}

2
modules/common/Sanhe.Abp.Wrapper/Sanhe/Abp/Wrapper/WrapResult`T.cs

@ -41,7 +41,7 @@ public class WrapResult<TResult>
public WrapResult(
string code,
TResult result,
string message = "OK")
string message = "ok")
{
Code = code;
Result = result;

99
services/book-store/BookStore.csproj

@ -0,0 +1,99 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Autofac" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Swashbuckle" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.PostgreSql" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Account.Application" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Account.HttpApi" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Account.Web.IdentityServer" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Identity.Application" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Identity.HttpApi" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Identity.EntityFrameworkCore" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.IdentityServer.EntityFrameworkCore" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.PermissionManagement.Application" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.PermissionManagement.HttpApi" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.TenantManagement.Application" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.TenantManagement.EntityFrameworkCore" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.TenantManagement.HttpApi" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Featuremanagement.Application" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Featuremanagement.EntityFrameworkCore" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.Featuremanagement.HttpApi" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.SettingManagement.Application" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="$(VoloAbpVersion)" />
<PackageReference Include="Volo.Abp.SettingManagement.HttpApi" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AuditLogging.EntityFrameworkCore" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" Version="$(VoloAbpVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>compile; contentFiles; build; buildMultitargeting; buildTransitive; analyzers; native</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Content Remove="Localization\BookStore\*.json" />
<EmbeddedResource Include="Localization\BookStore\*.json" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Logs\**" />
<Content Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\mvc\Sanhe.Abp.AspNetCore.Mvc.Wrapper\Sanhe.Abp.AspNetCore.Mvc.Wrapper.csproj" />
</ItemGroup>
</Project>

345
services/book-store/BookStoreModule.cs

@ -0,0 +1,345 @@
using BookStore.Data;
using BookStore.Localization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.OpenApi.Models;
using Sanhe.Abp.AspNetCore.Mvc.Wrapper;
using Sanhe.Abp.Wrapper;
using StackExchange.Redis;
using Volo.Abp;
using Volo.Abp.Account;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.PostgreSql;
using Volo.Abp.FeatureManagement;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.IdentityServer.EntityFrameworkCore;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.HttpApi;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.SettingManagement;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.Swashbuckle;
using Volo.Abp.TenantManagement;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.Validation.Localization;
using Volo.Abp.VirtualFileSystem;
namespace BookStore;
[DependsOn(
// ABP Framework packages
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAspNetCoreMultiTenancyModule),
typeof(AbpAutofacModule),
typeof(AbpAutoMapperModule),
//typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpEntityFrameworkCorePostgreSqlModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpSwashbuckleModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpAspNetCoreSerilogModule),
// Account module packages
typeof(AbpAccountApplicationModule),
typeof(AbpAccountHttpApiModule),
typeof(AbpAccountWebIdentityServerModule),
// Identity module packages
typeof(AbpPermissionManagementDomainIdentityModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpIdentityHttpApiModule),
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpIdentityServerEntityFrameworkCoreModule),
// Audit logging module packages
typeof(AbpAuditLoggingEntityFrameworkCoreModule),
// Permission Management module packages
typeof(AbpPermissionManagementApplicationModule),
typeof(AbpPermissionManagementHttpApiModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
// Tenant Management module packages
typeof(AbpTenantManagementApplicationModule),
typeof(AbpTenantManagementHttpApiModule),
typeof(AbpTenantManagementEntityFrameworkCoreModule),
// Feature Management module packages
typeof(AbpFeatureManagementApplicationModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementHttpApiModule),
// Setting Management module packages
typeof(AbpSettingManagementApplicationModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementHttpApiModule),
typeof(AbpAspNetCoreMvcWrapperModule)
)]
public class BookStoreModule : AbpModule
{
/* Single point to enable/disable multi-tenancy */
private const bool IsMultiTenant = true;
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
options.AddAssemblyResource(
typeof(BookStoreResource)
);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
context.Services.AddAlwaysAllowAuthorization();
// wrap
Configure<AbpWrapperOptions>(options =>
{
options.IsEnabled = true;
options.IgnoreNamespaces.Clear();
});
ConfigureBundles();
ConfigureMultiTenancy();
ConfigureUrls(configuration);
ConfigureAutoMapper();
ConfigureSwagger(context.Services);
ConfigureAutoApiControllers();
ConfigureVirtualFiles(hostingEnvironment);
ConfigureLocalization();
ConfigureAuthentication(context.Services, configuration);
ConfigureCors(context, configuration);
//ConfigureDataProtection(context, configuration, hostingEnvironment);
ConfigureEfCore(context);
}
private void ConfigureBundles()
{
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(
BasicThemeBundles.Styles.Global,
bundle => { bundle.AddFiles("/global-styles.css"); }
);
});
}
private void ConfigureMultiTenancy()
{
Configure<AbpMultiTenancyOptions>(options =>
{
options.IsEnabled = IsMultiTenant;
});
}
private void ConfigureUrls(IConfiguration configuration)
{
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(','));
options.Applications["Angular"].RootUrl = configuration["App:ClientUrl"];
options.Applications["Angular"].Urls[AccountUrlNames.PasswordReset] = "account/reset-password";
});
}
private void ConfigureAuthentication(IServiceCollection services, IConfiguration configuration)
{
services.AddAuthentication()
.AddJwtBearer(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
options.Audience = "BookStore";
});
}
private void ConfigureLocalization()
{
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<BookStoreResource>("en")
.AddBaseTypes(typeof(AbpValidationResource))
.AddVirtualJson("/Localization/BookStore");
options.DefaultResourceType = typeof(BookStoreResource);
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("BookStore", typeof(BookStoreResource));
});
}
private void ConfigureVirtualFiles(IWebHostEnvironment hostingEnvironment)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<BookStoreModule>();
if (hostingEnvironment.IsDevelopment())
{
/* Using physical files in development, so we don't need to recompile on changes */
options.FileSets.ReplaceEmbeddedByPhysical<BookStoreModule>(hostingEnvironment.ContentRootPath);
}
});
}
private void ConfigureAutoApiControllers()
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(BookStoreModule).Assembly);
});
}
private void ConfigureSwagger(IServiceCollection services)
{
services.AddAbpSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "BookStore API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
}
);
}
private void ConfigureAutoMapper()
{
Configure<AbpAutoMapperOptions>(options =>
{
/* Uncomment `validate: true` if you want to enable the Configuration Validation feature.
* See AutoMapper's documentation to learn what it is:
* https://docs.automapper.org/en/stable/Configuration-validation.html
*/
options.AddMaps<BookStoreModule>(/* validate: true */);
});
}
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();
});
});
}
private void ConfigureDataProtection(
ServiceConfigurationContext context,
IConfiguration configuration,
IWebHostEnvironment hostingEnvironment)
{
var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("BookStore");
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "BookStore-Protection-Keys");
}
}
private void ConfigureEfCore(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<BookStoreDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
});
Configure<AbpDbContextOptions>(options =>
{
options.Configure(configurationContext =>
{
configurationContext.UseNpgsql();
});
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
if (!env.IsDevelopment())
{
app.UseErrorPage();
}
app.UseCorrelationId();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseJwtTokenMiddleware();
if (IsMultiTenant)
{
app.UseMultiTenancy();
}
app.UseUnitOfWork();
app.UseIdentityServer();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "BookStore API");
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
}
}

12
services/book-store/Controllers/HomeController.cs

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
namespace BookStore.Controllers;
public class HomeController : AbpController
{
public ActionResult Index()
{
return Redirect("~/swagger");
}
}

46
services/book-store/Controllers/WrapController.cs

@ -0,0 +1,46 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Authorization;
namespace BookStore.Controllers;
[Route("api/wrap")]
public class WrapController : AbpControllerBase
{
[HttpGet("string")]
public Task<string> GetResultAsync()
{
return Task.FromResult("Hello!");
}
[HttpGet("person")]
public Task<Person> GetPersonAsync()
{
var person = new Person
{
Name = "wwwk",
Age = 18
};
return Task.FromResult(person);
}
[HttpGet("throw-exception")]
public Task ThrowException()
{
throw new UserFriendlyException("触发了一个异常!");
}
[HttpGet("throw-auth-exception")]
public Task ThrowAuthException()
{
throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedForGivenResource);
}
}
public class Person
{
public string? Name { get; set; }
public int Age { get; set; }
}

36
services/book-store/Data/BookStoreDbContext.cs

@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.IdentityServer.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
namespace BookStore.Data;
public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
{
public BookStoreDbContext(DbContextOptions<BookStoreDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
/* Include modules to your migration db context */
builder.ConfigurePermissionManagement();
builder.ConfigureSettingManagement();
builder.ConfigureAuditLogging();
builder.ConfigureIdentity();
builder.ConfigureIdentityServer();
builder.ConfigureFeatureManagement();
builder.ConfigureTenantManagement();
/* Configure your own entities here */
}
}

203
services/book-store/Data/BookStoreDbMigrationService.cs

@ -0,0 +1,203 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement;
namespace BookStore.Data;
public class BookStoreDbMigrationService : ITransientDependency
{
public ILogger<BookStoreDbMigrationService> Logger { get; set; }
private readonly IDataSeeder _dataSeeder;
private readonly BookStoreEFCoreDbSchemaMigrator _dbSchemaMigrator;
private readonly ITenantRepository _tenantRepository;
private readonly ICurrentTenant _currentTenant;
public BookStoreDbMigrationService(
IDataSeeder dataSeeder,
BookStoreEFCoreDbSchemaMigrator dbSchemaMigrator,
ITenantRepository tenantRepository,
ICurrentTenant currentTenant)
{
_dataSeeder = dataSeeder;
_dbSchemaMigrator = dbSchemaMigrator;
_tenantRepository = tenantRepository;
_currentTenant = currentTenant;
Logger = NullLogger<BookStoreDbMigrationService>.Instance;
}
public async Task MigrateAsync()
{
var initialMigrationAdded = AddInitialMigrationIfNotExist();
if (initialMigrationAdded)
{
return;
}
Logger.LogInformation("Started database migrations...");
await MigrateDatabaseSchemaAsync();
await SeedDataAsync();
Logger.LogInformation($"Successfully completed host database migrations.");
var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
var migratedDatabaseSchemas = new HashSet<string>();
foreach (var tenant in tenants)
{
using (_currentTenant.Change(tenant.Id))
{
if (tenant.ConnectionStrings.Any())
{
var tenantConnectionStrings = tenant.ConnectionStrings
.Select(x => x.Value)
.ToList();
if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
{
await MigrateDatabaseSchemaAsync(tenant);
migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
}
}
await SeedDataAsync(tenant);
}
Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
}
Logger.LogInformation("Successfully completed all database migrations.");
Logger.LogInformation("You can safely end this process...");
}
private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null)
{
Logger.LogInformation($"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
await _dbSchemaMigrator.MigrateAsync();
}
private async Task SeedDataAsync(Tenant tenant = null)
{
Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed...");
await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id)
.WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, IdentityDataSeedContributor.AdminEmailDefaultValue)
.WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, IdentityDataSeedContributor.AdminPasswordDefaultValue)
);
}
private bool AddInitialMigrationIfNotExist()
{
try
{
if (!DbMigrationsProjectExists())
{
return false;
}
}
catch (Exception)
{
return false;
}
try
{
if (!MigrationsFolderExists())
{
AddInitialMigration();
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
Logger.LogWarning("Couldn't determinate if any migrations exist : " + e.Message);
return false;
}
}
private bool DbMigrationsProjectExists()
{
return Directory.Exists(GetEntityFrameworkCoreProjectFolderPath());
}
private bool MigrationsFolderExists()
{
var dbMigrationsProjectFolder = GetEntityFrameworkCoreProjectFolderPath();
return Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "Migrations"));
}
private void AddInitialMigration()
{
Logger.LogInformation("Creating initial migration...");
string argumentPrefix;
string fileName;
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
argumentPrefix = "-c";
fileName = "/bin/bash";
}
else
{
argumentPrefix = "/C";
fileName = "cmd.exe";
}
var procStartInfo = new ProcessStartInfo(fileName,
$"{argumentPrefix} \"abp create-migration-and-run-migrator \"{GetEntityFrameworkCoreProjectFolderPath()}\" --nolayers\""
);
try
{
Process.Start(procStartInfo);
}
catch (Exception)
{
throw new Exception("Couldn't run ABP CLI...");
}
}
private string GetEntityFrameworkCoreProjectFolderPath()
{
var slnDirectoryPath = GetSolutionDirectoryPath();
if (slnDirectoryPath == null)
{
throw new Exception("Solution folder not found!");
}
return Path.Combine(slnDirectoryPath, "BookStore");
}
private string GetSolutionDirectoryPath()
{
var currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
while (Directory.GetParent(currentDirectory.FullName) != null)
{
currentDirectory = Directory.GetParent(currentDirectory.FullName);
if (Directory.GetFiles(currentDirectory.FullName).FirstOrDefault(f => f.EndsWith(".sln")) != null)
{
return currentDirectory.FullName;
}
}
return null;
}
}

29
services/book-store/Data/BookStoreEFCoreDbSchemaMigrator.cs

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.DependencyInjection;
namespace BookStore.Data;
public class BookStoreEFCoreDbSchemaMigrator : ITransientDependency
{
private readonly IServiceProvider _serviceProvider;
public BookStoreEFCoreDbSchemaMigrator(
IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task MigrateAsync()
{
/* We intentionally resolving the BookStoreDbContext
* from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the
* current scope.
*/
await _serviceProvider
.GetRequiredService<BookStoreDbContext>()
.Database
.MigrateAsync();
}
}

271
services/book-store/Data/IdentityServerDataSeedContributor.cs

@ -0,0 +1,271 @@
using IdentityServer4.Models;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.ApiScopes;
using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.IdentityServer.IdentityResources;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow;
using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource;
using ApiScope = Volo.Abp.IdentityServer.ApiScopes.ApiScope;
using Client = Volo.Abp.IdentityServer.Clients.Client;
namespace BookStore.Data;
public class IdentityServerDataSeedContributor : IDataSeedContributor, ITransientDependency
{
private readonly IApiResourceRepository _apiResourceRepository;
private readonly IApiScopeRepository _apiScopeRepository;
private readonly IClientRepository _clientRepository;
private readonly IIdentityResourceDataSeeder _identityResourceDataSeeder;
private readonly IGuidGenerator _guidGenerator;
private readonly IPermissionDataSeeder _permissionDataSeeder;
private readonly IConfiguration _configuration;
private readonly ICurrentTenant _currentTenant;
public IdentityServerDataSeedContributor(
IClientRepository clientRepository,
IApiResourceRepository apiResourceRepository,
IApiScopeRepository apiScopeRepository,
IIdentityResourceDataSeeder identityResourceDataSeeder,
IGuidGenerator guidGenerator,
IPermissionDataSeeder permissionDataSeeder,
IConfiguration configuration,
ICurrentTenant currentTenant)
{
_clientRepository = clientRepository;
_apiResourceRepository = apiResourceRepository;
_apiScopeRepository = apiScopeRepository;
_identityResourceDataSeeder = identityResourceDataSeeder;
_guidGenerator = guidGenerator;
_permissionDataSeeder = permissionDataSeeder;
_configuration = configuration;
_currentTenant = currentTenant;
}
[UnitOfWork]
public virtual async Task SeedAsync(DataSeedContext context)
{
using (_currentTenant.Change(context?.TenantId))
{
await _identityResourceDataSeeder.CreateStandardResourcesAsync();
await CreateApiResourcesAsync();
await CreateApiScopesAsync();
await CreateClientsAsync();
}
}
private async Task CreateApiScopesAsync()
{
await CreateApiScopeAsync("BookStore");
}
private async Task CreateApiResourcesAsync()
{
var commonApiUserClaims = new[] {"email", "email_verified", "name", "phone_number", "phone_number_verified", "role"};
await CreateApiResourceAsync("BookStore", commonApiUserClaims);
}
private async Task<ApiResource> CreateApiResourceAsync(string name, IEnumerable<string> claims)
{
var apiResource = await _apiResourceRepository.FindByNameAsync(name);
if (apiResource == null)
{
apiResource = await _apiResourceRepository.InsertAsync(
new ApiResource(
_guidGenerator.Create(),
name,
name + " API"
),
autoSave: true
);
}
foreach (var claim in claims)
{
if (apiResource.FindClaim(claim) == null)
{
apiResource.AddUserClaim(claim);
}
}
return await _apiResourceRepository.UpdateAsync(apiResource);
}
private async Task<ApiScope> CreateApiScopeAsync(string name)
{
var apiScope = await _apiScopeRepository.FindByNameAsync(name);
if (apiScope == null)
{
apiScope = await _apiScopeRepository.InsertAsync(
new ApiScope(
_guidGenerator.Create(),
name,
name + " API"
),
autoSave: true
);
}
return apiScope;
}
private async Task CreateClientsAsync()
{
var commonScopes = new[]
{
"email",
"openid",
"profile",
"role",
"phone",
"address",
"BookStore"
};
var configurationSection = _configuration.GetSection("IdentityServer:Clients");
// Angular Client
var consoleAndAngularClientId = configurationSection["BookStore_App:ClientId"];
if (!consoleAndAngularClientId.IsNullOrWhiteSpace())
{
var webClientRootUrl = configurationSection["BookStore_App:RootUrl"]?.TrimEnd('/');
await CreateClientAsync(
name: consoleAndAngularClientId,
scopes: commonScopes,
grantTypes: new[] { "password", "client_credentials", "authorization_code" },
secret: (configurationSection["BookStore_App:ClientSecret"] ?? "1q2w3e*").Sha256(),
requireClientSecret: false,
redirectUri: webClientRootUrl,
postLogoutRedirectUri: webClientRootUrl,
corsOrigins: new[] { webClientRootUrl.RemovePostFix("/") }
);
}
// Swagger Client
var swaggerClientId = configurationSection["BookStore_Swagger:ClientId"];
if (!swaggerClientId.IsNullOrWhiteSpace())
{
var swaggerRootUrl = configurationSection["BookStore_Swagger:RootUrl"].TrimEnd('/');
await CreateClientAsync(
name: swaggerClientId,
scopes: commonScopes,
grantTypes: new[] { "authorization_code" },
secret: configurationSection["BookStore_Swagger:ClientSecret"]?.Sha256(),
requireClientSecret: false,
redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html",
corsOrigins: new[] { swaggerRootUrl.RemovePostFix("/") }
);
}
}
private async Task<Client> CreateClientAsync(
string name,
IEnumerable<string> scopes,
IEnumerable<string> grantTypes,
string secret = null,
string redirectUri = null,
string postLogoutRedirectUri = null,
string frontChannelLogoutUri = null,
bool requireClientSecret = true,
bool requirePkce = false,
IEnumerable<string> permissions = null,
IEnumerable<string> corsOrigins = null)
{
var client = await _clientRepository.FindByClientIdAsync(name);
if (client == null)
{
client = await _clientRepository.InsertAsync(
new Client(
_guidGenerator.Create(),
name
)
{
ClientName = name,
ProtocolType = "oidc",
Description = name,
AlwaysIncludeUserClaimsInIdToken = true,
AllowOfflineAccess = true,
AbsoluteRefreshTokenLifetime = 31536000, //365 days
AccessTokenLifetime = 31536000, //365 days
AuthorizationCodeLifetime = 300,
IdentityTokenLifetime = 300,
RequireConsent = false,
FrontChannelLogoutUri = frontChannelLogoutUri,
RequireClientSecret = requireClientSecret,
RequirePkce = requirePkce
},
autoSave: true
);
}
foreach (var scope in scopes)
{
if (client.FindScope(scope) == null)
{
client.AddScope(scope);
}
}
foreach (var grantType in grantTypes)
{
if (client.FindGrantType(grantType) == null)
{
client.AddGrantType(grantType);
}
}
if (!secret.IsNullOrEmpty())
{
if (client.FindSecret(secret) == null)
{
client.AddSecret(secret);
}
}
if (redirectUri != null)
{
if (client.FindRedirectUri(redirectUri) == null)
{
client.AddRedirectUri(redirectUri);
}
}
if (postLogoutRedirectUri != null)
{
if (client.FindPostLogoutRedirectUri(postLogoutRedirectUri) == null)
{
client.AddPostLogoutRedirectUri(postLogoutRedirectUri);
}
}
if (permissions != null)
{
await _permissionDataSeeder.SeedAsync(
ClientPermissionValueProvider.ProviderName,
name,
permissions,
null
);
}
if (corsOrigins != null)
{
foreach (var origin in corsOrigins)
{
if (!origin.IsNullOrWhiteSpace() && client.FindCorsOrigin(origin) == null)
{
client.AddCorsOrigin(origin);
}
}
}
return await _clientRepository.UpdateAsync(client);
}
}

0
services/book-store/Entities/.gitkeep

8
services/book-store/Localization/BookStore/ar.json

@ -0,0 +1,8 @@
{
"culture": "ar",
"texts": {
"Welcome_Title": "مرحبا",
"Welcome_Text": "هذا هو قالب بدء تشغيل تطبيق ذو طبقة واحدة مبسط لإطار عمل ABP.",
"Menu:Home": "الرئيسية"
}
}

8
services/book-store/Localization/BookStore/cs.json

@ -0,0 +1,8 @@
{
"culture": "cs",
"texts": {
"Welcome_Title": "Vítejte",
"Welcome_Text": "Toto je minimalistická šablona pro spuštění aplikace s jednou vrstvou pro ABP Framework.",
"Menu:Home": "Úvod"
}
}

8
services/book-store/Localization/BookStore/de-DE.json

@ -0,0 +1,8 @@
{
"culture": "de-DE",
"texts": {
"Welcome_Title": "Willkommen",
"Welcome_Text": "Dies ist eine minimalistische, einschichtige Anwendungsstartvorlage für das ABP-Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/en-GB.json

@ -0,0 +1,8 @@
{
"culture": "en-GB",
"texts": {
"Welcome_Title": "Welcome_Title",
"Welcome_Text": "This is a minimalist, single layer application startup template for the ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/en.json

@ -0,0 +1,8 @@
{
"culture": "en",
"texts": {
"Welcome_Title": "Welcome",
"Welcome_Text": "This is a minimalist, single layer application startup template for the ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/es.json

@ -0,0 +1,8 @@
{
"culture": "es",
"texts": {
"Welcome_Title": "Bienvenido",
"Welcome_Text": "Esta es una plantilla de inicio de aplicación minimalista de una sola capa para ABP Framework.",
"Menu:Home": "Inicio"
}
}

8
services/book-store/Localization/BookStore/fi.json

@ -0,0 +1,8 @@
{
"culture": "fi",
"texts": {
"Welcome_Title": "Tervetuloa",
"Welcome_Text": "Tämä on minimalistinen yksikerroksinen sovelluksen käynnistysmalli ABP Frameworkille.",
"Menu:Home": "Koti"
}
}

8
services/book-store/Localization/BookStore/fr.json

@ -0,0 +1,8 @@
{
"culture": "fr",
"texts": {
"Welcome_Title": "Bienvenue",
"Welcome_Text": "Il s'agit d'un modèle de démarrage d'application minimaliste à une seule couche pour le cadre ABP.",
"Menu:Home": "Accueil"
}
}

8
services/book-store/Localization/BookStore/hi.json

@ -0,0 +1,8 @@
{
"culture": "hi",
"texts": {
"Welcome_Title": "सगत ह",
"Welcome_Text": "यह एबमवरक किए एक ननतम, सिगल लयर एपिशन सटअप टट ह।",
"Menu:Home": "घर"
}
}

8
services/book-store/Localization/BookStore/hu.json

@ -0,0 +1,8 @@
{
"culture": "hu",
"texts": {
"Welcome_Title": "Üdvözlöm",
"Welcome_Text": "Ez egy minimalista, egyrétegű alkalmazásindítási sablon az ABP-keretrendszerhez.",
"Menu:Home": "Kezdőlap"
}
}

8
services/book-store/Localization/BookStore/is.json

@ -0,0 +1,8 @@
{
"culture": "is",
"texts": {
"Welcome_Title": "Velkomin",
"Welcome_Text": "Þetta er lægstur, eins lags ræsingarsniðmát fyrir ABP Framework.",
"Menu:Home": "Heim"
}
}

8
services/book-store/Localization/BookStore/it.json

@ -0,0 +1,8 @@
{
"culture": "it",
"texts": {
"Welcome_Title": "Benvenuto",
"Welcome_Text": "Questo è un modello di avvio dell'applicazione minimalista a livello singolo per ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/nl.json

@ -0,0 +1,8 @@
{
"culture": "nl",
"texts": {
"Welcome_Title": "Welkom",
"Welcome_Text": "Dit is een minimalistische, enkellaagse applicatie-opstartsjabloon voor het ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/pl-PL.json

@ -0,0 +1,8 @@
{
"culture": "pl-PL",
"texts": {
"Welcome_Title": "Witaj",
"Welcome_Text": "Jest to minimalistyczny, jednowarstwowy szablon uruchamiania aplikacji dla ABP Framework.",
"Menu:Home": "Home"
}
}

8
services/book-store/Localization/BookStore/pt-BR.json

@ -0,0 +1,8 @@
{
"culture": "pt-BR",
"texts": {
"Welcome_Title": "Seja bem-vindo!",
"Welcome_Text": "Este é um modelo de inicialização de aplicativo de camada única minimalista para o ABP Framework.",
"Menu:Home": "Principal"
}
}

8
services/book-store/Localization/BookStore/ro-RO.json

@ -0,0 +1,8 @@
{
"culture": "ro-RO",
"texts": {
"Welcome_Title": "Bun venit",
"Welcome_Text": "Acesta este un șablon de pornire a aplicației minimaliste, cu un singur strat, pentru Cadrul ABP.",
"Menu:Home": "Acasă"
}
}

8
services/book-store/Localization/BookStore/ru.json

@ -0,0 +1,8 @@
{
"culture": "ru",
"texts": {
"Welcome_Title": "Bine ati venit",
"Welcome_Text": "Acesta este un șablon de pornire a aplicației minimaliste, cu un singur strat, pentru Cadrul ABP.",
"Menu:Home": "Главная"
}
}

8
services/book-store/Localization/BookStore/sk.json

@ -0,0 +1,8 @@
{
"culture": "sk",
"texts": {
"Welcome_Title": "Vitajte",
"Welcome_Text": "Toto je minimalistická šablóna na spustenie aplikácie s jednou vrstvou pre rámec ABP.",
"Menu:Home": "Domov"
}
}

8
services/book-store/Localization/BookStore/sl.json

@ -0,0 +1,8 @@
{
"culture": "sl",
"texts": {
"Welcome_Title": "Dobrodošli",
"Welcome_Text": "To je minimalistična enoslojna predloga za zagon aplikacije za ABP Framework.",
"Menu:Home": "Domov"
}
}

8
services/book-store/Localization/BookStore/tr.json

@ -0,0 +1,8 @@
{
"culture": "tr",
"texts": {
"Welcome_Title": "Hoşgeldiniz",
"Welcome_Text": "Bu proje tek katmanlı ABP uygulamaları yapmak için bir başlangıç şablonudur.",
"Menu:Home": "Ana sayfa"
}
}

8
services/book-store/Localization/BookStore/vi.json

@ -0,0 +1,8 @@
{
"culture": "vi",
"texts": {
"Welcome_Title": "Chào mừng bạn",
"Welcome_Text": "Đây là một mẫu khởi động ứng dụng lớp đơn, tối giản cho ABP Framework.",
"Menu:Home": "Trang chủ"
}
}

8
services/book-store/Localization/BookStore/zh-Hans.json

@ -0,0 +1,8 @@
{
"culture": "zh-Hans",
"texts": {
"Welcome_Title": "欢迎",
"Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.",
"Menu:Home": "首页"
}
}

8
services/book-store/Localization/BookStore/zh-Hant.json

@ -0,0 +1,8 @@
{
"culture": "zh-Hant",
"texts": {
"Welcome_Title": "歡迎",
"Welcome_Text": "這是 ABP 框架的極簡單層應用程序啟動模板.",
"Menu:Home": "首頁"
}
}

9
services/book-store/Localization/BookStoreResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace BookStore.Localization;
[LocalizationResourceName("BookStore")]
public class BookStoreResource
{
}

11
services/book-store/ObjectMapping/BookStoreAutoMapperProfile.cs

@ -0,0 +1,11 @@
using AutoMapper;
namespace BookStore.ObjectMapping;
public class BookStoreAutoMapperProfile : Profile
{
public BookStoreAutoMapperProfile()
{
/* Create your AutoMapper object mappings here */
}
}

77
services/book-store/Program.cs

@ -0,0 +1,77 @@
using System;
using BookStore.Data;
using Serilog;
using Serilog.Events;
namespace BookStore;
public class Program
{
public async static Task<int> Main(string[] args)
{
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
var loggerConfiguration = new LoggerConfiguration()
#if DEBUG
.MinimumLevel.Debug()
#else
.MinimumLevel.Information()
#endif
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
#if DEBUG
.WriteTo.Async(c => c.File("Logs/logs.txt"))
.WriteTo.Async(c => c.Console());
#else
.WriteTo.Async(c => c.File("Logs/logs.txt"));
#endif
if (IsMigrateDatabase(args))
{
loggerConfiguration.MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning);
loggerConfiguration.MinimumLevel.Override("Microsoft", LogEventLevel.Warning);
loggerConfiguration.MinimumLevel.Override("IdentityServer4.Startup", LogEventLevel.Warning);
}
Log.Logger = loggerConfiguration.CreateLogger();
try
{
var builder = WebApplication.CreateBuilder(args);
builder.Host.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<BookStoreModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
if (IsMigrateDatabase(args))
{
await app.Services.GetRequiredService<BookStoreDbMigrationService>().MigrateAsync();
return 0;
}
Log.Information("Starting BookStore.");
await app.RunAsync();
return 0;
}
catch (Exception ex)
{
if (ex.GetType().Name.Equals("StopTheHostException", StringComparison.Ordinal))
{
throw;
}
Log.Fatal(ex, "BookStore terminated unexpectedly!");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
private static bool IsMigrateDatabase(string[] args)
{
return args.Any(x => x.Contains("--migrate-database", StringComparison.OrdinalIgnoreCase));
}
}

20
services/book-store/Properties/launchSettings.json

@ -0,0 +1,20 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://localhost:44357",
"sslPort": 44357
}
},
"profiles": {
"BookStore": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:44357",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

0
services/book-store/Services/Dtos/.gitkeep

37
services/book-store/appsettings.json

@ -0,0 +1,37 @@
{
"App": {
"SelfUrl": "https://localhost:44357",
"ClientUrl": "http://localhost:4200",
"CorsOrigins": "https://*.BookStore.com,http://localhost:4200",
"RedirectAllowedUrls": "http://localhost:4200"
},
"ConnectionStrings": {
"Default": "Host=localhost;Port=5432;Database=BookStore;User ID=postgres;Password=123456;"
},
"Redis": {
"Configuration": "127.0.0.1"
},
"AuthServer": {
"Authority": "https://localhost:44357",
"RequireHttpsMetadata": "false",
"SwaggerClientId": "BookStore_Swagger",
"SwaggerClientSecret": "1q2w3e*"
},
"StringEncryption": {
"DefaultPassPhrase": "Q4ki8okY7ZyMNWDw"
},
"IdentityServer": {
"Clients": {
"BookStore_App": {
"ClientId": "BookStore_App",
"ClientSecret": "1q2w3e*",
"RootUrl": "http://localhost:4200"
},
"BookStore_Swagger": {
"ClientId": "BookStore_Swagger",
"ClientSecret": "1q2w3e*",
"RootUrl": "https://localhost:44357"
}
}
}
}

2
services/book-store/appsettings.secrets.json

@ -0,0 +1,2 @@
{
}

8
services/book-store/package.json

@ -0,0 +1,8 @@
{
"version": "1.0.0",
"name": "my-app",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "^5.2.0-rc.2"
}
}

1
services/book-store/tempkey.jwk

@ -0,0 +1 @@
{"AdditionalData":{},"Alg":"RS256","Crv":null,"D":"PqIhXe397CUD48Ulbw-kT8MwuWFckXy3hGj-huiX63FpBSRCRd9cmV81h5WI0RX6i0nrKZ2go5cakNgIqx_8gFoOP5N5j8umcU32UtwXePilRjP9RrY_9ub-P0iSmqIEQEZSOg93W7sOVL9jnvd0BLBavqOmlErz9JhU3QU9ebY3lDSdTHZWqYSVb6yeXjZGCRYZgkCgVYx1CiKkFRA5MEEM_WUBhLxVhNmbvFbwlp54PPaBBBEA3RYilv8aK0RBmhdgKRLpfMegEeM3yJh2D92EV2lx3DEhycia72AuqFQ-ZEZBAXVIjxcA8YjtsJXhaOqLnd30EbXHA-sP81kAcQ","DP":"OL_P-Fktuq1YC4YzLuhbRuO0QnkV2xYqPPYNTFJenhOafyPzT2yIAFlJooLcZX6Fe10yFsS918ozn50huIxdfgxrNw2I011-sXYGNuhWnej7OdIUnJkXdSo2Ub8mJpro3iN_524P5cxda9MD5bQAKN1SmgSDHsOZZJALVJBO4dE","DQ":"C2I3Kqu0zaLtYl4OuJxyiMtA2UmK88yFTnDm4pvSWj9XXiiBs2VYLwGevhDTcYI1gT8zar4xeUoWimHzSQxbOcp7EXsjqo_eMTt_t7gwjDRs9tSOu0_mTUhisuM996wAa-QVVzvonxtVPyzHSuoXoxNHfRAUDl1MPVcqV9imTJs","E":"AQAB","K":null,"KeyId":"E845B5C99290199A39E6D83B31E223FA","Kid":"E845B5C99290199A39E6D83B31E223FA","Kty":"RSA","N":"qjXtEBYJMcDnFV59Tk9wTd516-U6Pq_NDujOBZh3ccSvsKc0-NdkAST45WjBscXzh6ByAQcHss1oqrj6YttvzfcReA6IrPVSz1fvBi67eoCjuBVv_94aCoT1fmUpxgv2V9ZqEp23goJ2oppkyTcE7VIoKGgAQREzE4kJ3YssMPYNfR9g_14DbPTMkDYfxfGI7j4wjAOFFNPlWfBToyH7U7dgBtBeu-5NYxFrBZ_Ze0tOoJ20D_u9UZ93rAi7FVhY5787MltstmJ2R-ZNWgZjBad8s_xA6vXHP_7rBh-taAu4ID23U2DeL8w_4XncAPDNdQAZmDJ8_BcN_0uvkaVPNQ","Oth":null,"P":"05r8Rgv5TEAghb4HiCZeI6QcDi1VAXTzHI1f7r_0lliulzk_jc48i9iHGt2cJTaTba_Ln2LDAhkaIKMmptUXVvQiEzy02yeH93Iv9myQHORIwDkSvapMadOn2aCRCa_TJ3K_Bem8Ac9XKV8x4dG1nOtPOchCstfrJRM5g0HiqtM","Q":"zeuwW8cnB0JHvYpbn0dgZZf2tgwHcYNLCbHxsTGZsI6QZJxKC2EgmVFPwKiPLh2_qUegCkns4qUwt7_1eLtoqEplCmbR-rz_TO0zdKcO7-NA4jfud5nMgIIDMvECiaSSrpCoHy204823HXeEv3G6-jMyi7v2kBmfGZt_5RQByNc","QI":"aknrgXL1ZUNAbK4TcVPjG6j-9iCJTsV5LYtzud0DW1usLd67k_XSrCptK3ova__OfnnlzzJpqtCL1LFxk-WTn4ZVT8E1YcjYeaW9DDUQ80DtpYXaL0mv1P8b7ma7FE-m4nuknZeB6D5pYKXT7Tm2tvOHpYn38zzDpt7elFoohVU","Use":null,"X":null,"X5t":null,"X5tS256":null,"X5u":null,"Y":null,"KeySize":2048,"HasPrivateKey":true,"CryptoProviderFactory":{"CryptoProviderCache":{},"CustomCryptoProvider":null,"CacheSignatureProviders":true,"SignatureProviderObjectPoolCacheSize":32}}

1
services/book-store/wwwroot/global-styles.css

@ -0,0 +1 @@
/* Your Global Styles */
Loading…
Cancel
Save