From 18a1846258590a38c8c3553d282a44f4af4fb1e6 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 12 Jun 2022 23:08:56 +0800 Subject: [PATCH 01/97] Add `EasyAbp.EShop.Plugins.FlashSales` Project --- EShop.sln | 180 +++++++++--- plugins/FlashSales/.gitattributes | 1 + plugins/FlashSales/.gitignore | 259 ++++++++++++++++++ plugins/FlashSales/.prettierrc | 5 + ...syAbp.EShop.Plugins.FlashSales.abpmdl.json | 111 ++++++++ ...syAbp.EShop.Plugins.FlashSales.abpsln.json | 7 + .../EasyAbp.EShop.Plugins.FlashSales.sln | 146 ++++++++++ ...p.EShop.Plugins.FlashSales.sln.DotSettings | 23 ++ plugins/FlashSales/NuGet.Config | 6 + .../FlashSales/docker-compose.migrations.yml | 13 + .../FlashSales/docker-compose.override.yml | 29 ++ plugins/FlashSales/docker-compose.yml | 25 ++ ...Plugins.FlashSales.Host.Shared.abppkg.json | 1 + ...Shop.Plugins.FlashSales.Host.Shared.csproj | 10 + .../MultiTenancy/MultiTenancyConsts.cs | 9 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...ashSales.Application.Contracts.abppkg.json | 3 + ...ns.FlashSales.Application.Contracts.csproj | 16 ++ .../FlashSalesApplicationContractsModule.cs | 15 + .../FlashSalesRemoteServiceConsts.cs | 8 + .../FlashSalesPermissionDefinitionProvider.cs | 18 ++ .../Permissions/FlashSalesPermissions.cs | 13 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...Plugins.FlashSales.Application.abppkg.json | 3 + ...Shop.Plugins.FlashSales.Application.csproj | 17 ++ .../FlashSales/FlashSalesAppService.cs | 13 + .../FlashSalesApplicationAutoMapperProfile.cs | 13 + .../FlashSales/FlashSalesApplicationModule.cs | 24 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...ugins.FlashSales.Domain.Shared.abppkg.json | 3 + ...op.Plugins.FlashSales.Domain.Shared.csproj | 24 ++ .../FlashSalesDomainSharedModule.cs | 36 +++ .../FlashSales/FlashSalesErrorCodes.cs | 6 + .../Localization/FlashSalesResource.cs | 9 + .../Plugins/FlashSales/Localization/en.json | 5 + .../FlashSales/Localization/zh-Hans.json | 5 + .../FlashSales/Localization/zh-Hant.json | 5 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...Shop.Plugins.FlashSales.Domain.abppkg.json | 3 + ...Abp.EShop.Plugins.FlashSales.Domain.csproj | 15 + .../FlashSales/FlashSalesDbProperties.cs | 10 + .../FlashSales/FlashSalesDomainModule.cs | 13 + .../FlashSalesSettingDefinitionProvider.cs | 13 + .../FlashSales/Settings/FlashSalesSettings.cs | 10 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...FlashSales.EntityFrameworkCore.abppkg.json | 3 + ...gins.FlashSales.EntityFrameworkCore.csproj | 15 + .../FlashSalesDbContext.cs | 26 ++ ...shSalesDbContextModelCreatingExtensions.cs | 33 +++ .../FlashSalesEntityFrameworkCoreModule.cs | 22 ++ .../IFlashSalesDbContext.cs | 12 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...gins.FlashSales.HttpApi.Client.abppkg.json | 3 + ...p.Plugins.FlashSales.HttpApi.Client.csproj | 20 ++ .../FlashSalesHttpApiClientModule.cs | 26 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...hop.Plugins.FlashSales.HttpApi.abppkg.json | 3 + ...bp.EShop.Plugins.FlashSales.HttpApi.csproj | 15 + .../FlashSales/FlashSalesController.cs | 12 + .../FlashSales/FlashSalesHttpApiModule.cs | 32 +++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ....EShop.Plugins.FlashSales.Installer.csproj | 21 ++ .../FlashSalesInstallerModule.cs | 20 ++ .../FlashSalesInstallerPipelineBuilder.cs | 16 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...hop.Plugins.FlashSales.MongoDB.abppkg.json | 3 + ...bp.EShop.Plugins.FlashSales.MongoDB.csproj | 15 + .../MongoDB/FlashSalesMongoDbContext.cs | 19 ++ .../FlashSalesMongoDbContextExtensions.cs | 13 + .../MongoDB/FlashSalesMongoDbModule.cs | 22 ++ .../MongoDB/IFlashSalesMongoDbContext.cs | 12 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...p.EShop.Plugins.FlashSales.Web.abppkg.json | 3 + ...asyAbp.EShop.Plugins.FlashSales.Web.csproj | 40 +++ .../FlashSalesWebAutoMapperProfile.cs | 13 + .../FlashSalesWebModule.cs | 58 ++++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ .../Menus/FlashSalesMenuContributor.cs | 23 ++ .../Menus/FlashSalesMenus.cs | 10 + .../EShop/Plugins/FlashSales/Index.cshtml | 11 + .../EShop/Plugins/FlashSales/Index.cshtml.cs | 8 + .../Plugins/FlashSales/_ViewImports.cshtml | 4 + .../Pages/FlashSalesPageModel.cs | 15 + .../Properties/launchSettings.json | 27 ++ ...s.FlashSales.Application.Tests.abppkg.json | 3 + ...lugins.FlashSales.Application.Tests.csproj | 14 + .../FlashSalesApplicationTestBase.cs | 9 + .../FlashSalesApplicationTestModule.cs | 12 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...lugins.FlashSales.Domain.Tests.abppkg.json | 3 + ...hop.Plugins.FlashSales.Domain.Tests.csproj | 13 + .../FlashSales/FlashSalesDomainTestBase.cs | 9 + .../FlashSales/FlashSalesDomainTestModule.cs | 16 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...ales.EntityFrameworkCore.Tests.abppkg.json | 3 + ...lashSales.EntityFrameworkCore.Tests.csproj | 16 ++ .../FlashSalesEntityFrameworkCoreTestBase.cs | 9 + ...FlashSalesEntityFrameworkCoreTestModule.cs | 42 +++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ....HttpApi.Client.ConsoleTestApp.abppkg.json | 1 + ...Sales.HttpApi.Client.ConsoleTestApp.csproj | 32 +++ .../Plugins/FlashSales/ClientDemoService.cs | 145 ++++++++++ .../FlashSales/ConsoleTestAppHostedService.cs | 40 +++ .../FlashSalesConsoleApiClientModule.cs | 15 + .../EShop/Plugins/FlashSales/Program.cs | 22 ++ .../appsettings.json | 21 ++ .../appsettings.secrets.json | 2 + ...ugins.FlashSales.MongoDB.Tests.abppkg.json | 3 + ...op.Plugins.FlashSales.MongoDB.Tests.csproj | 15 + .../MongoDB/FlashSalesMongoDbTestBase.cs | 9 + .../MongoDB/FlashSalesMongoDbTestModule.cs | 26 ++ .../FlashSales/MongoDB/MongoDbFixture.cs | 21 ++ .../FlashSales/MongoDB/MongoTestCollection.cs | 9 + .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...op.Plugins.FlashSales.TestBase.abppkg.json | 1 + ...p.EShop.Plugins.FlashSales.TestBase.csproj | 21 ++ .../FlashSalesDataSeedContributor.cs | 32 +++ .../Plugins/FlashSales/FlashSalesTestBase.cs | 59 ++++ .../FlashSales/FlashSalesTestBaseModule.cs | 41 +++ .../Security/FakeCurrentPrincipalAccessor.cs | 42 +++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ 137 files changed, 2901 insertions(+), 33 deletions(-) create mode 100644 plugins/FlashSales/.gitattributes create mode 100644 plugins/FlashSales/.gitignore create mode 100644 plugins/FlashSales/.prettierrc create mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json create mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json create mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln create mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings create mode 100644 plugins/FlashSales/NuGet.Config create mode 100644 plugins/FlashSales/docker-compose.migrations.yml create mode 100644 plugins/FlashSales/docker-compose.override.yml create mode 100644 plugins/FlashSales/docker-compose.yml create mode 100644 plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.abppkg.json create mode 100644 plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.csproj create mode 100644 plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp/EShop/Plugins/FlashSales/MultiTenancy/MultiTenancyConsts.cs create mode 100644 plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xml create mode 100644 plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationContractsModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesRemoteServiceConsts.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainSharedModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettingDefinitionProvider.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettings.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiClientModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesController.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/EasyAbp.EShop.Plugins.FlashSales.Installer.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerPipelineBuilder.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.abppkg.json create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebAutoMapperProfile.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/_ViewImports.cshtml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Properties/launchSettings.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.abppkg.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xml create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.abppkg.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestModule.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xml create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xsd create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.abppkg.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xml create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xsd create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.abppkg.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.csproj create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ClientDemoService.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/Program.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.secrets.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.abppkg.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoDbFixture.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoTestCollection.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xml create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xsd create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.abppkg.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDataSeedContributor.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBase.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/Security/FakeCurrentPrincipalAccessor.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xml create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xsd diff --git a/EShop.sln b/EShop.sln index 98b9f223..21fe6afe 100644 --- a/EShop.sln +++ b/EShop.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29020.237 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32526.322 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EShopSample.Domain", "samples\EShopSample\aspnet-core\src\EShopSample.Domain\EShopSample.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}" EndProject @@ -303,77 +303,113 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{D261 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EShopSample", "EShopSample", "{FE0A5FD6-AEE7-4738-9A6D-261BF086704D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Stores.Application.Shared", "modules\EasyAbp.EShop.Stores\src\EasyAbp.EShop.Stores.Application.Shared\EasyAbp.EShop.Stores.Application.Shared.csproj", "{06700175-4E04-4993-A1FB-24E7A8835E19}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Stores.Application.Shared", "modules\EasyAbp.EShop.Stores\src\EasyAbp.EShop.Stores.Application.Shared\EasyAbp.EShop.Stores.Application.Shared.csproj", "{06700175-4E04-4993-A1FB-24E7A8835E19}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{72F34527-9295-4F29-923E-4B075A4F31A2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.Application", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Application\EasyAbp.EShop.Plugins.Coupons.Application.csproj", "{1EB6504F-7FF0-4628-9D7C-81BDE33D9490}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.Application", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Application\EasyAbp.EShop.Plugins.Coupons.Application.csproj", "{1EB6504F-7FF0-4628-9D7C-81BDE33D9490}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.Application.Contracts", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Application.Contracts\EasyAbp.EShop.Plugins.Coupons.Application.Contracts.csproj", "{C7D05698-E509-4F5C-A792-0036190AE6FF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.Application.Contracts", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Application.Contracts\EasyAbp.EShop.Plugins.Coupons.Application.Contracts.csproj", "{C7D05698-E509-4F5C-A792-0036190AE6FF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.Domain", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Domain\EasyAbp.EShop.Plugins.Coupons.Domain.csproj", "{4DBC9216-80FD-4E71-BCB3-0F1ADA63AEC2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.Domain", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Domain\EasyAbp.EShop.Plugins.Coupons.Domain.csproj", "{4DBC9216-80FD-4E71-BCB3-0F1ADA63AEC2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.Domain.Shared", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Domain.Shared\EasyAbp.EShop.Plugins.Coupons.Domain.Shared.csproj", "{31F1DC02-5790-4FAD-A8F2-0D6F9FE21F00}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.Domain.Shared", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Domain.Shared\EasyAbp.EShop.Plugins.Coupons.Domain.Shared.csproj", "{31F1DC02-5790-4FAD-A8F2-0D6F9FE21F00}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.csproj", "{EE6B9D10-7038-4CDE-A6BF-3941AFD84D7A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.csproj", "{EE6B9D10-7038-4CDE-A6BF-3941AFD84D7A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.HttpApi", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.HttpApi\EasyAbp.EShop.Plugins.Coupons.HttpApi.csproj", "{0E22DE0A-032B-442E-AEB2-E299B333BADC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.HttpApi", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.HttpApi\EasyAbp.EShop.Plugins.Coupons.HttpApi.csproj", "{0E22DE0A-032B-442E-AEB2-E299B333BADC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.HttpApi.Client", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.csproj", "{85D39FAB-A9A8-4942-BF94-A6061FCFBF7A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.HttpApi.Client", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.csproj", "{85D39FAB-A9A8-4942-BF94-A6061FCFBF7A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.MongoDB", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.MongoDB\EasyAbp.EShop.Plugins.Coupons.MongoDB.csproj", "{C97330F5-4634-4865-9D7D-E33F87808938}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.MongoDB", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.MongoDB\EasyAbp.EShop.Plugins.Coupons.MongoDB.csproj", "{C97330F5-4634-4865-9D7D-E33F87808938}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.Web", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Web\EasyAbp.EShop.Plugins.Coupons.Web.csproj", "{C11BD71D-FA6B-4833-9CAE-82ED9D857A84}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.Web", "plugins\Coupons\src\EasyAbp.EShop.Plugins.Coupons.Web\EasyAbp.EShop.Plugins.Coupons.Web.csproj", "{C11BD71D-FA6B-4833-9CAE-82ED9D857A84}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{4001814E-A67B-490D-9E13-2FB9A34B0A0B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.Application.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.Application.Tests\EasyAbp.EShop.Plugins.Coupons.Application.Tests.csproj", "{10675CED-5689-4B2F-895A-E13820928A3B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.Application.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.Application.Tests\EasyAbp.EShop.Plugins.Coupons.Application.Tests.csproj", "{10675CED-5689-4B2F-895A-E13820928A3B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.Domain.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.Domain.Tests\EasyAbp.EShop.Plugins.Coupons.Domain.Tests.csproj", "{B29ABA23-37B2-419A-9E3C-F1A8703D584D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.Domain.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.Domain.Tests\EasyAbp.EShop.Plugins.Coupons.Domain.Tests.csproj", "{B29ABA23-37B2-419A-9E3C-F1A8703D584D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.Tests\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.Tests.csproj", "{D81EC4DC-3944-4CFE-875A-5DD07BE487AE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.Tests\EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore.Tests.csproj", "{D81EC4DC-3944-4CFE-875A-5DD07BE487AE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.ConsoleTestApp", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.ConsoleTestApp\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.ConsoleTestApp.csproj", "{8B22E009-5ABA-4878-83E5-38154F2B8E2F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.ConsoleTestApp", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.ConsoleTestApp\EasyAbp.EShop.Plugins.Coupons.HttpApi.Client.ConsoleTestApp.csproj", "{8B22E009-5ABA-4878-83E5-38154F2B8E2F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.MongoDB.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.MongoDB.Tests\EasyAbp.EShop.Plugins.Coupons.MongoDB.Tests.csproj", "{86CAD303-A0E5-42C9-89A5-61D9AAA4AD8F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.MongoDB.Tests", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.MongoDB.Tests\EasyAbp.EShop.Plugins.Coupons.MongoDB.Tests.csproj", "{86CAD303-A0E5-42C9-89A5-61D9AAA4AD8F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Coupons.TestBase", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.TestBase\EasyAbp.EShop.Plugins.Coupons.TestBase.csproj", "{B076C103-DF0B-464B-A9CB-4BE5CAFEE067}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Coupons.TestBase", "plugins\Coupons\test\EasyAbp.EShop.Plugins.Coupons.TestBase\EasyAbp.EShop.Plugins.Coupons.TestBase.csproj", "{B076C103-DF0B-464B-A9CB-4BE5CAFEE067}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Orders.Plugins.Coupons", "plugins\Coupons\src\EasyAbp.EShop.Orders.Plugins.Coupons\EasyAbp.EShop.Orders.Plugins.Coupons.csproj", "{3C385657-8365-470F-9F4F-30F31F9FCA42}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Orders.Plugins.Coupons", "plugins\Coupons\src\EasyAbp.EShop.Orders.Plugins.Coupons\EasyAbp.EShop.Orders.Plugins.Coupons.csproj", "{3C385657-8365-470F-9F4F-30F31F9FCA42}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Inventories", "Inventories", "{9AC27747-E175-487F-92C9-434DEE543273}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DaprActors", "DaprActors", "{6E6FE4B9-4117-4F57-B219-EE47E4046096}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.DaprActorsInventory.Domain", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Products.DaprActorsInventory.Domain\EasyAbp.EShop.Products.DaprActorsInventory.Domain.csproj", "{6CD1A8B5-8AB7-4A31-8333-024A7FB602D1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.DaprActorsInventory.Domain", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Products.DaprActorsInventory.Domain\EasyAbp.EShop.Products.DaprActorsInventory.Domain.csproj", "{6CD1A8B5-8AB7-4A31-8333-024A7FB602D1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions\EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions.csproj", "{CF4DE32D-9629-4C48-9BE8-5B83A1C27291}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions\EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions.csproj", "{CF4DE32D-9629-4C48-9BE8-5B83A1C27291}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors\EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj", "{B6F3ACD5-463E-4455-A094-057A82941A94}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors\EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj", "{B6F3ACD5-463E-4455-A094-057A82941A94}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F468A386-5660-4888-981A-6ECF15182D32}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{485204B1-7603-4EA0-B3A4-73CB89B0D5BC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests", "plugins\Inventories\DaprActors\test\EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests\EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests.csproj", "{733C51A3-19C8-45C4-8B22-3FD40CAF4EFB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests", "plugins\Inventories\DaprActors\test\EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests\EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests.csproj", "{733C51A3-19C8-45C4-8B22-3FD40CAF4EFB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore\EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore.csproj", "{3F0EA314-CCF4-4BB2-A8C1-79FAE4442884}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore", "plugins\Inventories\DaprActors\src\EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore\EasyAbp.EShop.Plugins.Inventories.DaprActors.AspNetCore.csproj", "{3F0EA314-CCF4-4BB2-A8C1-79FAE4442884}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.OrleansGrains", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Plugins.Inventories.OrleansGrains\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj", "{83F6434F-74DC-4389-870D-46510E28C029}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Inventories.OrleansGrains", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Plugins.Inventories.OrleansGrains\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj", "{83F6434F-74DC-4389-870D-46510E28C029}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OrleansGrains", "OrleansGrains", "{88D17635-75D7-48A1-B622-E6FB3DCACEF8}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8E978749-7972-4703-8A94-6A90080C78DE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions.csproj", "{AB3477DB-3457-4167-A086-BAD104D69604}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions.csproj", "{AB3477DB-3457-4167-A086-BAD104D69604}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Silo", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Silo\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Silo.csproj", "{0D613460-A0AD-4EAF-B719-785FE65E97E8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Silo", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Silo\EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Silo.csproj", "{0D613460-A0AD-4EAF-B719-785FE65E97E8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.OrleansGrainsInventory.Domain", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.csproj", "{DB1C55BF-0C0D-488C-9AFC-992A3DED2EAD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.OrleansGrainsInventory.Domain", "plugins\Inventories\OrleansGrains\src\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.csproj", "{DB1C55BF-0C0D-488C-9AFC-992A3DED2EAD}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F58B6EEF-5AFF-4B79-BC71-A2D8C71F5E77}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests", "plugins\Inventories\OrleansGrains\test\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests.csproj", "{D652EBF0-27CA-44C2-BB78-F446B87377C7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests", "plugins\Inventories\OrleansGrains\test\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests\EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests.csproj", "{D652EBF0-27CA-44C2-BB78-F446B87377C7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FlashSales", "FlashSales", "{867AD9F8-FD56-469D-A90D-C569EB9C3D2A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Application\EasyAbp.EShop.Plugins.FlashSales.Application.csproj", "{26611C4C-6910-498A-9FBA-BECC09392ADE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Contracts", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj", "{FCD72398-F832-4914-8ACF-EA4C1DD24BBF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Shared", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj", "{55145D4A-5A98-4B53-9293-CCB7236E69F5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Domain", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Domain\EasyAbp.EShop.Plugins.FlashSales.Domain.csproj", "{7E535D1A-3259-4098-8E47-A81B3D8B3920}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj", "{2D1C0E98-D86A-4C60-98CE-86C4E5571B91}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.MongoDB\EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj", "{B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj", "{0D5558BD-A22F-4565-A92A-BB14D517B1A5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F29C5BCD-E6C0-4556-A631-CACA41B1050B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{9C180C9E-50E9-4624-BE06-5C8C24A028E4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj", "{6658CE7D-CA7D-47A7-8B9E-6D8776CE607C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Web", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Web\EasyAbp.EShop.Plugins.FlashSales.Web.csproj", "{6F06F221-1371-433A-8C90-3123B5EF32AD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Tests", "plugins\FlashSales\test\EasyAbp.EShop.Plugins.FlashSales.Application.Tests\EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj", "{6EBE36C7-53DB-4194-BDDB-199F789F44E6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Tests", "plugins\FlashSales\test\EasyAbp.EShop.Plugins.FlashSales.Domain.Tests\EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj", "{654C320E-78BD-4074-AC2D-154E95457BBC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests", "plugins\FlashSales\test\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj", "{D2AAFF29-3F7B-4C90-AA99-AC686393B670}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp", "plugins\FlashSales\test\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.csproj", "{2291B087-FEC5-47BD-A7ED-04725D54E6A6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests", "plugins\FlashSales\test\EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests\EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj", "{68993D65-2C9C-438F-8B94-15E98C469A16}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.TestBase", "plugins\FlashSales\test\EasyAbp.EShop.Plugins.FlashSales.TestBase\EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj", "{417AB8E2-1488-4814-9699-3B189D1ABA67}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -969,6 +1005,66 @@ Global {D652EBF0-27CA-44C2-BB78-F446B87377C7}.Debug|Any CPU.Build.0 = Debug|Any CPU {D652EBF0-27CA-44C2-BB78-F446B87377C7}.Release|Any CPU.ActiveCfg = Release|Any CPU {D652EBF0-27CA-44C2-BB78-F446B87377C7}.Release|Any CPU.Build.0 = Release|Any CPU + {26611C4C-6910-498A-9FBA-BECC09392ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26611C4C-6910-498A-9FBA-BECC09392ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26611C4C-6910-498A-9FBA-BECC09392ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26611C4C-6910-498A-9FBA-BECC09392ADE}.Release|Any CPU.Build.0 = Release|Any CPU + {FCD72398-F832-4914-8ACF-EA4C1DD24BBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCD72398-F832-4914-8ACF-EA4C1DD24BBF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCD72398-F832-4914-8ACF-EA4C1DD24BBF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCD72398-F832-4914-8ACF-EA4C1DD24BBF}.Release|Any CPU.Build.0 = Release|Any CPU + {55145D4A-5A98-4B53-9293-CCB7236E69F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55145D4A-5A98-4B53-9293-CCB7236E69F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55145D4A-5A98-4B53-9293-CCB7236E69F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55145D4A-5A98-4B53-9293-CCB7236E69F5}.Release|Any CPU.Build.0 = Release|Any CPU + {7E535D1A-3259-4098-8E47-A81B3D8B3920}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E535D1A-3259-4098-8E47-A81B3D8B3920}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E535D1A-3259-4098-8E47-A81B3D8B3920}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E535D1A-3259-4098-8E47-A81B3D8B3920}.Release|Any CPU.Build.0 = Release|Any CPU + {2D1C0E98-D86A-4C60-98CE-86C4E5571B91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D1C0E98-D86A-4C60-98CE-86C4E5571B91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D1C0E98-D86A-4C60-98CE-86C4E5571B91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D1C0E98-D86A-4C60-98CE-86C4E5571B91}.Release|Any CPU.Build.0 = Release|Any CPU + {B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE}.Release|Any CPU.Build.0 = Release|Any CPU + {0D5558BD-A22F-4565-A92A-BB14D517B1A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D5558BD-A22F-4565-A92A-BB14D517B1A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D5558BD-A22F-4565-A92A-BB14D517B1A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D5558BD-A22F-4565-A92A-BB14D517B1A5}.Release|Any CPU.Build.0 = Release|Any CPU + {6658CE7D-CA7D-47A7-8B9E-6D8776CE607C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6658CE7D-CA7D-47A7-8B9E-6D8776CE607C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6658CE7D-CA7D-47A7-8B9E-6D8776CE607C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6658CE7D-CA7D-47A7-8B9E-6D8776CE607C}.Release|Any CPU.Build.0 = Release|Any CPU + {6F06F221-1371-433A-8C90-3123B5EF32AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F06F221-1371-433A-8C90-3123B5EF32AD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F06F221-1371-433A-8C90-3123B5EF32AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F06F221-1371-433A-8C90-3123B5EF32AD}.Release|Any CPU.Build.0 = Release|Any CPU + {6EBE36C7-53DB-4194-BDDB-199F789F44E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6EBE36C7-53DB-4194-BDDB-199F789F44E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6EBE36C7-53DB-4194-BDDB-199F789F44E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6EBE36C7-53DB-4194-BDDB-199F789F44E6}.Release|Any CPU.Build.0 = Release|Any CPU + {654C320E-78BD-4074-AC2D-154E95457BBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {654C320E-78BD-4074-AC2D-154E95457BBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {654C320E-78BD-4074-AC2D-154E95457BBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {654C320E-78BD-4074-AC2D-154E95457BBC}.Release|Any CPU.Build.0 = Release|Any CPU + {D2AAFF29-3F7B-4C90-AA99-AC686393B670}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2AAFF29-3F7B-4C90-AA99-AC686393B670}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2AAFF29-3F7B-4C90-AA99-AC686393B670}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2AAFF29-3F7B-4C90-AA99-AC686393B670}.Release|Any CPU.Build.0 = Release|Any CPU + {2291B087-FEC5-47BD-A7ED-04725D54E6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2291B087-FEC5-47BD-A7ED-04725D54E6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2291B087-FEC5-47BD-A7ED-04725D54E6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2291B087-FEC5-47BD-A7ED-04725D54E6A6}.Release|Any CPU.Build.0 = Release|Any CPU + {68993D65-2C9C-438F-8B94-15E98C469A16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {68993D65-2C9C-438F-8B94-15E98C469A16}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68993D65-2C9C-438F-8B94-15E98C469A16}.Release|Any CPU.ActiveCfg = Release|Any CPU + {68993D65-2C9C-438F-8B94-15E98C469A16}.Release|Any CPU.Build.0 = Release|Any CPU + {417AB8E2-1488-4814-9699-3B189D1ABA67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {417AB8E2-1488-4814-9699-3B189D1ABA67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {417AB8E2-1488-4814-9699-3B189D1ABA67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {417AB8E2-1488-4814-9699-3B189D1ABA67}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1141,21 +1237,39 @@ Global {3C385657-8365-470F-9F4F-30F31F9FCA42} = {72F34527-9295-4F29-923E-4B075A4F31A2} {9AC27747-E175-487F-92C9-434DEE543273} = {94CC5A11-DA0F-413C-96CA-01DB0FC426E0} {6E6FE4B9-4117-4F57-B219-EE47E4046096} = {9AC27747-E175-487F-92C9-434DEE543273} - {F468A386-5660-4888-981A-6ECF15182D32} = {6E6FE4B9-4117-4F57-B219-EE47E4046096} - {B6F3ACD5-463E-4455-A094-057A82941A94} = {F468A386-5660-4888-981A-6ECF15182D32} - {CF4DE32D-9629-4C48-9BE8-5B83A1C27291} = {F468A386-5660-4888-981A-6ECF15182D32} {6CD1A8B5-8AB7-4A31-8333-024A7FB602D1} = {F468A386-5660-4888-981A-6ECF15182D32} + {CF4DE32D-9629-4C48-9BE8-5B83A1C27291} = {F468A386-5660-4888-981A-6ECF15182D32} + {B6F3ACD5-463E-4455-A094-057A82941A94} = {F468A386-5660-4888-981A-6ECF15182D32} + {F468A386-5660-4888-981A-6ECF15182D32} = {6E6FE4B9-4117-4F57-B219-EE47E4046096} {485204B1-7603-4EA0-B3A4-73CB89B0D5BC} = {6E6FE4B9-4117-4F57-B219-EE47E4046096} {733C51A3-19C8-45C4-8B22-3FD40CAF4EFB} = {485204B1-7603-4EA0-B3A4-73CB89B0D5BC} {3F0EA314-CCF4-4BB2-A8C1-79FAE4442884} = {F468A386-5660-4888-981A-6ECF15182D32} + {83F6434F-74DC-4389-870D-46510E28C029} = {8E978749-7972-4703-8A94-6A90080C78DE} {88D17635-75D7-48A1-B622-E6FB3DCACEF8} = {9AC27747-E175-487F-92C9-434DEE543273} {8E978749-7972-4703-8A94-6A90080C78DE} = {88D17635-75D7-48A1-B622-E6FB3DCACEF8} - {83F6434F-74DC-4389-870D-46510E28C029} = {8E978749-7972-4703-8A94-6A90080C78DE} {AB3477DB-3457-4167-A086-BAD104D69604} = {8E978749-7972-4703-8A94-6A90080C78DE} {0D613460-A0AD-4EAF-B719-785FE65E97E8} = {8E978749-7972-4703-8A94-6A90080C78DE} {DB1C55BF-0C0D-488C-9AFC-992A3DED2EAD} = {8E978749-7972-4703-8A94-6A90080C78DE} {F58B6EEF-5AFF-4B79-BC71-A2D8C71F5E77} = {88D17635-75D7-48A1-B622-E6FB3DCACEF8} {D652EBF0-27CA-44C2-BB78-F446B87377C7} = {F58B6EEF-5AFF-4B79-BC71-A2D8C71F5E77} + {867AD9F8-FD56-469D-A90D-C569EB9C3D2A} = {94CC5A11-DA0F-413C-96CA-01DB0FC426E0} + {26611C4C-6910-498A-9FBA-BECC09392ADE} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {FCD72398-F832-4914-8ACF-EA4C1DD24BBF} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {55145D4A-5A98-4B53-9293-CCB7236E69F5} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {7E535D1A-3259-4098-8E47-A81B3D8B3920} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {2D1C0E98-D86A-4C60-98CE-86C4E5571B91} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {0D5558BD-A22F-4565-A92A-BB14D517B1A5} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {F29C5BCD-E6C0-4556-A631-CACA41B1050B} = {867AD9F8-FD56-469D-A90D-C569EB9C3D2A} + {9C180C9E-50E9-4624-BE06-5C8C24A028E4} = {867AD9F8-FD56-469D-A90D-C569EB9C3D2A} + {6658CE7D-CA7D-47A7-8B9E-6D8776CE607C} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {6F06F221-1371-433A-8C90-3123B5EF32AD} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {6EBE36C7-53DB-4194-BDDB-199F789F44E6} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} + {654C320E-78BD-4074-AC2D-154E95457BBC} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} + {D2AAFF29-3F7B-4C90-AA99-AC686393B670} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} + {2291B087-FEC5-47BD-A7ED-04725D54E6A6} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} + {68993D65-2C9C-438F-8B94-15E98C469A16} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} + {417AB8E2-1488-4814-9699-3B189D1ABA67} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/plugins/FlashSales/.gitattributes b/plugins/FlashSales/.gitattributes new file mode 100644 index 00000000..c941e526 --- /dev/null +++ b/plugins/FlashSales/.gitattributes @@ -0,0 +1 @@ +**/wwwroot/libs/** linguist-vendored diff --git a/plugins/FlashSales/.gitignore b/plugins/FlashSales/.gitignore new file mode 100644 index 00000000..b5e2674f --- /dev/null +++ b/plugins/FlashSales/.gitignore @@ -0,0 +1,259 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# FlashSales +host/EasyAbp.EShop.Plugins.FlashSales.IdentityServer/Logs/logs.txt +host/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host/Logs/logs.txt +host/EasyAbp.EShop.Plugins.FlashSales.Web.Host/Logs/logs.txt +host/EasyAbp.EShop.Plugins.FlashSales.Web.Unified/Logs/logs.txt +host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host/Logs/logs.txt \ No newline at end of file diff --git a/plugins/FlashSales/.prettierrc b/plugins/FlashSales/.prettierrc new file mode 100644 index 00000000..56af76bd --- /dev/null +++ b/plugins/FlashSales/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "useTabs": false, + "tabWidth": 4 +} diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json new file mode 100644 index 00000000..64cebbbb --- /dev/null +++ b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json @@ -0,0 +1,111 @@ +{ + "folders": { + "items": { + "src": {}, + "test": {}, + "host": {} + } + }, + "packages": { + "EasyAbp.EShop.Plugins.FlashSales.Domain.Shared": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.Domain": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.Application.Contracts": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.Application": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.MongoDB": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.HttpApi": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.TestBase": { + "path": "test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.abppkg.json", + "folder": "test" + }, + "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests": { + "path": "test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.abppkg.json", + "folder": "test" + }, + "EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests": { + "path": "test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.abppkg.json", + "folder": "test" + }, + "EasyAbp.EShop.Plugins.FlashSales.Domain.Tests": { + "path": "test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.abppkg.json", + "folder": "test" + }, + "EasyAbp.EShop.Plugins.FlashSales.Application.Tests": { + "path": "test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.abppkg.json", + "folder": "test" + }, + "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host": { + "path": "host/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host.abppkg.json", + "folder": "host" + }, + "EasyAbp.EShop.Plugins.FlashSales.Web": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp": { + "path": "test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.abppkg.json", + "folder": "test" + }, + "EasyAbp.EShop.Plugins.FlashSales.Web.Host": { + "path": "host/EasyAbp.EShop.Plugins.FlashSales.Web.Host/EasyAbp.EShop.Plugins.FlashSales.Web.Host.abppkg.json", + "folder": "host" + }, + "EasyAbp.EShop.Plugins.FlashSales.IdentityServer": { + "path": "host/EasyAbp.EShop.Plugins.FlashSales.IdentityServer/EasyAbp.EShop.Plugins.FlashSales.IdentityServer.abppkg.json", + "folder": "host" + }, + "EasyAbp.EShop.Plugins.FlashSales.Host.Shared": { + "path": "host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.abppkg.json", + "folder": "host" + }, + "EasyAbp.EShop.Plugins.FlashSales.Web.Unified": { + "path": "host/EasyAbp.EShop.Plugins.FlashSales.Web.Unified/EasyAbp.EShop.Plugins.FlashSales.Web.Unified.abppkg.json", + "folder": "host" + }, + "EasyAbp.EShop.Plugins.FlashSales.Blazor": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Blazor/EasyAbp.EShop.Plugins.FlashSales.Blazor.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.Blazor.Host": { + "path": "host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Host.abppkg.json", + "folder": "host" + }, + "EasyAbp.EShop.Plugins.FlashSales.Blazor.Server": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.Blazor.WebAssembly": { + "path": "src/EasyAbp.EShop.Plugins.FlashSales.Blazor.WebAssembly/EasyAbp.EShop.Plugins.FlashSales.Blazor.WebAssembly.abppkg.json", + "folder": "src" + }, + "EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host": { + "path": "host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host.abppkg.json", + "folder": "host" + } + } +} \ No newline at end of file diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json new file mode 100644 index 00000000..8939665d --- /dev/null +++ b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json @@ -0,0 +1,7 @@ +{ + "modules": { + "EasyAbp.EShop.Plugins.FlashSales": { + "path": "EasyAbp.EShop.Plugins.FlashSales.abpmdl.json" + } + } +} \ No newline at end of file diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln new file mode 100644 index 00000000..04554b96 --- /dev/null +++ b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln @@ -0,0 +1,146 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32526.322 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Shared", "src\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj", "{D64C1577-4929-4B60-939E-96DE1534891A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain", "src\EasyAbp.EShop.Plugins.FlashSales.Domain\EasyAbp.EShop.Plugins.FlashSales.Domain.csproj", "{F2840BC7-0188-4606-9126-DADD0F5ABF7A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Contracts", "src\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj", "{BD65D04F-08D5-40C1-8C24-77CA0BACB877}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application", "src\EasyAbp.EShop.Plugins.FlashSales.Application\EasyAbp.EShop.Plugins.FlashSales.Application.csproj", "{78040F9E-3501-4A40-82DF-00A597710F35}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{649A3FFA-182F-4E56-9717-E6A9A2BEC545}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{E400416D-2895-4512-9D17-90681EEC7E0A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore", "src\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj", "{0CE86223-D31D-4315-A1F5-87BA3EE1B844}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB", "src\EasyAbp.EShop.Plugins.FlashSales.MongoDB\EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj", "{F1C58097-4C08-4D88-8976-6B3389391481}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi", "src\EasyAbp.EShop.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj", "{077AA5F8-8B61-420C-A6B5-0150A66FDB34}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client", "src\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj", "{36E2735F-CEAB-44C8-A6D1-2CDAFF399751}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.TestBase", "test\EasyAbp.EShop.Plugins.FlashSales.TestBase\EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj", "{C5BB573D-3030-4BCB-88B7-F6A85C32766C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj", "{527F645C-C1FC-406E-8479-81386C8ECF13}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests\EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj", "{D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.Domain.Tests\EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj", "{E60895E5-79C4-447D-88B7-85CB5BA336A4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.Application.Tests\EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj", "{90CB5DC4-C040-45C7-8900-9688B26405BC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Web", "src\EasyAbp.EShop.Plugins.FlashSales.Web\EasyAbp.EShop.Plugins.FlashSales.Web.csproj", "{3B7B6317-1B85-4164-8E11-75574F80AE17}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp", "test\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.csproj", "{1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Host.Shared", "host\EasyAbp.EShop.Plugins.FlashSales.Host.Shared\EasyAbp.EShop.Plugins.FlashSales.Host.Shared.csproj", "{F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Installer", "src\EasyAbp.EShop.Plugins.FlashSales.Installer\EasyAbp.EShop.Plugins.FlashSales.Installer.csproj", "{BE39FD00-745B-4049-8161-FC129817CBE4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D64C1577-4929-4B60-939E-96DE1534891A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D64C1577-4929-4B60-939E-96DE1534891A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D64C1577-4929-4B60-939E-96DE1534891A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D64C1577-4929-4B60-939E-96DE1534891A}.Release|Any CPU.Build.0 = Release|Any CPU + {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Release|Any CPU.Build.0 = Release|Any CPU + {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Release|Any CPU.Build.0 = Release|Any CPU + {78040F9E-3501-4A40-82DF-00A597710F35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {78040F9E-3501-4A40-82DF-00A597710F35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {78040F9E-3501-4A40-82DF-00A597710F35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {78040F9E-3501-4A40-82DF-00A597710F35}.Release|Any CPU.Build.0 = Release|Any CPU + {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Release|Any CPU.Build.0 = Release|Any CPU + {F1C58097-4C08-4D88-8976-6B3389391481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1C58097-4C08-4D88-8976-6B3389391481}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1C58097-4C08-4D88-8976-6B3389391481}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1C58097-4C08-4D88-8976-6B3389391481}.Release|Any CPU.Build.0 = Release|Any CPU + {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Release|Any CPU.Build.0 = Release|Any CPU + {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Release|Any CPU.Build.0 = Release|Any CPU + {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Release|Any CPU.Build.0 = Release|Any CPU + {527F645C-C1FC-406E-8479-81386C8ECF13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {527F645C-C1FC-406E-8479-81386C8ECF13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {527F645C-C1FC-406E-8479-81386C8ECF13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {527F645C-C1FC-406E-8479-81386C8ECF13}.Release|Any CPU.Build.0 = Release|Any CPU + {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Release|Any CPU.Build.0 = Release|Any CPU + {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Release|Any CPU.Build.0 = Release|Any CPU + {90CB5DC4-C040-45C7-8900-9688B26405BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90CB5DC4-C040-45C7-8900-9688B26405BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90CB5DC4-C040-45C7-8900-9688B26405BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90CB5DC4-C040-45C7-8900-9688B26405BC}.Release|Any CPU.Build.0 = Release|Any CPU + {3B7B6317-1B85-4164-8E11-75574F80AE17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B7B6317-1B85-4164-8E11-75574F80AE17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B7B6317-1B85-4164-8E11-75574F80AE17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B7B6317-1B85-4164-8E11-75574F80AE17}.Release|Any CPU.Build.0 = Release|Any CPU + {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Release|Any CPU.Build.0 = Release|Any CPU + {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Release|Any CPU.Build.0 = Release|Any CPU + {BE39FD00-745B-4049-8161-FC129817CBE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE39FD00-745B-4049-8161-FC129817CBE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE39FD00-745B-4049-8161-FC129817CBE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE39FD00-745B-4049-8161-FC129817CBE4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D64C1577-4929-4B60-939E-96DE1534891A} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {F2840BC7-0188-4606-9126-DADD0F5ABF7A} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {BD65D04F-08D5-40C1-8C24-77CA0BACB877} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {78040F9E-3501-4A40-82DF-00A597710F35} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {0CE86223-D31D-4315-A1F5-87BA3EE1B844} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {F1C58097-4C08-4D88-8976-6B3389391481} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {077AA5F8-8B61-420C-A6B5-0150A66FDB34} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {36E2735F-CEAB-44C8-A6D1-2CDAFF399751} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {C5BB573D-3030-4BCB-88B7-F6A85C32766C} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} + {527F645C-C1FC-406E-8479-81386C8ECF13} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} + {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} + {E60895E5-79C4-447D-88B7-85CB5BA336A4} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} + {90CB5DC4-C040-45C7-8900-9688B26405BC} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} + {3B7B6317-1B85-4164-8E11-75574F80AE17} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} + {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB} = {E400416D-2895-4512-9D17-90681EEC7E0A} + {BE39FD00-745B-4049-8161-FC129817CBE4} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD} + EndGlobalSection +EndGlobal diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings new file mode 100644 index 00000000..cb0b2c91 --- /dev/null +++ b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings @@ -0,0 +1,23 @@ + + True + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + Required + Required + Required + Required + False + True + False + False + True + False + False + SQL + \ No newline at end of file diff --git a/plugins/FlashSales/NuGet.Config b/plugins/FlashSales/NuGet.Config new file mode 100644 index 00000000..be8a1ece --- /dev/null +++ b/plugins/FlashSales/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/docker-compose.migrations.yml b/plugins/FlashSales/docker-compose.migrations.yml new file mode 100644 index 00000000..f0823259 --- /dev/null +++ b/plugins/FlashSales/docker-compose.migrations.yml @@ -0,0 +1,13 @@ +version: '3.4' + +services: + migrations: + build: + context: ../../ + dockerfile: templates/service/database/Dockerfile + depends_on: + - sqlserver + environment: + - IdentityServer_DB=FlashSales_Identity + - FlashSales_DB=FlashSales_ModuleDb + - SA_PASSWORD=yourStrong(!)Password diff --git a/plugins/FlashSales/docker-compose.override.yml b/plugins/FlashSales/docker-compose.override.yml new file mode 100644 index 00000000..a84d1b0a --- /dev/null +++ b/plugins/FlashSales/docker-compose.override.yml @@ -0,0 +1,29 @@ +version: '3.4' + +services: + sqlserver: + environment: + - SA_PASSWORD=yourStrong(!)Password + - ACCEPT_EULA=Y + ports: + - "51599:1433" + + identity-server: + environment: + - ASPNETCORE_URLS=http://0.0.0.0:80 + - ConnectionStrings__Default=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false + - ConnectionStrings__SqlServerCache=Server=sqlserver;Database=FlashSales_Cache;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false + ports: + - "51600:80" + + flash-sales: + environment: + - ASPNETCORE_URLS=http://0.0.0.0:80 + - ConnectionStrings__Default=Server=sqlserver;Database=FlashSales_ModuleDb;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false + - ConnectionStrings__AbpSettingManagement=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false + - ConnectionStrings__AbpPermissionManagement=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false + - ConnectionStrings__AbpAuditLogging=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false + - ConnectionStrings__SqlServerCache=Server=sqlserver;Database=FlashSales_Cache;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false + - AuthServer__Authority=http://identity-server + ports: + - "51601:80" \ No newline at end of file diff --git a/plugins/FlashSales/docker-compose.yml b/plugins/FlashSales/docker-compose.yml new file mode 100644 index 00000000..88735dd6 --- /dev/null +++ b/plugins/FlashSales/docker-compose.yml @@ -0,0 +1,25 @@ +version: '3.4' + +services: + sqlserver: + image: mcr.microsoft.com/mssql/server + volumes: + - dbdata:/var/opt/mssql + + identity-server: + build: + context: ../../ + dockerfile: templates/service/host/IdentityServerHost/Dockerfile + depends_on: + - sqlserver + + flash-sales: + build: + context: ../../ + dockerfile: templates/service/host/EasyAbp.EShop.Plugins.FlashSales.Host/Dockerfile + depends_on: + - sqlserver + - identity-server + +volumes: + dbdata: \ No newline at end of file diff --git a/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.abppkg.json b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.abppkg.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.csproj b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.csproj new file mode 100644 index 00000000..1669f598 --- /dev/null +++ b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.csproj @@ -0,0 +1,10 @@ + + + + + + netstandard2.0 + + + + diff --git a/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp/EShop/Plugins/FlashSales/MultiTenancy/MultiTenancyConsts.cs b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp/EShop/Plugins/FlashSales/MultiTenancy/MultiTenancyConsts.cs new file mode 100644 index 00000000..6d205dd3 --- /dev/null +++ b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp/EShop/Plugins/FlashSales/MultiTenancy/MultiTenancyConsts.cs @@ -0,0 +1,9 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.MultiTenancy; + +public static class MultiTenancyConsts +{ + /* Enable/disable multi-tenancy in a single point + * to test your module with multi-tenancy. + */ + public const bool IsEnabled = false; +} diff --git a/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xml b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xsd b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.abppkg.json new file mode 100644 index 00000000..49032794 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application-contracts" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj new file mode 100644 index 00000000..b29cdfb9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj @@ -0,0 +1,16 @@ + + + + + + netstandard2.0 + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationContractsModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationContractsModule.cs new file mode 100644 index 00000000..b1f107e7 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationContractsModule.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Application; +using Volo.Abp.Modularity; +using Volo.Abp.Authorization; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(FlashSalesDomainSharedModule), + typeof(AbpDddApplicationContractsModule), + typeof(AbpAuthorizationModule) + )] +public class FlashSalesApplicationContractsModule : AbpModule +{ + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesRemoteServiceConsts.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesRemoteServiceConsts.cs new file mode 100644 index 00000000..ce2bfaac --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesRemoteServiceConsts.cs @@ -0,0 +1,8 @@ +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class FlashSalesRemoteServiceConsts +{ + public const string RemoteServiceName = "FlashSales"; + + public const string ModuleName = "flashSales"; +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs new file mode 100644 index 00000000..7f957669 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs @@ -0,0 +1,18 @@ +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace EasyAbp.EShop.Plugins.FlashSales.Permissions; + +public class FlashSalesPermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var myGroup = context.AddGroup(FlashSalesPermissions.GroupName, L("Permission:FlashSales")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs new file mode 100644 index 00000000..61f4f82d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Reflection; + +namespace EasyAbp.EShop.Plugins.FlashSales.Permissions; + +public class FlashSalesPermissions +{ + public const string GroupName = "FlashSales"; + + public static string[] GetAll() + { + return ReflectionHelper.GetPublicConstantsRecursively(typeof(FlashSalesPermissions)); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.abppkg.json new file mode 100644 index 00000000..412567ac --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.application" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj new file mode 100644 index 00000000..dfe3604c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj @@ -0,0 +1,17 @@ + + + + + + netstandard2.0 + + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs new file mode 100644 index 00000000..b17b4ff3 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs @@ -0,0 +1,13 @@ +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using Volo.Abp.Application.Services; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public abstract class FlashSalesAppService : ApplicationService +{ + protected FlashSalesAppService() + { + LocalizationResource = typeof(FlashSalesResource); + ObjectMapperContext = typeof(FlashSalesApplicationModule); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs new file mode 100644 index 00000000..68505ad8 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs @@ -0,0 +1,13 @@ +using AutoMapper; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class FlashSalesApplicationAutoMapperProfile : Profile +{ + public FlashSalesApplicationAutoMapperProfile() + { + /* You can configure your AutoMapper mapping configuration here. + * Alternatively, you can split your mapping configurations + * into multiple profile classes for a better organization. */ + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationModule.cs new file mode 100644 index 00000000..9aae63c7 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationModule.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; +using Volo.Abp.Application; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(FlashSalesDomainModule), + typeof(FlashSalesApplicationContractsModule), + typeof(AbpDddApplicationModule), + typeof(AbpAutoMapperModule) + )] +public class FlashSalesApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + Configure(options => + { + options.AddMaps(validate: true); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.abppkg.json new file mode 100644 index 00000000..8b3de05f --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain-shared" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj new file mode 100644 index 00000000..e5e0cdcf --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj @@ -0,0 +1,24 @@ + + + + + + netstandard2.0 + + true + + + + + + + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainSharedModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainSharedModule.cs new file mode 100644 index 00000000..69351ec3 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainSharedModule.cs @@ -0,0 +1,36 @@ +using Volo.Abp.Modularity; +using Volo.Abp.Localization; +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using Volo.Abp.Localization.ExceptionHandling; +using Volo.Abp.Validation; +using Volo.Abp.Validation.Localization; +using Volo.Abp.VirtualFileSystem; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(AbpValidationModule) +)] +public class FlashSalesDomainSharedModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add("en") + .AddBaseTypes(typeof(AbpValidationResource)) + .AddVirtualJson("EasyAbp/EShop/Plugins/FlashSales/Localization"); + }); + + Configure(options => + { + options.MapCodeNamespace("FlashSales", typeof(FlashSalesResource)); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs new file mode 100644 index 00000000..a71ad4c1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -0,0 +1,6 @@ +namespace EasyAbp.EShop.Plugins.FlashSales; + +public static class FlashSalesErrorCodes +{ + //Add your business exception error codes here... +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs new file mode 100644 index 00000000..a6e9fa61 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Localization; + +namespace EasyAbp.EShop.Plugins.FlashSales.Localization; + +[LocalizationResourceName("FlashSales")] +public class FlashSalesResource +{ + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json new file mode 100644 index 00000000..189662ee --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -0,0 +1,5 @@ +{ + "culture": "en", + "texts": { + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json new file mode 100644 index 00000000..df772fa6 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -0,0 +1,5 @@ +{ + "culture": "zh-Hans", + "texts": { + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json new file mode 100644 index 00000000..7de37982 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -0,0 +1,5 @@ +{ + "culture": "zh-Hant", + "texts": { + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.abppkg.json new file mode 100644 index 00000000..1d574efe --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.domain" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj new file mode 100644 index 00000000..87ad5a39 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj @@ -0,0 +1,15 @@ + + + + + + netstandard2.0 + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs new file mode 100644 index 00000000..e94eef4d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs @@ -0,0 +1,10 @@ +namespace EasyAbp.EShop.Plugins.FlashSales; + +public static class FlashSalesDbProperties +{ + public static string DbTablePrefix { get; set; } = "FlashSales"; + + public static string DbSchema { get; set; } = null; + + public const string ConnectionStringName = "FlashSales"; +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainModule.cs new file mode 100644 index 00000000..8e6806da --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainModule.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Domain; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(AbpDddDomainModule), + typeof(FlashSalesDomainSharedModule) +)] +public class FlashSalesDomainModule : AbpModule +{ + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettingDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettingDefinitionProvider.cs new file mode 100644 index 00000000..817f807d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettingDefinitionProvider.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Settings; + +namespace EasyAbp.EShop.Plugins.FlashSales.Settings; + +public class FlashSalesSettingDefinitionProvider : SettingDefinitionProvider +{ + public override void Define(ISettingDefinitionContext context) + { + /* Define module settings here. + * Use names from FlashSalesSettings class. + */ + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettings.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettings.cs new file mode 100644 index 00000000..1cae4330 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/Settings/FlashSalesSettings.cs @@ -0,0 +1,10 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.Settings; + +public static class FlashSalesSettings +{ + public const string GroupName = "FlashSales"; + + /* Add constants for setting names. Example: + * public const string MySettingName = GroupName + ".MySettingName"; + */ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.abppkg.json new file mode 100644 index 00000000..e1c64f01 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.ef" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj new file mode 100644 index 00000000..84e4197c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj @@ -0,0 +1,15 @@ + + + + + + net6.0 + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs new file mode 100644 index 00000000..3d3df1b4 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; + +namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; + +[ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] +public class FlashSalesDbContext : AbpDbContext, IFlashSalesDbContext +{ + /* Add DbSet for each Aggregate Root here. Example: + * public DbSet Questions { get; set; } + */ + + public FlashSalesDbContext(DbContextOptions options) + : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + + builder.ConfigureFlashSales(); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs new file mode 100644 index 00000000..209d4ba8 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; + +public static class FlashSalesDbContextModelCreatingExtensions +{ + public static void ConfigureFlashSales( + this ModelBuilder builder) + { + Check.NotNull(builder, nameof(builder)); + + /* Configure all entities here. Example: + + builder.Entity(b => + { + //Configure table & schema name + b.ToTable(FlashSalesDbProperties.DbTablePrefix + "Questions", FlashSalesDbProperties.DbSchema); + + b.ConfigureByConvention(); + + //Properties + b.Property(q => q.Title).IsRequired().HasMaxLength(QuestionConsts.MaxTitleLength); + + //Relations + b.HasMany(question => question.Tags).WithOne().HasForeignKey(qt => qt.QuestionId); + + //Indexes + b.HasIndex(q => q.CreationTime); + }); + */ + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreModule.cs new file mode 100644 index 00000000..a91237cf --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreModule.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; + +[DependsOn( + typeof(FlashSalesDomainModule), + typeof(AbpEntityFrameworkCoreModule) +)] +public class FlashSalesEntityFrameworkCoreModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAbpDbContext(options => + { + /* Add custom repositories here. Example: + * options.AddRepository(); + */ + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs new file mode 100644 index 00000000..5804039f --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Data; +using Volo.Abp.EntityFrameworkCore; + +namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; + +[ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] +public interface IFlashSalesDbContext : IEfCoreDbContext +{ + /* Add DbSet for each Aggregate Root here. Example: + * DbSet Questions { get; } + */ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.abppkg.json new file mode 100644 index 00000000..7deef5e3 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api-client" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj new file mode 100644 index 00000000..f9e540c6 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj @@ -0,0 +1,20 @@ + + + + + + netstandard2.0 + + + + + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiClientModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiClientModule.cs new file mode 100644 index 00000000..e29f7c9e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiClientModule.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(FlashSalesApplicationContractsModule), + typeof(AbpHttpClientModule))] +public class FlashSalesHttpApiClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(FlashSalesApplicationContractsModule).Assembly, + FlashSalesRemoteServiceConsts.RemoteServiceName + ); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.abppkg.json new file mode 100644 index 00000000..515bfe64 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.http-api" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj new file mode 100644 index 00000000..416585c3 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj @@ -0,0 +1,15 @@ + + + + + + net6.0 + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesController.cs new file mode 100644 index 00000000..f087a9c7 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesController.cs @@ -0,0 +1,12 @@ +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using Volo.Abp.AspNetCore.Mvc; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public abstract class FlashSalesController : AbpControllerBase +{ + protected FlashSalesController() + { + LocalizationResource = typeof(FlashSalesResource); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiModule.cs new file mode 100644 index 00000000..7d24d4c2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiModule.cs @@ -0,0 +1,32 @@ +using Localization.Resources.AbpUi; +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(FlashSalesApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule))] +public class FlashSalesHttpApiModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(FlashSalesHttpApiModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpUiResource)); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/EasyAbp.EShop.Plugins.FlashSales.Installer.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/EasyAbp.EShop.Plugins.FlashSales.Installer.csproj new file mode 100644 index 00000000..60bb3626 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/EasyAbp.EShop.Plugins.FlashSales.Installer.csproj @@ -0,0 +1,21 @@ + + + + + + net6.0 + true + EasyAbp.EShop.Plugins.FlashSales + + + + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerModule.cs new file mode 100644 index 00000000..619b2d4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerModule.cs @@ -0,0 +1,20 @@ +using Volo.Abp.Studio; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(AbpStudioModuleInstallerModule), + typeof(AbpVirtualFileSystemModule) + )] +public class FlashSalesInstallerModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerPipelineBuilder.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerPipelineBuilder.cs new file mode 100644 index 00000000..56e7fd3f --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FlashSalesInstallerPipelineBuilder.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Studio.ModuleInstalling; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] +[ExposeServices(typeof(IModuleInstallingPipelineBuilder))] +public class FlashSalesInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency +{ + public async Task BuildAsync(ModuleInstallingContext context) + { + return GetBasePipeline(context); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xml new file mode 100644 index 00000000..be0de3a9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xsd new file mode 100644 index 00000000..3f3946e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Installer/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.abppkg.json new file mode 100644 index 00000000..8b23fd1e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mongodb" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj new file mode 100644 index 00000000..b45e6e2e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj @@ -0,0 +1,15 @@ + + + + + + netstandard2.0 + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs new file mode 100644 index 00000000..537a2714 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs @@ -0,0 +1,19 @@ +using Volo.Abp.Data; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +[ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] +public class FlashSalesMongoDbContext : AbpMongoDbContext, IFlashSalesMongoDbContext +{ + /* Add mongo collections here. Example: + * public IMongoCollection Questions => Collection(); + */ + + protected override void CreateModel(IMongoModelBuilder modelBuilder) + { + base.CreateModel(modelBuilder); + + modelBuilder.ConfigureFlashSales(); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs new file mode 100644 index 00000000..91b45a39 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs @@ -0,0 +1,13 @@ +using Volo.Abp; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +public static class FlashSalesMongoDbContextExtensions +{ + public static void ConfigureFlashSales( + this IMongoModelBuilder builder) + { + Check.NotNull(builder, nameof(builder)); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbModule.cs new file mode 100644 index 00000000..0ca33494 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbModule.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +[DependsOn( + typeof(FlashSalesDomainModule), + typeof(AbpMongoDbModule) + )] +public class FlashSalesMongoDbModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddMongoDbContext(options => + { + /* Add custom repositories here. Example: + * options.AddRepository(); + */ + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs new file mode 100644 index 00000000..d0501265 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Data; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +[ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] +public interface IFlashSalesMongoDbContext : IAbpMongoDbContext +{ + /* Define mongo collections here. Example: + * IMongoCollection Questions { get; } + */ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.abppkg.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.abppkg.json new file mode 100644 index 00000000..930c4018 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.mvc" +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj new file mode 100644 index 00000000..cedf9892 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj @@ -0,0 +1,40 @@ + + + + + + net6.0 + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + true + Library + EasyAbp.EShop.Plugins.FlashSales.Web + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebAutoMapperProfile.cs new file mode 100644 index 00000000..34576538 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebAutoMapperProfile.cs @@ -0,0 +1,13 @@ +using AutoMapper; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web; + +public class FlashSalesWebAutoMapperProfile : Profile +{ + public FlashSalesWebAutoMapperProfile() + { + /* You can configure your AutoMapper mapping configuration here. + * Alternatively, you can split your mapping configurations + * into multiple profile classes for a better organization. */ + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebModule.cs new file mode 100644 index 00000000..f23e1e78 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebModule.cs @@ -0,0 +1,58 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.DependencyInjection; +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using EasyAbp.EShop.Plugins.FlashSales.Web.Menus; +using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; +using Volo.Abp.UI.Navigation; +using Volo.Abp.VirtualFileSystem; +using EasyAbp.EShop.Plugins.FlashSales.Permissions; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web; + +[DependsOn( + typeof(FlashSalesApplicationContractsModule), + typeof(AbpAspNetCoreMvcUiThemeSharedModule), + typeof(AbpAutoMapperModule) + )] +public class FlashSalesWebModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.PreConfigure(options => + { + options.AddAssemblyResource(typeof(FlashSalesResource), typeof(FlashSalesWebModule).Assembly); + }); + + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(FlashSalesWebModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.MenuContributors.Add(new FlashSalesMenuContributor()); + }); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + context.Services.AddAutoMapperObjectMapper(); + Configure(options => + { + options.AddMaps(validate: true); + }); + + Configure(options => + { + //Configure authorization. + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs new file mode 100644 index 00000000..e5f8ec0f --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Volo.Abp.UI.Navigation; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Menus; + +public class FlashSalesMenuContributor : IMenuContributor +{ + public async Task ConfigureMenuAsync(MenuConfigurationContext context) + { + if (context.Menu.Name == StandardMenus.Main) + { + await ConfigureMainMenuAsync(context); + } + } + + private Task ConfigureMainMenuAsync(MenuConfigurationContext context) + { + //Add main menu items. + context.Menu.AddItem(new ApplicationMenuItem(FlashSalesMenus.Prefix, displayName: "FlashSales", "~/FlashSales", icon: "fa fa-globe")); + + return Task.CompletedTask; + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs new file mode 100644 index 00000000..9faa7e22 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs @@ -0,0 +1,10 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Menus; + +public class FlashSalesMenus +{ + public const string Prefix = "FlashSales"; + + //Add your menu items here... + //public const string Home = Prefix + ".MyNewMenuItem"; + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml new file mode 100644 index 00000000..4eb1c2d9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml @@ -0,0 +1,11 @@ +@page +@using Microsoft.Extensions.Localization +@using EasyAbp.EShop.Plugins.FlashSales.Localization +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EasyAbp.EShop.Plugins.FlashSales +@model IndexModel +@inject IStringLocalizer L + +@{ +} +

FlashSales

+

@L["SamplePageMessage"]

diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml.cs new file mode 100644 index 00000000..7438e942 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml.cs @@ -0,0 +1,8 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EasyAbp.EShop.Plugins.FlashSales; + +public class IndexModel : FlashSalesPageModel +{ + public void OnGet() + { + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/_ViewImports.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/_ViewImports.cshtml new file mode 100644 index 00000000..c1da1f5f --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/_ViewImports.cshtml @@ -0,0 +1,4 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap +@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs new file mode 100644 index 00000000..8821d72e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs @@ -0,0 +1,15 @@ +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages; + +/* Inherit your PageModel classes from this class. + */ +public abstract class FlashSalesPageModel : AbpPageModel +{ + protected FlashSalesPageModel() + { + LocalizationResourceType = typeof(FlashSalesResource); + ObjectMapperContext = typeof(FlashSalesWebModule); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Properties/launchSettings.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Properties/launchSettings.json new file mode 100644 index 00000000..100df60b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:64779/", + "sslPort": 44326 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "EasyAbp.EShop.Plugins.FlashSales.Web": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" + } + } +} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.abppkg.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.abppkg.json new file mode 100644 index 00000000..a686451f --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj new file mode 100644 index 00000000..b2cb1a1b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + + + + + + + + + + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs new file mode 100644 index 00000000..77224ae3 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs @@ -0,0 +1,9 @@ +namespace EasyAbp.EShop.Plugins.FlashSales; + +/* Inherit from this class for your application layer tests. + * See SampleAppService_Tests for example. + */ +public abstract class FlashSalesApplicationTestBase : FlashSalesTestBase +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs new file mode 100644 index 00000000..5837fa10 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(FlashSalesApplicationModule), + typeof(FlashSalesDomainTestModule) + )] +public class FlashSalesApplicationTestModule : AbpModule +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xml b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.abppkg.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.abppkg.json new file mode 100644 index 00000000..a686451f --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj new file mode 100644 index 00000000..dc15e834 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + + + + + + + + + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs new file mode 100644 index 00000000..1cb6e93a --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs @@ -0,0 +1,9 @@ +namespace EasyAbp.EShop.Plugins.FlashSales; + +/* Inherit from this class for your domain layer tests. + * See SampleManager_Tests for example. + */ +public abstract class FlashSalesDomainTestBase : FlashSalesTestBase +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestModule.cs new file mode 100644 index 00000000..3a218f7f --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestModule.cs @@ -0,0 +1,16 @@ +using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +/* Domain tests are configured to use the EF Core provider. + * You can switch to MongoDB, however your domain tests should be + * database independent anyway. + */ +[DependsOn( + typeof(FlashSalesEntityFrameworkCoreTestModule) + )] +public class FlashSalesDomainTestModule : AbpModule +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xml b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xsd b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.abppkg.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.abppkg.json new file mode 100644 index 00000000..a686451f --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj new file mode 100644 index 00000000..9686e5b8 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj @@ -0,0 +1,16 @@ + + + + net6.0 + + + + + + + + + + + + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs new file mode 100644 index 00000000..01e83ba7 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs @@ -0,0 +1,9 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; + +/* This class can be used as a base class for EF Core integration tests, + * while SampleRepository_Tests uses a different approach. + */ +public abstract class FlashSalesEntityFrameworkCoreTestBase : FlashSalesTestBase +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs new file mode 100644 index 00000000..7ec4a72a --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs @@ -0,0 +1,42 @@ +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; + +[DependsOn( + typeof(FlashSalesTestBaseModule), + typeof(FlashSalesEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] +public class FlashSalesEntityFrameworkCoreTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var sqliteConnection = CreateDatabaseAndGetConnection(); + + Configure(options => + { + options.Configure(abpDbContextConfigurationContext => + { + abpDbContextConfigurationContext.DbContextOptions.UseSqlite(sqliteConnection); + }); + }); + } + + private static SqliteConnection CreateDatabaseAndGetConnection() + { + var connection = new SqliteConnection("Data Source=:memory:"); + connection.Open(); + + new FlashSalesDbContext( + new DbContextOptionsBuilder().UseSqlite(connection).Options + ).GetService().CreateTables(); + + return connection; + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xml b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xsd b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.abppkg.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.abppkg.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.csproj new file mode 100644 index 00000000..7f9b26a7 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.csproj @@ -0,0 +1,32 @@ + + + + Exe + net6.0 + + + + + + + + + + + + + PreserveNewest + Always + + + + PreserveNewest + Always + + + + + + + + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ClientDemoService.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ClientDemoService.cs new file mode 100644 index 00000000..e5c5c20b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ClientDemoService.cs @@ -0,0 +1,145 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using IdentityModel.Client; +using Microsoft.Extensions.Configuration; +using Volo.Abp.DependencyInjection; +using Volo.Abp.IdentityModel; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class ClientDemoService : ITransientDependency +{ + private readonly IIdentityModelAuthenticationService _authenticationService; + private readonly IConfiguration _configuration; + + public ClientDemoService( + IIdentityModelAuthenticationService authenticationService, + IConfiguration configuration) + { + _authenticationService = authenticationService; + _configuration = configuration; + } + + public async Task RunAsync() + { + await TestWithDynamicProxiesAsync(); + await TestWithHttpClientAndIdentityModelAuthenticationServiceAsync(); + await TestAllManuallyAsync(); + } + + /* Shows how to perform an HTTP request to the API using ABP's dynamic c# proxy + * feature. It is just simple as calling a local service method. + * Authorization and HTTP request details are handled by the ABP framework. + */ + private async Task TestWithDynamicProxiesAsync() + { + Console.WriteLine(); + Console.WriteLine($"***** {nameof(TestWithDynamicProxiesAsync)} *****"); + } + + /* Shows how to use HttpClient to perform a request to the HTTP API. + * It uses ABP's IIdentityModelAuthenticationService to simplify obtaining access tokens. + */ + private async Task TestWithHttpClientAndIdentityModelAuthenticationServiceAsync() + { + Console.WriteLine(); + Console.WriteLine($"***** {nameof(TestWithHttpClientAndIdentityModelAuthenticationServiceAsync)} *****"); + + //Get access token using ABP's IIdentityModelAuthenticationService + + var accessToken = await _authenticationService.GetAccessTokenAsync( + new IdentityClientConfiguration( + _configuration["IdentityClients:Default:Authority"], + _configuration["IdentityClients:Default:Scope"], + _configuration["IdentityClients:Default:ClientId"], + _configuration["IdentityClients:Default:ClientSecret"], + _configuration["IdentityClients:Default:GrantType"], + _configuration["IdentityClients:Default:UserName"], + _configuration["IdentityClients:Default:UserPassword"] + ) + ); + + //Perform the actual HTTP request + + using (var httpClient = new HttpClient()) + { + httpClient.SetBearerToken(accessToken); + + var url = _configuration["RemoteServices:FlashSales:BaseUrl"] + + "api/FlashSales/sample/authorized"; + + var responseMessage = await httpClient.GetAsync(url); + if (responseMessage.IsSuccessStatusCode) + { + var responseString = await responseMessage.Content.ReadAsStringAsync(); + Console.WriteLine("Result: " + responseString); + } + else + { + throw new Exception("Remote server returns error code: " + responseMessage.StatusCode); + } + } + } + + /* Shows how to use HttpClient to perform a request to the HTTP API. + * It obtains access token using IdentityServer's API. See its documentation: + * https://identityserver4.readthedocs.io/en/latest/quickstarts/2_resource_owner_passwords.html + */ + private async Task TestAllManuallyAsync() + { + Console.WriteLine(); + Console.WriteLine($"***** {nameof(TestAllManuallyAsync)} *****"); + + //Obtain access token from the IDS4 server + + // discover endpoints from metadata + var client = new HttpClient(); + var disco = await client.GetDiscoveryDocumentAsync(_configuration["IdentityClients:Default:Authority"]); + if (disco.IsError) + { + Console.WriteLine(disco.Error); + return; + } + + // request token + var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest + { + Address = disco.TokenEndpoint, + ClientId = _configuration["IdentityClients:Default:ClientId"], + ClientSecret = _configuration["IdentityClients:Default:ClientSecret"], + UserName = _configuration["IdentityClients:Default:UserName"], + Password = _configuration["IdentityClients:Default:UserPassword"], + Scope = _configuration["IdentityClients:Default:Scope"] + }); + + if (tokenResponse.IsError) + { + Console.WriteLine(tokenResponse.Error); + return; + } + + Console.WriteLine(tokenResponse.Json); + + //Perform the actual HTTP request + + using (var httpClient = new HttpClient()) + { + httpClient.SetBearerToken(tokenResponse.AccessToken); + + var url = _configuration["RemoteServices:FlashSales:BaseUrl"] + + "api/FlashSales/sample/authorized"; + + var responseMessage = await httpClient.GetAsync(url); + if (responseMessage.IsSuccessStatusCode) + { + var responseString = await responseMessage.Content.ReadAsStringAsync(); + Console.WriteLine("Result: " + responseString); + } + else + { + throw new Exception("Remote server returns error code: " + responseMessage.StatusCode); + } + } + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs new file mode 100644 index 00000000..d9e47d1d --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.Hosting; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class ConsoleTestAppHostedService : IHostedService +{ + private readonly IConfiguration _configuration; + + public ConsoleTestAppHostedService(IConfiguration configuration) + { + _configuration = configuration; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + using (var application = await AbpApplicationFactory.CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.UseAutofac(); + })) + { + await application.InitializeAsync(); + + var demo = application.ServiceProvider.GetRequiredService(); + await demo.RunAsync(); + + await application.ShutdownAsync(); + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs new file mode 100644 index 00000000..009a255a --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Autofac; +using Volo.Abp.Http.Client.IdentityModel; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(FlashSalesHttpApiClientModule), + typeof(AbpHttpClientIdentityModelModule) + )] +public class FlashSalesConsoleApiClientModule : AbpModule +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/Program.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/Program.cs new file mode 100644 index 00000000..d1f86ddb --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/Program.cs @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +class Program +{ + static async Task Main(string[] args) + { + await CreateHostBuilder(args).RunConsoleAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .AddAppSettingsSecretsJson() + .ConfigureServices((hostContext, services) => + { + services.AddHostedService(); + }); +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.json new file mode 100644 index 00000000..9ec421ef --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.json @@ -0,0 +1,21 @@ +{ + "RemoteServices": { + "Default": { + "BaseUrl": "https://localhost:44306/" + }, + "FlashSales": { + "BaseUrl": "https://localhost:44358/" + } + }, + "IdentityClients": { + "Default": { + "GrantType": "password", + "ClientId": "FlashSales_App", + "ClientSecret": "1q2w3e*", + "UserName": "admin", + "UserPassword": "1q2w3E*", + "Authority": "https://localhost:44306/", + "Scope": "FlashSales" + } + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.secrets.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.secrets.json new file mode 100644 index 00000000..7a73a41b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/appsettings.secrets.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.abppkg.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.abppkg.json new file mode 100644 index 00000000..a686451f --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj new file mode 100644 index 00000000..2ac3301a --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + + + + + + + + + + + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs new file mode 100644 index 00000000..0953ae82 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs @@ -0,0 +1,9 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +/* This class can be used as a base class for MongoDB integration tests, + * while SampleRepository_Tests uses a different approach. + */ +public abstract class FlashSalesMongoDbTestBase : FlashSalesTestBase +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs new file mode 100644 index 00000000..f9cc78c0 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs @@ -0,0 +1,26 @@ +using System; +using Volo.Abp.Data; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +[DependsOn( + typeof(FlashSalesTestBaseModule), + typeof(FlashSalesMongoDbModule) + )] +public class FlashSalesMongoDbTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var stringArray = MongoDbFixture.ConnectionString.Split('?'); + var connectionString = stringArray[0].EnsureEndsWith('/') + + "Db_" + + Guid.NewGuid().ToString("N") + "/?" + stringArray[1]; + + Configure(options => + { + options.ConnectionStrings.Default = connectionString; + }); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoDbFixture.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoDbFixture.cs new file mode 100644 index 00000000..24e29e8b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoDbFixture.cs @@ -0,0 +1,21 @@ +using System; +using Mongo2Go; + +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +public class MongoDbFixture : IDisposable +{ + private static readonly MongoDbRunner MongoDbRunner; + public static readonly string ConnectionString; + + static MongoDbFixture() + { + MongoDbRunner = MongoDbRunner.Start(singleNodeReplSet: true, singleNodeReplSetWaitTimeout: 20); + ConnectionString = MongoDbRunner.ConnectionString; + } + + public void Dispose() + { + MongoDbRunner?.Dispose(); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoTestCollection.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoTestCollection.cs new file mode 100644 index 00000000..3c9a8af5 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/MongoTestCollection.cs @@ -0,0 +1,9 @@ +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; + +[CollectionDefinition(Name)] +public class MongoTestCollection : ICollectionFixture +{ + public const string Name = "MongoDB Collection"; +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xml b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xsd b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.abppkg.json b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.abppkg.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.abppkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj new file mode 100644 index 00000000..c37c97c0 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + + + + + + + + + + + + + + + + + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDataSeedContributor.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDataSeedContributor.cs new file mode 100644 index 00000000..5b21992c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDataSeedContributor.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class FlashSalesDataSeedContributor : IDataSeedContributor, ITransientDependency +{ + private readonly IGuidGenerator _guidGenerator; + private readonly ICurrentTenant _currentTenant; + + public FlashSalesDataSeedContributor( + IGuidGenerator guidGenerator, ICurrentTenant currentTenant) + { + _guidGenerator = guidGenerator; + _currentTenant = currentTenant; + } + + public Task SeedAsync(DataSeedContext context) + { + /* Instead of returning the Task.CompletedTask, you can insert your test data + * at this point! + */ + + using (_currentTenant.Change(context?.TenantId)) + { + return Task.CompletedTask; + } + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBase.cs new file mode 100644 index 00000000..5522e93c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBase.cs @@ -0,0 +1,59 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; +using Volo.Abp.Testing; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +/* All test classes are derived from this class, directly or indirectly. */ +public abstract class FlashSalesTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + protected virtual Task WithUnitOfWorkAsync(Func func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func action) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + await action(); + + await uow.CompleteAsync(); + } + } + } + + protected virtual Task WithUnitOfWorkAsync(Func> func) + { + return WithUnitOfWorkAsync(new AbpUnitOfWorkOptions(), func); + } + + protected virtual async Task WithUnitOfWorkAsync(AbpUnitOfWorkOptions options, Func> func) + { + using (var scope = ServiceProvider.CreateScope()) + { + var uowManager = scope.ServiceProvider.GetRequiredService(); + + using (var uow = uowManager.Begin(options)) + { + var result = await func(); + await uow.CompleteAsync(); + return result; + } + } + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs new file mode 100644 index 00000000..25d5e1f9 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Authorization; +using Volo.Abp.Autofac; +using Volo.Abp.Data; +using Volo.Abp.Modularity; +using Volo.Abp.Threading; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(AbpAutofacModule), + typeof(AbpTestBaseModule), + typeof(AbpAuthorizationModule), + typeof(FlashSalesDomainModule) + )] +public class FlashSalesTestBaseModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAlwaysAllowAuthorization(); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + SeedTestData(context); + } + + private static void SeedTestData(ApplicationInitializationContext context) + { + AsyncHelper.RunSync(async () => + { + using (var scope = context.ServiceProvider.CreateScope()) + { + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync(); + } + }); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/Security/FakeCurrentPrincipalAccessor.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/Security/FakeCurrentPrincipalAccessor.cs new file mode 100644 index 00000000..db797d86 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/Security/FakeCurrentPrincipalAccessor.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Security.Claims; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Security.Claims; + +namespace EasyAbp.EShop.Plugins.FlashSales.Security; + +[Dependency(ReplaceServices = true)] +public class FakeCurrentPrincipalAccessor : ThreadCurrentPrincipalAccessor +{ + protected override ClaimsPrincipal GetClaimsPrincipal() + { + return GetPrincipal(); + } + + private ClaimsPrincipal _principal; + + private ClaimsPrincipal GetPrincipal() + { + if (_principal == null) + { + lock (this) + { + if (_principal == null) + { + _principal = new ClaimsPrincipal( + new ClaimsIdentity( + new List + { + new Claim(AbpClaimTypes.UserId,"2e701e62-0953-4dd3-910b-dc6cc93ccb0d"), + new Claim(AbpClaimTypes.UserName,"admin"), + new Claim(AbpClaimTypes.Email,"admin@abp.io") + } + ) + ); + } + } + } + + return _principal; + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xml b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xsd b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file From dedc6a4c9e74bfbdf48f3598264f6952f9ecd100 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 18 Jun 2022 17:38:23 +0800 Subject: [PATCH 02/97] Update FlashSales module name --- EShop.sln | 21 ++++++++----- ...ders.Plugins.FlashSales.Application.csproj | 15 ++++++++++ ...rdersPluginsFlashSalesApplicationModule.cs | 12 ++++++++ .../FodyWeavers.xml | 3 ++ .../FodyWeavers.xsd | 30 +++++++++++++++++++ ...nsFlashSalesApplicationContractsModule.cs} | 4 +-- ...opPluginsFlashSalesRemoteServiceConsts.cs} | 2 +- ...ShopPluginsFlashSalesApplicationModule.cs} | 10 +++---- .../FlashSales/FlashSalesAppService.cs | 2 +- ...hopPluginsFlashSalesDomainSharedModule.cs} | 6 ++-- .../FlashSales/FlashSalesErrorCodes.cs | 5 +++- ... => EShopPluginsFlashSalesDomainModule.cs} | 4 +-- ...insFlashSalesEntityFrameworkCoreModule.cs} | 4 +-- ...opPluginsFlashSalesHttpApiClientModule.cs} | 10 +++---- ...=> EShopPluginsFlashSalesHttpApiModule.cs} | 6 ++-- ...=> EShopPluginsFlashSalesMongoDbModule.cs} | 4 +-- ...pPluginsFlashSalesWebAutoMapperProfile.cs} | 4 +-- ....cs => EShopPluginsFlashSalesWebModule.cs} | 14 ++++----- .../Pages/FlashSalesPageModel.cs | 2 +- .../FlashSalesApplicationTestModule.cs | 2 +- ...FlashSalesEntityFrameworkCoreTestModule.cs | 2 +- .../FlashSalesConsoleApiClientModule.cs | 2 +- .../MongoDB/FlashSalesMongoDbTestModule.cs | 2 +- .../FlashSales/FlashSalesTestBaseModule.cs | 2 +- 24 files changed, 119 insertions(+), 49 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xsd rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesApplicationContractsModule.cs => EShopPluginsFlashSalesApplicationContractsModule.cs} (65%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesRemoteServiceConsts.cs => EShopPluginsFlashSalesRemoteServiceConsts.cs} (74%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesApplicationModule.cs => EShopPluginsFlashSalesApplicationModule.cs} (55%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesDomainSharedModule.cs => EShopPluginsFlashSalesDomainSharedModule.cs} (78%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesDomainModule.cs => EShopPluginsFlashSalesDomainModule.cs} (57%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/{FlashSalesEntityFrameworkCoreModule.cs => EShopPluginsFlashSalesEntityFrameworkCoreModule.cs} (82%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesHttpApiClientModule.cs => EShopPluginsFlashSalesHttpApiClientModule.cs} (56%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesHttpApiModule.cs => EShopPluginsFlashSalesHttpApiModule.cs} (77%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/{FlashSalesMongoDbModule.cs => EShopPluginsFlashSalesMongoDbModule.cs} (83%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/{FlashSalesWebAutoMapperProfile.cs => EShopPluginsFlashSalesWebAutoMapperProfile.cs} (71%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/{FlashSalesWebModule.cs => EShopPluginsFlashSalesWebModule.cs} (73%) diff --git a/EShop.sln b/EShop.sln index 21fe6afe..930dccee 100644 --- a/EShop.sln +++ b/EShop.sln @@ -377,19 +377,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Orle EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FlashSales", "FlashSales", "{867AD9F8-FD56-469D-A90D-C569EB9C3D2A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Application\EasyAbp.EShop.Plugins.FlashSales.Application.csproj", "{26611C4C-6910-498A-9FBA-BECC09392ADE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Application\EasyAbp.EShop.Plugins.FlashSales.Application.csproj", "{26611C4C-6910-498A-9FBA-BECC09392ADE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Contracts", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj", "{FCD72398-F832-4914-8ACF-EA4C1DD24BBF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Contracts", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj", "{FCD72398-F832-4914-8ACF-EA4C1DD24BBF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Shared", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj", "{55145D4A-5A98-4B53-9293-CCB7236E69F5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Shared", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj", "{55145D4A-5A98-4B53-9293-CCB7236E69F5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.Domain", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Domain\EasyAbp.EShop.Plugins.FlashSales.Domain.csproj", "{7E535D1A-3259-4098-8E47-A81B3D8B3920}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.Domain\EasyAbp.EShop.Plugins.FlashSales.Domain.csproj", "{7E535D1A-3259-4098-8E47-A81B3D8B3920}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj", "{2D1C0E98-D86A-4C60-98CE-86C4E5571B91}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj", "{2D1C0E98-D86A-4C60-98CE-86C4E5571B91}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.MongoDB\EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj", "{B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.MongoDB\EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj", "{B5ED3D8B-E2DC-4B38-A9C7-2A18B47385EE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj", "{0D5558BD-A22F-4565-A92A-BB14D517B1A5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi", "plugins\FlashSales\src\EasyAbp.EShop.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj", "{0D5558BD-A22F-4565-A92A-BB14D517B1A5}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F29C5BCD-E6C0-4556-A631-CACA41B1050B}" EndProject @@ -411,6 +411,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Flash EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.TestBase", "plugins\FlashSales\test\EasyAbp.EShop.Plugins.FlashSales.TestBase\EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj", "{417AB8E2-1488-4814-9699-3B189D1ABA67}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Orders.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Orders.Plugins.FlashSales.Application\EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj", "{5732E880-CB72-49A0-AC4F-A0620F4E4D16}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1065,6 +1067,10 @@ Global {417AB8E2-1488-4814-9699-3B189D1ABA67}.Debug|Any CPU.Build.0 = Debug|Any CPU {417AB8E2-1488-4814-9699-3B189D1ABA67}.Release|Any CPU.ActiveCfg = Release|Any CPU {417AB8E2-1488-4814-9699-3B189D1ABA67}.Release|Any CPU.Build.0 = Release|Any CPU + {5732E880-CB72-49A0-AC4F-A0620F4E4D16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5732E880-CB72-49A0-AC4F-A0620F4E4D16}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5732E880-CB72-49A0-AC4F-A0620F4E4D16}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5732E880-CB72-49A0-AC4F-A0620F4E4D16}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1270,6 +1276,7 @@ Global {2291B087-FEC5-47BD-A7ED-04725D54E6A6} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} {68993D65-2C9C-438F-8B94-15E98C469A16} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} {417AB8E2-1488-4814-9699-3B189D1ABA67} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} + {5732E880-CB72-49A0-AC4F-A0620F4E4D16} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj new file mode 100644 index 00000000..5455d3fd --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj @@ -0,0 +1,15 @@ + + + + + + net6.0 + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs new file mode 100644 index 00000000..7dd104d1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs @@ -0,0 +1,12 @@ +using EasyAbp.EShop.Orders; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(EShopOrdersApplicationModule), + typeof(EShopPluginsFlashSalesApplicationContractsModule) +)] +public class EShopOrdersPluginsFlashSalesApplicationModule : AbpModule +{ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml new file mode 100644 index 00000000..00e1d9a1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xsd new file mode 100644 index 00000000..3f3946e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationContractsModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationContractsModule.cs similarity index 65% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationContractsModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationContractsModule.cs index b1f107e7..bfdd3261 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationContractsModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationContractsModule.cs @@ -5,11 +5,11 @@ using Volo.Abp.Authorization; namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( - typeof(FlashSalesDomainSharedModule), + typeof(EShopPluginsFlashSalesDomainSharedModule), typeof(AbpDddApplicationContractsModule), typeof(AbpAuthorizationModule) )] -public class FlashSalesApplicationContractsModule : AbpModule +public class EShopPluginsFlashSalesApplicationContractsModule : AbpModule { } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesRemoteServiceConsts.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs similarity index 74% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesRemoteServiceConsts.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs index ce2bfaac..262522a2 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesRemoteServiceConsts.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs @@ -1,6 +1,6 @@ namespace EasyAbp.EShop.Plugins.FlashSales; -public class FlashSalesRemoteServiceConsts +public class EShopPluginsFlashSalesRemoteServiceConsts { public const string RemoteServiceName = "FlashSales"; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs similarity index 55% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs index 9aae63c7..403f6949 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs @@ -6,19 +6,19 @@ using Volo.Abp.Application; namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( - typeof(FlashSalesDomainModule), - typeof(FlashSalesApplicationContractsModule), + typeof(EShopPluginsFlashSalesDomainModule), + typeof(EShopPluginsFlashSalesApplicationContractsModule), typeof(AbpDddApplicationModule), typeof(AbpAutoMapperModule) )] -public class FlashSalesApplicationModule : AbpModule +public class EShopPluginsFlashSalesApplicationModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.AddAutoMapperObjectMapper(); + context.Services.AddAutoMapperObjectMapper(); Configure(options => { - options.AddMaps(validate: true); + options.AddMaps(validate: true); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs index b17b4ff3..4d6c6e6a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesAppService.cs @@ -8,6 +8,6 @@ public abstract class FlashSalesAppService : ApplicationService protected FlashSalesAppService() { LocalizationResource = typeof(FlashSalesResource); - ObjectMapperContext = typeof(FlashSalesApplicationModule); + ObjectMapperContext = typeof(EShopPluginsFlashSalesApplicationModule); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainSharedModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainSharedModule.cs similarity index 78% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainSharedModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainSharedModule.cs index 69351ec3..2063355f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainSharedModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainSharedModule.cs @@ -11,13 +11,13 @@ namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( typeof(AbpValidationModule) )] -public class FlashSalesDomainSharedModule : AbpModule +public class EShopPluginsFlashSalesDomainSharedModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => { - options.FileSets.AddEmbedded(); + options.FileSets.AddEmbedded(); }); Configure(options => @@ -30,7 +30,7 @@ public class FlashSalesDomainSharedModule : AbpModule Configure(options => { - options.MapCodeNamespace("FlashSales", typeof(FlashSalesResource)); + options.MapCodeNamespace(FlashSalesErrorCodes.Namespace, typeof(FlashSalesResource)); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index a71ad4c1..b02a0801 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -2,5 +2,8 @@ public static class FlashSalesErrorCodes { - //Add your business exception error codes here... + public const string Namespace = "EasyAbp.EShop.Plugins.FlashSales"; + + public const string EndTimeMustBeLaterThanBeginTime = $"{Namespace}:{nameof(EndTimeMustBeLaterThanBeginTime)}"; + } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs similarity index 57% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs index 8e6806da..f3b45e32 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs @@ -5,9 +5,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( typeof(AbpDddDomainModule), - typeof(FlashSalesDomainSharedModule) + typeof(EShopPluginsFlashSalesDomainSharedModule) )] -public class FlashSalesDomainModule : AbpModule +public class EShopPluginsFlashSalesDomainModule : AbpModule { } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs similarity index 82% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs index a91237cf..07383dc2 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs @@ -5,10 +5,10 @@ using Volo.Abp.Modularity; namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; [DependsOn( - typeof(FlashSalesDomainModule), + typeof(EShopPluginsFlashSalesDomainModule), typeof(AbpEntityFrameworkCoreModule) )] -public class FlashSalesEntityFrameworkCoreModule : AbpModule +public class EShopPluginsFlashSalesEntityFrameworkCoreModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiClientModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesHttpApiClientModule.cs similarity index 56% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiClientModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesHttpApiClientModule.cs index e29f7c9e..07577fda 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiClientModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesHttpApiClientModule.cs @@ -6,20 +6,20 @@ using Volo.Abp.VirtualFileSystem; namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( - typeof(FlashSalesApplicationContractsModule), + typeof(EShopPluginsFlashSalesApplicationContractsModule), typeof(AbpHttpClientModule))] -public class FlashSalesHttpApiClientModule : AbpModule +public class EShopPluginsFlashSalesHttpApiClientModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddHttpClientProxies( - typeof(FlashSalesApplicationContractsModule).Assembly, - FlashSalesRemoteServiceConsts.RemoteServiceName + typeof(EShopPluginsFlashSalesApplicationContractsModule).Assembly, + EShopPluginsFlashSalesRemoteServiceConsts.RemoteServiceName ); Configure(options => { - options.FileSets.AddEmbedded(); + options.FileSets.AddEmbedded(); }); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesHttpApiModule.cs similarity index 77% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesHttpApiModule.cs index 7d24d4c2..b3c4a90d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesHttpApiModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesHttpApiModule.cs @@ -8,15 +8,15 @@ using Microsoft.Extensions.DependencyInjection; namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( - typeof(FlashSalesApplicationContractsModule), + typeof(EShopPluginsFlashSalesApplicationContractsModule), typeof(AbpAspNetCoreMvcModule))] -public class FlashSalesHttpApiModule : AbpModule +public class EShopPluginsFlashSalesHttpApiModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { PreConfigure(mvcBuilder => { - mvcBuilder.AddApplicationPartIfNotExists(typeof(FlashSalesHttpApiModule).Assembly); + mvcBuilder.AddApplicationPartIfNotExists(typeof(EShopPluginsFlashSalesHttpApiModule).Assembly); }); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs similarity index 83% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs index 0ca33494..9e39be35 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs @@ -5,10 +5,10 @@ using Volo.Abp.MongoDB; namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; [DependsOn( - typeof(FlashSalesDomainModule), + typeof(EShopPluginsFlashSalesDomainModule), typeof(AbpMongoDbModule) )] -public class FlashSalesMongoDbModule : AbpModule +public class EShopPluginsFlashSalesMongoDbModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs similarity index 71% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebAutoMapperProfile.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs index 34576538..a6afd47a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs @@ -2,9 +2,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales.Web; -public class FlashSalesWebAutoMapperProfile : Profile +public class EShopPluginsFlashSalesWebAutoMapperProfile : Profile { - public FlashSalesWebAutoMapperProfile() + public EShopPluginsFlashSalesWebAutoMapperProfile() { /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebModule.cs similarity index 73% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebModule.cs index f23e1e78..41e96f9d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/FlashSalesWebModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebModule.cs @@ -13,22 +13,22 @@ using EasyAbp.EShop.Plugins.FlashSales.Permissions; namespace EasyAbp.EShop.Plugins.FlashSales.Web; [DependsOn( - typeof(FlashSalesApplicationContractsModule), + typeof(EShopPluginsFlashSalesApplicationContractsModule), typeof(AbpAspNetCoreMvcUiThemeSharedModule), typeof(AbpAutoMapperModule) )] -public class FlashSalesWebModule : AbpModule +public class EShopPluginsFlashSalesWebModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { context.Services.PreConfigure(options => { - options.AddAssemblyResource(typeof(FlashSalesResource), typeof(FlashSalesWebModule).Assembly); + options.AddAssemblyResource(typeof(FlashSalesResource), typeof(EShopPluginsFlashSalesWebModule).Assembly); }); PreConfigure(mvcBuilder => { - mvcBuilder.AddApplicationPartIfNotExists(typeof(FlashSalesWebModule).Assembly); + mvcBuilder.AddApplicationPartIfNotExists(typeof(EShopPluginsFlashSalesWebModule).Assembly); }); } @@ -41,13 +41,13 @@ public class FlashSalesWebModule : AbpModule Configure(options => { - options.FileSets.AddEmbedded(); + options.FileSets.AddEmbedded(); }); - context.Services.AddAutoMapperObjectMapper(); + context.Services.AddAutoMapperObjectMapper(); Configure(options => { - options.AddMaps(validate: true); + options.AddMaps(validate: true); }); Configure(options => diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs index 8821d72e..2844b9d8 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/FlashSalesPageModel.cs @@ -10,6 +10,6 @@ public abstract class FlashSalesPageModel : AbpPageModel protected FlashSalesPageModel() { LocalizationResourceType = typeof(FlashSalesResource); - ObjectMapperContext = typeof(FlashSalesWebModule); + ObjectMapperContext = typeof(EShopPluginsFlashSalesWebModule); } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs index 5837fa10..3a60972a 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs @@ -3,7 +3,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( - typeof(FlashSalesApplicationModule), + typeof(EShopPluginsFlashSalesApplicationModule), typeof(FlashSalesDomainTestModule) )] public class FlashSalesApplicationTestModule : AbpModule diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs index 7ec4a72a..fb28fd4a 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs @@ -10,7 +10,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; [DependsOn( typeof(FlashSalesTestBaseModule), - typeof(FlashSalesEntityFrameworkCoreModule), + typeof(EShopPluginsFlashSalesEntityFrameworkCoreModule), typeof(AbpEntityFrameworkCoreSqliteModule) )] public class FlashSalesEntityFrameworkCoreTestModule : AbpModule diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs index 009a255a..1d081c6c 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs @@ -6,7 +6,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( typeof(AbpAutofacModule), - typeof(FlashSalesHttpApiClientModule), + typeof(EShopPluginsFlashSalesHttpApiClientModule), typeof(AbpHttpClientIdentityModelModule) )] public class FlashSalesConsoleApiClientModule : AbpModule diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs index f9cc78c0..2d101fa3 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs @@ -7,7 +7,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; [DependsOn( typeof(FlashSalesTestBaseModule), - typeof(FlashSalesMongoDbModule) + typeof(EShopPluginsFlashSalesMongoDbModule) )] public class FlashSalesMongoDbTestModule : AbpModule { diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs index 25d5e1f9..33ce5497 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs @@ -12,7 +12,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales; typeof(AbpAutofacModule), typeof(AbpTestBaseModule), typeof(AbpAuthorizationModule), - typeof(FlashSalesDomainModule) + typeof(EShopPluginsFlashSalesDomainModule) )] public class FlashSalesTestBaseModule : AbpModule { From 9ae75cd0b7ddef5f65c13dfd5d8a0fbec00df39e Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 27 Jun 2022 01:44:42 +0800 Subject: [PATCH 03/97] Implement basic FlashSales --- plugins/FlashSales/.editorconfig | 223 +++++++++++ .../CreateFlashSalesOrderEventHandler.cs | 95 +++++ ...hSalesOrderCreationAuthorizationHandler.cs | 40 ++ ...sFlashSalesApplicationAutoMapperProfile.cs | 35 ++ ...rdersPluginsFlashSalesApplicationModule.cs | 25 ++ ...hopPluginsFlashSalesRemoteServiceConsts.cs | 2 +- .../FlashSalesPlans/Dtos/CreateOrderInput.cs | 9 + .../Dtos/FlashSalesPlanCreateDto.cs | 21 + .../FlashSalesPlans/Dtos/FlashSalesPlanDto.cs | 23 ++ .../Dtos/FlashSalesPlanGetListInput.cs | 20 + .../Dtos/FlashSalesPlanUpdateDto.cs | 21 + .../IFlashSalesPlanAppService.cs | 21 + .../Dtos/FlashSalesResultDto.cs | 19 + .../Dtos/FlashSalesResultGetListInput.cs | 17 + .../IFlashSalesResultAppService.cs | 14 + .../FlashSalesPermissionDefinitionProvider.cs | 11 +- .../Permissions/FlashSalesPermissions.cs | 19 +- ...Shop.Plugins.FlashSales.Application.csproj | 3 + ...EShopPluginsFlashSalesApplicationModule.cs | 22 +- .../FlashSalesApplicationAutoMapperProfile.cs | 41 +- .../FlashSalesPlanAppService.cs | 362 ++++++++++++++++++ .../FlashSalesPlanCacheInvalidator.cs | 18 + .../FlashSalesPlanCacheItem.cs | 9 + .../FlashSalesResultAppService.cs | 51 +++ ...op.Plugins.FlashSales.Domain.Shared.csproj | 4 + .../FlashSales/FlashSalesErrorCodes.cs | 13 + .../CreateFlashSalesOrderCompleteEto.cs | 25 ++ .../CreateFlashSalesOrderEto.cs | 32 ++ .../FlashSalesPlans/FlashSalesPlanEto.cs | 22 ++ .../FlashSalesProductAttributeEto.cs | 16 + .../FlashSalesProductAttributeOptionEto.cs | 13 + .../FlashSalesPlans/FlashSalesProductEto.cs | 39 ++ .../FlashSalesProductSkuEto.cs | 25 ++ .../FlashSalesPlans/ProductDetailEto.cs | 10 + .../FlashSalesResultStatus.cs | 12 + .../FlashSales/FullAuditedEntityEto.cs | 23 ++ .../Localization/FlashSalesResource.cs | 2 +- .../Plugins/FlashSales/Localization/en.json | 31 +- .../FlashSales/Localization/zh-Hans.json | 31 +- .../FlashSales/Localization/zh-Hant.json | 31 +- ...Abp.EShop.Plugins.FlashSales.Domain.csproj | 1 + ...luginsFlashSalesDomainAutoMapperProfile.cs | 16 + .../EShopPluginsFlashSalesDomainModule.cs | 22 +- .../FlashSales/FlashSalesDbProperties.cs | 4 +- ...ndTimeMustBeLaterThanBeginTimeException.cs | 12 + .../FlashSalesPlans/FlashSalesPlan.cs | 58 +++ .../FlashSalesPlans/FlashSalesPlanManager.cs | 44 +++ .../IFlashSalesPlanRepository.cs | 8 + ...eateFlashSalesOrderCompleteEventHandler.cs | 37 ++ .../FlashSalesResults/FlashSalesResult.cs | 49 +++ .../IFlashSalesResultRepository.cs | 9 + ...ginsFlashSalesEntityFrameworkCoreModule.cs | 9 +- .../FlashSalesDbContext.cs | 12 +- ...shSalesDbContextModelCreatingExtensions.cs | 29 +- .../IFlashSalesDbContext.cs | 11 +- .../EfCoreFlashSalesPlanRepository.cs | 21 + .../FlashSalesPlanEfCoreQuerableExtensions.cs | 18 + .../EfCoreFlashSalesResultRepository.cs | 20 + ...lashSalesResultEfCoreQuerableExtensions.cs | 16 + .../FlashSalesPlanController.cs | 71 ++++ .../FlashSalesResultController.cs | 33 ++ .../MongoFlashSalesPlanRepository.cs | 13 + .../MongoFlashSalesResultRepository.cs | 13 + .../EShopPluginsFlashSalesMongoDbModule.cs | 9 +- .../MongoDB/FlashSalesMongoDbContext.cs | 11 +- .../FlashSalesMongoDbContextExtensions.cs | 8 +- .../MongoDB/IFlashSalesMongoDbContext.cs | 11 +- ...opPluginsFlashSalesWebAutoMapperProfile.cs | 12 + .../EShopPluginsFlashSalesWebModule.cs | 2 +- ...asyAbp.EShop.Plugins.FlashSales.Web.csproj | 5 + .../Menus/FlashSalesMenuContributor.cs | 40 +- .../Menus/FlashSalesMenus.cs | 12 +- .../FlashSalesPlan/CreateModal.cshtml | 21 + .../FlashSalesPlan/CreateModal.cshtml.cs | 27 ++ .../FlashSalesPlan/EditModal.cshtml | 22 ++ .../FlashSalesPlan/EditModal.cshtml.cs | 38 ++ .../FlashSalesPlan/Index.cshtml | 50 +++ .../FlashSalesPlan/Index.cshtml.cs | 11 + .../CreateFlashSalesPlanViewModel.cs | 25 ++ .../ViewModels/EditFlashSalesPlanViewModel.cs | 33 ++ .../FlashSalesPlans/FlashSalesPlan/index.css | 0 .../FlashSalesPlans/FlashSalesPlan/index.js | 87 +++++ .../FlashSalesResult/Index.cshtml | 41 ++ .../FlashSalesResult/Index.cshtml.cs | 11 + .../FlashSalesResult/ViewModal.cshtml | 22 ++ .../FlashSalesResult/ViewModal.cshtml.cs | 31 ++ .../ViewFlashSalesResultViewModel.cs | 23 ++ .../FlashSalesResult/index.css | 0 .../FlashSalesResult/index.js | 62 +++ .../EShop/Plugins/FlashSales/Index.cshtml | 5 +- .../EShop/Plugins/FlashSales/Index.cshtml.cs | 2 +- .../Plugins/FlashSales/_ViewImports.cshtml | 0 92 files changed, 2524 insertions(+), 73 deletions(-) create mode 100644 plugins/FlashSales/.editorconfig create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanDto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultDto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultAppService.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FullAuditedEntityEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanController.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.css create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.css create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/{EasyAbp => }/EShop/Plugins/FlashSales/Index.cshtml (73%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/{EasyAbp => }/EShop/Plugins/FlashSales/Index.cshtml.cs (50%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/{EasyAbp => }/EShop/Plugins/FlashSales/_ViewImports.cshtml (100%) diff --git a/plugins/FlashSales/.editorconfig b/plugins/FlashSales/.editorconfig new file mode 100644 index 00000000..2e55c103 --- /dev/null +++ b/plugins/FlashSales/.editorconfig @@ -0,0 +1,223 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = omit_if_default + +# Expression-level preferences +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = all + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = 0 + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = false +dotnet_style_allow_statement_immediately_after_block_experimental = false + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false +csharp_style_var_for_built_in_types = false +csharp_style_var_when_type_is_apparent = false + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true +csharp_style_expression_bodied_constructors = false +csharp_style_expression_bodied_indexers = true +csharp_style_expression_bodied_lambdas = true +csharp_style_expression_bodied_local_functions = false +csharp_style_expression_bodied_methods = false +csharp_style_expression_bodied_operators = false +csharp_style_expression_bodied_properties = true + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true +csharp_style_pattern_matching_over_is_with_cast_check = true +csharp_style_prefer_extended_property_pattern = true +csharp_style_prefer_not_pattern = true +csharp_style_prefer_pattern_matching = true +csharp_style_prefer_switch_expression = true + +# Null-checking preferences +csharp_style_conditional_delegate_call = true +csharp_style_prefer_parameter_null_checking = true + +# Modifier preferences +csharp_prefer_static_local_function = true +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async + +# Code-block preferences +csharp_prefer_braces = true +csharp_prefer_simple_using_statement = true +csharp_style_namespace_declarations = file_scoped +csharp_style_prefer_method_group_conversion = true + +# Expression-level preferences +csharp_prefer_simple_default_expression = true +csharp_style_deconstructed_variable_declaration = true +csharp_style_implicit_object_creation_when_type_is_apparent = true +csharp_style_inlined_variable_declaration = true +csharp_style_prefer_index_operator = true +csharp_style_prefer_local_over_anonymous_function = true +csharp_style_prefer_null_check_over_type_check = true +csharp_style_prefer_range_operator = true +csharp_style_prefer_tuple_swap = true +csharp_style_throw_expression = true +csharp_style_unused_value_assignment_preference = discard_variable +csharp_style_unused_value_expression_statement_preference = discard_variable + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:suggestion + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false +csharp_style_allow_embedded_statements_on_same_line_experimental = true + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs new file mode 100644 index 00000000..2deefa73 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using EasyAbp.EShop.Orders.Orders.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.EShop.Products.Products.Dtos; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Orders.Orders; + +public class CreateFlashSalesOrderEventHandler : IDistributedEventHandler, ITransientDependency +{ + protected INewOrderGenerator NewOrderGenerator { get; } + + protected IObjectMapper ObjectMapper { get; } + + protected IEnumerable OrderDiscountProviders { get; } + + protected IOrderRepository OrderRepository { get; } + + protected IDistributedEventBus DistributedEventBus { get; } + + public CreateFlashSalesOrderEventHandler( + INewOrderGenerator newOrderGenerator, + IObjectMapper objectMapper, + IEnumerable orderDiscountProviders, + IOrderRepository orderRepository, + IDistributedEventBus distributedEventBus) + { + NewOrderGenerator = newOrderGenerator; + ObjectMapper = objectMapper; + OrderDiscountProviders = orderDiscountProviders; + OrderRepository = orderRepository; + DistributedEventBus = distributedEventBus; + } + + [UnitOfWork(true)] + public virtual async Task HandleEventAsync(CreateFlashSalesOrderEto eventData) + { + //How to check product is available? + //How to reduce product stock? + + var input = new CreateOrderDto() + { + StoreId = eventData.StoreId, + CustomerRemark = eventData.CustomerRemark, + OrderLines = new List() + { + new CreateOrderLineDto() + { + ProductId = eventData.Plan.ProductId, + ProductSkuId = eventData.Plan.ProductSkuId, + Quantity = eventData.Quantity + } + } + }; + var productDict = new Dictionary() + { + {eventData.Product.Id, ObjectMapper.Map(eventData.Product)} + }; + var productDetailDict = new Dictionary() + { + {eventData.ProductDetail.Id, ObjectMapper.Map(eventData.ProductDetail)} + }; + + var order = await NewOrderGenerator.GenerateAsync(eventData.UserId, input, productDict, productDetailDict); + + await DiscountOrderAsync(order, productDict); + + await OrderRepository.InsertAsync(order, autoSave: true); + + await DistributedEventBus.PublishAsync(new CreateFlashSalesOrderCompleteEto() + { + TenantId = eventData.TenantId, + PlanId = eventData.PlanId, + OrderId = order.Id, + UserId = eventData.UserId, + StoreId = eventData.StoreId, + PendingResultId = eventData.PendingResultId, + Success = true + }); + } + + protected virtual async Task DiscountOrderAsync(Order order, Dictionary productDict) + { + foreach (var provider in OrderDiscountProviders) + { + await provider.DiscountAsync(order, productDict); + } + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs new file mode 100644 index 00000000..16750493 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs @@ -0,0 +1,40 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using Microsoft.AspNetCore.Authorization; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.EShop.Orders.Orders; + +public class FlashSalesOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler +{ + protected IAbpLazyServiceProvider LazyServiceProvider { get; } + + public FlashSalesOrderCreationAuthorizationHandler(IAbpLazyServiceProvider lazyServiceProvider) + { + LazyServiceProvider = lazyServiceProvider; + } + + protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context, + OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource) + { + var flashSalesPlanAppService = LazyServiceProvider.LazyGetRequiredService(); + foreach (var orderLine in resource.Input.OrderLines) + { + var plans = await flashSalesPlanAppService.GetListAsync(new FlashSalesPlanGetListInput() + { + StoreId = resource.Input.StoreId, + ProductId = orderLine.ProductId, + ProductSkuId = orderLine.ProductSkuId, + OnlyShowPublished = true + }); + if (plans.Items.Count > 0) + { + context.Fail(); + return; + } + } + + context.Succeed(requirement); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs new file mode 100644 index 00000000..2c6dcb70 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System; +using AutoMapper; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Json; + +namespace EasyAbp.EShop.Orders +{ + public class EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile : Profile, ISingletonDependency + { + public EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile(IJsonSerializer jsonSerializer) + { + /* You can configure your AutoMapper mapping configuration here. + * Alternatively, you can split your mapping configurations + * into multiple profile classes for a better organization. */ + CreateMap(MemberList.Source) + .ForSourceMember(x => x.TenantId, opt => opt.DoNotValidate()) + .MapExtraProperties(); + CreateMap(MemberList.Source) + .ForMember(x => x.AttributeOptionIds, opt => opt.Ignore()) + .AfterMap((src, dest) => dest.AttributeOptionIds = jsonSerializer.Deserialize>(src.SerializedAttributeOptionIds)) + .MapExtraProperties(); + CreateMap(MemberList.Source) + .MapExtraProperties(); + CreateMap(MemberList.Source) + .MapExtraProperties(); + CreateMap(MemberList.Source) + .MapExtraProperties(); + } + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs index 7dd104d1..a0ecf1f7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs @@ -1,12 +1,37 @@ using EasyAbp.EShop.Orders; +using EasyAbp.EShop.Orders.Orders; +using EasyAbp.EShop.Products; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( typeof(EShopOrdersApplicationModule), + typeof(EShopProductsApplicationContractsModule), typeof(EShopPluginsFlashSalesApplicationContractsModule) )] public class EShopOrdersPluginsFlashSalesApplicationModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddSingleton(); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + Configure(options => + { + options.Configurators.Add(abpAutoMapperConfigurationContext => + { + var profile = abpAutoMapperConfigurationContext.ServiceProvider + .GetRequiredService(); + + abpAutoMapperConfigurationContext.MapperConfiguration.AddProfile(profile); + }); + }); + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs index 262522a2..f00bae2e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs @@ -4,5 +4,5 @@ public class EShopPluginsFlashSalesRemoteServiceConsts { public const string RemoteServiceName = "FlashSales"; - public const string ModuleName = "flashSales"; + public const string ModuleName = "flash-sales"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs new file mode 100644 index 00000000..b696292b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs @@ -0,0 +1,9 @@ +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; + +public class CreateOrderInput : ExtensibleEntityDto +{ + public string CustomerRemark { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs new file mode 100644 index 00000000..c3be88e7 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs @@ -0,0 +1,21 @@ +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Domain.Entities; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; + +[Serializable] +public class FlashSalesPlanCreateDto : ExtensibleEntityDto +{ + public Guid StoreId { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime EndTime { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public bool IsPublished { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanDto.cs new file mode 100644 index 00000000..d488fe6d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanDto.cs @@ -0,0 +1,23 @@ +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Domain.Entities; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; + +[Serializable] +public class FlashSalesPlanDto : ExtensibleFullAuditedEntityDto, IHasConcurrencyStamp +{ + public Guid StoreId { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime EndTime { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public bool IsPublished { get; set; } + + public string ConcurrencyStamp { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs new file mode 100644 index 00000000..e1b4f1fe --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs @@ -0,0 +1,20 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; + +[Serializable] +public class FlashSalesPlanGetListInput : ExtensiblePagedAndSortedResultRequestDto +{ + public Guid? StoreId { get; set; } + + public Guid? ProductId { get; set; } + + public Guid? ProductSkuId { get; set; } + + public bool OnlyShowPublished { get; set; } + + public DateTime? Start { get; set; } + + public DateTime? End { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs new file mode 100644 index 00000000..868f0657 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs @@ -0,0 +1,21 @@ +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Domain.Entities; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; + +[Serializable] +public class FlashSalesPlanUpdateDto : ExtensibleEntityDto, IHasConcurrencyStamp +{ + public DateTime BeginTime { get; set; } + + public DateTime EndTime { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public bool IsPublished { get; set; } + + public string ConcurrencyStamp { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs new file mode 100644 index 00000000..0dcaafc6 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs @@ -0,0 +1,21 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using Volo.Abp.Application.Services; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public interface IFlashSalesPlanAppService : + ICrudAppService< + FlashSalesPlanDto, + Guid, + FlashSalesPlanGetListInput, + FlashSalesPlanCreateDto, + FlashSalesPlanUpdateDto> +{ + Task PreOrderAsync(Guid id); + + Task CheckPreOrderAsync(Guid id); + + Task CreateOrderAsync(Guid id, CreateOrderInput input); +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultDto.cs new file mode 100644 index 00000000..8cd4cd9f --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultDto.cs @@ -0,0 +1,19 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; + +public class FlashSalesResultDto : ExtensibleFullAuditedEntityDto +{ + public virtual Guid StoreId { get; set; } + + public virtual Guid PlanId { get; set; } + + public virtual FlashSalesResultStatus Status { get; set; } + + public virtual string Reason { get; set; } + + public virtual Guid UserId { get; set; } + + public virtual Guid? OrderId { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs new file mode 100644 index 00000000..4b063273 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs @@ -0,0 +1,17 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; + +public class FlashSalesResultGetListInput : ExtensiblePagedAndSortedResultRequestDto +{ + public virtual Guid? StoreId { get; set; } + + public virtual Guid? PlanId { get; set; } + + public virtual FlashSalesResultStatus? Status { get; set; } + + public virtual Guid? UserId { get; set; } + + public virtual Guid? OrderId { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs new file mode 100644 index 00000000..0b9a013e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs @@ -0,0 +1,14 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +using Volo.Abp.Application.Services; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public interface IFlashSalesResultAppService : + IReadOnlyAppService< + FlashSalesResultDto, + Guid, + FlashSalesResultGetListInput> +{ + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs index 7f957669..49b3e55a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs @@ -1,4 +1,4 @@ -using EasyAbp.EShop.Plugins.FlashSales.Localization; +using EasyAbp.EShop.Plugins.FlashSales.Localization; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Localization; @@ -9,6 +9,15 @@ public class FlashSalesPermissionDefinitionProvider : PermissionDefinitionProvid public override void Define(IPermissionDefinitionContext context) { var myGroup = context.AddGroup(FlashSalesPermissions.GroupName, L("Permission:FlashSales")); + + var flashSalesPlanPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSalesPlan.Default, L("Permission:FlashSalesPlan")); + flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Manage, L("Permission:Manage")); + flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Create, L("Permission:Create")); + flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Update, L("Permission:Update")); + flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Delete, L("Permission:Delete")); + + var flashSalesResultPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSalesResult.Default, L("Permission:FlashSalesResult")); + flashSalesResultPermission.AddChild(FlashSalesPermissions.FlashSalesResult.Manage, L("Permission:Manage")); } private static LocalizableString L(string name) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs index 61f4f82d..0ccaa1a5 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs @@ -1,13 +1,28 @@ -using Volo.Abp.Reflection; +using Volo.Abp.Reflection; namespace EasyAbp.EShop.Plugins.FlashSales.Permissions; public class FlashSalesPermissions { - public const string GroupName = "FlashSales"; + public const string GroupName = "EasyAbp.EShop.Plugins.FlashSales"; public static string[] GetAll() { return ReflectionHelper.GetPublicConstantsRecursively(typeof(FlashSalesPermissions)); } + + public class FlashSalesPlan + { + public const string Default = GroupName + ".FlashSalesPlan"; + public const string Manage = Default + ".Manage"; + public const string Update = Default + ".Update"; + public const string Create = Default + ".Create"; + public const string Delete = Default + ".Delete"; + } + + public class FlashSalesResult + { + public const string Default = GroupName + ".FlashSalesResult"; + public const string Manage = Default + ".Manage"; + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj index dfe3604c..3b42dbb7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj @@ -9,7 +9,10 @@ + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs index 403f6949..260175c9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs @@ -1,15 +1,20 @@ -using Microsoft.Extensions.DependencyInjection; +using EasyAbp.EShop.Products; +using EasyAbp.EShop.Stores; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Application; using Volo.Abp.AutoMapper; +using Volo.Abp.Caching; using Volo.Abp.Modularity; -using Volo.Abp.Application; namespace EasyAbp.EShop.Plugins.FlashSales; - [DependsOn( + typeof(EShopProductsApplicationContractsModule), typeof(EShopPluginsFlashSalesDomainModule), typeof(EShopPluginsFlashSalesApplicationContractsModule), + typeof(EShopStoresApplicationSharedModule), typeof(AbpDddApplicationModule), - typeof(AbpAutoMapperModule) + typeof(AbpAutoMapperModule), + typeof(AbpCachingModule) )] public class EShopPluginsFlashSalesApplicationModule : AbpModule { @@ -18,7 +23,14 @@ public class EShopPluginsFlashSalesApplicationModule : AbpModule context.Services.AddAutoMapperObjectMapper(); Configure(options => { - options.AddMaps(validate: true); + options.Configurators.Add(abpAutoMapperConfigurationContext => + { + var profile = abpAutoMapperConfigurationContext.ServiceProvider + .GetRequiredService(); + + abpAutoMapperConfigurationContext.MapperConfiguration.AddProfile(profile); + }); }); + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs index 68505ad8..a5bf39b1 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs @@ -1,13 +1,48 @@ -using AutoMapper; +using System.Linq; +using AutoMapper; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.EShop.Products.Products.Dtos; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Json; namespace EasyAbp.EShop.Plugins.FlashSales; -public class FlashSalesApplicationAutoMapperProfile : Profile +public class FlashSalesApplicationAutoMapperProfile : Profile, ISingletonDependency { - public FlashSalesApplicationAutoMapperProfile() + public FlashSalesApplicationAutoMapperProfile(IJsonSerializer jsonSerializer) { /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ + CreateMap() + .MapExtraProperties(); + CreateMap() + .ForMember(x => x.TenantId, opt => opt.Ignore()) + .MapExtraProperties(); + CreateMap(MemberList.Source); + CreateMap(MemberList.Source); + CreateMap() + .MapExtraProperties(); + + CreateMap() + .MapExtraProperties(); + + CreateMap() + .ForMember(x => x.TenantId, opt => opt.Ignore()) + .MapExtraProperties(); + CreateMap() + .ForMember(x => x.SerializedAttributeOptionIds, opt => opt.Ignore()) + .AfterMap((src, dest) => dest.SerializedAttributeOptionIds = jsonSerializer.Serialize(src.AttributeOptionIds.OrderBy(x => x))) + .MapExtraProperties(); + CreateMap() + .MapExtraProperties(); + CreateMap() + .MapExtraProperties(); + CreateMap() + .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs new file mode 100644 index 00000000..67e8ddeb --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -0,0 +1,362 @@ +using System; +using System.Linq; +using System.Numerics; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.Permissions; +using EasyAbp.EShop.Products.ProductDetails; +using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Caching.Distributed; +using Volo.Abp; +using Volo.Abp.Application.Services; +using Volo.Abp.Caching; +using Volo.Abp.Data; +using Volo.Abp.DistributedLocking; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Users; +using static EasyAbp.EShop.Products.Permissions.ProductsPermissions; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +[Authorize] +public class FlashSalesPlanAppService : + CrudAppService, + IFlashSalesPlanAppService +{ + protected override string GetPolicyName { get; set; } + protected override string GetListPolicyName { get; set; } + protected override string CreatePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Create; + protected override string UpdatePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Update; + protected override string DeletePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Delete; + + protected IFlashSalesPlanRepository FlashSalesPlanRepository { get; } + protected IProductAppService ProductAppService { get; } + protected IProductDetailAppService ProductDetailAppService { get; } + protected IDistributedCache TokenDistributedCache { get; } + protected IDistributedCache DistributedCache { get; } + protected IDistributedEventBus DistributedEventBus { get; } + protected FlashSalesPlanManager FlashSalesPlanManager { get; } + protected IFlashSalesResultRepository FlashSalesResultRepository { get; } + protected IAbpDistributedLock DistributedLock { get; } + + public FlashSalesPlanAppService( + IFlashSalesPlanRepository flashSalesPlanRepository, + IProductAppService productAppService, + IProductDetailAppService productDetailAppService, + IDistributedCache tokenDistributedCache, + IDistributedCache distributedCache, + IDistributedEventBus distributedEventBus, + FlashSalesPlanManager flashSalesPlanManager, + IFlashSalesResultRepository flashSalesResultRepository, + IAbpDistributedLock distributedLock) + : base(flashSalesPlanRepository) + { + FlashSalesPlanRepository = flashSalesPlanRepository; + ProductAppService = productAppService; + ProductDetailAppService = productDetailAppService; + TokenDistributedCache = tokenDistributedCache; + DistributedCache = distributedCache; + DistributedEventBus = distributedEventBus; + FlashSalesPlanManager = flashSalesPlanManager; + FlashSalesResultRepository = flashSalesResultRepository; + DistributedLock = distributedLock; + } + + public override async Task GetAsync(Guid id) + { + await CheckGetPolicyAsync(); + + var flashSalesPlan = await GetEntityByIdAsync(id); + + if (!flashSalesPlan.IsPublished) + { + await CheckPolicyAsync(FlashSalesPermissions.FlashSalesPlan.Manage); + } + + return await MapToGetOutputDtoAsync(flashSalesPlan); + } + + public override async Task CreateAsync(FlashSalesPlanCreateDto input) + { + await CheckCreatePolicyAsync(); + + var flashSalesPlan = await FlashSalesPlanManager.CreateAsync( + input.StoreId, + input.BeginTime, + input.EndTime, + input.ProductId, + input.ProductSkuId, + input.IsPublished + ); + + await FlashSalesPlanRepository.InsertAsync(flashSalesPlan, autoSave: true); + + return await MapToGetOutputDtoAsync(flashSalesPlan); + } + + public override async Task UpdateAsync(Guid id, FlashSalesPlanUpdateDto input) + { + await CheckUpdatePolicyAsync(); + + var flashSalesPlan = await GetEntityByIdAsync(id); + + await FlashSalesPlanManager.UpdateAsync( + flashSalesPlan, + input.BeginTime, + input.EndTime, + input.ProductId, + input.ProductSkuId, + input.IsPublished + ); + + flashSalesPlan.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); + + await FlashSalesPlanRepository.UpdateAsync(flashSalesPlan, autoSave: true); + + return await MapToGetOutputDtoAsync(flashSalesPlan); + } + + protected override async Task> CreateFilteredQueryAsync(FlashSalesPlanGetListInput input) + { + if (!input.OnlyShowPublished) + { + await CheckPolicyAsync(FlashSalesPermissions.FlashSalesPlan.Manage); + } + + return (await base.CreateFilteredQueryAsync(input)) + .WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId.Value) + .WhereIf(input.ProductId.HasValue, x => x.ProductId == input.ProductId.Value) + .WhereIf(input.ProductSkuId.HasValue, x => x.ProductSkuId == input.ProductSkuId.Value) + .WhereIf(input.OnlyShowPublished, x => x.IsPublished) + .WhereIf(input.Start.HasValue, x => x.BeginTime >= input.Start.Value) + .WhereIf(input.End.HasValue, x => x.BeginTime <= input.End.Value); + } + + public virtual async Task PreOrderAsync(Guid id) + { + var plan = await GetFlashSalesPlanCacheAsync(id); + var product = await ProductAppService.GetAsync(plan.ProductId); + var productSku = product.GetSkuById(plan.ProductSkuId); + + if (!product.IsPublished) + { + throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); + } + + if (product.InventoryStrategy != InventoryStrategy.FlashSales) + { + throw new BusinessException(FlashSalesErrorCodes.IsNotFlashSalesProduct); + } + + if (!plan.IsPublished) + { + throw new EntityNotFoundException(typeof(FlashSalesPlan), id); + } + + if (Clock.Now > plan.EndTime) + { + throw new BusinessException(FlashSalesErrorCodes.FlashSalesPlanIsExpired); + } + + await SetCacheHashTokenAsync(plan, product, productSku); + } + + public virtual async Task CheckPreOrderAsync(Guid id) + { + var plan = await GetFlashSalesPlanCacheAsync(id); + if (Clock.Now > plan.EndTime) + { + throw new BusinessException(FlashSalesErrorCodes.FlashSalesPlanIsExpired); + } + + var cacheHashToken = await GetCacheHashTokenAsync(plan); + if (cacheHashToken.IsNullOrWhiteSpace()) + { + throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); + } + + var product = await ProductAppService.GetAsync(plan.ProductId); + var productSku = product.GetSkuById(plan.ProductSkuId); + + if (!await ComparekHashTokenAsync(cacheHashToken, plan, product, productSku)) + { + throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); + } + } + + public virtual async Task CreateOrderAsync(Guid id, CreateOrderInput input) + { + var plan = await GetFlashSalesPlanCacheAsync(id); + var now = Clock.Now; + if (plan.BeginTime > now) + { + throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); + } + + if (now > plan.EndTime) + { + throw new BusinessException(FlashSalesErrorCodes.FlashSalesPlanIsExpired); + } + + var cacheHashToken = await GetCacheHashTokenAsync(plan); + if (cacheHashToken.IsNullOrWhiteSpace()) + { + throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); + } + + var product = await ProductAppService.GetAsync(plan.ProductId); + var productSku = product.GetSkuById(plan.ProductSkuId); + + if (!await ComparekHashTokenAsync(cacheHashToken, plan, product, productSku)) + { + throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); + } + + await RemoveCacheHashTokenAsync(plan); + + var userId = CurrentUser.GetId(); + + var result = await CreatePendingFlashSalesResultAsync(plan, userId); + + var CreateFlashSalesOrderEto = await PrepareCreateFlashSalesOrderEtoAsync(plan, product, productSku, result, input, userId, now); + + await DistributedEventBus.PublishAsync(CreateFlashSalesOrderEto); + } + + protected virtual async Task PrepareCreateFlashSalesOrderEtoAsync( + FlashSalesPlanDto plan, + ProductDto product, + ProductSkuDto productSku, + FlashSalesResult result, + CreateOrderInput input, + Guid userId, + DateTime now) + { + FlashSalesProductDetailEto productDetail = null; + var productDetailId = productSku.ProductDetailId ?? product.ProductDetailId; + if (productDetailId.HasValue) + { + productDetail = ObjectMapper.Map(await ProductDetailAppService.GetAsync(productDetailId.Value)); + } + var productEto = ObjectMapper.Map(product); + productEto.TenantId = CurrentTenant.Id; + var planEto = ObjectMapper.Map(plan); + planEto.TenantId = CurrentTenant.Id; + + var eto = new CreateFlashSalesOrderEto() + { + TenantId = CurrentTenant.Id, + PlanId = plan.Id, + UserId = userId, + PendingResultId = result.Id, + StoreId = plan.StoreId, + CreateTime = now, + CustomerRemark = input.CustomerRemark, + Quantity = 1,//should configure + Product = productEto, + ProductDetail = productDetail, + Plan = planEto + }; + + foreach (var item in input.ExtraProperties) + { + eto.ExtraProperties.Add(item.Key, item.Value); + } + + return eto; + } + + protected virtual async Task GetFlashSalesPlanCacheAsync(Guid id) + { + return await DistributedCache.GetOrAddAsync(id, async () => + { + var flashSalesPlan = await FlashSalesPlanRepository.GetAsync(id); + return ObjectMapper.Map(flashSalesPlan); + }); + } + + protected virtual Task GetCacheKeyAsync(FlashSalesPlanDto plan) + { + return Task.FromResult($"eshopflashsales_{CurrentUser.Id}_{plan.ProductSkuId}"); + } + + protected virtual async Task GetCacheHashTokenAsync(FlashSalesPlanDto plan) + { + return await TokenDistributedCache.GetStringAsync(await GetCacheKeyAsync(plan)); + } + + protected virtual async Task RemoveCacheHashTokenAsync(FlashSalesPlanDto plan) + { + await TokenDistributedCache.RemoveAsync(await GetCacheKeyAsync(plan)); + } + + protected virtual async Task SetCacheHashTokenAsync(FlashSalesPlanDto plan, ProductDto product, ProductSkuDto productSku) + { + await TokenDistributedCache.SetStringAsync(await GetCacheKeyAsync(plan), await GetHashTokenAsync(plan, product, productSku), new DistributedCacheEntryOptions() + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(3) + }); + } + + protected virtual Task GetHashTokenAsync(FlashSalesPlanDto plan, ProductDto product, ProductSkuDto productSku) + { + using var md5 = MD5.Create(); + var inputBytes = Encoding.UTF8.GetBytes($"{plan.LastModificationTime}|{product.LastModificationTime}|{productSku.LastModificationTime}"); + var sb = new StringBuilder(); + foreach (var t in md5.ComputeHash(inputBytes)) + { + sb.Append(t.ToString("X2")); + } + return Task.FromResult(sb.ToString()); + } + + protected virtual async Task ComparekHashTokenAsync(string cacheHashToken, FlashSalesPlanDto plan, ProductDto product, ProductSkuDto productSku) + { + if (cacheHashToken.IsNullOrWhiteSpace()) + { + return false; + } + + var hashToken = await GetHashTokenAsync(plan, product, productSku); + + return cacheHashToken == hashToken; + } + + protected virtual async Task CreatePendingFlashSalesResultAsync(FlashSalesPlanDto plan, Guid userId) + { + var lockKey = $"create-flash-sales-order-{plan.Id}-{userId}"; + + await using var handle = await DistributedLock.TryAcquireAsync(lockKey); + + if (handle == null) + { + throw new BusinessException(FlashSalesErrorCodes.CreateFlashSalesOrderBusy); + } + + // Prevent repeat submit + if (await FlashSalesResultRepository.AnyAsync(x => x.PlanId == plan.Id && x.UserId == userId)) + { + throw new BusinessException(FlashSalesErrorCodes.AlreadySubmitCreateFlashSalesOrder); + } + + var result = new FlashSalesResult( + id: GuidGenerator.Create(), + tenantId: CurrentTenant.Id, + storeId: plan.StoreId, + planId: plan.Id, + status: FlashSalesResultStatus.Pending, + reason: null, + userId: userId, + orderId: null + ); + return await FlashSalesResultRepository.InsertAsync(result, autoSave: true); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs new file mode 100644 index 00000000..7bc37dd3 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using Volo.Abp.Caching; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesPlanCacheInvalidator : ILocalEventHandler> +{ + protected IDistributedCache DistributedCache { get; } + + public virtual async Task HandleEventAsync(EntityChangedEventData eventData) + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs new file mode 100644 index 00000000..f28bee5e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs @@ -0,0 +1,9 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +[Serializable] +public class FlashSalesPlanCacheItem : FlashSalesPlanDto +{ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultAppService.cs new file mode 100644 index 00000000..854ca5e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultAppService.cs @@ -0,0 +1,51 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Permissions; +using Volo.Abp.Application.Services; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public class FlashSalesResultAppService : + ReadOnlyAppService, + IFlashSalesResultAppService +{ + protected override string GetPolicyName { get; set; } + protected override string GetListPolicyName { get; set; } + + protected IFlashSalesResultRepository FlashSalesResultRepository { get; } + + public FlashSalesResultAppService(IFlashSalesResultRepository flashSalesResultRepository) : base(flashSalesResultRepository) + { + } + + public override async Task GetAsync(Guid id) + { + await CheckGetPolicyAsync(); + + var flashSalesPlan = await GetEntityByIdAsync(id); + + if (flashSalesPlan.UserId != CurrentUser.Id) + { + await CheckPolicyAsync(FlashSalesPermissions.FlashSalesResult.Manage); + } + + return await MapToGetOutputDtoAsync(flashSalesPlan); + } + + protected override async Task> CreateFilteredQueryAsync(FlashSalesResultGetListInput input) + { + if (input.UserId != CurrentUser.Id) + { + await CheckPolicyAsync(FlashSalesPermissions.FlashSalesResult.Manage); + } + + return (await base.CreateFilteredQueryAsync(input)) + .WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId.Value) + .WhereIf(input.PlanId.HasValue, x => x.PlanId == input.PlanId.Value) + .WhereIf(input.Status.HasValue, x => x.Status == input.Status.Value) + .WhereIf(input.UserId.HasValue, x => x.UserId == input.UserId.Value) + .WhereIf(input.OrderId.HasValue, x => x.OrderId == input.OrderId.Value); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj index e5e0cdcf..95717151 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj @@ -21,4 +21,8 @@ + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index b02a0801..033cd4a7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -6,4 +6,17 @@ public static class FlashSalesErrorCodes public const string EndTimeMustBeLaterThanBeginTime = $"{Namespace}:{nameof(EndTimeMustBeLaterThanBeginTime)}"; + public const string ProductIsNotPublished = $"{Namespace}:{nameof(ProductIsNotPublished)}"; + + public const string IsNotFlashSalesProduct = $"{Namespace}:{nameof(IsNotFlashSalesProduct)}"; + + public const string PreOrderExipred = $"{Namespace}:{nameof(PreOrderExipred)}"; + + public const string FlashSalesPlanIsNotStart = $"{Namespace}:{nameof(FlashSalesPlanIsNotStart)}"; + + public const string FlashSalesPlanIsExpired = $"{Namespace}:{nameof(FlashSalesPlanIsExpired)}"; + + public const string CreateFlashSalesOrderBusy = $"{Namespace}:{nameof(CreateFlashSalesOrderBusy)}"; + + public const string AlreadySubmitCreateFlashSalesOrder = $"{Namespace}:{nameof(AlreadySubmitCreateFlashSalesOrder)}"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs new file mode 100644 index 00000000..5c6942b5 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs @@ -0,0 +1,25 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectExtending; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class CreateFlashSalesOrderCompleteEto : ExtensibleObject, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid PendingResultId { get; set; } + + public bool Success { get; set; } + + public Guid StoreId { get; set; } + + public Guid PlanId { get; set; } + + public string Reason { get; set; } + + public Guid UserId { get; set; } + + public Guid? OrderId { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderEto.cs new file mode 100644 index 00000000..27a45274 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderEto.cs @@ -0,0 +1,32 @@ +using System; +using EasyAbp.EShop.Products.Products; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectExtending; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +[Serializable] +public class CreateFlashSalesOrderEto : ExtensibleObject, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid StoreId { get; set; } + + public Guid PlanId { get; set; } + + public Guid UserId { get; set; } + + public Guid PendingResultId { get; set; } + + public DateTime CreateTime { get; set; } + + public string CustomerRemark { get; set; } + + public int Quantity { get; set; } + + public FlashSalesProductEto Product { get; set; } + + public FlashSalesProductDetailEto ProductDetail { get; set; } + + public FlashSalesPlanEto Plan { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs new file mode 100644 index 00000000..23450eca --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectExtending; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesPlanEto : FullAuditedEntityEto, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid StoreId { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime EndTime { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public bool IsPublished { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs new file mode 100644 index 00000000..c26be79e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using EasyAbp.EShop.Products.Products; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesProductAttributeEto : FullAuditedEntityEto, IProductAttribute +{ + public string DisplayName { get; set; } + + public string Description { get; set; } + + public int DisplayOrder { get; set; } + + public List ProductAttributeOptions { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs new file mode 100644 index 00000000..3e613049 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs @@ -0,0 +1,13 @@ +using System; +using EasyAbp.EShop.Products.Products; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesProductAttributeOptionEto : FullAuditedEntityEto, IProductAttributeOption +{ + public string DisplayName { get; set; } + + public string Description { get; set; } + + public int DisplayOrder { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs new file mode 100644 index 00000000..7a0a4a99 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using EasyAbp.EShop.Products.Products; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesProductEto : FullAuditedEntityEto, IProduct, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid StoreId { get; set; } + + public string ProductGroupName { get; set; } + + public Guid? ProductDetailId { get; set; } + + public string UniqueName { get; set; } + + public string DisplayName { get; set; } + + public InventoryStrategy InventoryStrategy { get; set; } + + public string InventoryProviderName { get; set; } + + public string MediaResources { get; set; } + + public int DisplayOrder { get; set; } + + public bool IsPublished { get; set; } + + public bool IsStatic { get; set; } + + public bool IsHidden { get; set; } + + public List ProductAttributes { get; set; } + + public List ProductSkus { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs new file mode 100644 index 00000000..09abe06c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs @@ -0,0 +1,25 @@ +using System; +using EasyAbp.EShop.Products.Products; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesProductSkuEto : FullAuditedEntityEto, IProductSku +{ + public string SerializedAttributeOptionIds { get; set; } + + public string Name { get; set; } + + public string Currency { get; set; } + + public decimal? OriginalPrice { get; set; } + + public decimal Price { get; set; } + + public int OrderMinQuantity { get; set; } + + public int OrderMaxQuantity { get; set; } + + public string MediaResources { get; set; } + + public Guid? ProductDetailId { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs new file mode 100644 index 00000000..d9ebef4d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs @@ -0,0 +1,10 @@ +using System; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesProductDetailEto : FullAuditedEntityEto +{ + public Guid? StoreId { get; set; } + + public string Description { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs new file mode 100644 index 00000000..3d88d0cc --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public enum FlashSalesResultStatus +{ + Pending, + Successful, + Failed +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FullAuditedEntityEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FullAuditedEntityEto.cs new file mode 100644 index 00000000..7961d1f6 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FullAuditedEntityEto.cs @@ -0,0 +1,23 @@ +using System; +using Volo.Abp.ObjectExtending; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class FullAuditedEntityEto : ExtensibleObject +{ + public TPrimaryKey Id { get; set; } + + public DateTime CreationTime { get; set; } + + public Guid? CreatorId { get; set; } + + public DateTime? LastModificationTime { get; set; } + + public Guid? LastModifierId { get; set; } + + public bool IsDeleted { get; set; } + + public Guid? DeleterId { get; set; } + + public DateTime? DeletionTime { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs index a6e9fa61..b2519b45 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/FlashSalesResource.cs @@ -2,7 +2,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.Localization; -[LocalizationResourceName("FlashSales")] +[LocalizationResourceName("EasyAbpEShopPluginsFlashSales")] public class FlashSalesResource { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json index 189662ee..f92545a9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -1,5 +1,34 @@ { "culture": "en", "texts": { + "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "End time must be later than start time", + "Menu:FlashSalesManagement": "FlashSalesManagement", + "Permission:FlashSalesPlan": "FlashSalesPlan", + "Permission:Manage": "Manage", + "Permission:Create": "Create", + "Permission:Update": "Update", + "Permission:Delete": "Delete", + "Menu:FlashSalesPlan": "FlashSalesPlan", + "FlashSalesPlan": "FlashSalesPlan", + "FlashSalesPlanStoreId": "Store ID", + "FlashSalesPlanBeginTime": "Begin Time", + "FlashSalesPlanEndTime": "End Time", + "FlashSalesPlanProductId": "Product ID", + "FlashSalesPlanProductSkuId": "Product SKU ID", + "FlashSalesPlanIsPublished": "Is Published", + "CreateFlashSalesPlan": "Create", + "EditFlashSalesPlan": "Edit", + "FlashSalesPlanDeletionConfirmationMessage": "Are you sure to delete the flashSalesPlan {0}?", + "SuccessfullyDeleted": "Successfully deleted", + "Permission:FlashSalesResult": "FlashSalesResult", + "Menu:FlashSalesResult": "FlashSalesResult", + "FlashSalesResult": "FlashSalesResult", + "FlashSalesResultStoreId": "Store ID", + "FlashSalesResultPlanId": "Plan ID", + "FlashSalesResultStatus": "Status", + "FlashSalesResultUserId": "User ID", + "FlashSalesResultOrderId": "Order ID", + "FlashSalesResultCreationTime": "Creation Time", + "ViewFlashSalesPlan": "View" } -} \ No newline at end of file +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json index df772fa6..5061f16b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -1,5 +1,34 @@ { "culture": "zh-Hans", "texts": { + "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "结束时间必须晚于开始时间", + "Menu:FlashSalesManagement": "闪购", + "Permission:FlashSalesPlan": "闪购计划", + "Permission:Manage": "管理", + "Permission:Create": "新建", + "Permission:Update": "更新", + "Permission:Delete": "删除", + "Menu:FlashSalesPlan": "闪购计划", + "FlashSalesPlan": "闪购计划", + "FlashSalesPlanStoreId": "店铺 ID", + "FlashSalesPlanBeginTime": "开始时间", + "FlashSalesPlanEndTime": "结束时间", + "FlashSalesPlanProductId": "产品 ID", + "FlashSalesPlanProductSkuId": "产品SKU ID", + "FlashSalesPlanIsPublished": "发布", + "CreateFlashSalesPlan": "新建", + "EditFlashSalesPlan": "编辑", + "FlashSalesPlanDeletionConfirmationMessage": "确认删除闪购计划 {0}?", + "SuccessfullyDeleted": "删除成功", + "Permission:FlashSalesResult": "闪购结果", + "Menu:FlashSalesResult": "闪购结果", + "FlashSalesResult": "闪购结果", + "FlashSalesResultStoreId": "店铺 ID", + "FlashSalesResultPlanId": "计划 ID", + "FlashSalesResultStatus": "状态", + "FlashSalesResultUserId": "用户 ID", + "FlashSalesResultOrderId": "订单 ID", + "FlashSalesResultCreationTime": "创建时间", + "ViewFlashSalesPlan": "查看" } -} \ No newline at end of file +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json index 7de37982..24fd0adc 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -1,5 +1,34 @@ { "culture": "zh-Hant", "texts": { + "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "結束時間必須晚於開始時間", + "Menu:FlashSalesManagement": "FlashSalesManagement", + "Permission:FlashSalesPlan": "FlashSalesPlan", + "Permission:Manage": "Manage", + "Permission:Create": "Create", + "Permission:Update": "Update", + "Permission:Delete": "Delete", + "Menu:FlashSalesPlan": "FlashSalesPlan", + "FlashSalesPlan": "FlashSalesPlan", + "FlashSalesPlanStoreId": "FlashSalesPlanStoreId", + "FlashSalesPlanBeginTime": "FlashSalesPlanBeginTime", + "FlashSalesPlanEndTime": "FlashSalesPlanEndTime", + "FlashSalesPlanProductId": "FlashSalesPlanProductId", + "FlashSalesPlanProductSkuId": "FlashSalesPlanProductSkuId", + "FlashSalesPlanIsPublished": "FlashSalesPlanIsActive", + "CreateFlashSalesPlan": "CreateFlashSalesPlan", + "EditFlashSalesPlan": "EditFlashSalesPlan", + "FlashSalesPlanDeletionConfirmationMessage": "Are you sure to delete the flashSalesPlan {0}?", + "SuccessfullyDeleted": "Successfully deleted", + "Permission:FlashSalesResult": "闪购结果", + "Menu:FlashSalesResult": "闪购计划", + "FlashSalesResult": "闪购结果", + "FlashSalesResultStoreId": "店铺 ID", + "FlashSalesResultPlanId": "计划 ID", + "FlashSalesResultStatus": "状态", + "FlashSalesResultUserId": "用户 ID", + "FlashSalesResultOrderId": "订单 ID", + "FlashSalesResultCreationTime": "创建时间", + "ViewFlashSalesPlan": "查看" } -} \ No newline at end of file +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj index 87ad5a39..b8f4224b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj @@ -8,6 +8,7 @@ + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs new file mode 100644 index 00000000..df4eb669 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs @@ -0,0 +1,16 @@ +using AutoMapper; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class EShopPluginsFlashSalesDomainAutoMapperProfile : Profile +{ + public EShopPluginsFlashSalesDomainAutoMapperProfile() + { + /* You can configure your AutoMapper mapping configuration here. + * Alternatively, you can split your mapping configurations + * into multiple profile classes for a better organization. */ + CreateMap() + .MapExtraProperties(); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs index f3b45e32..0ce9dd05 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs @@ -1,13 +1,33 @@ -using Volo.Abp.Domain; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; +using Volo.Abp.Domain; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( typeof(AbpDddDomainModule), + typeof(AbpAutoMapperModule), typeof(EShopPluginsFlashSalesDomainSharedModule) )] public class EShopPluginsFlashSalesDomainModule : AbpModule { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + Configure(options => + { + options.AddProfile(validate: true); + }); + + Configure(options => + { + options.EtoMappings.Add(typeof(EShopPluginsFlashSalesDomainModule)); + + options.AutoEventSelectors.Add(); + }); + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs index e94eef4d..909df743 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDbProperties.cs @@ -2,9 +2,9 @@ public static class FlashSalesDbProperties { - public static string DbTablePrefix { get; set; } = "FlashSales"; + public static string DbTablePrefix { get; set; } = "EasyAbpEShopPluginsFlashSales"; public static string DbSchema { get; set; } = null; - public const string ConnectionStringName = "FlashSales"; + public const string ConnectionStringName = "EasyAbpEShopPluginsFlashSales"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs new file mode 100644 index 00000000..4b9fdad2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs @@ -0,0 +1,12 @@ +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +internal class EndTimeMustBeLaterThanBeginTimeException : BusinessException +{ + public EndTimeMustBeLaterThanBeginTimeException() + : base(FlashSalesErrorCodes.EndTimeMustBeLaterThanBeginTime) + { + + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs new file mode 100644 index 00000000..0de27f9a --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs @@ -0,0 +1,58 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant +{ + public virtual Guid? TenantId { get; protected set; } + + public virtual Guid StoreId { get; protected set; } + + public virtual DateTime BeginTime { get; set; } + + public virtual DateTime EndTime { get; set; } + + public virtual Guid ProductId { get; protected set; } + + public virtual Guid ProductSkuId { get; protected set; } + + public virtual bool IsPublished { get; protected set; } + + protected FlashSalesPlan() + { + } + + public FlashSalesPlan(Guid id, Guid? tenantId, Guid storeId, DateTime beginTime, DateTime endTime, Guid productId, Guid productSkuId, bool isPublished) + : base(id) + { + TenantId = tenantId; + StoreId = storeId; + SetTimeRange(beginTime, endTime); + SetProduct(productId, productSkuId); + SetPublished(isPublished); + } + + public void SetTimeRange(DateTime beginTime, DateTime endTime) + { + if (beginTime > endTime) + { + throw new EndTimeMustBeLaterThanBeginTimeException(); + } + + BeginTime = beginTime; + EndTime = endTime; + } + + public void SetProduct(Guid productId, Guid productSkuId) + { + ProductId = productId; + ProductSkuId = productSkuId; + } + + public void SetPublished(bool isPublished) + { + IsPublished = isPublished; + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs new file mode 100644 index 00000000..d8654316 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Domain.Services; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesPlanManager : DomainService +{ + public virtual Task CreateAsync( + Guid storeId, + DateTime beginTime, + DateTime endTime, + Guid productId, + Guid productSkuId, + bool isActive) + { + var flashSalesPlan = new FlashSalesPlan( + GuidGenerator.Create(), + CurrentTenant.Id, + storeId, + beginTime, + endTime, + productId, + productSkuId, + isActive + ); + return Task.FromResult(flashSalesPlan); + } + + public virtual Task UpdateAsync( + FlashSalesPlan flashSalesPlan, + DateTime beginTime, + DateTime endTime, + Guid productId, + Guid productSkuId, + bool isPublished) + { + flashSalesPlan.SetTimeRange(beginTime, endTime); + flashSalesPlan.SetProduct(productId, productSkuId); + flashSalesPlan.SetPublished(isPublished); + + return Task.FromResult(flashSalesPlan); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs new file mode 100644 index 00000000..41f32db0 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs @@ -0,0 +1,8 @@ +using System; +using Volo.Abp.Domain.Repositories; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public interface IFlashSalesPlanRepository : IRepository +{ +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs new file mode 100644 index 00000000..b7dc305a --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs @@ -0,0 +1,37 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Guids; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public class CreateFlashSalesOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency +{ + protected IFlashSalesResultRepository FlashSalesResultRepository { get; } + protected IGuidGenerator GuidGenerator { get; } + + public CreateFlashSalesOrderCompleteEventHandler(IFlashSalesResultRepository flashSalesResultRepository, IGuidGenerator guidGenerator) + { + FlashSalesResultRepository = flashSalesResultRepository; + GuidGenerator = guidGenerator; + } + + [UnitOfWork] + public virtual async Task HandleEventAsync(CreateFlashSalesOrderCompleteEto eventData) + { + var flashSalesResult = await FlashSalesResultRepository.GetAsync(eventData.PendingResultId); + + if (eventData.Success) + { + flashSalesResult.MarkAsSuccessful(eventData.OrderId.Value); + } + else + { + flashSalesResult.MarkAsFailed(eventData.Reason); + } + + await FlashSalesResultRepository.UpdateAsync(flashSalesResult, autoSave: true); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult.cs new file mode 100644 index 00000000..de3a83df --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult.cs @@ -0,0 +1,49 @@ +using System; +using Volo.Abp; +using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public class FlashSalesResult : FullAuditedAggregateRoot, IMultiTenant +{ + public virtual Guid? TenantId { get; protected set; } + + public virtual Guid StoreId { get; protected set; } + + public virtual Guid PlanId { get; protected set; } + + public virtual FlashSalesResultStatus Status { get; protected set; } + + public virtual string Reason { get; protected set; } + + public virtual Guid UserId { get; protected set; } + + public virtual Guid? OrderId { get; protected set; } + + protected FlashSalesResult() { } + + public FlashSalesResult(Guid id, Guid? tenantId, Guid storeId, Guid planId, FlashSalesResultStatus status, string reason, Guid userId, Guid? orderId) + : base(id) + { + TenantId = tenantId; + StoreId = storeId; + PlanId = planId; + Status = status; + Reason = reason; + UserId = userId; + OrderId = orderId; + } + + public void MarkAsSuccessful(Guid orderId) + { + Status = FlashSalesResultStatus.Successful; + OrderId = orderId; + } + + public void MarkAsFailed(string reason) + { + Status = FlashSalesResultStatus.Failed; + Reason = Check.NotNullOrEmpty(reason, nameof(reason)); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs new file mode 100644 index 00000000..d09be083 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs @@ -0,0 +1,9 @@ +using System; +using Volo.Abp.Domain.Repositories; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public interface IFlashSalesResultRepository : IRepository +{ + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs index 07383dc2..a573c7e9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.DependencyInjection; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; @@ -14,9 +16,8 @@ public class EShopPluginsFlashSalesEntityFrameworkCoreModule : AbpModule { context.Services.AddAbpDbContext(options => { - /* Add custom repositories here. Example: - * options.AddRepository(); - */ + options.AddRepository(); + options.AddRepository(); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs index 3d3df1b4..41d0d253 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs @@ -1,4 +1,6 @@ -using Microsoft.EntityFrameworkCore; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; @@ -7,9 +9,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public class FlashSalesDbContext : AbpDbContext, IFlashSalesDbContext { - /* Add DbSet for each Aggregate Root here. Example: - * public DbSet Questions { get; set; } - */ + public DbSet Plans { get; set; } + + public DbSet Results { get; set; } public FlashSalesDbContext(DbContextOptions options) : base(options) @@ -21,6 +23,6 @@ public class FlashSalesDbContext : AbpDbContext, IFlashSale { base.OnModelCreating(builder); - builder.ConfigureFlashSales(); + builder.ConfigureEShopPluginsFlashSales(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs index 209d4ba8..284a5122 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs @@ -1,33 +1,32 @@ -using Microsoft.EntityFrameworkCore; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using Microsoft.EntityFrameworkCore; using Volo.Abp; +using Volo.Abp.EntityFrameworkCore.Modeling; namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; public static class FlashSalesDbContextModelCreatingExtensions { - public static void ConfigureFlashSales( + public static void ConfigureEShopPluginsFlashSales( this ModelBuilder builder) { Check.NotNull(builder, nameof(builder)); - /* Configure all entities here. Example: - - builder.Entity(b => + builder.Entity(b => { - //Configure table & schema name - b.ToTable(FlashSalesDbProperties.DbTablePrefix + "Questions", FlashSalesDbProperties.DbSchema); - + b.ToTable(FlashSalesDbProperties.DbTablePrefix + "Plans", FlashSalesDbProperties.DbSchema); b.ConfigureByConvention(); - //Properties - b.Property(q => q.Title).IsRequired().HasMaxLength(QuestionConsts.MaxTitleLength); + /* Configure more properties here */ + }); - //Relations - b.HasMany(question => question.Tags).WithOne().HasForeignKey(qt => qt.QuestionId); + builder.Entity(b => + { + b.ToTable(FlashSalesDbProperties.DbTablePrefix + "Results", FlashSalesDbProperties.DbSchema); + b.ConfigureByConvention(); - //Indexes - b.HasIndex(q => q.CreationTime); + /* Configure more properties here */ }); - */ } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs index 5804039f..46a6766b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs @@ -1,4 +1,7 @@ -using Volo.Abp.Data; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; @@ -6,7 +9,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public interface IFlashSalesDbContext : IEfCoreDbContext { - /* Add DbSet for each Aggregate Root here. Example: - * DbSet Questions { get; } - */ + DbSet Plans { get; set; } + + DbSet Results { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs new file mode 100644 index 00000000..7926de36 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans +{ + public class EfCoreFlashSalesPlanRepository : EfCoreRepository, IFlashSalesPlanRepository + { + public EfCoreFlashSalesPlanRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public override async Task> WithDetailsAsync() + { + return (await GetQueryableAsync()).IncludeDetails(); + } + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs new file mode 100644 index 00000000..5bccbeee --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs @@ -0,0 +1,18 @@ +using System.Linq; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public static class FlashSalesPlanEfCoreQueryableExtensions +{ + public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true) + { + if (!include) + { + return queryable; + } + + return queryable + // .Include(x => x.xxx) // TODO: AbpHelper generated + ; + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs new file mode 100644 index 00000000..e4fc4185 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs @@ -0,0 +1,20 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public class EfCoreFlashSalesResultRepository : EfCoreRepository, IFlashSalesResultRepository +{ + public EfCoreFlashSalesResultRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public override async Task> WithDetailsAsync() + { + return (await GetQueryableAsync()).IncludeDetails(); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs new file mode 100644 index 00000000..141898bd --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs @@ -0,0 +1,16 @@ +using System.Linq; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public static class FlashSalesResultEfCoreQuerableExtensions +{ + public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true) + { + if (!include) + { + return queryable; + } + + return queryable; + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanController.cs new file mode 100644 index 00000000..1bd611d8 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanController.cs @@ -0,0 +1,71 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +[Area(EShopPluginsFlashSalesRemoteServiceConsts.ModuleName)] +[RemoteService(Name = EShopPluginsFlashSalesRemoteServiceConsts.RemoteServiceName)] +[Route("/api/e-shop/plugins/flash-sales/flash-sales-plan")] +public class FlashSalesPlanController : + FlashSalesController, + IFlashSalesPlanAppService +{ + protected IFlashSalesPlanAppService Service { get; } + + public FlashSalesPlanController(IFlashSalesPlanAppService flashSalesPlanAppService) + { + Service = flashSalesPlanAppService; + } + + [HttpGet("{id}")] + public virtual Task GetAsync(Guid id) + { + return Service.GetAsync(id); + } + + [HttpGet] + public virtual Task> GetListAsync(FlashSalesPlanGetListInput input) + { + return Service.GetListAsync(input); + } + + [HttpPost("{id}")] + public virtual Task CreateAsync(FlashSalesPlanCreateDto input) + { + return Service.CreateAsync(input); + } + + [HttpPut("{id}")] + public virtual Task UpdateAsync(Guid id, FlashSalesPlanUpdateDto input) + { + return Service.UpdateAsync(id, input); + } + + [HttpDelete("{id}")] + public virtual Task DeleteAsync(Guid id) + { + return Service.DeleteAsync(id); + } + + [HttpPost("{id}/pre-order")] + public virtual Task PreOrderAsync(Guid id) + { + return Service.PreOrderAsync(id); + } + + [HttpGet("{id}/check-pre-order")] + public virtual Task CheckPreOrderAsync(Guid id) + { + return Service.CheckPreOrderAsync(id); + } + + [HttpPost("{id}/order")] + public virtual Task CreateOrderAsync(Guid id, CreateOrderInput input) + { + return Service.CreateOrderAsync(id, input); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs new file mode 100644 index 00000000..f74846e3 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +[Area(EShopPluginsFlashSalesRemoteServiceConsts.ModuleName)] +[RemoteService(Name = EShopPluginsFlashSalesRemoteServiceConsts.RemoteServiceName)] +[Route("/api/e-shop/plugins/flash-sales/flash-sales-result")] +public class FlashSalesResultController : FlashSalesController, IFlashSalesResultAppService +{ + protected IFlashSalesResultAppService Service { get; } + + public FlashSalesResultController(IFlashSalesResultAppService service) + { + Service = service; + } + + [HttpGet("{id}")] + public virtual Task GetAsync(Guid id) + { + return Service.GetAsync(id); + } + + [HttpGet] + public virtual Task> GetListAsync(FlashSalesResultGetListInput input) + { + return Service.GetListAsync(input); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs new file mode 100644 index 00000000..e573f156 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs @@ -0,0 +1,13 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.MongoDB; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class MongoFlashSalesPlanRepository : MongoDbRepository, IFlashSalesPlanRepository +{ + public MongoFlashSalesPlanRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs new file mode 100644 index 00000000..8621e83e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs @@ -0,0 +1,13 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.MongoDB; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public class MongoFlashSalesResultRepository : MongoDbRepository, IFlashSalesResultRepository +{ + public MongoFlashSalesResultRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs index 9e39be35..728dbbde 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.DependencyInjection; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; using Volo.Abp.MongoDB; @@ -14,9 +16,8 @@ public class EShopPluginsFlashSalesMongoDbModule : AbpModule { context.Services.AddMongoDbContext(options => { - /* Add custom repositories here. Example: - * options.AddRepository(); - */ + options.AddRepository(); + options.AddRepository(); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs index 537a2714..3e2028e8 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs @@ -1,4 +1,7 @@ -using Volo.Abp.Data; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using MongoDB.Driver; +using Volo.Abp.Data; using Volo.Abp.MongoDB; namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; @@ -6,9 +9,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public class FlashSalesMongoDbContext : AbpMongoDbContext, IFlashSalesMongoDbContext { - /* Add mongo collections here. Example: - * public IMongoCollection Questions => Collection(); - */ + public IMongoCollection Plans => Collection(); + + public IMongoCollection Results => Collection(); protected override void CreateModel(IMongoModelBuilder modelBuilder) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs index 91b45a39..5bdad8d4 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs @@ -1,4 +1,6 @@ -using Volo.Abp; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using Volo.Abp; using Volo.Abp.MongoDB; namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; @@ -9,5 +11,9 @@ public static class FlashSalesMongoDbContextExtensions this IMongoModelBuilder builder) { Check.NotNull(builder, nameof(builder)); + + builder.Entity(b => b.CollectionName = FlashSalesDbProperties.DbTablePrefix + "Plans"); + + builder.Entity(b => b.CollectionName = FlashSalesDbProperties.DbTablePrefix + "Results"); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs index d0501265..5cc3f8e8 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs @@ -1,4 +1,7 @@ -using Volo.Abp.Data; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using MongoDB.Driver; +using Volo.Abp.Data; using Volo.Abp.MongoDB; namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; @@ -6,7 +9,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public interface IFlashSalesMongoDbContext : IAbpMongoDbContext { - /* Define mongo collections here. Example: - * IMongoCollection Questions { get; } - */ + IMongoCollection Plans { get; } + + IMongoCollection Results { get; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs index a6afd47a..4eb9cde3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs @@ -1,4 +1,8 @@ using AutoMapper; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult.ViewModels; namespace EasyAbp.EShop.Plugins.FlashSales.Web; @@ -9,5 +13,13 @@ public class EShopPluginsFlashSalesWebAutoMapperProfile : Profile /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ + CreateMap() + .ForMember(dest => dest.ExtraProperties, opt => opt.Ignore()); + CreateMap() + .ForMember(dest => dest.ExtraProperties, opt => opt.Ignore()); + CreateMap() + .ForSourceMember(dest => dest.ExtraProperties, opt => opt.DoNotValidate()); + CreateMap() + .ForSourceMember(dest => dest.ExtraProperties, opt => opt.DoNotValidate()); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebModule.cs index 41e96f9d..443dc336 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebModule.cs @@ -53,6 +53,6 @@ public class EShopPluginsFlashSalesWebModule : AbpModule Configure(options => { //Configure authorization. - }); + }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj index cedf9892..94d9b52e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj @@ -37,4 +37,9 @@ + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs index e5f8ec0f..6ab46dea 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs @@ -1,4 +1,7 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.Localization; +using EasyAbp.EShop.Plugins.FlashSales.Permissions; using Volo.Abp.UI.Navigation; namespace EasyAbp.EShop.Plugins.FlashSales.Web.Menus; @@ -13,11 +16,40 @@ public class FlashSalesMenuContributor : IMenuContributor } } - private Task ConfigureMainMenuAsync(MenuConfigurationContext context) + private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) { + var l = context.GetLocalizer(); //Add main menu items. - context.Menu.AddItem(new ApplicationMenuItem(FlashSalesMenus.Prefix, displayName: "FlashSales", "~/FlashSales", icon: "fa fa-globe")); + var flashSalesManagementMenuItem = new ApplicationMenuItem(FlashSalesMenus.Prefix, l["Menu:FlashSalesManagement"]); - return Task.CompletedTask; + if (await context.IsGrantedAsync(FlashSalesPermissions.FlashSalesPlan.Default)) + { + flashSalesManagementMenuItem.AddItem( + new ApplicationMenuItem( + FlashSalesMenus.FlashSalesPlan, + l["Menu:FlashSalesPlan"], + "/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan" + ) + ); + } + + if (await context.IsGrantedAsync(FlashSalesPermissions.FlashSalesResult.Default)) + { + flashSalesManagementMenuItem.AddItem( + new ApplicationMenuItem( + FlashSalesMenus.FlashSalesResult, + l["Menu:FlashSalesResult"], + "/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult" + ) + ); + } + + if (!flashSalesManagementMenuItem.Items.IsNullOrEmpty()) + { + var eShopMenuItem = context.Menu.Items.GetOrAdd(i => i.Name == FlashSalesMenus.ModuleGroupPrefix, + () => new ApplicationMenuItem(FlashSalesMenus.ModuleGroupPrefix, l["Menu:EasyAbpEShop"], icon: "fa fa-shopping-bag")); + + eShopMenuItem.Items.Add(flashSalesManagementMenuItem); + } } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs index 9faa7e22..cad519a2 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs @@ -1,10 +1,12 @@ -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Menus; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Menus; -public class FlashSalesMenus +public static class FlashSalesMenus { - public const string Prefix = "FlashSales"; + public const string ModuleGroupPrefix = "EasyAbp.EShop"; - //Add your menu items here... - //public const string Home = Prefix + ".MyNewMenuItem"; + public const string Prefix = ModuleGroupPrefix + ".Plugins.FlashSales"; + public const string FlashSalesPlan = Prefix + ".FlashSalesPlan"; + + public const string FlashSalesResult = Prefix + ".FlashSalesResult"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml new file mode 100644 index 00000000..32a1aa21 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml @@ -0,0 +1,21 @@ +@page +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using EasyAbp.EShop.Plugins.FlashSales.Localization +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan + +@inject IHtmlLocalizer L +@model CreateModalModel +@{ + Layout = null; +} + + + + + + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs new file mode 100644 index 00000000..760d498a --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan; + +public class CreateModalModel : FlashSalesPageModel +{ + [BindProperty] + public CreateFlashSalesPlanViewModel ViewModel { get; set; } + + protected IFlashSalesPlanAppService Service { get; } + + public CreateModalModel(IFlashSalesPlanAppService service) + { + Service = service; + } + + public virtual async Task OnPostAsync() + { + var dto = ObjectMapper.Map(ViewModel); + await Service.CreateAsync(dto); + return NoContent(); + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml new file mode 100644 index 00000000..faa6ffc9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml @@ -0,0 +1,22 @@ +@page +@using EasyAbp.EShop.Plugins.FlashSales.Localization +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan + +@inject IHtmlLocalizer L +@model EditModalModel +@{ + Layout = null; +} + + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml.cs new file mode 100644 index 00000000..faa49dd3 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan; + +public class EditModalModel : FlashSalesPageModel +{ + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid Id { get; set; } + + [BindProperty] + public EditFlashSalesPlanViewModel ViewModel { get; set; } + + protected IFlashSalesPlanAppService Service { get; } + + public EditModalModel(IFlashSalesPlanAppService service) + { + Service = service; + } + + public virtual async Task OnGetAsync() + { + var dto = await Service.GetAsync(Id); + ViewModel = ObjectMapper.Map(dto); + } + + public virtual async Task OnPostAsync() + { + var dto = ObjectMapper.Map(ViewModel); + await Service.UpdateAsync(Id, dto); + return NoContent(); + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml new file mode 100644 index 00000000..d96bb645 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml @@ -0,0 +1,50 @@ +@page +@using EasyAbp.EShop.Plugins.FlashSales.Permissions +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan +@using EasyAbp.EShop.Plugins.FlashSales.Localization +@using EasyAbp.EShop.Plugins.FlashSales.Web.Menus + +@model IndexModel + +@inject IPageLayout PageLayout +@inject IHtmlLocalizer L +@inject IAuthorizationService Authorization +@{ + PageLayout.Content.Title = L["FlashSalesPlan"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:FlashSalesPlan"].Value); + PageLayout.Content.MenuItemName = FlashSalesMenus.FlashSalesPlan; +} + +@section scripts +{ + +} +@section styles +{ + +} + + + + + + @L["FlashSalesPlan"] + + + @if (await Authorization.IsGrantedAsync(FlashSalesPermissions.FlashSalesPlan.Create)) + { + + } + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml.cs new file mode 100644 index 00000000..2203fdef --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan; + +public class IndexModel : FlashSalesPageModel +{ + public virtual async Task OnGetAsync() + { + await Task.CompletedTask; + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs new file mode 100644 index 00000000..d65ae9bb --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; + +public class CreateFlashSalesPlanViewModel +{ + [Display(Name = "FlashSalesPlanStoreId")] + public Guid StoreId { get; set; } + + [Display(Name = "FlashSalesPlanBeginTime")] + public DateTime BeginTime { get; set; } + + [Display(Name = "FlashSalesPlanEndTime")] + public DateTime EndTime { get; set; } + + [Display(Name = "FlashSalesPlanProductId")] + public Guid ProductId { get; set; } + + [Display(Name = "FlashSalesPlanProductSkuId")] + public Guid ProductSkuId { get; set; } + + [Display(Name = "FlashSalesPlanIsPublished")] + public bool IsPublished { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs new file mode 100644 index 00000000..972d0980 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs @@ -0,0 +1,33 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; +using Volo.Abp.Domain.Entities; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; + +public class EditFlashSalesPlanViewModel : IHasConcurrencyStamp +{ + [DisabledInput] + [ReadOnlyInput] + [Display(Name = "FlashSalesPlanStoreId")] + public Guid StoreId { get; set; } + + [Display(Name = "FlashSalesPlanBeginTime")] + public DateTime BeginTime { get; set; } + + [Display(Name = "FlashSalesPlanEndTime")] + public DateTime EndTime { get; set; } + + [Display(Name = "FlashSalesPlanProductId")] + public Guid ProductId { get; set; } + + [Display(Name = "FlashSalesPlanProductSkuId")] + public Guid ProductSkuId { get; set; } + + [Display(Name = "FlashSalesPlanIsPublished")] + public bool IsPublished { get; set; } + + [HiddenInput] + public string ConcurrencyStamp { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.css b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.css new file mode 100644 index 00000000..e69de29b diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js new file mode 100644 index 00000000..8b4a951e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js @@ -0,0 +1,87 @@ +$(function () { + + var l = abp.localization.getResource('EasyAbpEShopPluginsFlashSales'); + + var service = easyAbp.eShop.plugins.flashSales.flashSalesPlans.flashSalesPlan; + var createModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal'); + var editModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal'); + + var dataTable = $('#FlashSalesPlanTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + order: [[2, "asc"]], + ajax: abp.libs.datatables.createAjax(service.getList), + columnDefs: [ + { + rowAction: { + items: + [ + { + text: l('Edit'), + visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlan.Update'), + action: function (data) { + editModal.open({ id: data.record.id }); + } + }, + { + text: l('Delete'), + visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlan.Delete'), + confirmMessage: function (data) { + return l('FlashSalesPlanDeletionConfirmationMessage', data.record.id); + }, + action: function (data) { + service.delete(data.record.id) + .then(function () { + abp.notify.info(l('SuccessfullyDeleted')); + dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { + title: l('FlashSalesPlanStoreId'), + data: "storeId" + }, + { + title: l('FlashSalesPlanBeginTime'), + data: "beginTime" + }, + { + title: l('FlashSalesPlanEndTime'), + data: "endTime" + }, + { + title: l('FlashSalesPlanProductId'), + data: "productId" + }, + { + title: l('FlashSalesPlanProductSkuId'), + data: "productSkuId" + }, + { + title: l('FlashSalesPlanIsPublished'), + data: "isPublished", + dataFormat: 'boolean' + }, + ] + })); + + createModal.onResult(function () { + dataTable.ajax.reload(); + }); + + editModal.onResult(function () { + dataTable.ajax.reload(); + }); + + $('#NewFlashSalesPlanButton').click(function (e) { + e.preventDefault(); + createModal.open(); + }); +}); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml new file mode 100644 index 00000000..ba1d6a72 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml @@ -0,0 +1,41 @@ +@page +@using EasyAbp.EShop.Plugins.FlashSales.Permissions +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult +@using EasyAbp.EShop.Plugins.FlashSales.Localization +@using EasyAbp.EShop.Plugins.FlashSales.Web.Menus + +@model IndexModel + +@inject IPageLayout PageLayout +@inject IHtmlLocalizer L +@inject IAuthorizationService Authorization +@{ + PageLayout.Content.Title = L["FlashSalesResult"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:FlashSalesResult"].Value); + PageLayout.Content.MenuItemName = FlashSalesMenus.FlashSalesResult; +} + +@section scripts +{ + +} +@section styles +{ + +} + + + + + + @L["FlashSalesResult"] + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml.cs new file mode 100644 index 00000000..ae48fd64 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult; + +public class IndexModel : PageModel +{ + public void OnGet() + { + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml new file mode 100644 index 00000000..ef929eab --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml @@ -0,0 +1,22 @@ +@page +@using EasyAbp.EShop.Plugins.FlashSales.Localization +@using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult + +@inject IHtmlLocalizer L +@model ViewModalModel +@{ + Layout = null; +} + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml.cs new file mode 100644 index 00000000..9d5fa316 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult; + +public class ViewModalModel : FlashSalesPageModel +{ + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid Id { get; set; } + + [BindProperty] + public ViewFlashSalesResultViewModel ViewModel { get; set; } + + protected IFlashSalesResultAppService Service { get; } + + public ViewModalModel(IFlashSalesResultAppService service) + { + Service = service; + } + + public virtual async Task OnGetAsync() + { + var dto = await Service.GetAsync(Id); + ViewModel = ObjectMapper.Map(dto); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs new file mode 100644 index 00000000..c72ba9f0 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult.ViewModels; + +public class ViewFlashSalesResultViewModel +{ + [Display(Name = "FlashSalesResultStoreId")] + public virtual Guid StoreId { get; protected set; } + + [Display(Name = "FlashSalesResultPlanId")] + public virtual Guid PlanId { get; protected set; } + + [Display(Name = "FlashSalesResultStatus")] + public virtual FlashSalesResultStatus Status { get; protected set; } + + [Display(Name = "FlashSalesResultUserId")] + public virtual Guid UserId { get; protected set; } + + [Display(Name = "FlashSalesResultOrderId")] + public virtual Guid? OrderId { get; protected set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.css b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.css new file mode 100644 index 00000000..e69de29b diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js new file mode 100644 index 00000000..d29f6825 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js @@ -0,0 +1,62 @@ +$(function () { + + var l = abp.localization.getResource('EasyAbpEShopPluginsFlashSales'); + + var service = easyAbp.eShop.plugins.flashSales.flashSalesPlans.flashSalesPlan; + var viewModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal'); + + var dataTable = $('#FlashSalesResultTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + order: [[6, "desc"]], + ajax: abp.libs.datatables.createAjax(service.getList), + columnDefs: [ + { + rowAction: { + items: + [ + { + text: l('ViewFlashSalesPlan'), + action: function (data) { + viewModal.open({ id: data.record.id }); + } + } + ] + } + }, + { + title: l('FlashSalesResultStoreId'), + data: "storeId" + }, + { + title: l('FlashSalesResultPlanId'), + data: "planId" + }, + { + title: l('FlashSalesResultStatus'), + data: "status" + }, + { + title: l('FlashSalesResultUserId'), + data: "userId" + }, + { + title: l('FlashSalesResultOrderId'), + data: "orderId" + }, + { + title: l('FlashSalesResultCreationTime'), + data: "creationTime", + dataFormat: 'datetime' + }, + ] + })); + + viewModal.onResult(function () { + dataTable.ajax.reload(); + }); +}); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/Index.cshtml similarity index 73% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/Index.cshtml index 4eb1c2d9..fed6c363 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/Index.cshtml @@ -1,11 +1,12 @@ @page @using Microsoft.Extensions.Localization @using EasyAbp.EShop.Plugins.FlashSales.Localization -@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EasyAbp.EShop.Plugins.FlashSales +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales + @model IndexModel @inject IStringLocalizer L - @{ } +

FlashSales

@L["SamplePageMessage"]

diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/Index.cshtml.cs similarity index 50% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/Index.cshtml.cs index 7438e942..a4551d28 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/Index.cshtml.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/Index.cshtml.cs @@ -1,4 +1,4 @@ -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EasyAbp.EShop.Plugins.FlashSales; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales; public class IndexModel : FlashSalesPageModel { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/_ViewImports.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/_ViewImports.cshtml similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EasyAbp/EShop/Plugins/FlashSales/_ViewImports.cshtml rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/_ViewImports.cshtml From 51b4118a5ae784bccea194e39d0406c079de0135 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 27 Jun 2022 01:44:49 +0800 Subject: [PATCH 04/97] Add FlashSales Plugin to sample --- .../EShopSample.Application.Contracts.csproj | 1 + .../EShopSampleApplicationContractsModule.cs | 2 + .../EShopSample.Application.csproj | 2 + .../EShopSampleApplicationModule.cs | 3 + .../EShopSample.Domain.Shared.csproj | 1 + .../EShopSampleDomainSharedModule.cs | 2 + .../EShopSample.Domain.csproj | 1 + .../EShopSampleDomainModule.cs | 2 + .../EShopSample.EntityFrameworkCore.csproj | 1 + .../EShopSampleDbContext.cs | 13 +- .../EShopSampleEntityFrameworkCoreModule.cs | 2 + ...20220626174330_AddedFlashSales.Designer.cs | 5323 +++++++++++++++++ .../20220626174330_AddedFlashSales.cs | 76 + .../EShopSampleDbContextModelSnapshot.cs | 148 +- .../EShopSample.HttpApi.Client.csproj | 1 + .../EShopSampleHttpApiClientModule.cs | 2 + .../EShopSample.HttpApi.csproj | 1 + .../EShopSampleHttpApiModule.cs | 2 + .../EShopSample.Web/EShopSample.Web.csproj | 1 + .../EShopSample.Web/EShopSampleWebModule.cs | 9 + .../src/EShopSample.Web/Program.cs | 1 + 21 files changed, 5587 insertions(+), 7 deletions(-) create mode 100644 samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.Designer.cs create mode 100644 samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.cs diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj index c835b5b3..4c75b80b 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj @@ -11,6 +11,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs index 9706aad0..9a48e836 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs @@ -1,6 +1,7 @@ using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -25,6 +26,7 @@ namespace EShopSample typeof(EShopApplicationContractsModule), typeof(EShopPluginsBasketsApplicationContractsModule), typeof(EShopPluginsCouponsApplicationContractsModule), + typeof(EShopPluginsFlashSalesApplicationContractsModule), typeof(PaymentServiceApplicationContractsModule), typeof(PaymentServiceWeChatPayApplicationContractsModule), typeof(PaymentServicePrepaymentApplicationContractsModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj index 6889685b..c106fcf0 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj @@ -12,6 +12,8 @@ + + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs index b6eb7520..6ff2e91d 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs @@ -2,6 +2,7 @@ using EasyAbp.EShop.Orders.Plugins.Coupons; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -27,6 +28,8 @@ namespace EShopSample typeof(EShopPluginsBasketsApplicationModule), typeof(EShopPluginsCouponsApplicationModule), typeof(EShopOrdersPluginsCouponsModule), + typeof(EShopPluginsFlashSalesApplicationModule), + typeof(EShopOrdersPluginsFlashSalesApplicationModule), typeof(PaymentServiceApplicationModule), typeof(PaymentServiceWeChatPayApplicationModule), typeof(PaymentServicePrepaymentApplicationModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj index 011d48d8..80b78801 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj @@ -23,6 +23,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs index e62aabb9..1bf60753 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs @@ -1,6 +1,7 @@ using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -32,6 +33,7 @@ namespace EShopSample typeof(EShopDomainSharedModule), typeof(EShopPluginsBasketsDomainSharedModule), typeof(EShopPluginsCouponsDomainSharedModule), + typeof(EShopPluginsFlashSalesDomainSharedModule), typeof(PaymentServiceDomainSharedModule), typeof(PaymentServiceWeChatPayDomainSharedModule), typeof(PaymentServicePrepaymentDomainSharedModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj index b9eb99bf..81d3b57c 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj @@ -11,6 +11,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs index 77db8a10..dbf698cb 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs @@ -1,6 +1,7 @@ using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Options; using EasyAbp.PaymentService.Payments; @@ -40,6 +41,7 @@ namespace EShopSample typeof(EShopDomainModule), typeof(EShopPluginsBasketsDomainModule), typeof(EShopPluginsCouponsDomainModule), + typeof(EShopPluginsFlashSalesDomainModule), typeof(PaymentServiceDomainModule), typeof(PaymentServiceWeChatPayDomainModule), typeof(PaymentServicePrepaymentDomainModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj index bd724e09..630b7e3f 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj @@ -11,6 +11,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs index 28d59311..7f5018e8 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs @@ -1,6 +1,7 @@ using EasyAbp.EShop.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore; +using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; using EasyAbp.PaymentService.EntityFrameworkCore; using EasyAbp.PaymentService.Prepayment.EntityFrameworkCore; using EasyAbp.PaymentService.WeChatPay.EntityFrameworkCore; @@ -30,9 +31,9 @@ namespace EShopSample.EntityFrameworkCore ITenantManagementDbContext { /* Add DbSet properties for your Aggregate Roots / Entities here. */ - + #region Entities from the modules - + /* Notice: We only implemented IIdentityDbContext and ITenantManagementDbContext * and replaced them for this DbContext. This allows you to perform JOIN * queries for the entities of these modules over the repositories easily. You @@ -43,7 +44,7 @@ namespace EShopSample.EntityFrameworkCore * More info: Replacing a DbContext of a module ensures that the related module * uses this DbContext on runtime. Otherwise, it will use its own DbContext class. */ - + //Identity public DbSet Users { get; set; } public DbSet Roles { get; set; } @@ -51,7 +52,7 @@ namespace EShopSample.EntityFrameworkCore public DbSet OrganizationUnits { get; set; } public DbSet SecurityLogs { get; set; } public DbSet LinkUsers { get; set; } - + // Tenant Management public DbSet Tenants { get; set; } public DbSet TenantConnectionStrings { get; set; } @@ -61,7 +62,6 @@ namespace EShopSample.EntityFrameworkCore public EShopSampleDbContext(DbContextOptions options) : base(options) { - } protected override void OnModelCreating(ModelBuilder builder) @@ -82,10 +82,11 @@ namespace EShopSample.EntityFrameworkCore builder.ConfigureEShop(); builder.ConfigureEShopPluginsBaskets(); builder.ConfigureEShopPluginsCoupons(); + builder.ConfigureEShopPluginsFlashSales(); builder.ConfigurePaymentService(); builder.ConfigurePaymentServiceWeChatPay(); builder.ConfigurePaymentServicePrepayment(); - + /* Configure your own tables/entities inside here */ } } diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs index 08171e3d..4be13390 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs @@ -1,6 +1,7 @@ using EasyAbp.EShop.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore; +using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; using EasyAbp.PaymentService.EntityFrameworkCore; using EasyAbp.PaymentService.Prepayment.EntityFrameworkCore; using EasyAbp.PaymentService.WeChatPay.EntityFrameworkCore; @@ -33,6 +34,7 @@ namespace EShopSample.EntityFrameworkCore typeof(EShopEntityFrameworkCoreModule), typeof(EShopPluginsBasketsEntityFrameworkCoreModule), typeof(EShopPluginsCouponsEntityFrameworkCoreModule), + typeof(EShopPluginsFlashSalesEntityFrameworkCoreModule), typeof(PaymentServiceEntityFrameworkCoreModule), typeof(PaymentServiceWeChatPayEntityFrameworkCoreModule), typeof(PaymentServicePrepaymentEntityFrameworkCoreModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.Designer.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.Designer.cs new file mode 100644 index 00000000..9463dc56 --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.Designer.cs @@ -0,0 +1,5323 @@ +// +using System; +using EShopSample.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace EShopSample.Migrations +{ + [DbContext(typeof(EShopSampleDbContext))] + [Migration("20220626174330_AddedFlashSales")] + partial class AddedFlashSales + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("ProductVersion", "6.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CancellationReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderNumber") + .HasColumnType("nvarchar(450)"); + + b.Property("OrderStatus") + .HasColumnType("int"); + + b.Property("PaidTime") + .HasColumnType("datetime2"); + + b.Property("PaymentExpiration") + .HasColumnType("datetime2"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("ReducedInventoryAfterPaymentTime") + .HasColumnType("datetime2"); + + b.Property("ReducedInventoryAfterPlacingTime") + .HasColumnType("datetime2"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderNumber") + .IsUnique() + .HasFilter("[OrderNumber] IS NOT NULL"); + + b.ToTable("EasyAbpEShopOrdersOrders", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Key") + .HasColumnType("nvarchar(450)"); + + b.Property("Fee") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("OrderId", "Name", "Key"); + + b.ToTable("EasyAbpEShopOrdersOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("EasyAbpEShopOrdersOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsPayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpEShopPaymentsPaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("OrderLineId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.BasketItems.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BasketName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsInvalid") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpEShopPluginsBasketsBasketItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.ProductUpdates.ProductUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopPluginsBasketsProductUpdates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.Coupons.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DiscountedAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("ExpirationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UsedTime") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCoupons", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConditionAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CouponType") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscountAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsUnscoped") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("UsableBeginTime") + .HasColumnType("datetime2"); + + b.Property("UsableDuration") + .HasColumnType("time"); + + b.Property("UsableEndTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CouponTemplateId"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplateScopes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BeginTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesPlans", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PlanId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesResults", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpEShopProductsCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductCategories.ProductCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetailHistories.ProductDetailHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductDetailId"); + + b.ToTable("EasyAbpEShopProductsProductDetailHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetails.ProductDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductDetails", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductHistories.ProductHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductInventories.ProductInventory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopProductsProductInventories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProducts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductAttributes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductAttributeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAttributeId"); + + b.ToTable("EasyAbpEShopProductsProductAttributeOptions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderMaxQuantity") + .HasColumnType("int"); + + b.Property("OrderMinQuantity") + .HasColumnType("int"); + + b.Property("OriginalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedAttributeOptionIds") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductSkus", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductView", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("MaximumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("MinimumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProductViews", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.StoreOwners.StoreOwner", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OwnerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("OwnerUserId", "StoreId") + .IsUnique(); + + b.ToTable("EasyAbpEShopStoresStoreOwners", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Stores.Store", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresStores", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServicePaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Accounts.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Balance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingTopUpPaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingWithdrawalAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingWithdrawalRecordId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentAccounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OriginalBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("AccountUserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRecords.WithdrawalRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("CancellationTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ResultErrorCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ResultErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("WithdrawalMethod") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRequests.WithdrawalRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsApproved") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ReviewTime") + .HasColumnType("datetime2"); + + b.Property("ReviewerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRequests", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServiceRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpPaymentServiceRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.PaymentRecords.PaymentRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("Attach") + .HasColumnType("nvarchar(max)"); + + b.Property("BankType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponCount") + .HasColumnType("int"); + + b.Property("CouponFee") + .HasColumnType("int"); + + b.Property("CouponFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeviceInfo") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCodeDes") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("IsSubscribe") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("Openid") + .HasColumnType("nvarchar(max)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ResultCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TimeEnd") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TradeType") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayPaymentRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.RefundRecords.RefundRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashRefundFee") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponRefundCount") + .HasColumnType("int"); + + b.Property("CouponRefundFee") + .HasColumnType("int"); + + b.Property("CouponRefundFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("OutRefundNo") + .HasColumnType("nvarchar(max)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundFee") + .HasColumnType("int"); + + b.Property("RefundId") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRecvAccout") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRequestSource") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundStatus") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementRefundFee") + .HasColumnType("int"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("SuccessTime") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayRefundRecords", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasColumnType("nvarchar(max)"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorTenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ImpersonatorTenantName"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("ImpersonatorUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ImpersonatorUserName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("TenantName"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsAbandoned") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("JobArgs") + .IsRequired() + .HasMaxLength(1048576) + .HasColumnType("nvarchar(max)"); + + b.Property("JobName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("LastTryTime") + .HasColumnType("datetime2"); + + b.Property("NextTryTime") + .HasColumnType("datetime2"); + + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint") + .HasDefaultValue((byte)15); + + b.Property("TryCount") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasDefaultValue((short)0); + + b.HasKey("Id"); + + b.HasIndex("IsAbandoned", "NextTryTime"); + + b.ToTable("AbpBackgroundJobs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpFeatureValues", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowedAccessTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Type"); + + b.ToTable("IdentityServerApiResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiResourceId", "Key", "Value"); + + b.ToTable("IdentityServerApiResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Scope"); + + b.ToTable("IdentityServerApiResourceScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ApiResourceId", "Type", "Value"); + + b.ToTable("IdentityServerApiResourceSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiScopeId", "Type"); + + b.ToTable("IdentityServerApiScopeClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiScopeId", "Key", "Value"); + + b.ToTable("IdentityServerApiScopeProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("bit"); + + b.Property("AllowOfflineAccess") + .HasColumnType("bit"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("bit"); + + b.Property("AllowRememberConsent") + .HasColumnType("bit"); + + b.Property("AllowedIdentityTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("bit"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("bit"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("BackChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ClientClaimsPrefix") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LogoUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("PairWiseSubjectSalt") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProtocolType") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("bit"); + + b.Property("RequireConsent") + .HasColumnType("bit"); + + b.Property("RequirePkce") + .HasColumnType("bit"); + + b.Property("RequireRequestObject") + .HasColumnType("bit"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("bit"); + + b.Property("UserCodeType") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("IdentityServerClients", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Origin") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.HasKey("ClientId", "Origin"); + + b.ToTable("IdentityServerClientCorsOrigins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("GrantType") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "GrantType"); + + b.ToTable("IdentityServerClientGrantTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Provider") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Provider"); + + b.ToTable("IdentityServerClientIdPRestrictions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("PostLogoutRedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "PostLogoutRedirectUri"); + + b.ToTable("IdentityServerClientPostLogoutRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "Key", "Value"); + + b.ToTable("IdentityServerClientProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("RedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "RedirectUri"); + + b.ToTable("IdentityServerClientRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Scope"); + + b.ToTable("IdentityServerClientScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Devices.DeviceFlowCodes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("DeviceCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UserCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.HasIndex("UserCode"); + + b.ToTable("IdentityServerDeviceFlowCodes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Grants.PersistedGrant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsumedTime") + .HasColumnType("datetime2"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.HasIndex("SubjectId", "SessionId", "Type"); + + b.ToTable("IdentityServerPersistedGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerIdentityResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("IdentityResourceId", "Type"); + + b.ToTable("IdentityServerIdentityResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("IdentityResourceId", "Key", "Value"); + + b.ToTable("IdentityServerIdentityResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[TenantId] IS NOT NULL"); + + b.ToTable("AbpPermissionGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpSettings", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderExtraFees") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderLines") + .HasForeignKey("OrderId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderExtraFees") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderLines") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", null) + .WithMany("Scopes") + .HasForeignKey("CouponTemplateId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.HasOne("EasyAbp.EShop.Products.Categories.Category", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductAttributes") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.ProductAttribute", null) + .WithMany("ProductAttributeOptions") + .HasForeignKey("ProductAttributeId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductSkus") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.PaymentService.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.PaymentService.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("Properties") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Navigation("Scopes"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Navigation("ProductAttributes"); + + b.Navigation("ProductSkus"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Navigation("ProductAttributeOptions"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Navigation("Properties"); + + b.Navigation("Scopes"); + + b.Navigation("Secrets"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Navigation("AllowedCorsOrigins"); + + b.Navigation("AllowedGrantTypes"); + + b.Navigation("AllowedScopes"); + + b.Navigation("Claims"); + + b.Navigation("ClientSecrets"); + + b.Navigation("IdentityProviderRestrictions"); + + b.Navigation("PostLogoutRedirectUris"); + + b.Navigation("Properties"); + + b.Navigation("RedirectUris"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.cs new file mode 100644 index 00000000..9174e969 --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.cs @@ -0,0 +1,76 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EShopSample.Migrations +{ + public partial class AddedFlashSales : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "EasyAbpEShopPluginsFlashSalesPlans", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + StoreId = table.Column(type: "uniqueidentifier", nullable: false), + BeginTime = table.Column(type: "datetime2", nullable: false), + EndTime = table.Column(type: "datetime2", nullable: false), + ProductId = table.Column(type: "uniqueidentifier", nullable: false), + ProductSkuId = table.Column(type: "uniqueidentifier", nullable: false), + IsPublished = table.Column(type: "bit", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpEShopPluginsFlashSalesPlans", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpEShopPluginsFlashSalesResults", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + StoreId = table.Column(type: "uniqueidentifier", nullable: false), + PlanId = table.Column(type: "uniqueidentifier", nullable: false), + Status = table.Column(type: "int", nullable: false), + Reason = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + OrderId = table.Column(type: "uniqueidentifier", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpEShopPluginsFlashSalesResults", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "EasyAbpEShopPluginsFlashSalesPlans"); + + migrationBuilder.DropTable( + name: "EasyAbpEShopPluginsFlashSalesResults"); + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs index 476f87e1..63bee2e4 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs @@ -19,7 +19,7 @@ namespace EShopSample.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "6.0.5") + .HasAnnotation("ProductVersion", "6.0.6") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); @@ -1022,6 +1022,152 @@ namespace EShopSample.Migrations b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplateScopes", (string)null); }); + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BeginTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesPlans", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PlanId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesResults", (string)null); + }); + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => { b.Property("Id") diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj index 0f335bdc..6378093c 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj @@ -11,6 +11,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs index 712d8884..f5ca37ee 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs @@ -1,6 +1,7 @@ using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -25,6 +26,7 @@ namespace EShopSample typeof(EShopHttpApiClientModule), typeof(EShopPluginsBasketsHttpApiClientModule), typeof(EShopPluginsCouponsHttpApiClientModule), + typeof(EShopPluginsFlashSalesHttpApiClientModule), typeof(PaymentServiceHttpApiClientModule), typeof(PaymentServiceWeChatPayHttpApiClientModule), typeof(PaymentServicePrepaymentHttpApiClientModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj index bd575558..c9446266 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj @@ -11,6 +11,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs index daf52607..846adf32 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs @@ -1,6 +1,7 @@ using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -23,6 +24,7 @@ namespace EShopSample typeof(EShopHttpApiModule), typeof(EShopPluginsBasketsHttpApiModule), typeof(EShopPluginsCouponsHttpApiModule), + typeof(EShopPluginsFlashSalesHttpApiModule), typeof(PaymentServiceHttpApiModule), typeof(PaymentServiceWeChatPayHttpApiModule), typeof(PaymentServicePrepaymentHttpApiModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj index c602502d..55735ebb 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj @@ -41,6 +41,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs index a0c5e671..4a14fe9e 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs @@ -52,6 +52,8 @@ using Volo.Abp.TenantManagement.Web; using Volo.Abp.UI.Navigation.Urls; using Volo.Abp.UI.Navigation; using Volo.Abp.VirtualFileSystem; +using EasyAbp.EShop.Plugins.FlashSales.Web; +using EasyAbp.EShop.Plugins.FlashSales; namespace EShopSample.Web { @@ -72,6 +74,7 @@ namespace EShopSample.Web typeof(EShopWebModule), typeof(EShopPluginsBasketsWebModule), typeof(EShopPluginsCouponsWebModule), + typeof(EShopPluginsFlashSalesWebModule), typeof(PaymentServiceWebModule), typeof(PaymentServiceWeChatPayWebModule), typeof(PaymentServicePrepaymentWebModule) @@ -207,6 +210,12 @@ namespace EShopSample.Web options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}Coupons{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.Coupons.Application.Contracts")); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}Coupons{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.Coupons.Application")); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}Coupons{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.Coupons.Web")); + + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}FlashSales{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.FlashSales.Domain.Shared")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}FlashSales{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.FlashSales.Domain")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}FlashSales{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.FlashSales.Application.Contracts")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}FlashSales{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.FlashSales.Application")); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}FlashSales{Path.DirectorySeparatorChar}src{Path.DirectorySeparatorChar}EasyAbp.EShop.Plugins.FlashSales.Web")); }); } } diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs index 7c5a516e..988c0a99 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs @@ -18,6 +18,7 @@ namespace EShopSample.Web #endif .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .Enrich.FromLogContext() + .WriteTo.Async(c => c.Console()) .WriteTo.Async(c => c.File("Logs/logs.txt")) .CreateLogger(); From 8c3338ce982acf263aca283f126b2cbcb242a9ca Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 27 Jun 2022 01:51:41 +0800 Subject: [PATCH 05/97] Fix CakeProduct sample --- .../aspnet-core/src/EShopSample.Web/Pages/Index.cshtml.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Pages/Index.cshtml.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Web/Pages/Index.cshtml.cs index c6d2443a..b796c5a8 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Pages/Index.cshtml.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Web/Pages/Index.cshtml.cs @@ -57,12 +57,12 @@ public class IndexModel : EShopSamplePageModel Sorting = "CreationTime DESC" }); - Order = OrderList.Items.FirstOrDefault(x => x.OrderStatus is OrderStatus.Pending); - Store = await _storeAppService.GetDefaultAsync(); CakeProduct = await _productAppService.GetByUniqueNameAsync(Store.Id, SampleDataConsts.CakeProductUniqueName); + Order = OrderList.Items.FirstOrDefault(x => x.OrderStatus is OrderStatus.Pending && x.OrderLines.Any(ol => ol.ProductId == CakeProduct.Id)); + Wallet = (await _accountAppService.GetListAsync(new GetAccountListInput { UserId = CurrentUser.Id })).Items[0]; } @@ -90,7 +90,7 @@ public class IndexModel : EShopSamplePageModel sb.Append(','); } } - + sb.Append('}'); sb.Append($",\"skuId\":\"{sku.Id}\""); From e7c4383c7e9ea67dfdee90ec9b94fda7c0051ce7 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Tue, 28 Jun 2022 01:06:34 +0800 Subject: [PATCH 06/97] Improve FlashSales --- EShop.sln | 7 ++ .../EasyAbp.EShop.Plugins.FlashSales.sln | 14 +++ .../CreateFlashSalesOrderEventHandler.cs | 3 - ...sFlashSalesApplicationAutoMapperProfile.cs | 33 ++--- ...rdersPluginsFlashSalesApplicationModule.cs | 16 +-- .../Dtos/FlashSalesPlanUpdateDto.cs | 2 + ...EShopPluginsFlashSalesApplicationModule.cs | 10 +- .../FlashSalesApplicationAutoMapperProfile.cs | 28 +---- .../FlashSalesPlanAppService.cs | 115 +++++++++--------- .../FlashSalesPlanCacheInvalidator.cs | 9 +- .../FlashSalesPlanCacheItem.cs | 1 + .../CreateFlashSalesOrderCompleteEto.cs | 1 - .../FlashSalesPlans/FlashSalesPlanEto.cs | 1 + .../FlashSalesPlans/FlashSalesPlanHasher.cs | 31 +++++ .../FlashSalesProductAttributeEto.cs | 1 + .../FlashSalesProductAttributeOptionEto.cs | 1 + .../FlashSalesPlans/FlashSalesProductEto.cs | 5 + .../FlashSalesProductSkuEto.cs | 6 + .../FlashSalesReduceInventoryEto.cs | 29 +++++ .../FlashSalesPlans/IFlashSalesPlanHasher.cs | 9 ++ .../FlashSalesPlans/ProductDetailEto.cs | 6 +- .../FlashSalesResultFailedReason.cs | 8 ++ .../EShopPluginsFlashSalesDomainModule.cs | 2 +- .../ViewModels/EditFlashSalesPlanViewModel.cs | 2 - ...ucts.Plugins.FlashSales.Application.csproj | 15 +++ ...sFlashSalesApplicationAutoMapperProfile.cs | 37 ++++++ ...ductsPluginsFlashSalesApplicationModule.cs | 28 +++++ .../FlashSalesReduceInventoryEventHandler.cs | 113 +++++++++++++++++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 +++++ .../EShopSample.Application.csproj | 1 + .../EShopSampleApplicationModule.cs | 3 + 32 files changed, 441 insertions(+), 129 deletions(-) rename plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/{ => Orders}/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs (62%) rename plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/{ => Orders}/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs (61%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanHasher.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesReduceInventoryEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanHasher.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultFailedReason.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSalesReduceInventoryEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xsd diff --git a/EShop.sln b/EShop.sln index 930dccee..44fc2380 100644 --- a/EShop.sln +++ b/EShop.sln @@ -413,6 +413,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Flash EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Orders.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Orders.Plugins.FlashSales.Application\EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj", "{5732E880-CB72-49A0-AC4F-A0620F4E4D16}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Application\EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj", "{6AD2F468-D86C-4F9A-B280-3BCC15661C47}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1071,6 +1073,10 @@ Global {5732E880-CB72-49A0-AC4F-A0620F4E4D16}.Debug|Any CPU.Build.0 = Debug|Any CPU {5732E880-CB72-49A0-AC4F-A0620F4E4D16}.Release|Any CPU.ActiveCfg = Release|Any CPU {5732E880-CB72-49A0-AC4F-A0620F4E4D16}.Release|Any CPU.Build.0 = Release|Any CPU + {6AD2F468-D86C-4F9A-B280-3BCC15661C47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AD2F468-D86C-4F9A-B280-3BCC15661C47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AD2F468-D86C-4F9A-B280-3BCC15661C47}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AD2F468-D86C-4F9A-B280-3BCC15661C47}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1277,6 +1283,7 @@ Global {68993D65-2C9C-438F-8B94-15E98C469A16} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} {417AB8E2-1488-4814-9699-3B189D1ABA67} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} {5732E880-CB72-49A0-AC4F-A0620F4E4D16} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {6AD2F468-D86C-4F9A-B280-3BCC15661C47} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln index 04554b96..11fd3b59 100644 --- a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln +++ b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln @@ -43,6 +43,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Flash EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Installer", "src\EasyAbp.EShop.Plugins.FlashSales.Installer\EasyAbp.EShop.Plugins.FlashSales.Installer.csproj", "{BE39FD00-745B-4049-8161-FC129817CBE4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Orders.Plugins.FlashSales.Application", "src\EasyAbp.EShop.Orders.Plugins.FlashSales.Application\EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj", "{AC7079C6-FEFE-4277-844B-2C9B8C21432D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application", "src\EasyAbp.EShop.Products.Plugins.FlashSales.Application\EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj", "{5711E14D-ADF0-4BAB-BDDB-28A663A07442}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -117,6 +121,14 @@ Global {BE39FD00-745B-4049-8161-FC129817CBE4}.Debug|Any CPU.Build.0 = Debug|Any CPU {BE39FD00-745B-4049-8161-FC129817CBE4}.Release|Any CPU.ActiveCfg = Release|Any CPU {BE39FD00-745B-4049-8161-FC129817CBE4}.Release|Any CPU.Build.0 = Release|Any CPU + {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Release|Any CPU.Build.0 = Release|Any CPU + {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -139,6 +151,8 @@ Global {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB} = {E400416D-2895-4512-9D17-90681EEC7E0A} {BE39FD00-745B-4049-8161-FC129817CBE4} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {AC7079C6-FEFE-4277-844B-2C9B8C21432D} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} + {5711E14D-ADF0-4BAB-BDDB-28A663A07442} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs index 2deefa73..2e524250 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs @@ -41,9 +41,6 @@ public class CreateFlashSalesOrderEventHandler : IDistributedEventHandler(MemberList.Source) - .ForSourceMember(x => x.TenantId, opt => opt.DoNotValidate()) + CreateMap(MemberList.Destination) + .Ignore(dto => dto.Sold) + .Ignore(dto => dto.MinimumPrice) + .Ignore(dto => dto.MaximumPrice) .MapExtraProperties(); - CreateMap(MemberList.Source) - .ForMember(x => x.AttributeOptionIds, opt => opt.Ignore()) - .AfterMap((src, dest) => dest.AttributeOptionIds = jsonSerializer.Deserialize>(src.SerializedAttributeOptionIds)) + CreateMap(MemberList.Destination) + .ForSourceMember(entity => entity.SerializedAttributeOptionIds, opt => opt.DoNotValidate()) + .Ignore(dto => dto.DiscountedPrice) + .Ignore(dto => dto.Inventory) + .Ignore(dto => dto.Sold) .MapExtraProperties(); - CreateMap(MemberList.Source) + CreateMap(MemberList.Destination) .MapExtraProperties(); - CreateMap(MemberList.Source) + CreateMap(MemberList.Destination) .MapExtraProperties(); - CreateMap(MemberList.Source) + CreateMap(MemberList.Destination) .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs similarity index 61% rename from plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs index a0ecf1f7..75ba925b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs @@ -1,12 +1,12 @@ -using EasyAbp.EShop.Orders; -using EasyAbp.EShop.Orders.Orders; +using EasyAbp.EShop.Orders.Orders; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.EShop.Products; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; -namespace EasyAbp.EShop.Plugins.FlashSales; +namespace EasyAbp.EShop.Orders.Plugins.FlashSales; [DependsOn( typeof(EShopOrdersApplicationModule), @@ -22,16 +22,10 @@ public class EShopOrdersPluginsFlashSalesApplicationModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.AddAutoMapperObjectMapper(); + context.Services.AddAutoMapperObjectMapper(); Configure(options => { - options.Configurators.Add(abpAutoMapperConfigurationContext => - { - var profile = abpAutoMapperConfigurationContext.ServiceProvider - .GetRequiredService(); - - abpAutoMapperConfigurationContext.MapperConfiguration.AddProfile(profile); - }); + options.AddMaps(validate: true); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs index 868f0657..36db2173 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs @@ -7,6 +7,8 @@ namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; [Serializable] public class FlashSalesPlanUpdateDto : ExtensibleEntityDto, IHasConcurrencyStamp { + public Guid StoreId { get; set; } + public DateTime BeginTime { get; set; } public DateTime EndTime { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs index 260175c9..c88bd54a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs @@ -7,6 +7,7 @@ using Volo.Abp.Caching; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Plugins.FlashSales; + [DependsOn( typeof(EShopProductsApplicationContractsModule), typeof(EShopPluginsFlashSalesDomainModule), @@ -23,14 +24,7 @@ public class EShopPluginsFlashSalesApplicationModule : AbpModule context.Services.AddAutoMapperObjectMapper(); Configure(options => { - options.Configurators.Add(abpAutoMapperConfigurationContext => - { - var profile = abpAutoMapperConfigurationContext.ServiceProvider - .GetRequiredService(); - - abpAutoMapperConfigurationContext.MapperConfiguration.AddProfile(profile); - }); + options.AddMaps(validate: true); }); - } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs index a5bf39b1..8e597523 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs @@ -1,48 +1,28 @@ -using System.Linq; using AutoMapper; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; -using EasyAbp.EShop.Products.ProductDetails.Dtos; -using EasyAbp.EShop.Products.Products.Dtos; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Json; namespace EasyAbp.EShop.Plugins.FlashSales; -public class FlashSalesApplicationAutoMapperProfile : Profile, ISingletonDependency +public class FlashSalesApplicationAutoMapperProfile : Profile { - public FlashSalesApplicationAutoMapperProfile(IJsonSerializer jsonSerializer) + public FlashSalesApplicationAutoMapperProfile() { /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ CreateMap() .MapExtraProperties(); - CreateMap() - .ForMember(x => x.TenantId, opt => opt.Ignore()) - .MapExtraProperties(); CreateMap(MemberList.Source); CreateMap(MemberList.Source); CreateMap() .MapExtraProperties(); - - CreateMap() + CreateMap() .MapExtraProperties(); - CreateMap() - .ForMember(x => x.TenantId, opt => opt.Ignore()) - .MapExtraProperties(); - CreateMap() - .ForMember(x => x.SerializedAttributeOptionIds, opt => opt.Ignore()) - .AfterMap((src, dest) => dest.SerializedAttributeOptionIds = jsonSerializer.Serialize(src.AttributeOptionIds.OrderBy(x => x))) - .MapExtraProperties(); - CreateMap() - .MapExtraProperties(); - CreateMap() - .MapExtraProperties(); - CreateMap() + CreateMap() .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs index 67e8ddeb..72794d3b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -1,16 +1,13 @@ using System; using System.Linq; -using System.Numerics; -using System.Security.Cryptography; -using System.Text; using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using EasyAbp.EShop.Products.ProductDetails; -using EasyAbp.EShop.Products.ProductDetails.Dtos; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; +using EasyAbp.EShop.Stores.Authorization; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Caching.Distributed; using Volo.Abp; @@ -22,7 +19,6 @@ using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Users; -using static EasyAbp.EShop.Products.Permissions.ProductsPermissions; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; @@ -38,15 +34,25 @@ public class FlashSalesPlanAppService : protected override string DeletePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Delete; protected IFlashSalesPlanRepository FlashSalesPlanRepository { get; } + protected IProductAppService ProductAppService { get; } + protected IProductDetailAppService ProductDetailAppService { get; } + protected IDistributedCache TokenDistributedCache { get; } + protected IDistributedCache DistributedCache { get; } + protected IDistributedEventBus DistributedEventBus { get; } + protected FlashSalesPlanManager FlashSalesPlanManager { get; } + protected IFlashSalesResultRepository FlashSalesResultRepository { get; } + protected IAbpDistributedLock DistributedLock { get; } + protected IFlashSalesPlanHasher FlashSalesPlanHasher { get; } + public FlashSalesPlanAppService( IFlashSalesPlanRepository flashSalesPlanRepository, IProductAppService productAppService, @@ -56,7 +62,8 @@ public class FlashSalesPlanAppService : IDistributedEventBus distributedEventBus, FlashSalesPlanManager flashSalesPlanManager, IFlashSalesResultRepository flashSalesResultRepository, - IAbpDistributedLock distributedLock) + IAbpDistributedLock distributedLock, + IFlashSalesPlanHasher flashSalesPlanHasher) : base(flashSalesPlanRepository) { FlashSalesPlanRepository = flashSalesPlanRepository; @@ -68,6 +75,7 @@ public class FlashSalesPlanAppService : FlashSalesPlanManager = flashSalesPlanManager; FlashSalesResultRepository = flashSalesResultRepository; DistributedLock = distributedLock; + FlashSalesPlanHasher = flashSalesPlanHasher; } public override async Task GetAsync(Guid id) @@ -86,7 +94,7 @@ public class FlashSalesPlanAppService : public override async Task CreateAsync(FlashSalesPlanCreateDto input) { - await CheckCreatePolicyAsync(); + await AuthorizationService.CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); var flashSalesPlan = await FlashSalesPlanManager.CreateAsync( input.StoreId, @@ -104,7 +112,7 @@ public class FlashSalesPlanAppService : public override async Task UpdateAsync(Guid id, FlashSalesPlanUpdateDto input) { - await CheckUpdatePolicyAsync(); + await AuthorizationService.CheckMultiStorePolicyAsync(input.StoreId, UpdatePolicyName); var flashSalesPlan = await GetEntityByIdAsync(id); @@ -124,6 +132,15 @@ public class FlashSalesPlanAppService : return await MapToGetOutputDtoAsync(flashSalesPlan); } + public override async Task DeleteAsync(Guid id) + { + var flashSalesPlan = await GetEntityByIdAsync(id); + + await AuthorizationService.CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, DeletePolicyName); + + await FlashSalesPlanRepository.DeleteAsync(flashSalesPlan); + } + protected override async Task> CreateFilteredQueryAsync(FlashSalesPlanGetListInput input) { if (!input.OnlyShowPublished) @@ -212,58 +229,44 @@ public class FlashSalesPlanAppService : throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); } - var product = await ProductAppService.GetAsync(plan.ProductId); - var productSku = product.GetSkuById(plan.ProductSkuId); - - if (!await ComparekHashTokenAsync(cacheHashToken, plan, product, productSku)) - { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); - } - await RemoveCacheHashTokenAsync(plan); var userId = CurrentUser.GetId(); var result = await CreatePendingFlashSalesResultAsync(plan, userId); - var CreateFlashSalesOrderEto = await PrepareCreateFlashSalesOrderEtoAsync(plan, product, productSku, result, input, userId, now); + var flashSalesReduceInventoryEto = await PrepareFlashSalesReduceInventoryEtoAsync(plan, result.Id, input, userId, now, cacheHashToken); - await DistributedEventBus.PublishAsync(CreateFlashSalesOrderEto); + /* + * FlashSalesReduceInventoryEto(success) -> CreateFlashSalesOrderEto -> CreateFlashSalesOrderCompleteEto + * FlashSalesReduceInventoryEto(failed) -> CreateFlashSalesOrderCompleteEto + */ + await DistributedEventBus.PublishAsync(flashSalesReduceInventoryEto); } - protected virtual async Task PrepareCreateFlashSalesOrderEtoAsync( - FlashSalesPlanDto plan, - ProductDto product, - ProductSkuDto productSku, - FlashSalesResult result, + protected virtual Task PrepareFlashSalesReduceInventoryEtoAsync( + FlashSalesPlanCacheItem plan, + Guid resultId, CreateOrderInput input, Guid userId, - DateTime now) + DateTime now, + string hashToken) { - FlashSalesProductDetailEto productDetail = null; - var productDetailId = productSku.ProductDetailId ?? product.ProductDetailId; - if (productDetailId.HasValue) - { - productDetail = ObjectMapper.Map(await ProductDetailAppService.GetAsync(productDetailId.Value)); - } - var productEto = ObjectMapper.Map(product); - productEto.TenantId = CurrentTenant.Id; - var planEto = ObjectMapper.Map(plan); + var planEto = ObjectMapper.Map(plan); planEto.TenantId = CurrentTenant.Id; - var eto = new CreateFlashSalesOrderEto() + var eto = new FlashSalesReduceInventoryEto() { TenantId = CurrentTenant.Id, PlanId = plan.Id, UserId = userId, - PendingResultId = result.Id, + PendingResultId = resultId, StoreId = plan.StoreId, CreateTime = now, CustomerRemark = input.CustomerRemark, Quantity = 1,//should configure - Product = productEto, - ProductDetail = productDetail, - Plan = planEto + Plan = planEto, + HashToken = hashToken }; foreach (var item in input.ExtraProperties) @@ -271,7 +274,7 @@ public class FlashSalesPlanAppService : eto.ExtraProperties.Add(item.Key, item.Value); } - return eto; + return Task.FromResult(eto); } protected virtual async Task GetFlashSalesPlanCacheAsync(Guid id) @@ -283,54 +286,44 @@ public class FlashSalesPlanAppService : }); } - protected virtual Task GetCacheKeyAsync(FlashSalesPlanDto plan) + protected virtual Task GetCacheKeyAsync(FlashSalesPlanCacheItem plan) { return Task.FromResult($"eshopflashsales_{CurrentUser.Id}_{plan.ProductSkuId}"); } - protected virtual async Task GetCacheHashTokenAsync(FlashSalesPlanDto plan) + protected virtual async Task GetCacheHashTokenAsync(FlashSalesPlanCacheItem plan) { return await TokenDistributedCache.GetStringAsync(await GetCacheKeyAsync(plan)); } - protected virtual async Task RemoveCacheHashTokenAsync(FlashSalesPlanDto plan) + protected virtual async Task RemoveCacheHashTokenAsync(FlashSalesPlanCacheItem plan) { await TokenDistributedCache.RemoveAsync(await GetCacheKeyAsync(plan)); } - protected virtual async Task SetCacheHashTokenAsync(FlashSalesPlanDto plan, ProductDto product, ProductSkuDto productSku) + protected virtual async Task SetCacheHashTokenAsync(FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { - await TokenDistributedCache.SetStringAsync(await GetCacheKeyAsync(plan), await GetHashTokenAsync(plan, product, productSku), new DistributedCacheEntryOptions() + var hashToken = await FlashSalesPlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + + await TokenDistributedCache.SetStringAsync(await GetCacheKeyAsync(plan), hashToken, new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(3) }); } - protected virtual Task GetHashTokenAsync(FlashSalesPlanDto plan, ProductDto product, ProductSkuDto productSku) - { - using var md5 = MD5.Create(); - var inputBytes = Encoding.UTF8.GetBytes($"{plan.LastModificationTime}|{product.LastModificationTime}|{productSku.LastModificationTime}"); - var sb = new StringBuilder(); - foreach (var t in md5.ComputeHash(inputBytes)) - { - sb.Append(t.ToString("X2")); - } - return Task.FromResult(sb.ToString()); - } - - protected virtual async Task ComparekHashTokenAsync(string cacheHashToken, FlashSalesPlanDto plan, ProductDto product, ProductSkuDto productSku) + protected virtual async Task ComparekHashTokenAsync(string cacheHashToken, FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (cacheHashToken.IsNullOrWhiteSpace()) { return false; } - var hashToken = await GetHashTokenAsync(plan, product, productSku); + var hashToken = await FlashSalesPlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); return cacheHashToken == hashToken; } - protected virtual async Task CreatePendingFlashSalesResultAsync(FlashSalesPlanDto plan, Guid userId) + protected virtual async Task CreatePendingFlashSalesResultAsync(FlashSalesPlanCacheItem plan, Guid userId) { var lockKey = $"create-flash-sales-order-{plan.Id}-{userId}"; @@ -342,7 +335,9 @@ public class FlashSalesPlanAppService : } // Prevent repeat submit - if (await FlashSalesResultRepository.AnyAsync(x => x.PlanId == plan.Id && x.UserId == userId)) + if (await FlashSalesResultRepository.AnyAsync(x => + x.PlanId == plan.Id && x.UserId == userId && (x.Status == FlashSalesResultStatus.Successful || x.Status == FlashSalesResultStatus.Pending)) + ) { throw new BusinessException(FlashSalesErrorCodes.AlreadySubmitCreateFlashSalesOrder); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs index 7bc37dd3..94434dbd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs @@ -1,16 +1,21 @@ using System; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.EventBus; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -public class FlashSalesPlanCacheInvalidator : ILocalEventHandler> +public class FlashSalesPlanCacheInvalidator : ILocalEventHandler>, ITransientDependency { protected IDistributedCache DistributedCache { get; } + public FlashSalesPlanCacheInvalidator(IDistributedCache distributedCache) + { + DistributedCache = distributedCache; + } + public virtual async Task HandleEventAsync(EntityChangedEventData eventData) { await DistributedCache.RemoveAsync(eventData.Entity.Id); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs index f28bee5e..c6ea6537 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs @@ -6,4 +6,5 @@ namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; [Serializable] public class FlashSalesPlanCacheItem : FlashSalesPlanDto { + public Guid? TenantId { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs index 5c6942b5..6427320b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs @@ -1,5 +1,4 @@ using System; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs index 23450eca..06cc6fdd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs @@ -4,6 +4,7 @@ using Volo.Abp.ObjectExtending; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +[Serializable] public class FlashSalesPlanEto : FullAuditedEntityEto, IMultiTenant { public Guid? TenantId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanHasher.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanHasher.cs new file mode 100644 index 00000000..069689c4 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanHasher.cs @@ -0,0 +1,31 @@ +using System; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class FlashSalesPlanHasher : IFlashSalesPlanHasher, ITransientDependency +{ + public virtual Task HashAsync(DateTime? planLastModificationTime, DateTime? productLastModificationTime, DateTime? productSkuLastModificationTime) + { + var input = $"{planLastModificationTime}|{productLastModificationTime}|{productSkuLastModificationTime}"; + + return Task.FromResult(CreateMd5(input)); + } + + private static string CreateMd5(string input) + { + using var md5 = MD5.Create(); + + var inputBytes = Encoding.UTF8.GetBytes(input); + + var sb = new StringBuilder(); + foreach (var t in md5.ComputeHash(inputBytes)) + { + sb.Append(t.ToString("X2")); + } + return sb.ToString(); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs index c26be79e..d68e06af 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs @@ -4,6 +4,7 @@ using EasyAbp.EShop.Products.Products; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +[Serializable] public class FlashSalesProductAttributeEto : FullAuditedEntityEto, IProductAttribute { public string DisplayName { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs index 3e613049..67116407 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs @@ -3,6 +3,7 @@ using EasyAbp.EShop.Products.Products; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +[Serializable] public class FlashSalesProductAttributeOptionEto : FullAuditedEntityEto, IProductAttributeOption { public string DisplayName { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs index 7a0a4a99..57922d52 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs @@ -5,6 +5,7 @@ using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +[Serializable] public class FlashSalesProductEto : FullAuditedEntityEto, IProduct, IMultiTenant { public Guid? TenantId { get; set; } @@ -13,6 +14,8 @@ public class FlashSalesProductEto : FullAuditedEntityEto, IProduct, IMulti public string ProductGroupName { get; set; } + public string ProductGroupDisplayName { get; set; } + public Guid? ProductDetailId { get; set; } public string UniqueName { get; set; } @@ -33,6 +36,8 @@ public class FlashSalesProductEto : FullAuditedEntityEto, IProduct, IMulti public bool IsHidden { get; set; } + public TimeSpan? PaymentExpireIn { get; set; } + public List ProductAttributes { get; set; } public List ProductSkus { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs index 09abe06c..3df32c9b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs @@ -1,10 +1,14 @@ using System; +using System.Collections.Generic; using EasyAbp.EShop.Products.Products; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +[Serializable] public class FlashSalesProductSkuEto : FullAuditedEntityEto, IProductSku { + public List AttributeOptionIds { get; set; } + public string SerializedAttributeOptionIds { get; set; } public string Name { get; set; } @@ -19,6 +23,8 @@ public class FlashSalesProductSkuEto : FullAuditedEntityEto, IProductSku public int OrderMaxQuantity { get; set; } + public TimeSpan? PaymentExpireIn { get; set; } + public string MediaResources { get; set; } public Guid? ProductDetailId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesReduceInventoryEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesReduceInventoryEto.cs new file mode 100644 index 00000000..4286811c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesReduceInventoryEto.cs @@ -0,0 +1,29 @@ +using System; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectExtending; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +[Serializable] +public class FlashSalesReduceInventoryEto : ExtensibleObject, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid StoreId { get; set; } + + public Guid PlanId { get; set; } + + public Guid UserId { get; set; } + + public Guid PendingResultId { get; set; } + + public DateTime CreateTime { get; set; } + + public string CustomerRemark { get; set; } + + public int Quantity { get; set; } + + public FlashSalesPlanEto Plan { get; set; } + + public string HashToken { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanHasher.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanHasher.cs new file mode 100644 index 00000000..153f7b11 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanHasher.cs @@ -0,0 +1,9 @@ +using System; +using System.Threading.Tasks; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public interface IFlashSalesPlanHasher +{ + Task HashAsync(DateTime? planLastModificationTime, DateTime? productLastModificationTime, DateTime? productSkuLastModificationTime); +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs index d9ebef4d..71e05917 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs @@ -1,9 +1,13 @@ using System; +using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -public class FlashSalesProductDetailEto : FullAuditedEntityEto +[Serializable] +public class FlashSalesProductDetailEto : FullAuditedEntityEto, IMultiTenant { + public Guid? TenantId { get; set; } + public Guid? StoreId { get; set; } public string Description { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultFailedReason.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultFailedReason.cs new file mode 100644 index 00000000..76f3d5c7 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultFailedReason.cs @@ -0,0 +1,8 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; + +public static class FlashSalesResultFailedReason +{ + public const string InsufficientInventory = nameof(InsufficientInventory); + + public const string PreOrderExipred = nameof(PreOrderExipred); +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs index 0ce9dd05..826de7aa 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs @@ -20,7 +20,7 @@ public class EShopPluginsFlashSalesDomainModule : AbpModule Configure(options => { - options.AddProfile(validate: true); + options.AddMaps(validate: true); }); Configure(options => diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs index 972d0980..73ca7dfe 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs @@ -8,8 +8,6 @@ namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.Fl public class EditFlashSalesPlanViewModel : IHasConcurrencyStamp { - [DisabledInput] - [ReadOnlyInput] [Display(Name = "FlashSalesPlanStoreId")] public Guid StoreId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj new file mode 100644 index 00000000..308d5504 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj @@ -0,0 +1,15 @@ + + + + + + net6.0 + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs new file mode 100644 index 00000000..2e2636eb --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs @@ -0,0 +1,37 @@ +using System.Linq; +using AutoMapper; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Products.Options; +using EasyAbp.EShop.Products.ProductDetails; +using EasyAbp.EShop.Products.Products; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public class EShopProductsPluginsFlashSalesApplicationAutoMapperProfile : Profile, ISingletonDependency +{ + public EShopProductsPluginsFlashSalesApplicationAutoMapperProfile( + IAttributeOptionIdsSerializer attributeOptionIdsSerializer, + IOptionsMonitor options) + { + CreateMap() + .ForMember(x => x.ProductGroupDisplayName, opt => opt.Ignore()) + .AfterMap((src, dest) => + { + var dict = options.CurrentValue.Groups.GetConfigurationsDictionary(); + dest.ProductGroupDisplayName = dict[src.ProductGroupName].DisplayName; + }) + .MapExtraProperties(); + CreateMap() + .ForMember(x => x.AttributeOptionIds, opt => opt.Ignore()) + .AfterMap(async (src, dest) => dest.AttributeOptionIds = (await attributeOptionIdsSerializer.DeserializeAsync(src.SerializedAttributeOptionIds)).ToList()) + .MapExtraProperties(); + CreateMap() + .MapExtraProperties(); + CreateMap() + .MapExtraProperties(); + CreateMap() + .MapExtraProperties(); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs new file mode 100644 index 00000000..a1a599dc --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs @@ -0,0 +1,28 @@ +using EasyAbp.EShop.Plugins.FlashSales; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Products.Plugins.FlashSales; + +[DependsOn( + typeof(EShopProductsApplicationModule), + typeof(EShopPluginsFlashSalesApplicationContractsModule) +)] +public class EShopProductsPluginsFlashSalesApplicationModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAutoMapperObjectMapper(); + Configure(options => + { + options.Configurators.Add(abpAutoMapperConfigurationContext => + { + var profile = abpAutoMapperConfigurationContext.ServiceProvider + .GetRequiredService(); + + abpAutoMapperConfigurationContext.MapperConfiguration.AddProfile(profile); + }); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSalesReduceInventoryEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSalesReduceInventoryEventHandler.cs new file mode 100644 index 00000000..d5a0375b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSalesReduceInventoryEventHandler.cs @@ -0,0 +1,113 @@ +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Products.ProductDetails; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Products.Products; + +public class FlashSalesReduceInventoryEventHandler : IDistributedEventHandler, ITransientDependency +{ + protected IProductRepository ProductRepository { get; } + + protected IProductDetailRepository ProductDetailRepository { get; } + + protected ProductManager ProductManager { get; } + + protected IDistributedEventBus DistributedEventBus { get; } + + protected IObjectMapper ObjectMapper { get; } + + protected IFlashSalesPlanHasher FlashSalesPlanHasher { get; } + + public FlashSalesReduceInventoryEventHandler( + IProductRepository productRepository, + IProductDetailRepository productDetailRepository, + ProductManager productManager, + IDistributedEventBus distributedEventBus, + IObjectMapper objectMapper, + IFlashSalesPlanHasher flashSalesPlanHasher) + { + ProductRepository = productRepository; + ProductDetailRepository = productDetailRepository; + ProductManager = productManager; + DistributedEventBus = distributedEventBus; + ObjectMapper = objectMapper; + FlashSalesPlanHasher = flashSalesPlanHasher; + } + + [UnitOfWork] + public virtual async Task HandleEventAsync(FlashSalesReduceInventoryEto eventData) + { + var product = await ProductRepository.GetAsync(eventData.Plan.ProductId); + var productSku = product.ProductSkus.Single(x => x.Id == eventData.Plan.ProductSkuId); + + var hashToken = await FlashSalesPlanHasher.HashAsync(eventData.Plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + + if (hashToken != eventData.HashToken) + { + await DistributedEventBus.PublishAsync(new CreateFlashSalesOrderCompleteEto() + { + TenantId = eventData.TenantId, + PlanId = eventData.PlanId, + OrderId = null, + UserId = eventData.UserId, + StoreId = eventData.StoreId, + PendingResultId = eventData.PendingResultId, + Success = false, + Reason = FlashSalesResultFailedReason.PreOrderExipred + }); + return; + } + + if (!await ProductManager.TryReduceInventoryAsync(product, productSku, eventData.Quantity, true)) + { + await DistributedEventBus.PublishAsync(new CreateFlashSalesOrderCompleteEto() + { + TenantId = eventData.TenantId, + PlanId = eventData.PlanId, + OrderId = null, + UserId = eventData.UserId, + StoreId = eventData.StoreId, + PendingResultId = eventData.PendingResultId, + Success = false, + Reason = FlashSalesResultFailedReason.InsufficientInventory + }); + return; + } + + var productDetailId = productSku.ProductDetailId ?? product.ProductDetailId; + + var productDetailEto = productDetailId.HasValue ? + ObjectMapper.Map(await ProductDetailRepository.GetAsync(productDetailId.Value)) : + null; + + var productEto = ObjectMapper.Map(product); + + var createFlashSalesOrderEto = new CreateFlashSalesOrderEto() + { + TenantId = eventData.TenantId, + PlanId = eventData.PlanId, + UserId = eventData.UserId, + PendingResultId = eventData.PendingResultId, + StoreId = eventData.StoreId, + CreateTime = eventData.CreateTime, + CustomerRemark = eventData.CustomerRemark, + Quantity = eventData.Quantity, + Product = productEto, + ProductDetail = productDetailEto, + Plan = eventData.Plan + }; + + foreach (var item in eventData.ExtraProperties) + { + createFlashSalesOrderEto.ExtraProperties.Add(item.Key, item.Value); + } + + await DistributedEventBus.PublishAsync(createFlashSalesOrderEto); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml new file mode 100644 index 00000000..00e1d9a1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xsd new file mode 100644 index 00000000..3f3946e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj index c106fcf0..c2fe33cb 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj @@ -14,6 +14,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs index 6ff2e91d..6e580e6f 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs @@ -1,8 +1,10 @@ using EasyAbp.EShop; using EasyAbp.EShop.Orders.Plugins.Coupons; +using EasyAbp.EShop.Orders.Plugins.FlashSales; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; using EasyAbp.EShop.Plugins.FlashSales; +using EasyAbp.EShop.Products.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -30,6 +32,7 @@ namespace EShopSample typeof(EShopOrdersPluginsCouponsModule), typeof(EShopPluginsFlashSalesApplicationModule), typeof(EShopOrdersPluginsFlashSalesApplicationModule), + typeof(EShopProductsPluginsFlashSalesApplicationModule), typeof(PaymentServiceApplicationModule), typeof(PaymentServiceWeChatPayApplicationModule), typeof(PaymentServicePrepaymentApplicationModule) From f805c3b1773c0dd619c0ead967a9cf5ed4496049 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 2 Jul 2022 16:04:23 +0800 Subject: [PATCH 07/97] Improve FlashSales --- ...hSalesOrderCreationAuthorizationHandler.cs | 23 ++++-- .../Dtos/FlashSalesPlanCreateDto.cs | 17 +---- .../FlashSalesPlanCreateOrUpdateDtoBase.cs | 20 ++++++ .../Dtos/FlashSalesPlanUpdateDto.cs | 15 +--- .../FlashSalesPlanAppService.cs | 65 ++++++++++++----- .../ProductIsNotInThisStoreException.cs | 13 ++++ .../ProductSkuIsNotFoundException.cs | 12 ++++ .../FlashSales/FlashSalesErrorCodes.cs | 10 ++- .../FlashSalesResultStatus.cs | 12 ++-- .../Plugins/FlashSales/Localization/en.json | 34 ++++++--- .../FlashSales/Localization/zh-Hans.json | 22 +++++- .../FlashSales/Localization/zh-Hant.json | 72 ++++++++++++------- ...ndTimeMustBeLaterThanBeginTimeException.cs | 2 +- .../FlashSalesPlans/FlashSalesPlan.cs | 6 +- .../FlashSalesPlans/FlashSalesPlanManager.cs | 44 ------------ .../FlashSalesPlans/FlashSalesPlan/index.js | 6 +- .../ViewFlashSalesResultViewModel.cs | 13 ++-- .../FlashSalesResult/index.js | 13 +++- 18 files changed, 243 insertions(+), 156 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductIsNotInThisStoreException.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductSkuIsNotFoundException.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs index 16750493..3723c4d6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs @@ -1,7 +1,9 @@ using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Localization; using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Localization; using Volo.Abp.DependencyInjection; namespace EasyAbp.EShop.Orders.Orders; @@ -9,14 +11,28 @@ namespace EasyAbp.EShop.Orders.Orders; public class FlashSalesOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler { protected IAbpLazyServiceProvider LazyServiceProvider { get; } + protected IStringLocalizer Localizer { get; } - public FlashSalesOrderCreationAuthorizationHandler(IAbpLazyServiceProvider lazyServiceProvider) + public FlashSalesOrderCreationAuthorizationHandler( + IAbpLazyServiceProvider lazyServiceProvider, + IStringLocalizer localizer) { LazyServiceProvider = lazyServiceProvider; + Localizer = localizer; } protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context, OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource) + { + if (await IsFlashSalesPlanProductSkuAsync(resource)) + { + context.Fail(new AuthorizationFailureReason(this, Localizer["ExistFlashSalesPlanProduct"])); + } + + context.Succeed(requirement); + } + + protected virtual async Task IsFlashSalesPlanProductSkuAsync(OrderCreationResource resource) { var flashSalesPlanAppService = LazyServiceProvider.LazyGetRequiredService(); foreach (var orderLine in resource.Input.OrderLines) @@ -30,11 +46,10 @@ public class FlashSalesOrderCreationAuthorizationHandler : OrderCreationAuthoriz }); if (plans.Items.Count > 0) { - context.Fail(); - return; + return true; } } - context.Succeed(requirement); + return false; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs index c3be88e7..45c740bc 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs @@ -1,21 +1,8 @@ using System; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Domain.Entities; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; [Serializable] -public class FlashSalesPlanCreateDto : ExtensibleEntityDto +public class FlashSalesPlanCreateDto : FlashSalesPlanCreateOrUpdateDtoBase { - public Guid StoreId { get; set; } - - public DateTime BeginTime { get; set; } - - public DateTime EndTime { get; set; } - - public Guid ProductId { get; set; } - - public Guid ProductSkuId { get; set; } - - public bool IsPublished { get; set; } -} \ No newline at end of file +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs new file mode 100644 index 00000000..85403c03 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs @@ -0,0 +1,20 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; + +[Serializable] +public abstract class FlashSalesPlanCreateOrUpdateDtoBase : ExtensibleEntityDto +{ + public Guid StoreId { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime EndTime { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public bool IsPublished { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs index 36db2173..4a02dfa7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs @@ -1,23 +1,10 @@ using System; -using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Entities; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; [Serializable] -public class FlashSalesPlanUpdateDto : ExtensibleEntityDto, IHasConcurrencyStamp +public class FlashSalesPlanUpdateDto : FlashSalesPlanCreateOrUpdateDtoBase, IHasConcurrencyStamp { - public Guid StoreId { get; set; } - - public DateTime BeginTime { get; set; } - - public DateTime EndTime { get; set; } - - public Guid ProductId { get; set; } - - public Guid ProductSkuId { get; set; } - - public bool IsPublished { get; set; } - public string ConcurrencyStamp { get; set; } } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs index 72794d3b..db951ed3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -45,8 +45,6 @@ public class FlashSalesPlanAppService : protected IDistributedEventBus DistributedEventBus { get; } - protected FlashSalesPlanManager FlashSalesPlanManager { get; } - protected IFlashSalesResultRepository FlashSalesResultRepository { get; } protected IAbpDistributedLock DistributedLock { get; } @@ -60,7 +58,6 @@ public class FlashSalesPlanAppService : IDistributedCache tokenDistributedCache, IDistributedCache distributedCache, IDistributedEventBus distributedEventBus, - FlashSalesPlanManager flashSalesPlanManager, IFlashSalesResultRepository flashSalesResultRepository, IAbpDistributedLock distributedLock, IFlashSalesPlanHasher flashSalesPlanHasher) @@ -72,7 +69,6 @@ public class FlashSalesPlanAppService : TokenDistributedCache = tokenDistributedCache; DistributedCache = distributedCache; DistributedEventBus = distributedEventBus; - FlashSalesPlanManager = flashSalesPlanManager; FlashSalesResultRepository = flashSalesResultRepository; DistributedLock = distributedLock; FlashSalesPlanHasher = flashSalesPlanHasher; @@ -96,7 +92,22 @@ public class FlashSalesPlanAppService : { await AuthorizationService.CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); - var flashSalesPlan = await FlashSalesPlanManager.CreateAsync( + var product = await ProductAppService.GetAsync(input.ProductId); + var productSku = product.FindSkuById(input.ProductSkuId); + + if (product.StoreId != input.StoreId) + { + throw new ProductIsNotInThisStoreException(input.ProductId, input.StoreId); + } + + if (productSku == null) + { + throw new ProductSkuIsNotFoundException(input.ProductSkuId); + } + + var flashSalesPlan = new FlashSalesPlan( + GuidGenerator.Create(), + CurrentTenant.Id, input.StoreId, input.BeginTime, input.EndTime, @@ -114,16 +125,24 @@ public class FlashSalesPlanAppService : { await AuthorizationService.CheckMultiStorePolicyAsync(input.StoreId, UpdatePolicyName); + var product = await ProductAppService.GetAsync(input.ProductId); + var productSku = product.FindSkuById(input.ProductSkuId); + + if (product.StoreId != input.StoreId) + { + throw new ProductIsNotInThisStoreException(input.ProductId, input.StoreId); + } + + if (productSku == null) + { + throw new ProductSkuIsNotFoundException(input.ProductSkuId); + } + var flashSalesPlan = await GetEntityByIdAsync(id); - await FlashSalesPlanManager.UpdateAsync( - flashSalesPlan, - input.BeginTime, - input.EndTime, - input.ProductId, - input.ProductSkuId, - input.IsPublished - ); + flashSalesPlan.SetTimeRange(input.BeginTime, input.EndTime); + flashSalesPlan.SetProductSku(input.StoreId, input.ProductId, input.ProductSkuId); + flashSalesPlan.SetPublished(input.IsPublished); flashSalesPlan.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); @@ -170,7 +189,7 @@ public class FlashSalesPlanAppService : if (product.InventoryStrategy != InventoryStrategy.FlashSales) { - throw new BusinessException(FlashSalesErrorCodes.IsNotFlashSalesProduct); + throw new BusinessException(FlashSalesErrorCodes.ProductInventoryStrategyIsNotFlashSales); } if (!plan.IsPublished) @@ -183,6 +202,11 @@ public class FlashSalesPlanAppService : throw new BusinessException(FlashSalesErrorCodes.FlashSalesPlanIsExpired); } + if (productSku.Inventory < 1) + { + throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); + } + await SetCacheHashTokenAsync(plan, product, productSku); } @@ -197,15 +221,20 @@ public class FlashSalesPlanAppService : var cacheHashToken = await GetCacheHashTokenAsync(plan); if (cacheHashToken.IsNullOrWhiteSpace()) { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); + throw new BusinessException(FlashSalesErrorCodes.PreOrderExpried); } var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); + if (productSku.Inventory < 1) + { + throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); + } + if (!await ComparekHashTokenAsync(cacheHashToken, plan, product, productSku)) { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); + throw new BusinessException(FlashSalesErrorCodes.PreOrderExpried); } } @@ -226,7 +255,7 @@ public class FlashSalesPlanAppService : var cacheHashToken = await GetCacheHashTokenAsync(plan); if (cacheHashToken.IsNullOrWhiteSpace()) { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExipred); + throw new BusinessException(FlashSalesErrorCodes.PreOrderExpried); } await RemoveCacheHashTokenAsync(plan); @@ -288,7 +317,7 @@ public class FlashSalesPlanAppService : protected virtual Task GetCacheKeyAsync(FlashSalesPlanCacheItem plan) { - return Task.FromResult($"eshopflashsales_{CurrentUser.Id}_{plan.ProductSkuId}"); + return Task.FromResult($"eshopflashsales_{CurrentTenant.Id}_{CurrentUser.Id}_{plan.ProductSkuId}"); } protected virtual async Task GetCacheHashTokenAsync(FlashSalesPlanCacheItem plan) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductIsNotInThisStoreException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductIsNotInThisStoreException.cs new file mode 100644 index 00000000..b6f7e9f9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductIsNotInThisStoreException.cs @@ -0,0 +1,13 @@ +using System; +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class ProductIsNotInThisStoreException : BusinessException +{ + public ProductIsNotInThisStoreException(Guid productId, Guid storeId) : base(FlashSalesErrorCodes.ProductIsNotInThisStore) + { + WithData(nameof(productId), productId); + WithData(nameof(storeId), storeId); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductSkuIsNotFoundException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductSkuIsNotFoundException.cs new file mode 100644 index 00000000..f3679fe6 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductSkuIsNotFoundException.cs @@ -0,0 +1,12 @@ +using System; +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class ProductSkuIsNotFoundException : BusinessException +{ + public ProductSkuIsNotFoundException(Guid productSkuId) : base(FlashSalesErrorCodes.ProductSkuIsNotFound) + { + WithData(nameof(productSkuId), productSkuId); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index 033cd4a7..a445de23 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -6,11 +6,17 @@ public static class FlashSalesErrorCodes public const string EndTimeMustBeLaterThanBeginTime = $"{Namespace}:{nameof(EndTimeMustBeLaterThanBeginTime)}"; + public const string ProductIsNotInThisStore = $"{Namespace}:{nameof(ProductIsNotInThisStore)}"; + + public const string ProductSkuIsNotFound = $"{Namespace}:{nameof(ProductSkuIsNotFound)}"; + public const string ProductIsNotPublished = $"{Namespace}:{nameof(ProductIsNotPublished)}"; - public const string IsNotFlashSalesProduct = $"{Namespace}:{nameof(IsNotFlashSalesProduct)}"; + public const string ProductSkuInventoryExceeded = $"{Namespace}:{nameof(ProductSkuInventoryExceeded)}"; + + public const string ProductInventoryStrategyIsNotFlashSales = $"{Namespace}:{nameof(ProductInventoryStrategyIsNotFlashSales)}"; - public const string PreOrderExipred = $"{Namespace}:{nameof(PreOrderExipred)}"; + public const string PreOrderExpried = $"{Namespace}:{nameof(PreOrderExpried)}"; public const string FlashSalesPlanIsNotStart = $"{Namespace}:{nameof(FlashSalesPlanIsNotStart)}"; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs index 3d88d0cc..2f242858 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; public enum FlashSalesResultStatus { - Pending, - Successful, - Failed + Pending = 0, + Successful = 1, + Failed = 2 } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json index f92545a9..7bd649b8 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -2,14 +2,25 @@ "culture": "en", "texts": { "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "End time must be later than start time", - "Menu:FlashSalesManagement": "FlashSalesManagement", - "Permission:FlashSalesPlan": "FlashSalesPlan", + "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotInThisStore": "Product '{productId}' is not in this store '{storeId}'", + "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "ProductSku '{productSkuId}' is not found", + "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "Product is not published", + "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "Product SKU inventory exceeded", + "EasyAbp.EShop.Plugins.FlashSales:ProductInventoryStrategyIsNotFlashSales": "Product inventory strategy is not flash-sales", + "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpried": "Pre order expired", + "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsNotStart": "FlashSales plan is not start", + "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsExpired": "FlashSales plan is expired", + "EasyAbp.EShop.Plugins.FlashSales:CreateFlashSalesOrderBusy": "Create flash-sales order busy", + "EasyAbp.EShop.Plugins.FlashSales:AlreadySubmitCreateFlashSalesOrder": "Already submit create flash-sales order", + "ExistFlashSalesPlanProduct": "Exist unexpected flash-sales plan product", + "Menu:FlashSalesManagement": "FlashSales Management", + "Permission:FlashSalesPlan": "FlashSales Plan", "Permission:Manage": "Manage", "Permission:Create": "Create", "Permission:Update": "Update", "Permission:Delete": "Delete", - "Menu:FlashSalesPlan": "FlashSalesPlan", - "FlashSalesPlan": "FlashSalesPlan", + "Menu:FlashSalesPlan": "FlashSales Plan", + "FlashSalesPlan": "FlashSales Plan", "FlashSalesPlanStoreId": "Store ID", "FlashSalesPlanBeginTime": "Begin Time", "FlashSalesPlanEndTime": "End Time", @@ -20,15 +31,22 @@ "EditFlashSalesPlan": "Edit", "FlashSalesPlanDeletionConfirmationMessage": "Are you sure to delete the flashSalesPlan {0}?", "SuccessfullyDeleted": "Successfully deleted", - "Permission:FlashSalesResult": "FlashSalesResult", - "Menu:FlashSalesResult": "FlashSalesResult", - "FlashSalesResult": "FlashSalesResult", + "Permission:FlashSalesResult": "FlashSales Result", + "Menu:FlashSalesResult": "FlashSales Result", + "FlashSalesResult": "FlashSales Result", "FlashSalesResultStoreId": "Store ID", "FlashSalesResultPlanId": "Plan ID", "FlashSalesResultStatus": "Status", + "FlashSalesResultReason": "Reason", "FlashSalesResultUserId": "User ID", "FlashSalesResultOrderId": "Order ID", "FlashSalesResultCreationTime": "Creation Time", - "ViewFlashSalesPlan": "View" + "ViewFlashSalesResult": "View", + "Enum:FlashSalesResultStatus.Pending": "Pending", + "Enum:FlashSalesResultStatus.Successful": "Successful", + "Enum:FlashSalesResultStatus.Failed": "Failed", + "Enum:FlashSalesResultStatus.0": "Pending", + "Enum:FlashSalesResultStatus.1": "Successful", + "Enum:FlashSalesResultStatus.2": "Failed" } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json index 5061f16b..c13420e7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -2,6 +2,17 @@ "culture": "zh-Hans", "texts": { "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "结束时间必须晚于开始时间", + "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotInThisStore": "产品'{productId}'不在此店铺'{storeId}'中", + "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "产品SKU'{productSkuId}'不存在", + "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "产品尚未发布", + "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "产品SKU库存不足", + "EasyAbp.EShop.Plugins.FlashSales:ProductInventoryStrategyIsNotFlashSales": "产品库存策略不是闪购", + "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpried": "预下单已过期", + "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsNotStart": "闪购计划尚未开始", + "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsExpired": "闪购计划已经结束", + "EasyAbp.EShop.Plugins.FlashSales:CreateFlashSalesOrderBusy": "闪购计划下单繁忙", + "EasyAbp.EShop.Plugins.FlashSales:AlreadySubmitCreateFlashSalesOrder": "已经提交闪购下单", + "ExistFlashSalesPlanProduct": "清單中不允許存在閃購計畫中的產品", "Menu:FlashSalesManagement": "闪购", "Permission:FlashSalesPlan": "闪购计划", "Permission:Manage": "管理", @@ -17,7 +28,7 @@ "FlashSalesPlanProductSkuId": "产品SKU ID", "FlashSalesPlanIsPublished": "发布", "CreateFlashSalesPlan": "新建", - "EditFlashSalesPlan": "编辑", + "EditFlashSalesPlan": "編輯", "FlashSalesPlanDeletionConfirmationMessage": "确认删除闪购计划 {0}?", "SuccessfullyDeleted": "删除成功", "Permission:FlashSalesResult": "闪购结果", @@ -26,9 +37,16 @@ "FlashSalesResultStoreId": "店铺 ID", "FlashSalesResultPlanId": "计划 ID", "FlashSalesResultStatus": "状态", + "FlashSalesResultReason": "原因", "FlashSalesResultUserId": "用户 ID", "FlashSalesResultOrderId": "订单 ID", "FlashSalesResultCreationTime": "创建时间", - "ViewFlashSalesPlan": "查看" + "ViewFlashSalesResult": "查看", + "Enum:FlashSalesResultStatus.Pending": "等待中", + "Enum:FlashSalesResultStatus.Successful": "成功", + "Enum:FlashSalesResultStatus.Failed": "失败", + "Enum:FlashSalesResultStatus.0": "等待中", + "Enum:FlashSalesResultStatus.1": "成功", + "Enum:FlashSalesResultStatus.2": "失败" } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json index 24fd0adc..2311abec 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -2,33 +2,51 @@ "culture": "zh-Hant", "texts": { "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "結束時間必須晚於開始時間", - "Menu:FlashSalesManagement": "FlashSalesManagement", - "Permission:FlashSalesPlan": "FlashSalesPlan", - "Permission:Manage": "Manage", - "Permission:Create": "Create", - "Permission:Update": "Update", - "Permission:Delete": "Delete", - "Menu:FlashSalesPlan": "FlashSalesPlan", - "FlashSalesPlan": "FlashSalesPlan", - "FlashSalesPlanStoreId": "FlashSalesPlanStoreId", - "FlashSalesPlanBeginTime": "FlashSalesPlanBeginTime", - "FlashSalesPlanEndTime": "FlashSalesPlanEndTime", - "FlashSalesPlanProductId": "FlashSalesPlanProductId", - "FlashSalesPlanProductSkuId": "FlashSalesPlanProductSkuId", - "FlashSalesPlanIsPublished": "FlashSalesPlanIsActive", - "CreateFlashSalesPlan": "CreateFlashSalesPlan", - "EditFlashSalesPlan": "EditFlashSalesPlan", - "FlashSalesPlanDeletionConfirmationMessage": "Are you sure to delete the flashSalesPlan {0}?", - "SuccessfullyDeleted": "Successfully deleted", - "Permission:FlashSalesResult": "闪购结果", - "Menu:FlashSalesResult": "闪购计划", - "FlashSalesResult": "闪购结果", + "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotInThisStore": "產品'{productId}'不在此店鋪'{storeId}'中", + "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "產品SKU'{productSkuId}'不存在", + "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "產品尚未發佈", + "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "產品SKU庫存不足", + "EasyAbp.EShop.Plugins.FlashSales:ProductInventoryStrategyIsNotFlashSales": "產品庫存策略不是閃購", + "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpried": "預下單已過期", + "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsNotStart": "閃購計畫尚未開始", + "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsExpired": "閃購計畫已經結束", + "EasyAbp.EShop.Plugins.FlashSales:CreateFlashSalesOrderBusy": "閃購計畫下單繁忙", + "EasyAbp.EShop.Plugins.FlashSales:AlreadySubmitCreateFlashSalesOrder": "已經提交閃購下單", + "ExistFlashSalesPlanProduct": "清单中不允许存在闪购计划中的产品", + "Menu:FlashSalesManagement": "閃購管理", + "Permission:FlashSalesPlan": "閃購計畫", + "Permission:Manage": "管理", + "Permission:Create": "新建", + "Permission:Update": "更新", + "Permission:Delete": "删除", + "Menu:FlashSalesPlan": "閃購計畫", + "FlashSalesPlan": "閃購計畫", + "FlashSalesPlanStoreId": "店鋪ID", + "FlashSalesPlanBeginTime": "開始時間", + "FlashSalesPlanEndTime": "結束時間", + "FlashSalesPlanProductId": "產品ID", + "FlashSalesPlanProductSkuId": "產品SKU ID", + "FlashSalesPlanIsPublished": "發佈", + "CreateFlashSalesPlan": "新建", + "EditFlashSalesPlan": "更新", + "FlashSalesPlanDeletionConfirmationMessage": "確認删除閃購計畫 {0}?", + "SuccessfullyDeleted": "删除成功", + "Permission:FlashSalesResult": "閃購結果", + "Menu:FlashSalesResult": "閃購結果", + "FlashSalesResult": "閃購結果", "FlashSalesResultStoreId": "店铺 ID", - "FlashSalesResultPlanId": "计划 ID", - "FlashSalesResultStatus": "状态", - "FlashSalesResultUserId": "用户 ID", - "FlashSalesResultOrderId": "订单 ID", - "FlashSalesResultCreationTime": "创建时间", - "ViewFlashSalesPlan": "查看" + "FlashSalesResultPlanId": "計畫 ID", + "FlashSalesResultStatus": "狀態", + "FlashSalesResultReason": "原因", + "FlashSalesResultUserId": "用戶 ID", + "FlashSalesResultOrderId": "訂單 ID", + "FlashSalesResultCreationTime": "創建時間", + "ViewFlashSalesResult": "查看", + "Enum:FlashSalesResultStatus.Pending": "等待中", + "Enum:FlashSalesResultStatus.Successful": "成功", + "Enum:FlashSalesResultStatus.Failed": "失敗", + "Enum:FlashSalesResultStatus.0": "等待中", + "Enum:FlashSalesResultStatus.1": "成功", + "Enum:FlashSalesResultStatus.2": "失敗" } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs index 4b9fdad2..7d3b0938 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs @@ -2,7 +2,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -internal class EndTimeMustBeLaterThanBeginTimeException : BusinessException +public class EndTimeMustBeLaterThanBeginTimeException : BusinessException { public EndTimeMustBeLaterThanBeginTimeException() : base(FlashSalesErrorCodes.EndTimeMustBeLaterThanBeginTime) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs index 0de27f9a..e52b4c1d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs @@ -28,9 +28,8 @@ public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant : base(id) { TenantId = tenantId; - StoreId = storeId; SetTimeRange(beginTime, endTime); - SetProduct(productId, productSkuId); + SetProductSku(storeId, productId, productSkuId); SetPublished(isPublished); } @@ -45,8 +44,9 @@ public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant EndTime = endTime; } - public void SetProduct(Guid productId, Guid productSkuId) + public void SetProductSku(Guid storeId, Guid productId, Guid productSkuId) { + StoreId = storeId; ProductId = productId; ProductSkuId = productSkuId; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs deleted file mode 100644 index d8654316..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanManager.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Threading.Tasks; -using Volo.Abp.Domain.Services; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; - -public class FlashSalesPlanManager : DomainService -{ - public virtual Task CreateAsync( - Guid storeId, - DateTime beginTime, - DateTime endTime, - Guid productId, - Guid productSkuId, - bool isActive) - { - var flashSalesPlan = new FlashSalesPlan( - GuidGenerator.Create(), - CurrentTenant.Id, - storeId, - beginTime, - endTime, - productId, - productSkuId, - isActive - ); - return Task.FromResult(flashSalesPlan); - } - - public virtual Task UpdateAsync( - FlashSalesPlan flashSalesPlan, - DateTime beginTime, - DateTime endTime, - Guid productId, - Guid productSkuId, - bool isPublished) - { - flashSalesPlan.SetTimeRange(beginTime, endTime); - flashSalesPlan.SetProduct(productId, productSkuId); - flashSalesPlan.SetPublished(isPublished); - - return Task.FromResult(flashSalesPlan); - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js index 8b4a951e..9845f13f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js @@ -50,11 +50,13 @@ $(function () { }, { title: l('FlashSalesPlanBeginTime'), - data: "beginTime" + data: "beginTime", + dataFormat: 'datetime' }, { title: l('FlashSalesPlanEndTime'), - data: "endTime" + data: "endTime", + dataFormat: 'datetime' }, { title: l('FlashSalesPlanProductId'), diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs index c72ba9f0..02a2267c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs @@ -7,17 +7,20 @@ namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.Fl public class ViewFlashSalesResultViewModel { [Display(Name = "FlashSalesResultStoreId")] - public virtual Guid StoreId { get; protected set; } + public Guid StoreId { get; set; } [Display(Name = "FlashSalesResultPlanId")] - public virtual Guid PlanId { get; protected set; } + public Guid PlanId { get; set; } [Display(Name = "FlashSalesResultStatus")] - public virtual FlashSalesResultStatus Status { get; protected set; } + public FlashSalesResultStatus Status { get; set; } + + [Display(Name = "FlashSalesResultReason")] + public string Reason { get; set; } [Display(Name = "FlashSalesResultUserId")] - public virtual Guid UserId { get; protected set; } + public Guid UserId { get; set; } [Display(Name = "FlashSalesResultOrderId")] - public virtual Guid? OrderId { get; protected set; } + public Guid? OrderId { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js index d29f6825..bd3bc6dd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js @@ -2,7 +2,7 @@ $(function () { var l = abp.localization.getResource('EasyAbpEShopPluginsFlashSales'); - var service = easyAbp.eShop.plugins.flashSales.flashSalesPlans.flashSalesPlan; + var service = easyAbp.eShop.plugins.flashSales.flashSalesResults.flashSalesResult; var viewModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal'); var dataTable = $('#FlashSalesResultTable').DataTable(abp.libs.datatables.normalizeConfiguration({ @@ -20,7 +20,7 @@ $(function () { items: [ { - text: l('ViewFlashSalesPlan'), + text: l('ViewFlashSalesResult'), action: function (data) { viewModal.open({ id: data.record.id }); } @@ -38,7 +38,14 @@ $(function () { }, { title: l('FlashSalesResultStatus'), - data: "status" + data: "status", + render: function (data) { + return l('Enum:FlashSalesResultStatus.' + data); + } + }, + { + title: l('FlashSalesResultReason'), + data: "reason" }, { title: l('FlashSalesResultUserId'), From 010c4c7dca70ae7b9c276ebd745ce64a3ffef14c Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 2 Jul 2022 16:43:31 +0800 Subject: [PATCH 08/97] Upgrade FlashSales to abp 5.3.1 --- .../EasyAbp.EShop.Plugins.FlashSales.Application.csproj | 2 +- .../EasyAbp.EShop.Plugins.FlashSales.Domain.csproj | 2 +- .../EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj | 2 +- .../EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj | 2 +- ...asyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj | 2 +- .../EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj | 2 +- ...Shop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj | 2 +- .../EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj | 2 +- .../EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj | 6 +++--- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj index 3b42dbb7..329ee275 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj @@ -3,7 +3,7 @@ - netstandard2.0 + net6.0 diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj index b8f4224b..15aa2bfd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.csproj @@ -3,7 +3,7 @@ - netstandard2.0 + net6.0 diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj index f9e540c6..918f6179 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj @@ -3,7 +3,7 @@ - netstandard2.0 + netstandard2.1 diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj index b45e6e2e..3900b394 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj @@ -3,7 +3,7 @@ - netstandard2.0 + net6.0 diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj index b2cb1a1b..d9dbd3e1 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj index dc15e834..72a84b4a 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj index 9686e5b8..15633c50 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj index 2ac3301a..97ff3afc 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj index c37c97c0..0c0c660b 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj @@ -6,12 +6,12 @@ - - + + - + From e5b3e36754d6fd72947b17291113e3ab314ff9f6 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 2 Jul 2022 18:16:48 +0800 Subject: [PATCH 09/97] Add `Microsoft.Bcl.AsyncInterfaces` package --- .../EasyAbp.EShop.Plugins.FlashSales.Application.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj index 329ee275..80f4e744 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj @@ -8,6 +8,7 @@ + From d76c1c73d9ba89ff94705631f47a93554e71f205 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 2 Jul 2022 18:17:24 +0800 Subject: [PATCH 10/97] Remove unnecessary services --- .../FlashSalesPlans/FlashSalesPlanAppService.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs index db951ed3..c51f6579 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; using EasyAbp.EShop.Plugins.FlashSales.Permissions; -using EasyAbp.EShop.Products.ProductDetails; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Stores.Authorization; @@ -37,8 +36,6 @@ public class FlashSalesPlanAppService : protected IProductAppService ProductAppService { get; } - protected IProductDetailAppService ProductDetailAppService { get; } - protected IDistributedCache TokenDistributedCache { get; } protected IDistributedCache DistributedCache { get; } @@ -54,7 +51,6 @@ public class FlashSalesPlanAppService : public FlashSalesPlanAppService( IFlashSalesPlanRepository flashSalesPlanRepository, IProductAppService productAppService, - IProductDetailAppService productDetailAppService, IDistributedCache tokenDistributedCache, IDistributedCache distributedCache, IDistributedEventBus distributedEventBus, @@ -65,7 +61,6 @@ public class FlashSalesPlanAppService : { FlashSalesPlanRepository = flashSalesPlanRepository; ProductAppService = productAppService; - ProductDetailAppService = productDetailAppService; TokenDistributedCache = tokenDistributedCache; DistributedCache = distributedCache; DistributedEventBus = distributedEventBus; @@ -232,7 +227,7 @@ public class FlashSalesPlanAppService : throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); } - if (!await ComparekHashTokenAsync(cacheHashToken, plan, product, productSku)) + if (!await CompareHashTokenAsync(cacheHashToken, plan, product, productSku)) { throw new BusinessException(FlashSalesErrorCodes.PreOrderExpried); } @@ -340,7 +335,7 @@ public class FlashSalesPlanAppService : }); } - protected virtual async Task ComparekHashTokenAsync(string cacheHashToken, FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + protected virtual async Task CompareHashTokenAsync(string cacheHashToken, FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (cacheHashToken.IsNullOrWhiteSpace()) { From c74a1b5fe79816a32ba172b547c2a537ac54687c Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 2 Jul 2022 18:17:37 +0800 Subject: [PATCH 11/97] Fix `FlashSalesOrderCreationAuthorizationHandler` --- .../Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs index 3723c4d6..cd7f0044 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs @@ -27,6 +27,7 @@ public class FlashSalesOrderCreationAuthorizationHandler : OrderCreationAuthoriz if (await IsFlashSalesPlanProductSkuAsync(resource)) { context.Fail(new AuthorizationFailureReason(this, Localizer["ExistFlashSalesPlanProduct"])); + return; } context.Succeed(requirement); From b99230e2bf465e20b87ee69e9f5d321147e92f94 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 2 Jul 2022 18:18:03 +0800 Subject: [PATCH 12/97] Cleanup FlashSales --- plugins/FlashSales/.editorconfig | 6 +- plugins/FlashSales/.gitattributes | 1 - plugins/FlashSales/.gitignore | 259 ------------------ plugins/FlashSales/.prettierrc | 5 - ...syAbp.EShop.Plugins.FlashSales.abpmdl.json | 111 -------- ...syAbp.EShop.Plugins.FlashSales.abpsln.json | 7 - .../EasyAbp.EShop.Plugins.FlashSales.sln | 160 ----------- ...p.EShop.Plugins.FlashSales.sln.DotSettings | 23 -- plugins/FlashSales/NuGet.Config | 6 - .../FlashSales/docker-compose.migrations.yml | 13 - .../FlashSales/docker-compose.override.yml | 29 -- plugins/FlashSales/docker-compose.yml | 25 -- 12 files changed, 3 insertions(+), 642 deletions(-) delete mode 100644 plugins/FlashSales/.gitattributes delete mode 100644 plugins/FlashSales/.gitignore delete mode 100644 plugins/FlashSales/.prettierrc delete mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json delete mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json delete mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln delete mode 100644 plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings delete mode 100644 plugins/FlashSales/NuGet.Config delete mode 100644 plugins/FlashSales/docker-compose.migrations.yml delete mode 100644 plugins/FlashSales/docker-compose.override.yml delete mode 100644 plugins/FlashSales/docker-compose.yml diff --git a/plugins/FlashSales/.editorconfig b/plugins/FlashSales/.editorconfig index 2e55c103..6f8b7846 100644 --- a/plugins/FlashSales/.editorconfig +++ b/plugins/FlashSales/.editorconfig @@ -75,9 +75,9 @@ dotnet_style_allow_statement_immediately_after_block_experimental = false #### C# Coding Conventions #### # var preferences -csharp_style_var_elsewhere = false -csharp_style_var_for_built_in_types = false -csharp_style_var_when_type_is_apparent = false +csharp_style_var_elsewhere = true +csharp_style_var_for_built_in_types = true +csharp_style_var_when_type_is_apparent = true # Expression-bodied members csharp_style_expression_bodied_accessors = true diff --git a/plugins/FlashSales/.gitattributes b/plugins/FlashSales/.gitattributes deleted file mode 100644 index c941e526..00000000 --- a/plugins/FlashSales/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -**/wwwroot/libs/** linguist-vendored diff --git a/plugins/FlashSales/.gitignore b/plugins/FlashSales/.gitignore deleted file mode 100644 index b5e2674f..00000000 --- a/plugins/FlashSales/.gitignore +++ /dev/null @@ -1,259 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# FlashSales -host/EasyAbp.EShop.Plugins.FlashSales.IdentityServer/Logs/logs.txt -host/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host/Logs/logs.txt -host/EasyAbp.EShop.Plugins.FlashSales.Web.Host/Logs/logs.txt -host/EasyAbp.EShop.Plugins.FlashSales.Web.Unified/Logs/logs.txt -host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host/Logs/logs.txt \ No newline at end of file diff --git a/plugins/FlashSales/.prettierrc b/plugins/FlashSales/.prettierrc deleted file mode 100644 index 56af76bd..00000000 --- a/plugins/FlashSales/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "singleQuote": true, - "useTabs": false, - "tabWidth": 4 -} diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json deleted file mode 100644 index 64cebbbb..00000000 --- a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpmdl.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "folders": { - "items": { - "src": {}, - "test": {}, - "host": {} - } - }, - "packages": { - "EasyAbp.EShop.Plugins.FlashSales.Domain.Shared": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.Domain": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp.EShop.Plugins.FlashSales.Domain.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.Application.Contracts": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.Application": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.MongoDB": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp.EShop.Plugins.FlashSales.MongoDB.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.HttpApi": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Plugins.FlashSales.HttpApi.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.TestBase": { - "path": "test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp.EShop.Plugins.FlashSales.TestBase.abppkg.json", - "folder": "test" - }, - "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests": { - "path": "test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.abppkg.json", - "folder": "test" - }, - "EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests": { - "path": "test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.abppkg.json", - "folder": "test" - }, - "EasyAbp.EShop.Plugins.FlashSales.Domain.Tests": { - "path": "test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.abppkg.json", - "folder": "test" - }, - "EasyAbp.EShop.Plugins.FlashSales.Application.Tests": { - "path": "test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.abppkg.json", - "folder": "test" - }, - "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host": { - "path": "host/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Host.abppkg.json", - "folder": "host" - }, - "EasyAbp.EShop.Plugins.FlashSales.Web": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp": { - "path": "test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.abppkg.json", - "folder": "test" - }, - "EasyAbp.EShop.Plugins.FlashSales.Web.Host": { - "path": "host/EasyAbp.EShop.Plugins.FlashSales.Web.Host/EasyAbp.EShop.Plugins.FlashSales.Web.Host.abppkg.json", - "folder": "host" - }, - "EasyAbp.EShop.Plugins.FlashSales.IdentityServer": { - "path": "host/EasyAbp.EShop.Plugins.FlashSales.IdentityServer/EasyAbp.EShop.Plugins.FlashSales.IdentityServer.abppkg.json", - "folder": "host" - }, - "EasyAbp.EShop.Plugins.FlashSales.Host.Shared": { - "path": "host/EasyAbp.EShop.Plugins.FlashSales.Host.Shared/EasyAbp.EShop.Plugins.FlashSales.Host.Shared.abppkg.json", - "folder": "host" - }, - "EasyAbp.EShop.Plugins.FlashSales.Web.Unified": { - "path": "host/EasyAbp.EShop.Plugins.FlashSales.Web.Unified/EasyAbp.EShop.Plugins.FlashSales.Web.Unified.abppkg.json", - "folder": "host" - }, - "EasyAbp.EShop.Plugins.FlashSales.Blazor": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Blazor/EasyAbp.EShop.Plugins.FlashSales.Blazor.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.Blazor.Host": { - "path": "host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Host.abppkg.json", - "folder": "host" - }, - "EasyAbp.EShop.Plugins.FlashSales.Blazor.Server": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.Blazor.WebAssembly": { - "path": "src/EasyAbp.EShop.Plugins.FlashSales.Blazor.WebAssembly/EasyAbp.EShop.Plugins.FlashSales.Blazor.WebAssembly.abppkg.json", - "folder": "src" - }, - "EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host": { - "path": "host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host/EasyAbp.EShop.Plugins.FlashSales.Blazor.Server.Host.abppkg.json", - "folder": "host" - } - } -} \ No newline at end of file diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json deleted file mode 100644 index 8939665d..00000000 --- a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.abpsln.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "modules": { - "EasyAbp.EShop.Plugins.FlashSales": { - "path": "EasyAbp.EShop.Plugins.FlashSales.abpmdl.json" - } - } -} \ No newline at end of file diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln deleted file mode 100644 index 11fd3b59..00000000 --- a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln +++ /dev/null @@ -1,160 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.2.32526.322 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Shared", "src\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared\EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.csproj", "{D64C1577-4929-4B60-939E-96DE1534891A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain", "src\EasyAbp.EShop.Plugins.FlashSales.Domain\EasyAbp.EShop.Plugins.FlashSales.Domain.csproj", "{F2840BC7-0188-4606-9126-DADD0F5ABF7A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Contracts", "src\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj", "{BD65D04F-08D5-40C1-8C24-77CA0BACB877}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application", "src\EasyAbp.EShop.Plugins.FlashSales.Application\EasyAbp.EShop.Plugins.FlashSales.Application.csproj", "{78040F9E-3501-4A40-82DF-00A597710F35}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{649A3FFA-182F-4E56-9717-E6A9A2BEC545}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{E400416D-2895-4512-9D17-90681EEC7E0A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore", "src\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.csproj", "{0CE86223-D31D-4315-A1F5-87BA3EE1B844}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB", "src\EasyAbp.EShop.Plugins.FlashSales.MongoDB\EasyAbp.EShop.Plugins.FlashSales.MongoDB.csproj", "{F1C58097-4C08-4D88-8976-6B3389391481}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi", "src\EasyAbp.EShop.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Plugins.FlashSales.HttpApi.csproj", "{077AA5F8-8B61-420C-A6B5-0150A66FDB34}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client", "src\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.csproj", "{36E2735F-CEAB-44C8-A6D1-2CDAFF399751}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.TestBase", "test\EasyAbp.EShop.Plugins.FlashSales.TestBase\EasyAbp.EShop.Plugins.FlashSales.TestBase.csproj", "{C5BB573D-3030-4BCB-88B7-F6A85C32766C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests\EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests.csproj", "{527F645C-C1FC-406E-8479-81386C8ECF13}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests\EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests.csproj", "{D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Domain.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.Domain.Tests\EasyAbp.EShop.Plugins.FlashSales.Domain.Tests.csproj", "{E60895E5-79C4-447D-88B7-85CB5BA336A4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Application.Tests", "test\EasyAbp.EShop.Plugins.FlashSales.Application.Tests\EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj", "{90CB5DC4-C040-45C7-8900-9688B26405BC}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Web", "src\EasyAbp.EShop.Plugins.FlashSales.Web\EasyAbp.EShop.Plugins.FlashSales.Web.csproj", "{3B7B6317-1B85-4164-8E11-75574F80AE17}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp", "test\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp\EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp.csproj", "{1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Host.Shared", "host\EasyAbp.EShop.Plugins.FlashSales.Host.Shared\EasyAbp.EShop.Plugins.FlashSales.Host.Shared.csproj", "{F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.FlashSales.Installer", "src\EasyAbp.EShop.Plugins.FlashSales.Installer\EasyAbp.EShop.Plugins.FlashSales.Installer.csproj", "{BE39FD00-745B-4049-8161-FC129817CBE4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Orders.Plugins.FlashSales.Application", "src\EasyAbp.EShop.Orders.Plugins.FlashSales.Application\EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj", "{AC7079C6-FEFE-4277-844B-2C9B8C21432D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application", "src\EasyAbp.EShop.Products.Plugins.FlashSales.Application\EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj", "{5711E14D-ADF0-4BAB-BDDB-28A663A07442}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D64C1577-4929-4B60-939E-96DE1534891A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D64C1577-4929-4B60-939E-96DE1534891A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D64C1577-4929-4B60-939E-96DE1534891A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D64C1577-4929-4B60-939E-96DE1534891A}.Release|Any CPU.Build.0 = Release|Any CPU - {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F2840BC7-0188-4606-9126-DADD0F5ABF7A}.Release|Any CPU.Build.0 = Release|Any CPU - {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BD65D04F-08D5-40C1-8C24-77CA0BACB877}.Release|Any CPU.Build.0 = Release|Any CPU - {78040F9E-3501-4A40-82DF-00A597710F35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {78040F9E-3501-4A40-82DF-00A597710F35}.Debug|Any CPU.Build.0 = Debug|Any CPU - {78040F9E-3501-4A40-82DF-00A597710F35}.Release|Any CPU.ActiveCfg = Release|Any CPU - {78040F9E-3501-4A40-82DF-00A597710F35}.Release|Any CPU.Build.0 = Release|Any CPU - {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0CE86223-D31D-4315-A1F5-87BA3EE1B844}.Release|Any CPU.Build.0 = Release|Any CPU - {F1C58097-4C08-4D88-8976-6B3389391481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1C58097-4C08-4D88-8976-6B3389391481}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1C58097-4C08-4D88-8976-6B3389391481}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1C58097-4C08-4D88-8976-6B3389391481}.Release|Any CPU.Build.0 = Release|Any CPU - {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Debug|Any CPU.Build.0 = Debug|Any CPU - {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Release|Any CPU.ActiveCfg = Release|Any CPU - {077AA5F8-8B61-420C-A6B5-0150A66FDB34}.Release|Any CPU.Build.0 = Release|Any CPU - {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Debug|Any CPU.Build.0 = Debug|Any CPU - {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Release|Any CPU.ActiveCfg = Release|Any CPU - {36E2735F-CEAB-44C8-A6D1-2CDAFF399751}.Release|Any CPU.Build.0 = Release|Any CPU - {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C5BB573D-3030-4BCB-88B7-F6A85C32766C}.Release|Any CPU.Build.0 = Release|Any CPU - {527F645C-C1FC-406E-8479-81386C8ECF13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {527F645C-C1FC-406E-8479-81386C8ECF13}.Debug|Any CPU.Build.0 = Debug|Any CPU - {527F645C-C1FC-406E-8479-81386C8ECF13}.Release|Any CPU.ActiveCfg = Release|Any CPU - {527F645C-C1FC-406E-8479-81386C8ECF13}.Release|Any CPU.Build.0 = Release|Any CPU - {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6}.Release|Any CPU.Build.0 = Release|Any CPU - {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E60895E5-79C4-447D-88B7-85CB5BA336A4}.Release|Any CPU.Build.0 = Release|Any CPU - {90CB5DC4-C040-45C7-8900-9688B26405BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {90CB5DC4-C040-45C7-8900-9688B26405BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {90CB5DC4-C040-45C7-8900-9688B26405BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {90CB5DC4-C040-45C7-8900-9688B26405BC}.Release|Any CPU.Build.0 = Release|Any CPU - {3B7B6317-1B85-4164-8E11-75574F80AE17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3B7B6317-1B85-4164-8E11-75574F80AE17}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3B7B6317-1B85-4164-8E11-75574F80AE17}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3B7B6317-1B85-4164-8E11-75574F80AE17}.Release|Any CPU.Build.0 = Release|Any CPU - {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8}.Release|Any CPU.Build.0 = Release|Any CPU - {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB}.Release|Any CPU.Build.0 = Release|Any CPU - {BE39FD00-745B-4049-8161-FC129817CBE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE39FD00-745B-4049-8161-FC129817CBE4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE39FD00-745B-4049-8161-FC129817CBE4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE39FD00-745B-4049-8161-FC129817CBE4}.Release|Any CPU.Build.0 = Release|Any CPU - {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AC7079C6-FEFE-4277-844B-2C9B8C21432D}.Release|Any CPU.Build.0 = Release|Any CPU - {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5711E14D-ADF0-4BAB-BDDB-28A663A07442}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {D64C1577-4929-4B60-939E-96DE1534891A} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {F2840BC7-0188-4606-9126-DADD0F5ABF7A} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {BD65D04F-08D5-40C1-8C24-77CA0BACB877} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {78040F9E-3501-4A40-82DF-00A597710F35} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {0CE86223-D31D-4315-A1F5-87BA3EE1B844} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {F1C58097-4C08-4D88-8976-6B3389391481} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {077AA5F8-8B61-420C-A6B5-0150A66FDB34} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {36E2735F-CEAB-44C8-A6D1-2CDAFF399751} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {C5BB573D-3030-4BCB-88B7-F6A85C32766C} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} - {527F645C-C1FC-406E-8479-81386C8ECF13} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} - {D0AD9179-125C-40B2-A8EE-CD4C1EE24BB6} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} - {E60895E5-79C4-447D-88B7-85CB5BA336A4} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} - {90CB5DC4-C040-45C7-8900-9688B26405BC} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} - {3B7B6317-1B85-4164-8E11-75574F80AE17} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {1EDCD6D4-DF3A-4E3B-ABB6-C0D0B373EAB8} = {CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D} - {F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB} = {E400416D-2895-4512-9D17-90681EEC7E0A} - {BE39FD00-745B-4049-8161-FC129817CBE4} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {AC7079C6-FEFE-4277-844B-2C9B8C21432D} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - {5711E14D-ADF0-4BAB-BDDB-28A663A07442} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD} - EndGlobalSection -EndGlobal diff --git a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings b/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings deleted file mode 100644 index cb0b2c91..00000000 --- a/plugins/FlashSales/EasyAbp.EShop.Plugins.FlashSales.sln.DotSettings +++ /dev/null @@ -1,23 +0,0 @@ - - True - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - Required - Required - Required - Required - False - True - False - False - True - False - False - SQL - \ No newline at end of file diff --git a/plugins/FlashSales/NuGet.Config b/plugins/FlashSales/NuGet.Config deleted file mode 100644 index be8a1ece..00000000 --- a/plugins/FlashSales/NuGet.Config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/plugins/FlashSales/docker-compose.migrations.yml b/plugins/FlashSales/docker-compose.migrations.yml deleted file mode 100644 index f0823259..00000000 --- a/plugins/FlashSales/docker-compose.migrations.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: '3.4' - -services: - migrations: - build: - context: ../../ - dockerfile: templates/service/database/Dockerfile - depends_on: - - sqlserver - environment: - - IdentityServer_DB=FlashSales_Identity - - FlashSales_DB=FlashSales_ModuleDb - - SA_PASSWORD=yourStrong(!)Password diff --git a/plugins/FlashSales/docker-compose.override.yml b/plugins/FlashSales/docker-compose.override.yml deleted file mode 100644 index a84d1b0a..00000000 --- a/plugins/FlashSales/docker-compose.override.yml +++ /dev/null @@ -1,29 +0,0 @@ -version: '3.4' - -services: - sqlserver: - environment: - - SA_PASSWORD=yourStrong(!)Password - - ACCEPT_EULA=Y - ports: - - "51599:1433" - - identity-server: - environment: - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionStrings__Default=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false - - ConnectionStrings__SqlServerCache=Server=sqlserver;Database=FlashSales_Cache;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false - ports: - - "51600:80" - - flash-sales: - environment: - - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionStrings__Default=Server=sqlserver;Database=FlashSales_ModuleDb;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false - - ConnectionStrings__AbpSettingManagement=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false - - ConnectionStrings__AbpPermissionManagement=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false - - ConnectionStrings__AbpAuditLogging=Server=sqlserver;Database=FlashSales_Identity;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false - - ConnectionStrings__SqlServerCache=Server=sqlserver;Database=FlashSales_Cache;Trusted_Connection=True;User=sa;Password=yourStrong(!)Password;Integrated Security=false - - AuthServer__Authority=http://identity-server - ports: - - "51601:80" \ No newline at end of file diff --git a/plugins/FlashSales/docker-compose.yml b/plugins/FlashSales/docker-compose.yml deleted file mode 100644 index 88735dd6..00000000 --- a/plugins/FlashSales/docker-compose.yml +++ /dev/null @@ -1,25 +0,0 @@ -version: '3.4' - -services: - sqlserver: - image: mcr.microsoft.com/mssql/server - volumes: - - dbdata:/var/opt/mssql - - identity-server: - build: - context: ../../ - dockerfile: templates/service/host/IdentityServerHost/Dockerfile - depends_on: - - sqlserver - - flash-sales: - build: - context: ../../ - dockerfile: templates/service/host/EasyAbp.EShop.Plugins.FlashSales.Host/Dockerfile - depends_on: - - sqlserver - - identity-server - -volumes: - dbdata: \ No newline at end of file From ccf853287ae77352fa7a468785e8866aba0cb128 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Wed, 6 Jul 2022 10:22:43 +0800 Subject: [PATCH 13/97] Improve FlashSales `ErrorCodes` and `GetList` --- ...hSalesOrderCreationAuthorizationHandler.cs | 3 +- .../FodyWeavers.xml | 2 +- .../Dtos/FlashSalesPlanGetListInput.cs | 2 +- .../FlashSalesPlanAppService.cs | 50 +++++++++++++------ .../UnexpectedInventoryStrategyException.cs | 11 ++++ .../FlashSales/FlashSalesErrorCodes.cs | 14 +++--- .../Plugins/FlashSales/Localization/en.json | 16 +++--- .../FlashSales/Localization/zh-Hans.json | 14 +++--- .../FlashSales/Localization/zh-Hant.json | 14 +++--- ...ndTimeMustBeLaterThanBeginTimeException.cs | 12 ----- .../FlashSalesPlans/FlashSalesPlan.cs | 2 +- .../InvalidEndTimeException.cs | 12 +++++ .../FlashSalesPlans/FlashSalesPlan/index.js | 6 ++- 13 files changed, 96 insertions(+), 62 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/UnexpectedInventoryStrategyException.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/InvalidEndTimeException.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs index cd7f0044..42505195 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs @@ -42,8 +42,7 @@ public class FlashSalesOrderCreationAuthorizationHandler : OrderCreationAuthoriz { StoreId = resource.Input.StoreId, ProductId = orderLine.ProductId, - ProductSkuId = orderLine.ProductSkuId, - OnlyShowPublished = true + ProductSkuId = orderLine.ProductSkuId }); if (plans.Items.Count > 0) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml index 00e1d9a1..be0de3a9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/FodyWeavers.xml @@ -1,3 +1,3 @@  - + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs index e1b4f1fe..13a623dd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs @@ -12,7 +12,7 @@ public class FlashSalesPlanGetListInput : ExtensiblePagedAndSortedResultRequestD public Guid? ProductSkuId { get; set; } - public bool OnlyShowPublished { get; set; } + public bool IncludeUnpublished { get; set; } public DateTime? Start { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs index c51f6579..4c06e0ab 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -157,7 +157,7 @@ public class FlashSalesPlanAppService : protected override async Task> CreateFilteredQueryAsync(FlashSalesPlanGetListInput input) { - if (!input.OnlyShowPublished) + if (input.IncludeUnpublished) { await CheckPolicyAsync(FlashSalesPermissions.FlashSalesPlan.Manage); } @@ -166,7 +166,7 @@ public class FlashSalesPlanAppService : .WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId.Value) .WhereIf(input.ProductId.HasValue, x => x.ProductId == input.ProductId.Value) .WhereIf(input.ProductSkuId.HasValue, x => x.ProductSkuId == input.ProductSkuId.Value) - .WhereIf(input.OnlyShowPublished, x => x.IsPublished) + .WhereIf(!input.IncludeUnpublished , x => x.IsPublished) .WhereIf(input.Start.HasValue, x => x.BeginTime >= input.Start.Value) .WhereIf(input.End.HasValue, x => x.BeginTime <= input.End.Value); } @@ -184,7 +184,7 @@ public class FlashSalesPlanAppService : if (product.InventoryStrategy != InventoryStrategy.FlashSales) { - throw new BusinessException(FlashSalesErrorCodes.ProductInventoryStrategyIsNotFlashSales); + throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); } if (!plan.IsPublished) @@ -192,9 +192,9 @@ public class FlashSalesPlanAppService : throw new EntityNotFoundException(typeof(FlashSalesPlan), id); } - if (Clock.Now > plan.EndTime) + if (Clock.Now >= plan.EndTime) { - throw new BusinessException(FlashSalesErrorCodes.FlashSalesPlanIsExpired); + throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } if (productSku.Inventory < 1) @@ -210,26 +210,46 @@ public class FlashSalesPlanAppService : var plan = await GetFlashSalesPlanCacheAsync(id); if (Clock.Now > plan.EndTime) { - throw new BusinessException(FlashSalesErrorCodes.FlashSalesPlanIsExpired); + throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } var cacheHashToken = await GetCacheHashTokenAsync(plan); if (cacheHashToken.IsNullOrWhiteSpace()) { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExpried); + throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); - if (productSku.Inventory < 1) + if (!await CompareHashTokenAsync(cacheHashToken, plan, product, productSku)) { - throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); + throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } - if (!await CompareHashTokenAsync(cacheHashToken, plan, product, productSku)) + if (!product.IsPublished) + { + throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); + } + + if (product.InventoryStrategy != InventoryStrategy.FlashSales) + { + throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); + } + + if (!plan.IsPublished) + { + throw new EntityNotFoundException(typeof(FlashSalesPlan), id); + } + + if (Clock.Now >= plan.EndTime) + { + throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); + } + + if (productSku.Inventory < 1) { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExpried); + throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); } } @@ -244,13 +264,13 @@ public class FlashSalesPlanAppService : if (now > plan.EndTime) { - throw new BusinessException(FlashSalesErrorCodes.FlashSalesPlanIsExpired); + throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } var cacheHashToken = await GetCacheHashTokenAsync(plan); if (cacheHashToken.IsNullOrWhiteSpace()) { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExpried); + throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } await RemoveCacheHashTokenAsync(plan); @@ -355,7 +375,7 @@ public class FlashSalesPlanAppService : if (handle == null) { - throw new BusinessException(FlashSalesErrorCodes.CreateFlashSalesOrderBusy); + throw new BusinessException(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); } // Prevent repeat submit @@ -363,7 +383,7 @@ public class FlashSalesPlanAppService : x.PlanId == plan.Id && x.UserId == userId && (x.Status == FlashSalesResultStatus.Successful || x.Status == FlashSalesResultStatus.Pending)) ) { - throw new BusinessException(FlashSalesErrorCodes.AlreadySubmitCreateFlashSalesOrder); + throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); } var result = new FlashSalesResult( diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/UnexpectedInventoryStrategyException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/UnexpectedInventoryStrategyException.cs new file mode 100644 index 00000000..bb2f6508 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/UnexpectedInventoryStrategyException.cs @@ -0,0 +1,11 @@ +using EasyAbp.EShop.Products.Products; +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +public class UnexpectedInventoryStrategyException : BusinessException +{ + public UnexpectedInventoryStrategyException(InventoryStrategy expectedInventoryStrategy) : base(FlashSalesErrorCodes.UnexpectedInventoryStrategy) + { + WithData(nameof(expectedInventoryStrategy), expectedInventoryStrategy); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index a445de23..ec85d72c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -4,7 +4,7 @@ public static class FlashSalesErrorCodes { public const string Namespace = "EasyAbp.EShop.Plugins.FlashSales"; - public const string EndTimeMustBeLaterThanBeginTime = $"{Namespace}:{nameof(EndTimeMustBeLaterThanBeginTime)}"; + public const string InvalidEndTime = $"{Namespace}:{nameof(InvalidEndTime)}"; public const string ProductIsNotInThisStore = $"{Namespace}:{nameof(ProductIsNotInThisStore)}"; @@ -14,15 +14,15 @@ public static class FlashSalesErrorCodes public const string ProductSkuInventoryExceeded = $"{Namespace}:{nameof(ProductSkuInventoryExceeded)}"; - public const string ProductInventoryStrategyIsNotFlashSales = $"{Namespace}:{nameof(ProductInventoryStrategyIsNotFlashSales)}"; + public const string UnexpectedInventoryStrategy = $"{Namespace}:{nameof(UnexpectedInventoryStrategy)}"; - public const string PreOrderExpried = $"{Namespace}:{nameof(PreOrderExpried)}"; + public const string PreOrderExpired = $"{Namespace}:{nameof(PreOrderExpired)}"; - public const string FlashSalesPlanIsNotStart = $"{Namespace}:{nameof(FlashSalesPlanIsNotStart)}"; + public const string FlashSaleNotStarted = $"{Namespace}:{nameof(FlashSaleNotStarted)}"; - public const string FlashSalesPlanIsExpired = $"{Namespace}:{nameof(FlashSalesPlanIsExpired)}"; + public const string FlashSaleIsOver = $"{Namespace}:{nameof(FlashSaleIsOver)}"; - public const string CreateFlashSalesOrderBusy = $"{Namespace}:{nameof(CreateFlashSalesOrderBusy)}"; + public const string BusyToCreateFlashSaleOrder = $"{Namespace}:{nameof(BusyToCreateFlashSaleOrder)}"; - public const string AlreadySubmitCreateFlashSalesOrder = $"{Namespace}:{nameof(AlreadySubmitCreateFlashSalesOrder)}"; + public const string DuplicateFlashSalesOrder = $"{Namespace}:{nameof(DuplicateFlashSalesOrder)}"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json index 7bd649b8..ff582ce7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -1,17 +1,17 @@ { "culture": "en", "texts": { - "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "End time must be later than start time", + "EasyAbp.EShop.Plugins.FlashSales:InvalidEndTime": "End time must be later than start time", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotInThisStore": "Product '{productId}' is not in this store '{storeId}'", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "ProductSku '{productSkuId}' is not found", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "Product is not published", - "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "Product SKU inventory exceeded", - "EasyAbp.EShop.Plugins.FlashSales:ProductInventoryStrategyIsNotFlashSales": "Product inventory strategy is not flash-sales", - "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpried": "Pre order expired", - "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsNotStart": "FlashSales plan is not start", - "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsExpired": "FlashSales plan is expired", - "EasyAbp.EShop.Plugins.FlashSales:CreateFlashSalesOrderBusy": "Create flash-sales order busy", - "EasyAbp.EShop.Plugins.FlashSales:AlreadySubmitCreateFlashSalesOrder": "Already submit create flash-sales order", + "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "ProductSku inventory exceeded", + "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "Only the specified inventory strategy {expectedInventoryStrategy} is allowed.", + "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpired": "Pre order expired", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleNotStarted": "Flash-sale not started", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "Flash-sale is over", + "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "Busy to create flash-sale Order", + "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "Duplicate flash-sales order", "ExistFlashSalesPlanProduct": "Exist unexpected flash-sales plan product", "Menu:FlashSalesManagement": "FlashSales Management", "Permission:FlashSalesPlan": "FlashSales Plan", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json index c13420e7..aef15648 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -1,17 +1,17 @@ { "culture": "zh-Hans", "texts": { - "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "结束时间必须晚于开始时间", + "EasyAbp.EShop.Plugins.FlashSales:InvalidEndTime": "结束时间必须晚于开始时间", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotInThisStore": "产品'{productId}'不在此店铺'{storeId}'中", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "产品SKU'{productSkuId}'不存在", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "产品尚未发布", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "产品SKU库存不足", - "EasyAbp.EShop.Plugins.FlashSales:ProductInventoryStrategyIsNotFlashSales": "产品库存策略不是闪购", - "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpried": "预下单已过期", - "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsNotStart": "闪购计划尚未开始", - "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsExpired": "闪购计划已经结束", - "EasyAbp.EShop.Plugins.FlashSales:CreateFlashSalesOrderBusy": "闪购计划下单繁忙", - "EasyAbp.EShop.Plugins.FlashSales:AlreadySubmitCreateFlashSalesOrder": "已经提交闪购下单", + "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "只允许使用指定的{expectedInventoryStrategy}库存策略", + "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpired": "预下单已过期", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleNotStarted": "闪购尚未开始", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "闪购已经结束", + "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "闪购下单繁忙", + "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重复闪购下单", "ExistFlashSalesPlanProduct": "清單中不允許存在閃購計畫中的產品", "Menu:FlashSalesManagement": "闪购", "Permission:FlashSalesPlan": "闪购计划", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json index 2311abec..81f10e24 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -1,17 +1,17 @@ { "culture": "zh-Hant", "texts": { - "EasyAbp.EShop.Plugins.FlashSales:EndTimeMustBeLaterThanBeginTime": "結束時間必須晚於開始時間", + "EasyAbp.EShop.Plugins.FlashSales:InvalidEndTime": "結束時間必須晚於開始時間", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotInThisStore": "產品'{productId}'不在此店鋪'{storeId}'中", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "產品SKU'{productSkuId}'不存在", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "產品尚未發佈", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "產品SKU庫存不足", - "EasyAbp.EShop.Plugins.FlashSales:ProductInventoryStrategyIsNotFlashSales": "產品庫存策略不是閃購", - "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpried": "預下單已過期", - "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsNotStart": "閃購計畫尚未開始", - "EasyAbp.EShop.Plugins.FlashSales:FlashSalesPlanIsExpired": "閃購計畫已經結束", - "EasyAbp.EShop.Plugins.FlashSales:CreateFlashSalesOrderBusy": "閃購計畫下單繁忙", - "EasyAbp.EShop.Plugins.FlashSales:AlreadySubmitCreateFlashSalesOrder": "已經提交閃購下單", + "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "只允許使用指定的{expectedInventoryStrategy}庫存策略", + "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpired": "預下單已過期", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleNotStarted": "閃購尚未開始", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "閃購已經結束", + "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "閃購下單繁忙", + "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重複閃購下單", "ExistFlashSalesPlanProduct": "清单中不允许存在闪购计划中的产品", "Menu:FlashSalesManagement": "閃購管理", "Permission:FlashSalesPlan": "閃購計畫", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs deleted file mode 100644 index 7d3b0938..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EndTimeMustBeLaterThanBeginTimeException.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Volo.Abp; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; - -public class EndTimeMustBeLaterThanBeginTimeException : BusinessException -{ - public EndTimeMustBeLaterThanBeginTimeException() - : base(FlashSalesErrorCodes.EndTimeMustBeLaterThanBeginTime) - { - - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs index e52b4c1d..a11acd7a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs @@ -37,7 +37,7 @@ public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant { if (beginTime > endTime) { - throw new EndTimeMustBeLaterThanBeginTimeException(); + throw new InvalidEndTimeException(); } BeginTime = beginTime; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/InvalidEndTimeException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/InvalidEndTimeException.cs new file mode 100644 index 00000000..e3721b43 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/InvalidEndTimeException.cs @@ -0,0 +1,12 @@ +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +public class InvalidEndTimeException : BusinessException +{ + public InvalidEndTimeException() + : base(FlashSalesErrorCodes.InvalidEndTime) + { + + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js index 9845f13f..04d2156e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js @@ -14,7 +14,11 @@ $(function () { autoWidth: false, scrollCollapse: true, order: [[2, "asc"]], - ajax: abp.libs.datatables.createAjax(service.getList), + ajax: abp.libs.datatables.createAjax(service.getList, function () { + return { + includeUnpublished: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlan.Manage') + }; + }), columnDefs: [ { rowAction: { From 01ce278905ae0a88b59641dc94fcfabb90fd590f Mon Sep 17 00:00:00 2001 From: Jadyn Date: Wed, 6 Jul 2022 11:03:46 +0800 Subject: [PATCH 14/97] Rename `RemoteServiceName` and `ModuleName` --- .../FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs index f00bae2e..0250ea15 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesRemoteServiceConsts.cs @@ -2,7 +2,7 @@ public class EShopPluginsFlashSalesRemoteServiceConsts { - public const string RemoteServiceName = "FlashSales"; + public const string RemoteServiceName = "EasyAbpEShopPluginsFlashSales"; - public const string ModuleName = "flash-sales"; + public const string ModuleName = "easyAbpEShopPluginsFlashSales"; } From 889fff0cd5fb7f72097ba6a07843ebe45c24f033 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Wed, 6 Jul 2022 11:04:59 +0800 Subject: [PATCH 15/97] Use `MultiStoreCrudAppService` replace `CrudAppService` --- .../FlashSalesPlanCreateOrUpdateDtoBase.cs | 3 +- .../FlashSalesPermissionDefinitionProvider.cs | 1 + .../Permissions/FlashSalesPermissions.cs | 1 + .../FlashSalesPlanAppService.cs | 108 +++++++----------- .../FlashSalesPlans/FlashSalesPlan.cs | 3 +- 5 files changed, 50 insertions(+), 66 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs index 85403c03..81f44718 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs @@ -1,10 +1,11 @@ using System; +using EasyAbp.EShop.Stores.Stores; using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; [Serializable] -public abstract class FlashSalesPlanCreateOrUpdateDtoBase : ExtensibleEntityDto +public abstract class FlashSalesPlanCreateOrUpdateDtoBase : ExtensibleEntityDto, IMultiStore { public Guid StoreId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs index 49b3e55a..f4edc186 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs @@ -12,6 +12,7 @@ public class FlashSalesPermissionDefinitionProvider : PermissionDefinitionProvid var flashSalesPlanPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSalesPlan.Default, L("Permission:FlashSalesPlan")); flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Manage, L("Permission:Manage")); + flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.CrossStore, L("Permission:CrossStore")); flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Create, L("Permission:Create")); flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Update, L("Permission:Update")); flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Delete, L("Permission:Delete")); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs index 0ccaa1a5..d7202cf5 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs @@ -15,6 +15,7 @@ public class FlashSalesPermissions { public const string Default = GroupName + ".FlashSalesPlan"; public const string Manage = Default + ".Manage"; + public const string CrossStore = Default + ".CrossStore"; public const string Update = Default + ".Update"; public const string Create = Default + ".Create"; public const string Delete = Default + ".Delete"; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs index 4c06e0ab..a3d51872 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -6,11 +6,10 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; -using EasyAbp.EShop.Stores.Authorization; +using EasyAbp.EShop.Stores.Stores; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Caching.Distributed; using Volo.Abp; -using Volo.Abp.Application.Services; using Volo.Abp.Caching; using Volo.Abp.Data; using Volo.Abp.DistributedLocking; @@ -23,9 +22,10 @@ namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; [Authorize] public class FlashSalesPlanAppService : - CrudAppService, + MultiStoreCrudAppService, IFlashSalesPlanAppService { + protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.CrossStore; protected override string GetPolicyName { get; set; } protected override string GetListPolicyName { get; set; } protected override string CreatePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Create; @@ -71,13 +71,13 @@ public class FlashSalesPlanAppService : public override async Task GetAsync(Guid id) { - await CheckGetPolicyAsync(); - var flashSalesPlan = await GetEntityByIdAsync(id); + await CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, GetPolicyName); + if (!flashSalesPlan.IsPublished) { - await CheckPolicyAsync(FlashSalesPermissions.FlashSalesPlan.Manage); + await CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, FlashSalesPermissions.FlashSalesPlan.Manage); } return await MapToGetOutputDtoAsync(flashSalesPlan); @@ -85,7 +85,7 @@ public class FlashSalesPlanAppService : public override async Task CreateAsync(FlashSalesPlanCreateDto input) { - await AuthorizationService.CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); + await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); var product = await ProductAppService.GetAsync(input.ProductId); var productSku = product.FindSkuById(input.ProductSkuId); @@ -118,7 +118,7 @@ public class FlashSalesPlanAppService : public override async Task UpdateAsync(Guid id, FlashSalesPlanUpdateDto input) { - await AuthorizationService.CheckMultiStorePolicyAsync(input.StoreId, UpdatePolicyName); + await CheckMultiStorePolicyAsync(input.StoreId, UpdatePolicyName); var product = await ProductAppService.GetAsync(input.ProductId); var productSku = product.FindSkuById(input.ProductSkuId); @@ -150,7 +150,7 @@ public class FlashSalesPlanAppService : { var flashSalesPlan = await GetEntityByIdAsync(id); - await AuthorizationService.CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, DeletePolicyName); + await CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, DeletePolicyName); await FlashSalesPlanRepository.DeleteAsync(flashSalesPlan); } @@ -159,14 +159,14 @@ public class FlashSalesPlanAppService : { if (input.IncludeUnpublished) { - await CheckPolicyAsync(FlashSalesPermissions.FlashSalesPlan.Manage); + await CheckMultiStorePolicyAsync(input.StoreId, FlashSalesPermissions.FlashSalesPlan.Manage); } return (await base.CreateFilteredQueryAsync(input)) .WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId.Value) .WhereIf(input.ProductId.HasValue, x => x.ProductId == input.ProductId.Value) .WhereIf(input.ProductSkuId.HasValue, x => x.ProductSkuId == input.ProductSkuId.Value) - .WhereIf(!input.IncludeUnpublished , x => x.IsPublished) + .WhereIf(!input.IncludeUnpublished, x => x.IsPublished) .WhereIf(input.Start.HasValue, x => x.BeginTime >= input.Start.Value) .WhereIf(input.End.HasValue, x => x.BeginTime <= input.End.Value); } @@ -177,30 +177,7 @@ public class FlashSalesPlanAppService : var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); - if (!product.IsPublished) - { - throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); - } - - if (product.InventoryStrategy != InventoryStrategy.FlashSales) - { - throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); - } - - if (!plan.IsPublished) - { - throw new EntityNotFoundException(typeof(FlashSalesPlan), id); - } - - if (Clock.Now >= plan.EndTime) - { - throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); - } - - if (productSku.Inventory < 1) - { - throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); - } + await CheckPreOrderAsync(plan, product, productSku); await SetCacheHashTokenAsync(plan, product, productSku); } @@ -208,10 +185,6 @@ public class FlashSalesPlanAppService : public virtual async Task CheckPreOrderAsync(Guid id) { var plan = await GetFlashSalesPlanCacheAsync(id); - if (Clock.Now > plan.EndTime) - { - throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); - } var cacheHashToken = await GetCacheHashTokenAsync(plan); if (cacheHashToken.IsNullOrWhiteSpace()) @@ -227,30 +200,7 @@ public class FlashSalesPlanAppService : throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } - if (!product.IsPublished) - { - throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); - } - - if (product.InventoryStrategy != InventoryStrategy.FlashSales) - { - throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); - } - - if (!plan.IsPublished) - { - throw new EntityNotFoundException(typeof(FlashSalesPlan), id); - } - - if (Clock.Now >= plan.EndTime) - { - throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); - } - - if (productSku.Inventory < 1) - { - throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); - } + await CheckPreOrderAsync(plan, product, productSku); } public virtual async Task CreateOrderAsync(Guid id, CreateOrderInput input) @@ -262,7 +212,7 @@ public class FlashSalesPlanAppService : throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); } - if (now > plan.EndTime) + if (now >= plan.EndTime) { throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } @@ -398,4 +348,34 @@ public class FlashSalesPlanAppService : ); return await FlashSalesResultRepository.InsertAsync(result, autoSave: true); } + + protected virtual Task CheckPreOrderAsync(FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + { + if (!product.IsPublished) + { + throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); + } + + if (product.InventoryStrategy != InventoryStrategy.FlashSales) + { + throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); + } + + if (!plan.IsPublished) + { + throw new EntityNotFoundException(typeof(FlashSalesPlan), plan.Id); + } + + if (Clock.Now >= plan.EndTime) + { + throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); + } + + if (productSku.Inventory < 1) + { + throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); + } + + return Task.CompletedTask; + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs index a11acd7a..83bf7f97 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs @@ -1,10 +1,11 @@ using System; +using EasyAbp.EShop.Stores.Stores; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant +public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant, IMultiStore { public virtual Guid? TenantId { get; protected set; } From 642ce1aa18ae51bc2a8f1045852ca4f9cfa74cf9 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Wed, 6 Jul 2022 14:34:07 +0800 Subject: [PATCH 16/97] Remove cache on unitofwork completed --- .../FlashSalesPlanCacheInvalidator.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs index 94434dbd..1fb0f488 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs @@ -4,20 +4,30 @@ using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.EventBus; +using Volo.Abp.Uow; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; public class FlashSalesPlanCacheInvalidator : ILocalEventHandler>, ITransientDependency { protected IDistributedCache DistributedCache { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } - public FlashSalesPlanCacheInvalidator(IDistributedCache distributedCache) + public FlashSalesPlanCacheInvalidator( + IDistributedCache distributedCache, + IUnitOfWorkManager unitOfWorkManager) { DistributedCache = distributedCache; + UnitOfWorkManager = unitOfWorkManager; } - public virtual async Task HandleEventAsync(EntityChangedEventData eventData) + public virtual Task HandleEventAsync(EntityChangedEventData eventData) { - await DistributedCache.RemoveAsync(eventData.Entity.Id); + UnitOfWorkManager.Current.OnCompleted(async () => + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + }); + + return Task.CompletedTask; } } From 7361d70ed0d2b01f74534370223936f51d9cea07 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Wed, 6 Jul 2022 14:37:30 +0800 Subject: [PATCH 17/97] Replace `FindSkuById` with `GetSkuById` --- .../FlashSalesPlans/FlashSalesPlanAppService.cs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs index a3d51872..4c0687f6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -88,18 +88,13 @@ public class FlashSalesPlanAppService : await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); var product = await ProductAppService.GetAsync(input.ProductId); - var productSku = product.FindSkuById(input.ProductSkuId); + product.GetSkuById(input.ProductSkuId); if (product.StoreId != input.StoreId) { throw new ProductIsNotInThisStoreException(input.ProductId, input.StoreId); } - if (productSku == null) - { - throw new ProductSkuIsNotFoundException(input.ProductSkuId); - } - var flashSalesPlan = new FlashSalesPlan( GuidGenerator.Create(), CurrentTenant.Id, @@ -121,18 +116,13 @@ public class FlashSalesPlanAppService : await CheckMultiStorePolicyAsync(input.StoreId, UpdatePolicyName); var product = await ProductAppService.GetAsync(input.ProductId); - var productSku = product.FindSkuById(input.ProductSkuId); + product.GetSkuById(input.ProductSkuId); if (product.StoreId != input.StoreId) { throw new ProductIsNotInThisStoreException(input.ProductId, input.StoreId); } - if (productSku == null) - { - throw new ProductSkuIsNotFoundException(input.ProductSkuId); - } - var flashSalesPlan = await GetEntityByIdAsync(id); flashSalesPlan.SetTimeRange(input.BeginTime, input.EndTime); From 2a76d3dc05ff565a9eecfc7305076ed525e687dc Mon Sep 17 00:00:00 2001 From: Jadyn Date: Wed, 6 Jul 2022 15:46:37 +0800 Subject: [PATCH 18/97] Validate create or update --- ...hSalesOrderCreationAuthorizationHandler.cs | 55 ----------------- .../Dtos/FlashSalesPlanCreateDto.cs | 15 ++++- .../FlashSalesPlanCreateOrUpdateDtoBase.cs | 21 ------- .../Dtos/FlashSalesPlanUpdateDto.cs | 13 +++- .../ExistRelatedFlashSalesResultsException.cs | 14 +++++ .../FlashSalesPlanAppService.cs | 60 ++++++++++++++----- .../FlashSales/FlashSalesErrorCodes.cs | 2 + .../Plugins/FlashSales/Localization/en.json | 4 +- .../FlashSales/Localization/zh-Hans.json | 2 +- .../FlashSales/Localization/zh-Hant.json | 2 +- .../ViewModels/EditFlashSalesPlanViewModel.cs | 2 + 11 files changed, 92 insertions(+), 98 deletions(-) delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs deleted file mode 100644 index 42505195..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/FlashSalesOrderCreationAuthorizationHandler.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.Localization; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.Localization; -using Volo.Abp.DependencyInjection; - -namespace EasyAbp.EShop.Orders.Orders; - -public class FlashSalesOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler -{ - protected IAbpLazyServiceProvider LazyServiceProvider { get; } - protected IStringLocalizer Localizer { get; } - - public FlashSalesOrderCreationAuthorizationHandler( - IAbpLazyServiceProvider lazyServiceProvider, - IStringLocalizer localizer) - { - LazyServiceProvider = lazyServiceProvider; - Localizer = localizer; - } - - protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context, - OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource) - { - if (await IsFlashSalesPlanProductSkuAsync(resource)) - { - context.Fail(new AuthorizationFailureReason(this, Localizer["ExistFlashSalesPlanProduct"])); - return; - } - - context.Succeed(requirement); - } - - protected virtual async Task IsFlashSalesPlanProductSkuAsync(OrderCreationResource resource) - { - var flashSalesPlanAppService = LazyServiceProvider.LazyGetRequiredService(); - foreach (var orderLine in resource.Input.OrderLines) - { - var plans = await flashSalesPlanAppService.GetListAsync(new FlashSalesPlanGetListInput() - { - StoreId = resource.Input.StoreId, - ProductId = orderLine.ProductId, - ProductSkuId = orderLine.ProductSkuId - }); - if (plans.Items.Count > 0) - { - return true; - } - } - - return false; - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs index 45c740bc..c8848d1d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs @@ -1,8 +1,21 @@ using System; +using EasyAbp.EShop.Stores.Stores; +using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; [Serializable] -public class FlashSalesPlanCreateDto : FlashSalesPlanCreateOrUpdateDtoBase +public class FlashSalesPlanCreateDto : ExtensibleEntityDto, IMultiStore { + public Guid StoreId { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime EndTime { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public bool IsPublished { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs deleted file mode 100644 index 81f44718..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateOrUpdateDtoBase.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using EasyAbp.EShop.Stores.Stores; -using Volo.Abp.Application.Dtos; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; - -[Serializable] -public abstract class FlashSalesPlanCreateOrUpdateDtoBase : ExtensibleEntityDto, IMultiStore -{ - public Guid StoreId { get; set; } - - public DateTime BeginTime { get; set; } - - public DateTime EndTime { get; set; } - - public Guid ProductId { get; set; } - - public Guid ProductSkuId { get; set; } - - public bool IsPublished { get; set; } -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs index 4a02dfa7..269fc645 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs @@ -1,10 +1,21 @@ using System; +using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Entities; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; [Serializable] -public class FlashSalesPlanUpdateDto : FlashSalesPlanCreateOrUpdateDtoBase, IHasConcurrencyStamp +public class FlashSalesPlanUpdateDto : ExtensibleEntityDto, IHasConcurrencyStamp { + public DateTime BeginTime { get; set; } + + public DateTime EndTime { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public bool IsPublished { get; set; } + public string ConcurrencyStamp { get; set; } } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs new file mode 100644 index 00000000..dcf50d5b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs @@ -0,0 +1,14 @@ +using System; +using System.Runtime.Serialization; +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; + +[Serializable] +public class ExistRelatedFlashSalesResultsException : BusinessException +{ + public ExistRelatedFlashSalesResultsException(Guid planId) : base(FlashSalesErrorCodes.ExistRelatedFlashSalesResults) + { + WithData(nameof(planId), planId); + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs index 4c0687f6..ac8c24f2 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs @@ -88,12 +88,9 @@ public class FlashSalesPlanAppService : await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); var product = await ProductAppService.GetAsync(input.ProductId); - product.GetSkuById(input.ProductSkuId); + var productSku = product.GetSkuById(input.ProductSkuId); - if (product.StoreId != input.StoreId) - { - throw new ProductIsNotInThisStoreException(input.ProductId, input.StoreId); - } + await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, input.StoreId); var flashSalesPlan = new FlashSalesPlan( GuidGenerator.Create(), @@ -113,20 +110,21 @@ public class FlashSalesPlanAppService : public override async Task UpdateAsync(Guid id, FlashSalesPlanUpdateDto input) { - await CheckMultiStorePolicyAsync(input.StoreId, UpdatePolicyName); - + var flashSalesPlan = await GetEntityByIdAsync(id); var product = await ProductAppService.GetAsync(input.ProductId); - product.GetSkuById(input.ProductSkuId); + var productSku = product.GetSkuById(input.ProductSkuId); - if (product.StoreId != input.StoreId) + await CheckMultiStorePolicyAsync(product.StoreId, UpdatePolicyName); + + await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, flashSalesPlan.StoreId); + + if (await ExistRelatedFlashSalesResultsAsync(id) && (input.ProductId != flashSalesPlan.ProductId || input.ProductSkuId != flashSalesPlan.ProductSkuId)) { - throw new ProductIsNotInThisStoreException(input.ProductId, input.StoreId); + throw new ExistRelatedFlashSalesResultsException(id); } - var flashSalesPlan = await GetEntityByIdAsync(id); - flashSalesPlan.SetTimeRange(input.BeginTime, input.EndTime); - flashSalesPlan.SetProductSku(input.StoreId, input.ProductId, input.ProductSkuId); + flashSalesPlan.SetProductSku(flashSalesPlan.StoreId, input.ProductId, input.ProductSkuId); flashSalesPlan.SetPublished(input.IsPublished); flashSalesPlan.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); @@ -142,6 +140,11 @@ public class FlashSalesPlanAppService : await CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, DeletePolicyName); + if (await ExistRelatedFlashSalesResultsAsync(id)) + { + throw new ExistRelatedFlashSalesResultsException(id); + } + await FlashSalesPlanRepository.DeleteAsync(flashSalesPlan); } @@ -167,7 +170,7 @@ public class FlashSalesPlanAppService : var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); - await CheckPreOrderAsync(plan, product, productSku); + await ValidatePreOrderAsync(plan, product, productSku); await SetCacheHashTokenAsync(plan, product, productSku); } @@ -190,7 +193,7 @@ public class FlashSalesPlanAppService : throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } - await CheckPreOrderAsync(plan, product, productSku); + await ValidatePreOrderAsync(plan, product, productSku); } public virtual async Task CreateOrderAsync(Guid id, CreateOrderInput input) @@ -339,7 +342,7 @@ public class FlashSalesPlanAppService : return await FlashSalesResultRepository.InsertAsync(result, autoSave: true); } - protected virtual Task CheckPreOrderAsync(FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + protected virtual Task ValidatePreOrderAsync(FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (!product.IsPublished) { @@ -368,4 +371,29 @@ public class FlashSalesPlanAppService : return Task.CompletedTask; } + + protected virtual async Task ExistRelatedFlashSalesResultsAsync(Guid planId) + { + return await FlashSalesResultRepository.AnyAsync(x => x.PlanId == planId); + } + + protected virtual Task ValidateCreateOrUpdateProductAsync(Guid productId, ProductDto product, Guid productSkuId, ProductSkuDto productSku, Guid storeId) + { + if (product.StoreId != storeId) + { + throw new ProductIsNotInThisStoreException(productId, storeId); + } + + if (productSku == null) + { + throw new ProductSkuIsNotFoundException(productSkuId); + } + + if (product.InventoryStrategy != InventoryStrategy.FlashSales) + { + throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); + } + + return Task.CompletedTask; + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index ec85d72c..ba672872 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -25,4 +25,6 @@ public static class FlashSalesErrorCodes public const string BusyToCreateFlashSaleOrder = $"{Namespace}:{nameof(BusyToCreateFlashSaleOrder)}"; public const string DuplicateFlashSalesOrder = $"{Namespace}:{nameof(DuplicateFlashSalesOrder)}"; + + public const string ExistRelatedFlashSalesResults = $"{Namespace}:{nameof(ExistRelatedFlashSalesResults)}"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json index ff582ce7..c4a32c55 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -10,9 +10,9 @@ "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpired": "Pre order expired", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleNotStarted": "Flash-sale not started", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "Flash-sale is over", - "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "Busy to create flash-sale Order", + "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "Busy to create flash-sale order", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "Duplicate flash-sales order", - "ExistFlashSalesPlanProduct": "Exist unexpected flash-sales plan product", + "EasyAbp.EShop.Plugins.FlashSales:ExistRelatedFlashSalesResults": "Exist Related flash-sales results", "Menu:FlashSalesManagement": "FlashSales Management", "Permission:FlashSalesPlan": "FlashSales Plan", "Permission:Manage": "Manage", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json index aef15648..8e7293e2 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -12,7 +12,7 @@ "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "闪购已经结束", "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "闪购下单繁忙", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重复闪购下单", - "ExistFlashSalesPlanProduct": "清單中不允許存在閃購計畫中的產品", + "EasyAbp.EShop.Plugins.FlashSales:ExistRelatedFlashSalesResults": "已存在关联的闪购结果", "Menu:FlashSalesManagement": "闪购", "Permission:FlashSalesPlan": "闪购计划", "Permission:Manage": "管理", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json index 81f10e24..14084ab1 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -12,7 +12,7 @@ "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "閃購已經結束", "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "閃購下單繁忙", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重複閃購下單", - "ExistFlashSalesPlanProduct": "清单中不允许存在闪购计划中的产品", + "EasyAbp.EShop.Plugins.FlashSales:ExistRelatedFlashSalesResults": "已存在關聯的閃購結果", "Menu:FlashSalesManagement": "閃購管理", "Permission:FlashSalesPlan": "閃購計畫", "Permission:Manage": "管理", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs index 73ca7dfe..972d0980 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs @@ -8,6 +8,8 @@ namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.Fl public class EditFlashSalesPlanViewModel : IHasConcurrencyStamp { + [DisabledInput] + [ReadOnlyInput] [Display(Name = "FlashSalesPlanStoreId")] public Guid StoreId { get; set; } From 4820c9358c33ffdf5cac3c2ab084f6b91140c4a6 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Thu, 7 Jul 2022 00:21:06 +0800 Subject: [PATCH 19/97] Rename to `FlashSalePlan` and `FlashSaleResult` --- ...cs => CreateFlashSaleOrderEventHandler.cs} | 13 +- ...sFlashSalesApplicationAutoMapperProfile.cs | 12 +- ...rdersPluginsFlashSalesApplicationModule.cs | 5 - .../FlashSalePlans/Dtos/CreateOrderInput.cs | 8 + .../Dtos/FlashSalePlanCreateDto.cs} | 4 +- .../Dtos/FlashSalePlanDto.cs} | 6 +- .../Dtos/FlashSalePlanGetListInput.cs} | 4 +- .../Dtos/FlashSalePlanUpdateDto.cs} | 4 +- .../IFlashSalePlanAppService.cs | 21 +++ .../Dtos/FlashSaleResultDto.cs} | 6 +- .../Dtos/FlashSaleResultGetListInput.cs} | 6 +- .../IFlashSaleResultAppService.cs | 14 ++ .../FlashSalesPlans/Dtos/CreateOrderInput.cs | 9 -- .../IFlashSalesPlanAppService.cs | 21 --- .../IFlashSalesResultAppService.cs | 14 -- .../FlashSalesPermissionDefinitionProvider.cs | 16 +- .../Permissions/FlashSalesPermissions.cs | 8 +- .../FlashSalePlanAppService.cs} | 145 +++++++++--------- .../FlashSalePlanCacheInvalidator.cs} | 11 +- .../FlashSalePlanCacheItem.cs} | 4 +- .../ProductIsNotInThisStoreException.cs | 0 .../ProductSkuIsNotFoundException.cs | 0 .../RelatedFlashSaleResultsExistException.cs} | 4 +- .../UnexpectedInventoryStrategyException.cs | 0 .../FlashSaleResultAppService.cs} | 21 +-- .../FlashSalesApplicationAutoMapperProfile.cs | 19 +-- .../CreateFlashSaleOrderCompleteEto.cs} | 2 +- .../CreateFlashSaleOrderEto.cs} | 11 +- .../FlashSalePlanEto.cs} | 4 +- .../FlashSalePlanHasher.cs} | 4 +- .../FlashSaleProductAttributeEto.cs} | 6 +- .../FlashSaleProductAttributeOptionEto.cs} | 4 +- .../FlashSaleProductDetailEto.cs} | 4 +- .../FlashSaleProductEto.cs} | 8 +- .../FlashSaleProductSkuEto.cs} | 4 +- .../FlashSaleReduceInventoryEto.cs} | 6 +- .../IFlashSalePlanHasher.cs} | 4 +- .../FlashSaleResultFailedReason.cs} | 4 +- .../FlashSaleResults/FlashSaleResultStatus.cs | 8 + .../FlashSales/FlashSalesErrorCodes.cs | 2 +- .../FlashSalesResultStatus.cs | 8 - .../Plugins/FlashSales/Localization/en.json | 64 ++++---- .../FlashSales/Localization/zh-Hans.json | 62 ++++---- .../FlashSales/Localization/zh-Hant.json | 62 ++++---- ...luginsFlashSalesDomainAutoMapperProfile.cs | 4 +- .../EShopPluginsFlashSalesDomainModule.cs | 6 +- .../FlashSalePlan.cs} | 8 +- .../IFlashSalePlanRepository.cs | 8 + .../InvalidEndTimeException.cs | 2 +- ...eateFlashSaleOrderCompleteEventHandler.cs} | 10 +- .../FlashSaleResult.cs} | 14 +- .../IFlashSaleResultRepository.cs | 9 ++ .../IFlashSalesPlanRepository.cs | 8 - .../IFlashSalesResultRepository.cs | 9 -- ...ginsFlashSalesEntityFrameworkCoreModule.cs | 8 +- .../FlashSalesDbContext.cs | 8 +- ...shSalesDbContextModelCreatingExtensions.cs | 12 +- .../IFlashSalesDbContext.cs | 8 +- .../EfCoreFlashSalePlanRepository.cs | 21 +++ .../FlashSalePlanEfCoreQuerableExtensions.cs | 18 +++ .../EfCoreFlashSaleResultRepository.cs | 20 +++ ...FlashSaleResultEfCoreQuerableExtensions.cs | 16 ++ .../EfCoreFlashSalesPlanRepository.cs | 21 --- .../FlashSalesPlanEfCoreQuerableExtensions.cs | 18 --- .../EfCoreFlashSalesResultRepository.cs | 20 --- ...lashSalesResultEfCoreQuerableExtensions.cs | 16 -- .../FlashSalePlanController.cs} | 24 +-- .../FlashSaleResultController.cs | 33 ++++ .../FlashSalesResultController.cs | 33 ---- .../MongoFlashSalePlanRepository.cs | 13 ++ .../MongoFlashSaleResultRepository.cs | 13 ++ .../MongoFlashSalesPlanRepository.cs | 13 -- .../MongoFlashSalesResultRepository.cs | 13 -- .../EShopPluginsFlashSalesMongoDbModule.cs | 8 +- .../MongoDB/FlashSalesMongoDbContext.cs | 8 +- .../FlashSalesMongoDbContextExtensions.cs | 8 +- .../MongoDB/IFlashSalesMongoDbContext.cs | 8 +- ...opPluginsFlashSalesWebAutoMapperProfile.cs | 16 +- ...asyAbp.EShop.Plugins.FlashSales.Web.csproj | 5 - .../Menus/FlashSalesMenuContributor.cs | 16 +- .../Menus/FlashSalesMenus.cs | 4 +- .../FlashSalePlan}/CreateModal.cshtml | 4 +- .../FlashSalePlan/CreateModal.cshtml.cs | 27 ++++ .../FlashSalePlan}/EditModal.cshtml | 4 +- .../FlashSalePlan}/EditModal.cshtml.cs | 18 +-- .../FlashSalePlan}/Index.cshtml | 22 +-- .../FlashSalePlan}/Index.cshtml.cs | 2 +- .../CreateFlashSalePlanViewModel.cs | 25 +++ .../ViewModels/EditFlashSalePlanViewModel.cs} | 16 +- .../FlashSalePlan}/index.css | 0 .../FlashSalePlan}/index.js | 28 ++-- .../FlashSaleResult}/Index.cshtml | 16 +- .../FlashSaleResult}/Index.cshtml.cs | 2 +- .../FlashSaleResult}/ViewModal.cshtml | 4 +- .../FlashSaleResult}/ViewModal.cshtml.cs | 16 +- .../ViewFlashSaleResultViewModel.cs | 26 ++++ .../FlashSaleResult}/index.css | 0 .../FlashSaleResult}/index.js | 24 +-- .../FlashSalesPlan/CreateModal.cshtml.cs | 27 ---- .../CreateFlashSalesPlanViewModel.cs | 25 --- .../ViewFlashSalesResultViewModel.cs | 26 ---- ...sFlashSalesApplicationAutoMapperProfile.cs | 12 +- ...> FlashSaleReduceInventoryEventHandler.cs} | 31 ++-- ...0220706160700_AddedFlashSales.Designer.cs} | 10 +- ...s.cs => 20220706160700_AddedFlashSales.cs} | 12 +- .../EShopSampleDbContextModelSnapshot.cs | 8 +- 106 files changed, 750 insertions(+), 756 deletions(-) rename plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/{CreateFlashSalesOrderEventHandler.cs => CreateFlashSaleOrderEventHandler.cs} (85%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderInput.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs => FlashSalePlans/Dtos/FlashSalePlanCreateDto.cs} (71%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/Dtos/FlashSalesPlanDto.cs => FlashSalePlans/Dtos/FlashSalePlanDto.cs} (71%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs => FlashSalePlans/Dtos/FlashSalePlanGetListInput.cs} (68%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs => FlashSalePlans/Dtos/FlashSalePlanUpdateDto.cs} (70%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesResults/Dtos/FlashSalesResultDto.cs => FlashSaleResults/Dtos/FlashSaleResultDto.cs} (59%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs => FlashSaleResults/Dtos/FlashSaleResultGetListInput.cs} (53%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlanAppService.cs => FlashSalePlans/FlashSalePlanAppService.cs} (66%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs => FlashSalePlans/FlashSalePlanCacheInvalidator.cs} (64%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlanCacheItem.cs => FlashSalePlans/FlashSalePlanCacheItem.cs} (53%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans => FlashSalePlans}/ProductIsNotInThisStoreException.cs (100%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans => FlashSalePlans}/ProductSkuIsNotFoundException.cs (100%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs => FlashSalePlans/RelatedFlashSaleResultsExistException.cs} (50%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans => FlashSalePlans}/UnexpectedInventoryStrategyException.cs (100%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResultAppService.cs => FlashSaleResults/FlashSaleResultAppService.cs} (64%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs => FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs} (85%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/CreateFlashSalesOrderEto.cs => FlashSalePlans/CreateFlashSaleOrderEto.cs} (56%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlanEto.cs => FlashSalePlans/FlashSalePlanEto.cs} (74%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlanHasher.cs => FlashSalePlans/FlashSalePlanHasher.cs} (85%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesProductAttributeEto.cs => FlashSalePlans/FlashSaleProductAttributeEto.cs} (50%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs => FlashSalePlans/FlashSaleProductAttributeOptionEto.cs} (55%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/ProductDetailEto.cs => FlashSalePlans/FlashSaleProductDetailEto.cs} (56%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesProductEto.cs => FlashSalePlans/FlashSaleProductEto.cs} (74%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesProductSkuEto.cs => FlashSalePlans/FlashSaleProductSkuEto.cs} (81%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesReduceInventoryEto.cs => FlashSalePlans/FlashSaleReduceInventoryEto.cs} (72%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/IFlashSalesPlanHasher.cs => FlashSalePlans/IFlashSalePlanHasher.cs} (66%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResultFailedReason.cs => FlashSaleResults/FlashSaleResultFailedReason.cs} (57%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatus.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan.cs => FlashSalePlans/FlashSalePlan.cs} (78%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanRepository.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans => FlashSalePlans}/InvalidEndTimeException.cs (75%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs => FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs} (61%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResult.cs => FlashSaleResults/FlashSaleResult.cs} (63%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultRepository.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/EfCoreFlashSalePlanRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanEfCoreQuerableExtensions.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/EfCoreFlashSaleResultRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultEfCoreQuerableExtensions.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlanController.cs => FlashSalePlans/FlashSalePlanController.cs} (60%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/MongoFlashSalePlanRepository.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/MongoFlashSaleResultRepository.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan => FlashSalePlans/FlashSalePlan}/CreateModal.cshtml (80%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal.cshtml.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan => FlashSalePlans/FlashSalePlan}/EditModal.cshtml (84%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan => FlashSalePlans/FlashSalePlan}/EditModal.cshtml.cs (52%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan => FlashSalePlans/FlashSalePlan}/Index.cshtml (53%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan => FlashSalePlans/FlashSalePlan}/Index.cshtml.cs (83%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/ViewModels/CreateFlashSalePlanViewModel.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs => FlashSalePlans/FlashSalePlan/ViewModels/EditFlashSalePlanViewModel.cs} (59%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan => FlashSalePlans/FlashSalePlan}/index.css (100%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesPlans/FlashSalesPlan => FlashSalePlans/FlashSalePlan}/index.js (75%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResult => FlashSaleResults/FlashSaleResult}/Index.cshtml (55%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResult => FlashSaleResults/FlashSaleResult}/Index.cshtml.cs (81%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResult => FlashSaleResults/FlashSaleResult}/ViewModal.cshtml (80%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResult => FlashSaleResults/FlashSaleResult}/ViewModal.cshtml.cs (50%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResult => FlashSaleResults/FlashSaleResult}/index.css (100%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/{FlashSalesResults/FlashSalesResult => FlashSaleResults/FlashSaleResult}/index.js (65%) delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs rename plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/{FlashSalesReduceInventoryEventHandler.cs => FlashSaleReduceInventoryEventHandler.cs} (73%) rename samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/{20220626174330_AddedFlashSales.Designer.cs => 20220706160700_AddedFlashSales.Designer.cs} (99%) rename samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/{20220626174330_AddedFlashSales.cs => 20220706160700_AddedFlashSales.cs} (92%) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs similarity index 85% rename from plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index 2e524250..7866406c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSalesOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using EasyAbp.EShop.Orders.Orders.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; using EasyAbp.EShop.Products.ProductDetails.Dtos; using EasyAbp.EShop.Products.Products.Dtos; @@ -12,7 +13,7 @@ using Volo.Abp.Uow; namespace EasyAbp.EShop.Orders.Orders; -public class CreateFlashSalesOrderEventHandler : IDistributedEventHandler, ITransientDependency +public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler, ITransientDependency { protected INewOrderGenerator NewOrderGenerator { get; } @@ -24,7 +25,7 @@ public class CreateFlashSalesOrderEventHandler : IDistributedEventHandler orderDiscountProviders, @@ -39,7 +40,7 @@ public class CreateFlashSalesOrderEventHandler : IDistributedEventHandler() { - {eventData.Product.Id, ObjectMapper.Map(eventData.Product)} + {eventData.Product.Id, ObjectMapper.Map(eventData.Product)} }; var productDetailDict = new Dictionary() { - {eventData.ProductDetail.Id, ObjectMapper.Map(eventData.ProductDetail)} + {eventData.ProductDetail.Id, ObjectMapper.Map(eventData.ProductDetail)} }; var order = await NewOrderGenerator.GenerateAsync(eventData.UserId, input, productDict, productDetailDict); @@ -70,7 +71,7 @@ public class CreateFlashSalesOrderEventHandler : IDistributedEventHandler(MemberList.Destination) + CreateMap(MemberList.Destination) .Ignore(dto => dto.Sold) .Ignore(dto => dto.MinimumPrice) .Ignore(dto => dto.MaximumPrice) .MapExtraProperties(); - CreateMap(MemberList.Destination) + CreateMap(MemberList.Destination) .ForSourceMember(entity => entity.SerializedAttributeOptionIds, opt => opt.DoNotValidate()) .Ignore(dto => dto.DiscountedPrice) .Ignore(dto => dto.Inventory) .Ignore(dto => dto.Sold) .MapExtraProperties(); - CreateMap(MemberList.Destination) + CreateMap(MemberList.Destination) .MapExtraProperties(); - CreateMap(MemberList.Destination) + CreateMap(MemberList.Destination) .MapExtraProperties(); - CreateMap(MemberList.Destination) + CreateMap(MemberList.Destination) .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs index 75ba925b..1f38ffa1 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs @@ -15,11 +15,6 @@ namespace EasyAbp.EShop.Orders.Plugins.FlashSales; )] public class EShopOrdersPluginsFlashSalesApplicationModule : AbpModule { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddSingleton(); - } - public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAutoMapperObjectMapper(); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderInput.cs new file mode 100644 index 00000000..a9661459 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderInput.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; + +public class CreateOrderInput : ExtensibleEntityDto +{ + public string CustomerRemark { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanCreateDto.cs similarity index 71% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanCreateDto.cs index c8848d1d..40b5d80c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanCreateDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanCreateDto.cs @@ -2,10 +2,10 @@ using System; using EasyAbp.EShop.Stores.Stores; using Volo.Abp.Application.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; [Serializable] -public class FlashSalesPlanCreateDto : ExtensibleEntityDto, IMultiStore +public class FlashSalePlanCreateDto : ExtensibleEntityDto, IMultiStore { public Guid StoreId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanDto.cs similarity index 71% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanDto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanDto.cs index d488fe6d..5e16106e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanDto.cs @@ -2,10 +2,10 @@ using System; using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Entities; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; [Serializable] -public class FlashSalesPlanDto : ExtensibleFullAuditedEntityDto, IHasConcurrencyStamp +public class FlashSalePlanDto : ExtensibleFullAuditedEntityDto, IHasConcurrencyStamp { public Guid StoreId { get; set; } @@ -18,6 +18,6 @@ public class FlashSalesPlanDto : ExtensibleFullAuditedEntityDto, IHasConcu public Guid ProductSkuId { get; set; } public bool IsPublished { get; set; } - + public string ConcurrencyStamp { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanGetListInput.cs similarity index 68% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanGetListInput.cs index 13a623dd..9192589a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanGetListInput.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanGetListInput.cs @@ -1,10 +1,10 @@ using System; using Volo.Abp.Application.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; [Serializable] -public class FlashSalesPlanGetListInput : ExtensiblePagedAndSortedResultRequestDto +public class FlashSalePlanGetListInput : ExtensiblePagedAndSortedResultRequestDto { public Guid? StoreId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanUpdateDto.cs similarity index 70% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanUpdateDto.cs index 269fc645..0a4075f3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/FlashSalesPlanUpdateDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanUpdateDto.cs @@ -2,10 +2,10 @@ using System; using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Entities; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; [Serializable] -public class FlashSalesPlanUpdateDto : ExtensibleEntityDto, IHasConcurrencyStamp +public class FlashSalePlanUpdateDto : ExtensibleEntityDto, IHasConcurrencyStamp { public DateTime BeginTime { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs new file mode 100644 index 00000000..d7b58b48 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs @@ -0,0 +1,21 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using Volo.Abp.Application.Services; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public interface IFlashSalePlanAppService : + ICrudAppService< + FlashSalePlanDto, + Guid, + FlashSalePlanGetListInput, + FlashSalePlanCreateDto, + FlashSalePlanUpdateDto> +{ + Task PreOrderAsync(Guid id); + + Task CheckPreOrderAsync(Guid id); + + Task CreateOrderAsync(Guid id, CreateOrderInput input); +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs similarity index 59% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultDto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs index 8cd4cd9f..db177a87 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs @@ -1,15 +1,15 @@ using System; using Volo.Abp.Application.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; -public class FlashSalesResultDto : ExtensibleFullAuditedEntityDto +public class FlashSaleResultDto : ExtensibleFullAuditedEntityDto { public virtual Guid StoreId { get; set; } public virtual Guid PlanId { get; set; } - public virtual FlashSalesResultStatus Status { get; set; } + public virtual FlashSaleResultStatus Status { get; set; } public virtual string Reason { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultGetListInput.cs similarity index 53% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultGetListInput.cs index 4b063273..b5e0b823 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/Dtos/FlashSalesResultGetListInput.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultGetListInput.cs @@ -1,15 +1,15 @@ using System; using Volo.Abp.Application.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; -public class FlashSalesResultGetListInput : ExtensiblePagedAndSortedResultRequestDto +public class FlashSaleResultGetListInput : ExtensiblePagedAndSortedResultRequestDto { public virtual Guid? StoreId { get; set; } public virtual Guid? PlanId { get; set; } - public virtual FlashSalesResultStatus? Status { get; set; } + public virtual FlashSaleResultStatus? Status { get; set; } public virtual Guid? UserId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs new file mode 100644 index 00000000..3c1bce94 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs @@ -0,0 +1,14 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using Volo.Abp.Application.Services; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public interface IFlashSaleResultAppService : + IReadOnlyAppService< + FlashSaleResultDto, + Guid, + FlashSaleResultGetListInput> +{ + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs deleted file mode 100644 index b696292b..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/Dtos/CreateOrderInput.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Volo.Abp.Application.Dtos; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; - -public class CreateOrderInput : ExtensibleEntityDto -{ - public string CustomerRemark { get; set; } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs deleted file mode 100644 index 0dcaafc6..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanAppService.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; -using Volo.Abp.Application.Services; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; - -public interface IFlashSalesPlanAppService : - ICrudAppService< - FlashSalesPlanDto, - Guid, - FlashSalesPlanGetListInput, - FlashSalesPlanCreateDto, - FlashSalesPlanUpdateDto> -{ - Task PreOrderAsync(Guid id); - - Task CheckPreOrderAsync(Guid id); - - Task CreateOrderAsync(Guid id, CreateOrderInput input); -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs deleted file mode 100644 index 0b9a013e..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultAppService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; -using Volo.Abp.Application.Services; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -public interface IFlashSalesResultAppService : - IReadOnlyAppService< - FlashSalesResultDto, - Guid, - FlashSalesResultGetListInput> -{ - -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs index f4edc186..fa604608 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs @@ -10,15 +10,15 @@ public class FlashSalesPermissionDefinitionProvider : PermissionDefinitionProvid { var myGroup = context.AddGroup(FlashSalesPermissions.GroupName, L("Permission:FlashSales")); - var flashSalesPlanPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSalesPlan.Default, L("Permission:FlashSalesPlan")); - flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Manage, L("Permission:Manage")); - flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.CrossStore, L("Permission:CrossStore")); - flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Create, L("Permission:Create")); - flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Update, L("Permission:Update")); - flashSalesPlanPermission.AddChild(FlashSalesPermissions.FlashSalesPlan.Delete, L("Permission:Delete")); + var flashSalePlanPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSalePlan.Default, L("Permission:FlashSalePlan")); + flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.Manage, L("Permission:Manage")); + flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.CrossStore, L("Permission:CrossStore")); + flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.Create, L("Permission:Create")); + flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.Update, L("Permission:Update")); + flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.Delete, L("Permission:Delete")); - var flashSalesResultPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSalesResult.Default, L("Permission:FlashSalesResult")); - flashSalesResultPermission.AddChild(FlashSalesPermissions.FlashSalesResult.Manage, L("Permission:Manage")); + var flashSaleResultPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSaleResult.Default, L("Permission:FlashSaleResult")); + flashSaleResultPermission.AddChild(FlashSalesPermissions.FlashSaleResult.Manage, L("Permission:Manage")); } private static LocalizableString L(string name) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs index d7202cf5..4259a5f3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs @@ -11,9 +11,9 @@ public class FlashSalesPermissions return ReflectionHelper.GetPublicConstantsRecursively(typeof(FlashSalesPermissions)); } - public class FlashSalesPlan + public class FlashSalePlan { - public const string Default = GroupName + ".FlashSalesPlan"; + public const string Default = GroupName + ".FlashSalePlan"; public const string Manage = Default + ".Manage"; public const string CrossStore = Default + ".CrossStore"; public const string Update = Default + ".Update"; @@ -21,9 +21,9 @@ public class FlashSalesPermissions public const string Delete = Default + ".Delete"; } - public class FlashSalesResult + public class FlashSaleResult { - public const string Default = GroupName + ".FlashSalesResult"; + public const string Default = GroupName + ".FlashSaleResult"; public const string Manage = Default + ".Manage"; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs similarity index 66% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index ac8c24f2..4dad2b85 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -1,8 +1,9 @@ using System; using System.Linq; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; @@ -21,69 +22,69 @@ using Volo.Abp.Users; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; [Authorize] -public class FlashSalesPlanAppService : - MultiStoreCrudAppService, - IFlashSalesPlanAppService +public class FlashSalePlanAppService : + MultiStoreCrudAppService, + IFlashSalePlanAppService { - protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.CrossStore; + protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.CrossStore; protected override string GetPolicyName { get; set; } protected override string GetListPolicyName { get; set; } - protected override string CreatePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Create; - protected override string UpdatePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Update; - protected override string DeletePolicyName { get; set; } = FlashSalesPermissions.FlashSalesPlan.Delete; + protected override string CreatePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Create; + protected override string UpdatePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Update; + protected override string DeletePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Delete; - protected IFlashSalesPlanRepository FlashSalesPlanRepository { get; } + protected IFlashSalePlanRepository FlashSalePlanRepository { get; } protected IProductAppService ProductAppService { get; } protected IDistributedCache TokenDistributedCache { get; } - protected IDistributedCache DistributedCache { get; } + protected IDistributedCache DistributedCache { get; } protected IDistributedEventBus DistributedEventBus { get; } - protected IFlashSalesResultRepository FlashSalesResultRepository { get; } + protected IFlashSaleResultRepository FlashSaleResultRepository { get; } protected IAbpDistributedLock DistributedLock { get; } - protected IFlashSalesPlanHasher FlashSalesPlanHasher { get; } + protected IFlashSalePlanHasher FlashSalesPlanHasher { get; } - public FlashSalesPlanAppService( - IFlashSalesPlanRepository flashSalesPlanRepository, + public FlashSalePlanAppService( + IFlashSalePlanRepository flashSalePlanRepository, IProductAppService productAppService, IDistributedCache tokenDistributedCache, - IDistributedCache distributedCache, + IDistributedCache distributedCache, IDistributedEventBus distributedEventBus, - IFlashSalesResultRepository flashSalesResultRepository, + IFlashSaleResultRepository flashSaleResultRepository, IAbpDistributedLock distributedLock, - IFlashSalesPlanHasher flashSalesPlanHasher) - : base(flashSalesPlanRepository) + IFlashSalePlanHasher flashSalesPlanHasher) + : base(flashSalePlanRepository) { - FlashSalesPlanRepository = flashSalesPlanRepository; + FlashSalePlanRepository = flashSalePlanRepository; ProductAppService = productAppService; TokenDistributedCache = tokenDistributedCache; DistributedCache = distributedCache; DistributedEventBus = distributedEventBus; - FlashSalesResultRepository = flashSalesResultRepository; + FlashSaleResultRepository = flashSaleResultRepository; DistributedLock = distributedLock; FlashSalesPlanHasher = flashSalesPlanHasher; } - public override async Task GetAsync(Guid id) + public override async Task GetAsync(Guid id) { - var flashSalesPlan = await GetEntityByIdAsync(id); + var flashSalePlan = await GetEntityByIdAsync(id); - await CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, GetPolicyName); + await CheckMultiStorePolicyAsync(flashSalePlan.StoreId, GetPolicyName); - if (!flashSalesPlan.IsPublished) + if (!flashSalePlan.IsPublished) { - await CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, FlashSalesPermissions.FlashSalesPlan.Manage); + await CheckMultiStorePolicyAsync(flashSalePlan.StoreId, FlashSalesPermissions.FlashSalePlan.Manage); } - return await MapToGetOutputDtoAsync(flashSalesPlan); + return await MapToGetOutputDtoAsync(flashSalePlan); } - public override async Task CreateAsync(FlashSalesPlanCreateDto input) + public override async Task CreateAsync(FlashSalePlanCreateDto input) { await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); @@ -92,7 +93,7 @@ public class FlashSalesPlanAppService : await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, input.StoreId); - var flashSalesPlan = new FlashSalesPlan( + var flashSalePlan = new FlashSalePlan( GuidGenerator.Create(), CurrentTenant.Id, input.StoreId, @@ -103,56 +104,56 @@ public class FlashSalesPlanAppService : input.IsPublished ); - await FlashSalesPlanRepository.InsertAsync(flashSalesPlan, autoSave: true); + await FlashSalePlanRepository.InsertAsync(flashSalePlan, autoSave: true); - return await MapToGetOutputDtoAsync(flashSalesPlan); + return await MapToGetOutputDtoAsync(flashSalePlan); } - public override async Task UpdateAsync(Guid id, FlashSalesPlanUpdateDto input) + public override async Task UpdateAsync(Guid id, FlashSalePlanUpdateDto input) { - var flashSalesPlan = await GetEntityByIdAsync(id); + var flashSalePlan = await GetEntityByIdAsync(id); var product = await ProductAppService.GetAsync(input.ProductId); var productSku = product.GetSkuById(input.ProductSkuId); await CheckMultiStorePolicyAsync(product.StoreId, UpdatePolicyName); - await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, flashSalesPlan.StoreId); + await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, flashSalePlan.StoreId); - if (await ExistRelatedFlashSalesResultsAsync(id) && (input.ProductId != flashSalesPlan.ProductId || input.ProductSkuId != flashSalesPlan.ProductSkuId)) + if (await ExistRelatedFlashSalesResultsAsync(id) && (input.ProductId != flashSalePlan.ProductId || input.ProductSkuId != flashSalePlan.ProductSkuId)) { - throw new ExistRelatedFlashSalesResultsException(id); + throw new RelatedFlashSaleResultsExistException(id); } - flashSalesPlan.SetTimeRange(input.BeginTime, input.EndTime); - flashSalesPlan.SetProductSku(flashSalesPlan.StoreId, input.ProductId, input.ProductSkuId); - flashSalesPlan.SetPublished(input.IsPublished); + flashSalePlan.SetTimeRange(input.BeginTime, input.EndTime); + flashSalePlan.SetProductSku(flashSalePlan.StoreId, input.ProductId, input.ProductSkuId); + flashSalePlan.SetPublished(input.IsPublished); - flashSalesPlan.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); + flashSalePlan.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); - await FlashSalesPlanRepository.UpdateAsync(flashSalesPlan, autoSave: true); + await FlashSalePlanRepository.UpdateAsync(flashSalePlan, autoSave: true); - return await MapToGetOutputDtoAsync(flashSalesPlan); + return await MapToGetOutputDtoAsync(flashSalePlan); } public override async Task DeleteAsync(Guid id) { - var flashSalesPlan = await GetEntityByIdAsync(id); + var flashSalePlan = await GetEntityByIdAsync(id); - await CheckMultiStorePolicyAsync(flashSalesPlan.StoreId, DeletePolicyName); + await CheckMultiStorePolicyAsync(flashSalePlan.StoreId, DeletePolicyName); if (await ExistRelatedFlashSalesResultsAsync(id)) { - throw new ExistRelatedFlashSalesResultsException(id); + throw new RelatedFlashSaleResultsExistException(id); } - await FlashSalesPlanRepository.DeleteAsync(flashSalesPlan); + await FlashSalePlanRepository.DeleteAsync(flashSalePlan); } - protected override async Task> CreateFilteredQueryAsync(FlashSalesPlanGetListInput input) + protected override async Task> CreateFilteredQueryAsync(FlashSalePlanGetListInput input) { if (input.IncludeUnpublished) { - await CheckMultiStorePolicyAsync(input.StoreId, FlashSalesPermissions.FlashSalesPlan.Manage); + await CheckMultiStorePolicyAsync(input.StoreId, FlashSalesPermissions.FlashSalePlan.Manage); } return (await base.CreateFilteredQueryAsync(input)) @@ -166,7 +167,7 @@ public class FlashSalesPlanAppService : public virtual async Task PreOrderAsync(Guid id) { - var plan = await GetFlashSalesPlanCacheAsync(id); + var plan = await GetFlashSalePlanCacheAsync(id); var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); @@ -177,7 +178,7 @@ public class FlashSalesPlanAppService : public virtual async Task CheckPreOrderAsync(Guid id) { - var plan = await GetFlashSalesPlanCacheAsync(id); + var plan = await GetFlashSalePlanCacheAsync(id); var cacheHashToken = await GetCacheHashTokenAsync(plan); if (cacheHashToken.IsNullOrWhiteSpace()) @@ -198,7 +199,7 @@ public class FlashSalesPlanAppService : public virtual async Task CreateOrderAsync(Guid id, CreateOrderInput input) { - var plan = await GetFlashSalesPlanCacheAsync(id); + var plan = await GetFlashSalePlanCacheAsync(id); var now = Clock.Now; if (plan.BeginTime > now) { @@ -231,18 +232,18 @@ public class FlashSalesPlanAppService : await DistributedEventBus.PublishAsync(flashSalesReduceInventoryEto); } - protected virtual Task PrepareFlashSalesReduceInventoryEtoAsync( - FlashSalesPlanCacheItem plan, + protected virtual Task PrepareFlashSalesReduceInventoryEtoAsync( + FlashSalePlanCacheItem plan, Guid resultId, CreateOrderInput input, Guid userId, DateTime now, string hashToken) { - var planEto = ObjectMapper.Map(plan); + var planEto = ObjectMapper.Map(plan); planEto.TenantId = CurrentTenant.Id; - var eto = new FlashSalesReduceInventoryEto() + var eto = new FlashSaleReduceInventoryEto() { TenantId = CurrentTenant.Id, PlanId = plan.Id, @@ -264,31 +265,31 @@ public class FlashSalesPlanAppService : return Task.FromResult(eto); } - protected virtual async Task GetFlashSalesPlanCacheAsync(Guid id) + protected virtual async Task GetFlashSalePlanCacheAsync(Guid id) { return await DistributedCache.GetOrAddAsync(id, async () => { - var flashSalesPlan = await FlashSalesPlanRepository.GetAsync(id); - return ObjectMapper.Map(flashSalesPlan); + var flashSalesPlan = await FlashSalePlanRepository.GetAsync(id); + return ObjectMapper.Map(flashSalesPlan); }); } - protected virtual Task GetCacheKeyAsync(FlashSalesPlanCacheItem plan) + protected virtual Task GetCacheKeyAsync(FlashSalePlanCacheItem plan) { return Task.FromResult($"eshopflashsales_{CurrentTenant.Id}_{CurrentUser.Id}_{plan.ProductSkuId}"); } - protected virtual async Task GetCacheHashTokenAsync(FlashSalesPlanCacheItem plan) + protected virtual async Task GetCacheHashTokenAsync(FlashSalePlanCacheItem plan) { return await TokenDistributedCache.GetStringAsync(await GetCacheKeyAsync(plan)); } - protected virtual async Task RemoveCacheHashTokenAsync(FlashSalesPlanCacheItem plan) + protected virtual async Task RemoveCacheHashTokenAsync(FlashSalePlanCacheItem plan) { await TokenDistributedCache.RemoveAsync(await GetCacheKeyAsync(plan)); } - protected virtual async Task SetCacheHashTokenAsync(FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + protected virtual async Task SetCacheHashTokenAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { var hashToken = await FlashSalesPlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); @@ -298,7 +299,7 @@ public class FlashSalesPlanAppService : }); } - protected virtual async Task CompareHashTokenAsync(string cacheHashToken, FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + protected virtual async Task CompareHashTokenAsync(string cacheHashToken, FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (cacheHashToken.IsNullOrWhiteSpace()) { @@ -310,7 +311,7 @@ public class FlashSalesPlanAppService : return cacheHashToken == hashToken; } - protected virtual async Task CreatePendingFlashSalesResultAsync(FlashSalesPlanCacheItem plan, Guid userId) + protected virtual async Task CreatePendingFlashSalesResultAsync(FlashSalePlanCacheItem plan, Guid userId) { var lockKey = $"create-flash-sales-order-{plan.Id}-{userId}"; @@ -322,27 +323,27 @@ public class FlashSalesPlanAppService : } // Prevent repeat submit - if (await FlashSalesResultRepository.AnyAsync(x => - x.PlanId == plan.Id && x.UserId == userId && (x.Status == FlashSalesResultStatus.Successful || x.Status == FlashSalesResultStatus.Pending)) + if (await FlashSaleResultRepository.AnyAsync(x => + x.PlanId == plan.Id && x.UserId == userId && (x.Status == FlashSaleResultStatus.Successful || x.Status == FlashSaleResultStatus.Pending)) ) { throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); } - var result = new FlashSalesResult( + var result = new FlashSaleResult( id: GuidGenerator.Create(), tenantId: CurrentTenant.Id, storeId: plan.StoreId, planId: plan.Id, - status: FlashSalesResultStatus.Pending, + status: FlashSaleResultStatus.Pending, reason: null, userId: userId, orderId: null ); - return await FlashSalesResultRepository.InsertAsync(result, autoSave: true); + return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); } - protected virtual Task ValidatePreOrderAsync(FlashSalesPlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + protected virtual Task ValidatePreOrderAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (!product.IsPublished) { @@ -356,7 +357,7 @@ public class FlashSalesPlanAppService : if (!plan.IsPublished) { - throw new EntityNotFoundException(typeof(FlashSalesPlan), plan.Id); + throw new EntityNotFoundException(typeof(FlashSalePlan), plan.Id); } if (Clock.Now >= plan.EndTime) @@ -374,7 +375,7 @@ public class FlashSalesPlanAppService : protected virtual async Task ExistRelatedFlashSalesResultsAsync(Guid planId) { - return await FlashSalesResultRepository.AnyAsync(x => x.PlanId == planId); + return await FlashSaleResultRepository.AnyAsync(x => x.PlanId == planId); } protected virtual Task ValidateCreateOrUpdateProductAsync(Guid productId, ProductDto product, Guid productSkuId, ProductSkuDto productSku, Guid storeId) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs similarity index 64% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs index 1fb0f488..1b56092a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheInvalidator.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events; @@ -8,20 +9,20 @@ using Volo.Abp.Uow; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -public class FlashSalesPlanCacheInvalidator : ILocalEventHandler>, ITransientDependency +public class FlashSalePlanCacheInvalidator : ILocalEventHandler>, ITransientDependency { - protected IDistributedCache DistributedCache { get; } + protected IDistributedCache DistributedCache { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; } - public FlashSalesPlanCacheInvalidator( - IDistributedCache distributedCache, + public FlashSalePlanCacheInvalidator( + IDistributedCache distributedCache, IUnitOfWorkManager unitOfWorkManager) { DistributedCache = distributedCache; UnitOfWorkManager = unitOfWorkManager; } - public virtual Task HandleEventAsync(EntityChangedEventData eventData) + public virtual Task HandleEventAsync(EntityChangedEventData eventData) { UnitOfWorkManager.Current.OnCompleted(async () => { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs similarity index 53% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs index c6ea6537..0bb2d31e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanCacheItem.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs @@ -1,10 +1,10 @@ using System; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; [Serializable] -public class FlashSalesPlanCacheItem : FlashSalesPlanDto +public class FlashSalePlanCacheItem : FlashSalePlanDto { public Guid? TenantId { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductIsNotInThisStoreException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductIsNotInThisStoreException.cs similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductIsNotInThisStoreException.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductIsNotInThisStoreException.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductSkuIsNotFoundException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductSkuIsNotFoundException.cs similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductSkuIsNotFoundException.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductSkuIsNotFoundException.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RelatedFlashSaleResultsExistException.cs similarity index 50% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RelatedFlashSaleResultsExistException.cs index dcf50d5b..e0c9f49f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ExistRelatedFlashSalesResultsException.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RelatedFlashSaleResultsExistException.cs @@ -5,9 +5,9 @@ using Volo.Abp; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; [Serializable] -public class ExistRelatedFlashSalesResultsException : BusinessException +public class RelatedFlashSaleResultsExistException : BusinessException { - public ExistRelatedFlashSalesResultsException(Guid planId) : base(FlashSalesErrorCodes.ExistRelatedFlashSalesResults) + public RelatedFlashSaleResultsExistException(Guid planId) : base(FlashSalesErrorCodes.RelatedFlashSaleResultsExist) { WithData(nameof(planId), planId); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/UnexpectedInventoryStrategyException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/UnexpectedInventoryStrategyException.cs similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/UnexpectedInventoryStrategyException.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/UnexpectedInventoryStrategyException.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs similarity index 64% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultAppService.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index 854ca5e2..a710c0f4 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -1,26 +1,27 @@ using System; using System.Linq; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using Volo.Abp.Application.Services; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; -public class FlashSalesResultAppService : - ReadOnlyAppService, - IFlashSalesResultAppService +public class FlashSaleResultAppService : + ReadOnlyAppService, + IFlashSaleResultAppService { protected override string GetPolicyName { get; set; } protected override string GetListPolicyName { get; set; } - protected IFlashSalesResultRepository FlashSalesResultRepository { get; } + protected IFlashSaleResultRepository FlashSaleResultRepository { get; } - public FlashSalesResultAppService(IFlashSalesResultRepository flashSalesResultRepository) : base(flashSalesResultRepository) + public FlashSaleResultAppService(IFlashSaleResultRepository flashSalesResultRepository) : base(flashSalesResultRepository) { } - public override async Task GetAsync(Guid id) + public override async Task GetAsync(Guid id) { await CheckGetPolicyAsync(); @@ -28,17 +29,17 @@ public class FlashSalesResultAppService : if (flashSalesPlan.UserId != CurrentUser.Id) { - await CheckPolicyAsync(FlashSalesPermissions.FlashSalesResult.Manage); + await CheckPolicyAsync(FlashSalesPermissions.FlashSaleResult.Manage); } return await MapToGetOutputDtoAsync(flashSalesPlan); } - protected override async Task> CreateFilteredQueryAsync(FlashSalesResultGetListInput input) + protected override async Task> CreateFilteredQueryAsync(FlashSaleResultGetListInput input) { if (input.UserId != CurrentUser.Id) { - await CheckPolicyAsync(FlashSalesPermissions.FlashSalesResult.Manage); + await CheckPolicyAsync(FlashSalesPermissions.FlashSaleResult.Manage); } return (await base.CreateFilteredQueryAsync(input)) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs index 8e597523..51b1f941 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs @@ -1,8 +1,9 @@ using AutoMapper; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales; @@ -13,16 +14,16 @@ public class FlashSalesApplicationAutoMapperProfile : Profile /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ - CreateMap() + CreateMap() .MapExtraProperties(); - CreateMap(MemberList.Source); - CreateMap(MemberList.Source); - CreateMap() + CreateMap(MemberList.Source); + CreateMap(MemberList.Source); + CreateMap() .MapExtraProperties(); - CreateMap() + CreateMap() .MapExtraProperties(); - CreateMap() + CreateMap() .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs similarity index 85% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs index 6427320b..083afbfb 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderCompleteEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs @@ -4,7 +4,7 @@ using Volo.Abp.ObjectExtending; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -public class CreateFlashSalesOrderCompleteEto : ExtensibleObject, IMultiTenant +public class CreateFlashSaleOrderCompleteEto : ExtensibleObject, IMultiTenant { public Guid? TenantId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs similarity index 56% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs index 27a45274..df9dc25a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/CreateFlashSalesOrderEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs @@ -1,12 +1,11 @@ using System; -using EasyAbp.EShop.Products.Products; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class CreateFlashSalesOrderEto : ExtensibleObject, IMultiTenant +public class CreateFlashSaleOrderEto : ExtensibleObject, IMultiTenant { public Guid? TenantId { get; set; } @@ -24,9 +23,9 @@ public class CreateFlashSalesOrderEto : ExtensibleObject, IMultiTenant public int Quantity { get; set; } - public FlashSalesProductEto Product { get; set; } + public FlashSaleProductEto Product { get; set; } - public FlashSalesProductDetailEto ProductDetail { get; set; } + public FlashSaleProductDetailEto ProductDetail { get; set; } - public FlashSalesPlanEto Plan { get; set; } + public FlashSalePlanEto Plan { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanEto.cs similarity index 74% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanEto.cs index 06cc6fdd..275e352f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanEto.cs @@ -2,10 +2,10 @@ using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalesPlanEto : FullAuditedEntityEto, IMultiTenant +public class FlashSalePlanEto : FullAuditedEntityEto, IMultiTenant { public Guid? TenantId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanHasher.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasher.cs similarity index 85% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanHasher.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasher.cs index 069689c4..8531b8a7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanHasher.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasher.cs @@ -4,9 +4,9 @@ using System.Text; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public class FlashSalesPlanHasher : IFlashSalesPlanHasher, ITransientDependency +public class FlashSalePlanHasher : IFlashSalePlanHasher, ITransientDependency { public virtual Task HashAsync(DateTime? planLastModificationTime, DateTime? productLastModificationTime, DateTime? productSkuLastModificationTime) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeEto.cs similarity index 50% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeEto.cs index d68e06af..7e9f1e8c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeEto.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using EasyAbp.EShop.Products.Products; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalesProductAttributeEto : FullAuditedEntityEto, IProductAttribute +public class FlashSaleProductAttributeEto : FullAuditedEntityEto, IProductAttribute { public string DisplayName { get; set; } @@ -13,5 +13,5 @@ public class FlashSalesProductAttributeEto : FullAuditedEntityEto, IProduc public int DisplayOrder { get; set; } - public List ProductAttributeOptions { get; set; } + public List ProductAttributeOptions { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeOptionEto.cs similarity index 55% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeOptionEto.cs index 67116407..4548b41c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductAttributeOptionEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeOptionEto.cs @@ -1,10 +1,10 @@ using System; using EasyAbp.EShop.Products.Products; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalesProductAttributeOptionEto : FullAuditedEntityEto, IProductAttributeOption +public class FlashSaleProductAttributeOptionEto : FullAuditedEntityEto, IProductAttributeOption { public string DisplayName { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductDetailEto.cs similarity index 56% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductDetailEto.cs index 71e05917..9b2a267d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/ProductDetailEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductDetailEto.cs @@ -1,10 +1,10 @@ using System; using Volo.Abp.MultiTenancy; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalesProductDetailEto : FullAuditedEntityEto, IMultiTenant +public class FlashSaleProductDetailEto : FullAuditedEntityEto, IMultiTenant { public Guid? TenantId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductEto.cs similarity index 74% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductEto.cs index 57922d52..6fe3f12c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductEto.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; using EasyAbp.EShop.Products.Products; using Volo.Abp.MultiTenancy; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalesProductEto : FullAuditedEntityEto, IProduct, IMultiTenant +public class FlashSaleProductEto : FullAuditedEntityEto, IProduct, IMultiTenant { public Guid? TenantId { get; set; } @@ -38,7 +38,7 @@ public class FlashSalesProductEto : FullAuditedEntityEto, IProduct, IMulti public TimeSpan? PaymentExpireIn { get; set; } - public List ProductAttributes { get; set; } + public List ProductAttributes { get; set; } - public List ProductSkus { get; set; } + public List ProductSkus { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductSkuEto.cs similarity index 81% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductSkuEto.cs index 3df32c9b..c629db7f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesProductSkuEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductSkuEto.cs @@ -2,10 +2,10 @@ using System.Collections.Generic; using EasyAbp.EShop.Products.Products; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalesProductSkuEto : FullAuditedEntityEto, IProductSku +public class FlashSaleProductSkuEto : FullAuditedEntityEto, IProductSku { public List AttributeOptionIds { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesReduceInventoryEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs similarity index 72% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesReduceInventoryEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs index 4286811c..a77bfb77 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesReduceInventoryEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs @@ -2,10 +2,10 @@ using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalesReduceInventoryEto : ExtensibleObject, IMultiTenant +public class FlashSaleReduceInventoryEto : ExtensibleObject, IMultiTenant { public Guid? TenantId { get; set; } @@ -23,7 +23,7 @@ public class FlashSalesReduceInventoryEto : ExtensibleObject, IMultiTenant public int Quantity { get; set; } - public FlashSalesPlanEto Plan { get; set; } + public FlashSalePlanEto Plan { get; set; } public string HashToken { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanHasher.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanHasher.cs similarity index 66% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanHasher.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanHasher.cs index 153f7b11..6da39e91 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanHasher.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanHasher.cs @@ -1,9 +1,9 @@ using System; using System.Threading.Tasks; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public interface IFlashSalesPlanHasher +public interface IFlashSalePlanHasher { Task HashAsync(DateTime? planLastModificationTime, DateTime? productLastModificationTime, DateTime? productSkuLastModificationTime); } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultFailedReason.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs similarity index 57% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultFailedReason.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs index 76f3d5c7..e18b76cb 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultFailedReason.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs @@ -1,6 +1,6 @@ -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -public static class FlashSalesResultFailedReason +public static class FlashSaleResultFailedReason { public const string InsufficientInventory = nameof(InsufficientInventory); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatus.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatus.cs new file mode 100644 index 00000000..4b2c972b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatus.cs @@ -0,0 +1,8 @@ +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public enum FlashSaleResultStatus +{ + Pending = 0, + Successful = 1, + Failed = 2 +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index ba672872..5857aaba 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -26,5 +26,5 @@ public static class FlashSalesErrorCodes public const string DuplicateFlashSalesOrder = $"{Namespace}:{nameof(DuplicateFlashSalesOrder)}"; - public const string ExistRelatedFlashSalesResults = $"{Namespace}:{nameof(ExistRelatedFlashSalesResults)}"; + public const string RelatedFlashSaleResultsExist = $"{Namespace}:{nameof(RelatedFlashSaleResultsExist)}"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs deleted file mode 100644 index 2f242858..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultStatus.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -public enum FlashSalesResultStatus -{ - Pending = 0, - Successful = 1, - Failed = 2 -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json index c4a32c55..a0863199 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -6,47 +6,47 @@ "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "ProductSku '{productSkuId}' is not found", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "Product is not published", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "ProductSku inventory exceeded", - "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "Only the specified inventory strategy {expectedInventoryStrategy} is allowed.", + "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "Only the specified inventory strategy {expectedInventoryStrategy} product is allowed.", "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpired": "Pre order expired", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleNotStarted": "Flash-sale not started", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "Flash-sale is over", "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "Busy to create flash-sale order", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "Duplicate flash-sales order", - "EasyAbp.EShop.Plugins.FlashSales:ExistRelatedFlashSalesResults": "Exist Related flash-sales results", - "Menu:FlashSalesManagement": "FlashSales Management", - "Permission:FlashSalesPlan": "FlashSales Plan", + "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "Related flash-sales results exist", + "Menu:FlashSalesManagement": "Flash-Sales Management", + "Permission:FlashSalePlan": "FlashSale Plan", "Permission:Manage": "Manage", "Permission:Create": "Create", "Permission:Update": "Update", "Permission:Delete": "Delete", - "Menu:FlashSalesPlan": "FlashSales Plan", - "FlashSalesPlan": "FlashSales Plan", - "FlashSalesPlanStoreId": "Store ID", - "FlashSalesPlanBeginTime": "Begin Time", - "FlashSalesPlanEndTime": "End Time", - "FlashSalesPlanProductId": "Product ID", - "FlashSalesPlanProductSkuId": "Product SKU ID", - "FlashSalesPlanIsPublished": "Is Published", - "CreateFlashSalesPlan": "Create", - "EditFlashSalesPlan": "Edit", - "FlashSalesPlanDeletionConfirmationMessage": "Are you sure to delete the flashSalesPlan {0}?", + "Menu:FlashSalePlan": "Flash-Sale Plan", + "FlashSalePlan": "Flash-Sale Plan", + "FlashSalePlanStoreId": "Store ID", + "FlashSalePlanBeginTime": "Begin Time", + "FlashSalePlanEndTime": "End Time", + "FlashSalePlanProductId": "Product ID", + "FlashSalePlanProductSkuId": "Product SKU ID", + "FlashSalePlanIsPublished": "Is Published", + "CreateFlashSalePlan": "Create", + "EditFlashSalePlan": "Edit", + "FlashSalePlanDeletionConfirmationMessage": "Are you sure to delete the flash-sale plan {0}?", "SuccessfullyDeleted": "Successfully deleted", - "Permission:FlashSalesResult": "FlashSales Result", - "Menu:FlashSalesResult": "FlashSales Result", - "FlashSalesResult": "FlashSales Result", - "FlashSalesResultStoreId": "Store ID", - "FlashSalesResultPlanId": "Plan ID", - "FlashSalesResultStatus": "Status", - "FlashSalesResultReason": "Reason", - "FlashSalesResultUserId": "User ID", - "FlashSalesResultOrderId": "Order ID", - "FlashSalesResultCreationTime": "Creation Time", - "ViewFlashSalesResult": "View", - "Enum:FlashSalesResultStatus.Pending": "Pending", - "Enum:FlashSalesResultStatus.Successful": "Successful", - "Enum:FlashSalesResultStatus.Failed": "Failed", - "Enum:FlashSalesResultStatus.0": "Pending", - "Enum:FlashSalesResultStatus.1": "Successful", - "Enum:FlashSalesResultStatus.2": "Failed" + "Permission:FlashSaleResult": "Flash-Sale Result", + "Menu:FlashSaleResult": "Flash-Sale Result", + "FlashSaleResult": "Flash-Sale Result", + "FlashSaleResultStoreId": "Store ID", + "FlashSaleResultPlanId": "Plan ID", + "FlashSaleResultStatus": "Status", + "FlashSaleResultReason": "Reason", + "FlashSaleResultUserId": "User ID", + "FlashSaleResultOrderId": "Order ID", + "FlashSaleResultCreationTime": "Creation Time", + "ViewFlashSaleResult": "View", + "Enum:FlashSaleResultStatus.Pending": "Pending", + "Enum:FlashSaleResultStatus.Successful": "Successful", + "Enum:FlashSaleResultStatus.Failed": "Failed", + "Enum:FlashSaleResultStatus.0": "Pending", + "Enum:FlashSaleResultStatus.1": "Successful", + "Enum:FlashSaleResultStatus.2": "Failed" } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json index 8e7293e2..2327818b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -6,47 +6,47 @@ "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "产品SKU'{productSkuId}'不存在", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "产品尚未发布", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "产品SKU库存不足", - "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "只允许使用指定的{expectedInventoryStrategy}库存策略", + "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "只允许使用指定{expectedInventoryStrategy}库存策略的产品", "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpired": "预下单已过期", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleNotStarted": "闪购尚未开始", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "闪购已经结束", "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "闪购下单繁忙", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重复闪购下单", - "EasyAbp.EShop.Plugins.FlashSales:ExistRelatedFlashSalesResults": "已存在关联的闪购结果", + "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "已存在关联的闪购结果", "Menu:FlashSalesManagement": "闪购", - "Permission:FlashSalesPlan": "闪购计划", + "Permission:FlashSalePlan": "闪购计划", "Permission:Manage": "管理", "Permission:Create": "新建", "Permission:Update": "更新", "Permission:Delete": "删除", - "Menu:FlashSalesPlan": "闪购计划", - "FlashSalesPlan": "闪购计划", - "FlashSalesPlanStoreId": "店铺 ID", - "FlashSalesPlanBeginTime": "开始时间", - "FlashSalesPlanEndTime": "结束时间", - "FlashSalesPlanProductId": "产品 ID", - "FlashSalesPlanProductSkuId": "产品SKU ID", - "FlashSalesPlanIsPublished": "发布", - "CreateFlashSalesPlan": "新建", - "EditFlashSalesPlan": "編輯", - "FlashSalesPlanDeletionConfirmationMessage": "确认删除闪购计划 {0}?", + "Menu:FlashSalePlan": "闪购计划", + "FlashSalePlan": "闪购计划", + "FlashSalePlanStoreId": "店铺 ID", + "FlashSalePlanBeginTime": "开始时间", + "FlashSalePlanEndTime": "结束时间", + "FlashSalePlanProductId": "产品 ID", + "FlashSalePlanProductSkuId": "产品SKU ID", + "FlashSalePlanIsPublished": "发布", + "CreateFlashSalePlan": "新建", + "EditFlashSalePlan": "編輯", + "FlashSalePlanDeletionConfirmationMessage": "确认删除闪购计划 {0}?", "SuccessfullyDeleted": "删除成功", - "Permission:FlashSalesResult": "闪购结果", - "Menu:FlashSalesResult": "闪购结果", - "FlashSalesResult": "闪购结果", - "FlashSalesResultStoreId": "店铺 ID", - "FlashSalesResultPlanId": "计划 ID", - "FlashSalesResultStatus": "状态", - "FlashSalesResultReason": "原因", - "FlashSalesResultUserId": "用户 ID", - "FlashSalesResultOrderId": "订单 ID", - "FlashSalesResultCreationTime": "创建时间", - "ViewFlashSalesResult": "查看", - "Enum:FlashSalesResultStatus.Pending": "等待中", - "Enum:FlashSalesResultStatus.Successful": "成功", - "Enum:FlashSalesResultStatus.Failed": "失败", - "Enum:FlashSalesResultStatus.0": "等待中", - "Enum:FlashSalesResultStatus.1": "成功", - "Enum:FlashSalesResultStatus.2": "失败" + "Permission:FlashSaleResult": "闪购结果", + "Menu:FlashSaleResult": "闪购结果", + "FlashSaleResult": "闪购结果", + "FlashSaleResultStoreId": "店铺 ID", + "FlashSaleResultPlanId": "计划 ID", + "FlashSaleResultStatus": "状态", + "FlashSaleResultReason": "原因", + "FlashSaleResultUserId": "用户 ID", + "FlashSaleResultOrderId": "订单 ID", + "FlashSaleResultCreationTime": "创建时间", + "ViewFlashSaleResult": "查看", + "Enum:FlashSaleResultStatus.Pending": "等待中", + "Enum:FlashSaleResultStatus.Successful": "成功", + "Enum:FlashSaleResultStatus.Failed": "失败", + "Enum:FlashSaleResultStatus.0": "等待中", + "Enum:FlashSaleResultStatus.1": "成功", + "Enum:FlashSaleResultStatus.2": "失败" } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json index 14084ab1..2b7767ee 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -6,47 +6,47 @@ "EasyAbp.EShop.Plugins.FlashSales:ProductSkuIsNotFound": "產品SKU'{productSkuId}'不存在", "EasyAbp.EShop.Plugins.FlashSales:ProductIsNotPublished": "產品尚未發佈", "EasyAbp.EShop.Plugins.FlashSales:ProductSkuInventoryExceeded": "產品SKU庫存不足", - "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "只允許使用指定的{expectedInventoryStrategy}庫存策略", + "EasyAbp.EShop.Plugins.FlashSales:UnexpectedInventoryStrategy": "只允許使用指定的{expectedInventoryStrategy}庫存策略的產品", "EasyAbp.EShop.Plugins.FlashSales:PreOrderExpired": "預下單已過期", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleNotStarted": "閃購尚未開始", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleIsOver": "閃購已經結束", "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "閃購下單繁忙", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重複閃購下單", - "EasyAbp.EShop.Plugins.FlashSales:ExistRelatedFlashSalesResults": "已存在關聯的閃購結果", + "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "已存在關聯的閃購結果", "Menu:FlashSalesManagement": "閃購管理", - "Permission:FlashSalesPlan": "閃購計畫", + "Permission:FlashSalePlan": "閃購計畫", "Permission:Manage": "管理", "Permission:Create": "新建", "Permission:Update": "更新", "Permission:Delete": "删除", - "Menu:FlashSalesPlan": "閃購計畫", - "FlashSalesPlan": "閃購計畫", - "FlashSalesPlanStoreId": "店鋪ID", - "FlashSalesPlanBeginTime": "開始時間", - "FlashSalesPlanEndTime": "結束時間", - "FlashSalesPlanProductId": "產品ID", - "FlashSalesPlanProductSkuId": "產品SKU ID", - "FlashSalesPlanIsPublished": "發佈", - "CreateFlashSalesPlan": "新建", - "EditFlashSalesPlan": "更新", - "FlashSalesPlanDeletionConfirmationMessage": "確認删除閃購計畫 {0}?", + "Menu:FlashSalePlan": "閃購計畫", + "FlashSalePlan": "閃購計畫", + "FlashSalePlanStoreId": "店鋪ID", + "FlashSalePlanBeginTime": "開始時間", + "FlashSalePlanEndTime": "結束時間", + "FlashSalePlanProductId": "產品ID", + "FlashSalePlanProductSkuId": "產品SKU ID", + "FlashSalePlanIsPublished": "發佈", + "CreateFlashSalePlan": "新建", + "EditFlashSalePlan": "更新", + "FlashSalePlanDeletionConfirmationMessage": "確認删除閃購計畫 {0}?", "SuccessfullyDeleted": "删除成功", - "Permission:FlashSalesResult": "閃購結果", - "Menu:FlashSalesResult": "閃購結果", - "FlashSalesResult": "閃購結果", - "FlashSalesResultStoreId": "店铺 ID", - "FlashSalesResultPlanId": "計畫 ID", - "FlashSalesResultStatus": "狀態", - "FlashSalesResultReason": "原因", - "FlashSalesResultUserId": "用戶 ID", - "FlashSalesResultOrderId": "訂單 ID", - "FlashSalesResultCreationTime": "創建時間", - "ViewFlashSalesResult": "查看", - "Enum:FlashSalesResultStatus.Pending": "等待中", - "Enum:FlashSalesResultStatus.Successful": "成功", - "Enum:FlashSalesResultStatus.Failed": "失敗", - "Enum:FlashSalesResultStatus.0": "等待中", - "Enum:FlashSalesResultStatus.1": "成功", - "Enum:FlashSalesResultStatus.2": "失敗" + "Permission:FlashSaleResult": "閃購結果", + "Menu:FlashSaleResult": "閃購結果", + "FlashSaleResult": "閃購結果", + "FlashSaleResultStoreId": "店铺 ID", + "FlashSaleResultPlanId": "計畫 ID", + "FlashSaleResultStatus": "狀態", + "FlashSaleResultReason": "原因", + "FlashSaleResultUserId": "用戶 ID", + "FlashSaleResultOrderId": "訂單 ID", + "FlashSaleResultCreationTime": "創建時間", + "ViewFlashSaleResult": "查看", + "Enum:FlashSaleResultStatus.Pending": "等待中", + "Enum:FlashSaleResultStatus.Successful": "成功", + "Enum:FlashSaleResultStatus.Failed": "失敗", + "Enum:FlashSaleResultStatus.0": "等待中", + "Enum:FlashSaleResultStatus.1": "成功", + "Enum:FlashSaleResultStatus.2": "失敗" } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs index df4eb669..fed8b5cd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainAutoMapperProfile.cs @@ -1,5 +1,5 @@ using AutoMapper; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; namespace EasyAbp.EShop.Plugins.FlashSales; @@ -10,7 +10,7 @@ public class EShopPluginsFlashSalesDomainAutoMapperProfile : Profile /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ - CreateMap() + CreateMap() .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs index 826de7aa..f05ee3d6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainModule.cs @@ -1,4 +1,4 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Domain; @@ -25,9 +25,9 @@ public class EShopPluginsFlashSalesDomainModule : AbpModule Configure(options => { - options.EtoMappings.Add(typeof(EShopPluginsFlashSalesDomainModule)); + options.EtoMappings.Add(typeof(EShopPluginsFlashSalesDomainModule)); - options.AutoEventSelectors.Add(); + options.AutoEventSelectors.Add(); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan.cs similarity index 78% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan.cs index 83bf7f97..45d9f05e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan.cs @@ -3,9 +3,9 @@ using EasyAbp.EShop.Stores.Stores; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant, IMultiStore +public class FlashSalePlan : FullAuditedAggregateRoot, IMultiTenant, IMultiStore { public virtual Guid? TenantId { get; protected set; } @@ -21,11 +21,11 @@ public class FlashSalesPlan : FullAuditedAggregateRoot, IMultiTenant, IMul public virtual bool IsPublished { get; protected set; } - protected FlashSalesPlan() + protected FlashSalePlan() { } - public FlashSalesPlan(Guid id, Guid? tenantId, Guid storeId, DateTime beginTime, DateTime endTime, Guid productId, Guid productSkuId, bool isPublished) + public FlashSalePlan(Guid id, Guid? tenantId, Guid storeId, DateTime beginTime, DateTime endTime, Guid productId, Guid productSkuId, bool isPublished) : base(id) { TenantId = tenantId; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanRepository.cs new file mode 100644 index 00000000..6fba405c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanRepository.cs @@ -0,0 +1,8 @@ +using System; +using Volo.Abp.Domain.Repositories; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public interface IFlashSalePlanRepository : IRepository +{ +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/InvalidEndTimeException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/InvalidEndTimeException.cs similarity index 75% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/InvalidEndTimeException.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/InvalidEndTimeException.cs index e3721b43..72ff19ef 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/InvalidEndTimeException.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/InvalidEndTimeException.cs @@ -1,6 +1,6 @@ using Volo.Abp; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; public class InvalidEndTimeException : BusinessException { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs similarity index 61% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs index b7dc305a..297a1342 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/CreateFlashSalesOrderCompleteEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs @@ -5,21 +5,21 @@ using Volo.Abp.EventBus.Distributed; using Volo.Abp.Guids; using Volo.Abp.Uow; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -public class CreateFlashSalesOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency +public class CreateFlashSaleOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency { - protected IFlashSalesResultRepository FlashSalesResultRepository { get; } + protected IFlashSaleResultRepository FlashSalesResultRepository { get; } protected IGuidGenerator GuidGenerator { get; } - public CreateFlashSalesOrderCompleteEventHandler(IFlashSalesResultRepository flashSalesResultRepository, IGuidGenerator guidGenerator) + public CreateFlashSaleOrderCompleteEventHandler(IFlashSaleResultRepository flashSalesResultRepository, IGuidGenerator guidGenerator) { FlashSalesResultRepository = flashSalesResultRepository; GuidGenerator = guidGenerator; } [UnitOfWork] - public virtual async Task HandleEventAsync(CreateFlashSalesOrderCompleteEto eventData) + public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) { var flashSalesResult = await FlashSalesResultRepository.GetAsync(eventData.PendingResultId); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs similarity index 63% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs index de3a83df..48f2cdfe 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs @@ -3,9 +3,9 @@ using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -public class FlashSalesResult : FullAuditedAggregateRoot, IMultiTenant +public class FlashSaleResult : FullAuditedAggregateRoot, IMultiTenant { public virtual Guid? TenantId { get; protected set; } @@ -13,7 +13,7 @@ public class FlashSalesResult : FullAuditedAggregateRoot, IMultiTenant public virtual Guid PlanId { get; protected set; } - public virtual FlashSalesResultStatus Status { get; protected set; } + public virtual FlashSaleResultStatus Status { get; protected set; } public virtual string Reason { get; protected set; } @@ -21,9 +21,9 @@ public class FlashSalesResult : FullAuditedAggregateRoot, IMultiTenant public virtual Guid? OrderId { get; protected set; } - protected FlashSalesResult() { } + protected FlashSaleResult() { } - public FlashSalesResult(Guid id, Guid? tenantId, Guid storeId, Guid planId, FlashSalesResultStatus status, string reason, Guid userId, Guid? orderId) + public FlashSaleResult(Guid id, Guid? tenantId, Guid storeId, Guid planId, FlashSaleResultStatus status, string reason, Guid userId, Guid? orderId) : base(id) { TenantId = tenantId; @@ -37,13 +37,13 @@ public class FlashSalesResult : FullAuditedAggregateRoot, IMultiTenant public void MarkAsSuccessful(Guid orderId) { - Status = FlashSalesResultStatus.Successful; + Status = FlashSaleResultStatus.Successful; OrderId = orderId; } public void MarkAsFailed(string reason) { - Status = FlashSalesResultStatus.Failed; + Status = FlashSaleResultStatus.Failed; Reason = Check.NotNullOrEmpty(reason, nameof(reason)); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultRepository.cs new file mode 100644 index 00000000..dc30ef1b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultRepository.cs @@ -0,0 +1,9 @@ +using System; +using Volo.Abp.Domain.Repositories; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public interface IFlashSaleResultRepository : IRepository +{ + +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs deleted file mode 100644 index 41f32db0..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/IFlashSalesPlanRepository.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; -using Volo.Abp.Domain.Repositories; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; - -public interface IFlashSalesPlanRepository : IRepository -{ -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs deleted file mode 100644 index d09be083..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/IFlashSalesResultRepository.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using Volo.Abp.Domain.Repositories; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -public interface IFlashSalesResultRepository : IRepository -{ - -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs index a573c7e9..336d42e3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreModule.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; @@ -16,8 +16,8 @@ public class EShopPluginsFlashSalesEntityFrameworkCoreModule : AbpModule { context.Services.AddAbpDbContext(options => { - options.AddRepository(); - options.AddRepository(); + options.AddRepository(); + options.AddRepository(); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs index 41d0d253..d9002f5c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContext.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; @@ -9,9 +9,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public class FlashSalesDbContext : AbpDbContext, IFlashSalesDbContext { - public DbSet Plans { get; set; } + public DbSet FlashSalePlans { get; set; } - public DbSet Results { get; set; } + public DbSet FlashSaleResults { get; set; } public FlashSalesDbContext(DbContextOptions options) : base(options) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs index 284a5122..f12853a7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesDbContextModelCreatingExtensions.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using Microsoft.EntityFrameworkCore; using Volo.Abp; using Volo.Abp.EntityFrameworkCore.Modeling; @@ -13,17 +13,17 @@ public static class FlashSalesDbContextModelCreatingExtensions { Check.NotNull(builder, nameof(builder)); - builder.Entity(b => + builder.Entity(b => { - b.ToTable(FlashSalesDbProperties.DbTablePrefix + "Plans", FlashSalesDbProperties.DbSchema); + b.ToTable(FlashSalesDbProperties.DbTablePrefix + "FlashSalePlans", FlashSalesDbProperties.DbSchema); b.ConfigureByConvention(); /* Configure more properties here */ }); - builder.Entity(b => + builder.Entity(b => { - b.ToTable(FlashSalesDbProperties.DbTablePrefix + "Results", FlashSalesDbProperties.DbSchema); + b.ToTable(FlashSalesDbProperties.DbTablePrefix + "FlashSaleResults", FlashSalesDbProperties.DbSchema); b.ConfigureByConvention(); /* Configure more properties here */ diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs index 46a6766b..a0bfd185 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/IFlashSalesDbContext.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; @@ -9,7 +9,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public interface IFlashSalesDbContext : IEfCoreDbContext { - DbSet Plans { get; set; } + DbSet FlashSalePlans { get; set; } - DbSet Results { get; set; } + DbSet FlashSaleResults { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/EfCoreFlashSalePlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/EfCoreFlashSalePlanRepository.cs new file mode 100644 index 00000000..b78bffbd --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/EfCoreFlashSalePlanRepository.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans +{ + public class EfCoreFlashSalePlanRepository : EfCoreRepository, IFlashSalePlanRepository + { + public EfCoreFlashSalePlanRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public override async Task> WithDetailsAsync() + { + return (await GetQueryableAsync()).IncludeDetails(); + } + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanEfCoreQuerableExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanEfCoreQuerableExtensions.cs new file mode 100644 index 00000000..cbbad1a8 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanEfCoreQuerableExtensions.cs @@ -0,0 +1,18 @@ +using System.Linq; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public static class FlashSalePlanEfCoreQueryableExtensions +{ + public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true) + { + if (!include) + { + return queryable; + } + + return queryable + // .Include(x => x.xxx) // TODO: AbpHelper generated + ; + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/EfCoreFlashSaleResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/EfCoreFlashSaleResultRepository.cs new file mode 100644 index 00000000..937ecdf5 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/EfCoreFlashSaleResultRepository.cs @@ -0,0 +1,20 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class EfCoreFlashSaleResultRepository : EfCoreRepository, IFlashSaleResultRepository +{ + public EfCoreFlashSaleResultRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public override async Task> WithDetailsAsync() + { + return (await GetQueryableAsync()).IncludeDetails(); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultEfCoreQuerableExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultEfCoreQuerableExtensions.cs new file mode 100644 index 00000000..ef21cde9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultEfCoreQuerableExtensions.cs @@ -0,0 +1,16 @@ +using System.Linq; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public static class FlashSaleResultEfCoreQuerableExtensions +{ + public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true) + { + if (!include) + { + return queryable; + } + + return queryable; + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs deleted file mode 100644 index 7926de36..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/EfCoreFlashSalesPlanRepository.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; -using Volo.Abp.Domain.Repositories.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans -{ - public class EfCoreFlashSalesPlanRepository : EfCoreRepository, IFlashSalesPlanRepository - { - public EfCoreFlashSalesPlanRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) - { - } - - public override async Task> WithDetailsAsync() - { - return (await GetQueryableAsync()).IncludeDetails(); - } - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs deleted file mode 100644 index 5bccbeee..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanEfCoreQuerableExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Linq; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; - -public static class FlashSalesPlanEfCoreQueryableExtensions -{ - public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true) - { - if (!include) - { - return queryable; - } - - return queryable - // .Include(x => x.xxx) // TODO: AbpHelper generated - ; - } -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs deleted file mode 100644 index e4fc4185..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/EfCoreFlashSalesResultRepository.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; -using Volo.Abp.Domain.Repositories.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -public class EfCoreFlashSalesResultRepository : EfCoreRepository, IFlashSalesResultRepository -{ - public EfCoreFlashSalesResultRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) - { - } - - public override async Task> WithDetailsAsync() - { - return (await GetQueryableAsync()).IncludeDetails(); - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs deleted file mode 100644 index 141898bd..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultEfCoreQuerableExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Linq; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -public static class FlashSalesResultEfCoreQuerableExtensions -{ - public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true) - { - if (!include) - { - return queryable; - } - - return queryable; - } -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs similarity index 60% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanController.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index 1bd611d8..90551b2f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -1,46 +1,46 @@ using System; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using Microsoft.AspNetCore.Mvc; using Volo.Abp; using Volo.Abp.Application.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Area(EShopPluginsFlashSalesRemoteServiceConsts.ModuleName)] [RemoteService(Name = EShopPluginsFlashSalesRemoteServiceConsts.RemoteServiceName)] -[Route("/api/e-shop/plugins/flash-sales/flash-sales-plan")] -public class FlashSalesPlanController : +[Route("/api/e-shop/plugins/flash-sales/flash-sale-plan")] +public class FlashSalePlanController : FlashSalesController, - IFlashSalesPlanAppService + IFlashSalePlanAppService { - protected IFlashSalesPlanAppService Service { get; } + protected IFlashSalePlanAppService Service { get; } - public FlashSalesPlanController(IFlashSalesPlanAppService flashSalesPlanAppService) + public FlashSalePlanController(IFlashSalePlanAppService flashSalePlanAppService) { - Service = flashSalesPlanAppService; + Service = flashSalePlanAppService; } [HttpGet("{id}")] - public virtual Task GetAsync(Guid id) + public virtual Task GetAsync(Guid id) { return Service.GetAsync(id); } [HttpGet] - public virtual Task> GetListAsync(FlashSalesPlanGetListInput input) + public virtual Task> GetListAsync(FlashSalePlanGetListInput input) { return Service.GetListAsync(input); } [HttpPost("{id}")] - public virtual Task CreateAsync(FlashSalesPlanCreateDto input) + public virtual Task CreateAsync(FlashSalePlanCreateDto input) { return Service.CreateAsync(input); } [HttpPut("{id}")] - public virtual Task UpdateAsync(Guid id, FlashSalesPlanUpdateDto input) + public virtual Task UpdateAsync(Guid id, FlashSalePlanUpdateDto input) { return Service.UpdateAsync(id, input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs new file mode 100644 index 00000000..b0095dcc --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +[Area(EShopPluginsFlashSalesRemoteServiceConsts.ModuleName)] +[RemoteService(Name = EShopPluginsFlashSalesRemoteServiceConsts.RemoteServiceName)] +[Route("/api/e-shop/plugins/flash-sales/flash-sale-result")] +public class FlashSaleResultController : FlashSalesController, IFlashSaleResultAppService +{ + protected IFlashSaleResultAppService Service { get; } + + public FlashSaleResultController(IFlashSaleResultAppService service) + { + Service = service; + } + + [HttpGet("{id}")] + public virtual Task GetAsync(Guid id) + { + return Service.GetAsync(id); + } + + [HttpGet] + public virtual Task> GetListAsync(FlashSaleResultGetListInput input) + { + return Service.GetListAsync(input); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs deleted file mode 100644 index f74846e3..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResultController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp; -using Volo.Abp.Application.Dtos; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -[Area(EShopPluginsFlashSalesRemoteServiceConsts.ModuleName)] -[RemoteService(Name = EShopPluginsFlashSalesRemoteServiceConsts.RemoteServiceName)] -[Route("/api/e-shop/plugins/flash-sales/flash-sales-result")] -public class FlashSalesResultController : FlashSalesController, IFlashSalesResultAppService -{ - protected IFlashSalesResultAppService Service { get; } - - public FlashSalesResultController(IFlashSalesResultAppService service) - { - Service = service; - } - - [HttpGet("{id}")] - public virtual Task GetAsync(Guid id) - { - return Service.GetAsync(id); - } - - [HttpGet] - public virtual Task> GetListAsync(FlashSalesResultGetListInput input) - { - return Service.GetListAsync(input); - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/MongoFlashSalePlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/MongoFlashSalePlanRepository.cs new file mode 100644 index 00000000..4e0c476b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/MongoFlashSalePlanRepository.cs @@ -0,0 +1,13 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.MongoDB; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public class MongoFlashSalePlanRepository : MongoDbRepository, IFlashSalePlanRepository +{ + public MongoFlashSalePlanRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/MongoFlashSaleResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/MongoFlashSaleResultRepository.cs new file mode 100644 index 00000000..fc8a74a2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/MongoFlashSaleResultRepository.cs @@ -0,0 +1,13 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.MongoDB; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class MongoFlashSaleResultRepository : MongoDbRepository, IFlashSaleResultRepository +{ + public MongoFlashSaleResultRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs deleted file mode 100644 index e573f156..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesPlans/MongoFlashSalesPlanRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using EasyAbp.EShop.Plugins.FlashSales.MongoDB; -using Volo.Abp.Domain.Repositories.MongoDB; -using Volo.Abp.MongoDB; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; - -public class MongoFlashSalesPlanRepository : MongoDbRepository, IFlashSalesPlanRepository -{ - public MongoFlashSalesPlanRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) - { - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs deleted file mode 100644 index 8621e83e..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/FlashSalesResults/MongoFlashSalesResultRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using EasyAbp.EShop.Plugins.FlashSales.MongoDB; -using Volo.Abp.Domain.Repositories.MongoDB; -using Volo.Abp.MongoDB; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -public class MongoFlashSalesResultRepository : MongoDbRepository, IFlashSalesResultRepository -{ - public MongoFlashSalesResultRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) - { - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs index 728dbbde..fcfceade 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbModule.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; using Volo.Abp.MongoDB; @@ -16,8 +16,8 @@ public class EShopPluginsFlashSalesMongoDbModule : AbpModule { context.Services.AddMongoDbContext(options => { - options.AddRepository(); - options.AddRepository(); + options.AddRepository(); + options.AddRepository(); }); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs index 3e2028e8..b7dfc7a2 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContext.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using MongoDB.Driver; using Volo.Abp.Data; using Volo.Abp.MongoDB; @@ -9,9 +9,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public class FlashSalesMongoDbContext : AbpMongoDbContext, IFlashSalesMongoDbContext { - public IMongoCollection Plans => Collection(); + public IMongoCollection FlashSalePlans => Collection(); - public IMongoCollection Results => Collection(); + public IMongoCollection FlashSaleResults => Collection(); protected override void CreateModel(IMongoModelBuilder modelBuilder) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs index 5bdad8d4..e3d2201a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbContextExtensions.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using Volo.Abp; using Volo.Abp.MongoDB; @@ -12,8 +12,8 @@ public static class FlashSalesMongoDbContextExtensions { Check.NotNull(builder, nameof(builder)); - builder.Entity(b => b.CollectionName = FlashSalesDbProperties.DbTablePrefix + "Plans"); + builder.Entity(b => b.CollectionName = FlashSalesDbProperties.DbTablePrefix + "FlashSalePlans"); - builder.Entity(b => b.CollectionName = FlashSalesDbProperties.DbTablePrefix + "Results"); + builder.Entity(b => b.CollectionName = FlashSalesDbProperties.DbTablePrefix + "FlashSaleResults"); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs index 5cc3f8e8..6a4c7951 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.MongoDB/EasyAbp/EShop/Plugins/FlashSales/MongoDB/IFlashSalesMongoDbContext.cs @@ -1,5 +1,5 @@ -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using MongoDB.Driver; using Volo.Abp.Data; using Volo.Abp.MongoDB; @@ -9,7 +9,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; [ConnectionStringName(FlashSalesDbProperties.ConnectionStringName)] public interface IFlashSalesMongoDbContext : IAbpMongoDbContext { - IMongoCollection Plans { get; } + IMongoCollection FlashSalePlans { get; } - IMongoCollection Results { get; } + IMongoCollection FlashSaleResults { get; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs index 4eb9cde3..5a88342e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EShopPluginsFlashSalesWebAutoMapperProfile.cs @@ -1,8 +1,8 @@ using AutoMapper; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; -using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult.ViewModels; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan.ViewModels; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult.ViewModels; namespace EasyAbp.EShop.Plugins.FlashSales.Web; @@ -13,13 +13,13 @@ public class EShopPluginsFlashSalesWebAutoMapperProfile : Profile /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ - CreateMap() + CreateMap(MemberList.Destination) .ForMember(dest => dest.ExtraProperties, opt => opt.Ignore()); - CreateMap() + CreateMap(MemberList.Destination) .ForMember(dest => dest.ExtraProperties, opt => opt.Ignore()); - CreateMap() + CreateMap(MemberList.Destination) .ForSourceMember(dest => dest.ExtraProperties, opt => opt.DoNotValidate()); - CreateMap() + CreateMap(MemberList.Destination) .ForSourceMember(dest => dest.ExtraProperties, opt => opt.DoNotValidate()); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj index 94d9b52e..cedf9892 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/EasyAbp.EShop.Plugins.FlashSales.Web.csproj @@ -37,9 +37,4 @@ - - - - - diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs index 6ab46dea..50d1a707 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenuContributor.cs @@ -22,24 +22,24 @@ public class FlashSalesMenuContributor : IMenuContributor //Add main menu items. var flashSalesManagementMenuItem = new ApplicationMenuItem(FlashSalesMenus.Prefix, l["Menu:FlashSalesManagement"]); - if (await context.IsGrantedAsync(FlashSalesPermissions.FlashSalesPlan.Default)) + if (await context.IsGrantedAsync(FlashSalesPermissions.FlashSalePlan.Default)) { flashSalesManagementMenuItem.AddItem( new ApplicationMenuItem( - FlashSalesMenus.FlashSalesPlan, - l["Menu:FlashSalesPlan"], - "/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan" + FlashSalesMenus.FlashSalePlan, + l["Menu:FlashSalePlan"], + "/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan" ) ); } - if (await context.IsGrantedAsync(FlashSalesPermissions.FlashSalesResult.Default)) + if (await context.IsGrantedAsync(FlashSalesPermissions.FlashSaleResult.Default)) { flashSalesManagementMenuItem.AddItem( new ApplicationMenuItem( - FlashSalesMenus.FlashSalesResult, - l["Menu:FlashSalesResult"], - "/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult" + FlashSalesMenus.FlashSaleResult, + l["Menu:FlashSaleResult"], + "/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult" ) ); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs index cad519a2..e792e1aa 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Menus/FlashSalesMenus.cs @@ -6,7 +6,7 @@ public static class FlashSalesMenus public const string Prefix = ModuleGroupPrefix + ".Plugins.FlashSales"; - public const string FlashSalesPlan = Prefix + ".FlashSalesPlan"; + public const string FlashSalePlan = Prefix + ".FlashSalePlan"; - public const string FlashSalesResult = Prefix + ".FlashSalesResult"; + public const string FlashSaleResult = Prefix + ".FlashSaleResult"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal.cshtml similarity index 80% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal.cshtml index 32a1aa21..8e86f4a7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal.cshtml @@ -2,7 +2,7 @@ @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal @using EasyAbp.EShop.Plugins.FlashSales.Localization -@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan @inject IHtmlLocalizer L @model CreateModalModel @@ -12,7 +12,7 @@ - + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal.cshtml.cs new file mode 100644 index 00000000..08eab7da --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal.cshtml.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan; + +public class CreateModalModel : FlashSalesPageModel +{ + [BindProperty] + public CreateFlashSalePlanViewModel ViewModel { get; set; } + + protected IFlashSalePlanAppService Service { get; } + + public CreateModalModel(IFlashSalePlanAppService service) + { + Service = service; + } + + public virtual async Task OnPostAsync() + { + var dto = ObjectMapper.Map(ViewModel); + await Service.CreateAsync(dto); + return NoContent(); + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/EditModal.cshtml similarity index 84% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/EditModal.cshtml index faa6ffc9..356d19dd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/EditModal.cshtml @@ -2,7 +2,7 @@ @using EasyAbp.EShop.Plugins.FlashSales.Localization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal -@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan @inject IHtmlLocalizer L @model EditModalModel @@ -12,7 +12,7 @@ - + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/EditModal.cshtml.cs similarity index 52% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/EditModal.cshtml.cs index faa49dd3..faa08b8e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal.cshtml.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/EditModal.cshtml.cs @@ -1,11 +1,11 @@ using System; using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan.ViewModels; using Microsoft.AspNetCore.Mvc; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan; public class EditModalModel : FlashSalesPageModel { @@ -14,11 +14,11 @@ public class EditModalModel : FlashSalesPageModel public Guid Id { get; set; } [BindProperty] - public EditFlashSalesPlanViewModel ViewModel { get; set; } + public EditFlashSalePlanViewModel ViewModel { get; set; } - protected IFlashSalesPlanAppService Service { get; } + protected IFlashSalePlanAppService Service { get; } - public EditModalModel(IFlashSalesPlanAppService service) + public EditModalModel(IFlashSalePlanAppService service) { Service = service; } @@ -26,12 +26,12 @@ public class EditModalModel : FlashSalesPageModel public virtual async Task OnGetAsync() { var dto = await Service.GetAsync(Id); - ViewModel = ObjectMapper.Map(dto); + ViewModel = ObjectMapper.Map(dto); } public virtual async Task OnPostAsync() { - var dto = ObjectMapper.Map(ViewModel); + var dto = ObjectMapper.Map(ViewModel); await Service.UpdateAsync(Id, dto); return NoContent(); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/Index.cshtml similarity index 53% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/Index.cshtml index d96bb645..ece592b6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/Index.cshtml @@ -3,7 +3,7 @@ @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Layout -@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan @using EasyAbp.EShop.Plugins.FlashSales.Localization @using EasyAbp.EShop.Plugins.FlashSales.Web.Menus @@ -13,31 +13,31 @@ @inject IHtmlLocalizer L @inject IAuthorizationService Authorization @{ - PageLayout.Content.Title = L["FlashSalesPlan"].Value; - PageLayout.Content.BreadCrumb.Add(L["Menu:FlashSalesPlan"].Value); - PageLayout.Content.MenuItemName = FlashSalesMenus.FlashSalesPlan; + PageLayout.Content.Title = L["FlashSalePlan"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:FlashSalePlan"].Value); + PageLayout.Content.MenuItemName = FlashSalesMenus.FlashSalePlan; } @section scripts { - + } @section styles { - + } - @L["FlashSalesPlan"] + @L["FlashSalePlan"] - @if (await Authorization.IsGrantedAsync(FlashSalesPermissions.FlashSalesPlan.Create)) + @if (await Authorization.IsGrantedAsync(FlashSalesPermissions.FlashSalePlan.Create)) { - } @@ -45,6 +45,6 @@ - + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/Index.cshtml.cs similarity index 83% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/Index.cshtml.cs index 2203fdef..c45df6d6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/Index.cshtml.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/Index.cshtml.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan; public class IndexModel : FlashSalesPageModel { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/ViewModels/CreateFlashSalePlanViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/ViewModels/CreateFlashSalePlanViewModel.cs new file mode 100644 index 00000000..8f167e89 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/ViewModels/CreateFlashSalePlanViewModel.cs @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan.ViewModels; + +public class CreateFlashSalePlanViewModel +{ + [Display(Name = "FlashSalePlanStoreId")] + public Guid StoreId { get; set; } + + [Display(Name = "FlashSalePlanBeginTime")] + public DateTime BeginTime { get; set; } + + [Display(Name = "FlashSalePlanEndTime")] + public DateTime EndTime { get; set; } + + [Display(Name = "FlashSalePlanProductId")] + public Guid ProductId { get; set; } + + [Display(Name = "FlashSalePlanProductSkuId")] + public Guid ProductSkuId { get; set; } + + [Display(Name = "FlashSalePlanIsPublished")] + public bool IsPublished { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/ViewModels/EditFlashSalePlanViewModel.cs similarity index 59% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/ViewModels/EditFlashSalePlanViewModel.cs index 972d0980..a7cab334 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/EditFlashSalesPlanViewModel.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/ViewModels/EditFlashSalePlanViewModel.cs @@ -4,28 +4,28 @@ using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; using Volo.Abp.Domain.Entities; -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan.ViewModels; -public class EditFlashSalesPlanViewModel : IHasConcurrencyStamp +public class EditFlashSalePlanViewModel : IHasConcurrencyStamp { [DisabledInput] [ReadOnlyInput] - [Display(Name = "FlashSalesPlanStoreId")] + [Display(Name = "FlashSalePlanStoreId")] public Guid StoreId { get; set; } - [Display(Name = "FlashSalesPlanBeginTime")] + [Display(Name = "FlashSalePlanBeginTime")] public DateTime BeginTime { get; set; } - [Display(Name = "FlashSalesPlanEndTime")] + [Display(Name = "FlashSalePlanEndTime")] public DateTime EndTime { get; set; } - [Display(Name = "FlashSalesPlanProductId")] + [Display(Name = "FlashSalePlanProductId")] public Guid ProductId { get; set; } - [Display(Name = "FlashSalesPlanProductSkuId")] + [Display(Name = "FlashSalePlanProductSkuId")] public Guid ProductSkuId { get; set; } - [Display(Name = "FlashSalesPlanIsPublished")] + [Display(Name = "FlashSalePlanIsPublished")] public bool IsPublished { get; set; } [HiddenInput] diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.css b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.css similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.css rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.css diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.js similarity index 75% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.js index 04d2156e..e9976c18 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/index.js +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.js @@ -2,11 +2,11 @@ $(function () { var l = abp.localization.getResource('EasyAbpEShopPluginsFlashSales'); - var service = easyAbp.eShop.plugins.flashSales.flashSalesPlans.flashSalesPlan; - var createModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal'); - var editModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/EditModal'); + var service = easyAbp.eShop.plugins.flashSales.flashSalePlans.flashSalePlan; + var createModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/CreateModal'); + var editModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/EditModal'); - var dataTable = $('#FlashSalesPlanTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + var dataTable = $('#FlashSalePlanTable').DataTable(abp.libs.datatables.normalizeConfiguration({ processing: true, serverSide: true, paging: true, @@ -16,7 +16,7 @@ $(function () { order: [[2, "asc"]], ajax: abp.libs.datatables.createAjax(service.getList, function () { return { - includeUnpublished: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlan.Manage') + includeUnpublished: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalePlan.Manage') }; }), columnDefs: [ @@ -26,14 +26,14 @@ $(function () { [ { text: l('Edit'), - visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlan.Update'), + visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalePlan.Update'), action: function (data) { editModal.open({ id: data.record.id }); } }, { text: l('Delete'), - visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlan.Delete'), + visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalePlan.Delete'), confirmMessage: function (data) { return l('FlashSalesPlanDeletionConfirmationMessage', data.record.id); }, @@ -49,29 +49,29 @@ $(function () { } }, { - title: l('FlashSalesPlanStoreId'), + title: l('FlashSalePlanStoreId'), data: "storeId" }, { - title: l('FlashSalesPlanBeginTime'), + title: l('FlashSalePlanBeginTime'), data: "beginTime", dataFormat: 'datetime' }, { - title: l('FlashSalesPlanEndTime'), + title: l('FlashSalePlanEndTime'), data: "endTime", dataFormat: 'datetime' }, { - title: l('FlashSalesPlanProductId'), + title: l('FlashSalePlanProductId'), data: "productId" }, { - title: l('FlashSalesPlanProductSkuId'), + title: l('FlashSalePlanProductSkuId'), data: "productSkuId" }, { - title: l('FlashSalesPlanIsPublished'), + title: l('FlashSalePlanIsPublished'), data: "isPublished", dataFormat: 'boolean' }, @@ -86,7 +86,7 @@ $(function () { dataTable.ajax.reload(); }); - $('#NewFlashSalesPlanButton').click(function (e) { + $('#NewFlashSalePlanButton').click(function (e) { e.preventDefault(); createModal.open(); }); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml similarity index 55% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml index ba1d6a72..38c98091 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml @@ -3,7 +3,7 @@ @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Layout -@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSalesResult @using EasyAbp.EShop.Plugins.FlashSales.Localization @using EasyAbp.EShop.Plugins.FlashSales.Web.Menus @@ -13,29 +13,29 @@ @inject IHtmlLocalizer L @inject IAuthorizationService Authorization @{ - PageLayout.Content.Title = L["FlashSalesResult"].Value; - PageLayout.Content.BreadCrumb.Add(L["Menu:FlashSalesResult"].Value); - PageLayout.Content.MenuItemName = FlashSalesMenus.FlashSalesResult; + PageLayout.Content.Title = L["FlashSaleResult"].Value; + PageLayout.Content.BreadCrumb.Add(L["Menu:FlashSaleResult"].Value); + PageLayout.Content.MenuItemName = FlashSalesMenus.FlashSaleResult; } @section scripts { - + } @section styles { - + } - @L["FlashSalesResult"] + @L["FlashSaleResult"] - + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml.cs similarity index 81% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml.cs index ae48fd64..a237d092 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/Index.cshtml.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSalesResult; public class IndexModel : PageModel { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModal.cshtml similarity index 80% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModal.cshtml index ef929eab..789f6864 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModal.cshtml @@ -2,7 +2,7 @@ @using EasyAbp.EShop.Plugins.FlashSales.Localization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal -@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult @inject IHtmlLocalizer L @model ViewModalModel @@ -12,7 +12,7 @@ - + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModal.cshtml.cs similarity index 50% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModal.cshtml.cs index 9d5fa316..40d67ff5 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal.cshtml.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModal.cshtml.cs @@ -1,11 +1,11 @@ using System; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult.ViewModels; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult.ViewModels; using Microsoft.AspNetCore.Mvc; -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult; public class ViewModalModel : FlashSalesPageModel { @@ -14,11 +14,11 @@ public class ViewModalModel : FlashSalesPageModel public Guid Id { get; set; } [BindProperty] - public ViewFlashSalesResultViewModel ViewModel { get; set; } + public ViewFlashSaleResultViewModel ViewModel { get; set; } - protected IFlashSalesResultAppService Service { get; } + protected IFlashSaleResultAppService Service { get; } - public ViewModalModel(IFlashSalesResultAppService service) + public ViewModalModel(IFlashSaleResultAppService service) { Service = service; } @@ -26,6 +26,6 @@ public class ViewModalModel : FlashSalesPageModel public virtual async Task OnGetAsync() { var dto = await Service.GetAsync(Id); - ViewModel = ObjectMapper.Map(dto); + ViewModel = ObjectMapper.Map(dto); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs new file mode 100644 index 00000000..49b9aae1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs @@ -0,0 +1,26 @@ +using System; +using System.ComponentModel.DataAnnotations; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult.ViewModels; + +public class ViewFlashSaleResultViewModel +{ + [Display(Name = "FlashSaleResultStoreId")] + public Guid StoreId { get; set; } + + [Display(Name = "FlashSaleResultPlanId")] + public Guid PlanId { get; set; } + + [Display(Name = "FlashSaleResultStatus")] + public FlashSaleResultStatus Status { get; set; } + + [Display(Name = "FlashSaleResultReason")] + public string Reason { get; set; } + + [Display(Name = "FlashSaleResultUserId")] + public Guid UserId { get; set; } + + [Display(Name = "FlashSaleResultOrderId")] + public Guid? OrderId { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.css b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.css similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.css rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.css diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.js similarity index 65% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.js index bd3bc6dd..aac69835 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/index.js +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.js @@ -2,10 +2,10 @@ $(function () { var l = abp.localization.getResource('EasyAbpEShopPluginsFlashSales'); - var service = easyAbp.eShop.plugins.flashSales.flashSalesResults.flashSalesResult; - var viewModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModal'); + var service = easyAbp.eShop.plugins.flashSales.flashSaleResults.flashSaleResult; + var viewModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModal'); - var dataTable = $('#FlashSalesResultTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + var dataTable = $('#FlashSaleResultTable').DataTable(abp.libs.datatables.normalizeConfiguration({ processing: true, serverSide: true, paging: true, @@ -20,7 +20,7 @@ $(function () { items: [ { - text: l('ViewFlashSalesResult'), + text: l('ViewFlashSaleResult'), action: function (data) { viewModal.open({ id: data.record.id }); } @@ -29,34 +29,34 @@ $(function () { } }, { - title: l('FlashSalesResultStoreId'), + title: l('FlashSaleResultStoreId'), data: "storeId" }, { - title: l('FlashSalesResultPlanId'), + title: l('FlashSaleResultPlanId'), data: "planId" }, { - title: l('FlashSalesResultStatus'), + title: l('FlashSaleResultStatus'), data: "status", render: function (data) { - return l('Enum:FlashSalesResultStatus.' + data); + return l('Enum:FlashSaleResultStatus.' + data); } }, { - title: l('FlashSalesResultReason'), + title: l('FlashSaleResultReason'), data: "reason" }, { - title: l('FlashSalesResultUserId'), + title: l('FlashSaleResultUserId'), data: "userId" }, { - title: l('FlashSalesResultOrderId'), + title: l('FlashSaleResultOrderId'), data: "orderId" }, { - title: l('FlashSalesResultCreationTime'), + title: l('FlashSaleResultCreationTime'), data: "creationTime", dataFormat: 'datetime' }, diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs deleted file mode 100644 index 760d498a..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/CreateModal.cshtml.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; -using Microsoft.AspNetCore.Mvc; - -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan; - -public class CreateModalModel : FlashSalesPageModel -{ - [BindProperty] - public CreateFlashSalesPlanViewModel ViewModel { get; set; } - - protected IFlashSalesPlanAppService Service { get; } - - public CreateModalModel(IFlashSalesPlanAppService service) - { - Service = service; - } - - public virtual async Task OnPostAsync() - { - var dto = ObjectMapper.Map(ViewModel); - await Service.CreateAsync(dto); - return NoContent(); - } -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs deleted file mode 100644 index d65ae9bb..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesPlans/FlashSalesPlan/ViewModels/CreateFlashSalesPlanViewModel.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; - -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan.ViewModels; - -public class CreateFlashSalesPlanViewModel -{ - [Display(Name = "FlashSalesPlanStoreId")] - public Guid StoreId { get; set; } - - [Display(Name = "FlashSalesPlanBeginTime")] - public DateTime BeginTime { get; set; } - - [Display(Name = "FlashSalesPlanEndTime")] - public DateTime EndTime { get; set; } - - [Display(Name = "FlashSalesPlanProductId")] - public Guid ProductId { get; set; } - - [Display(Name = "FlashSalesPlanProductSkuId")] - public Guid ProductSkuId { get; set; } - - [Display(Name = "FlashSalesPlanIsPublished")] - public bool IsPublished { get; set; } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs deleted file mode 100644 index 02a2267c..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalesResults/FlashSalesResult/ViewModels/ViewFlashSalesResultViewModel.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; - -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult.ViewModels; - -public class ViewFlashSalesResultViewModel -{ - [Display(Name = "FlashSalesResultStoreId")] - public Guid StoreId { get; set; } - - [Display(Name = "FlashSalesResultPlanId")] - public Guid PlanId { get; set; } - - [Display(Name = "FlashSalesResultStatus")] - public FlashSalesResultStatus Status { get; set; } - - [Display(Name = "FlashSalesResultReason")] - public string Reason { get; set; } - - [Display(Name = "FlashSalesResultUserId")] - public Guid UserId { get; set; } - - [Display(Name = "FlashSalesResultOrderId")] - public Guid? OrderId { get; set; } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs index 2e2636eb..fbb7050b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs @@ -1,6 +1,6 @@ using System.Linq; using AutoMapper; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Products.Options; using EasyAbp.EShop.Products.ProductDetails; using EasyAbp.EShop.Products.Products; @@ -15,7 +15,7 @@ public class EShopProductsPluginsFlashSalesApplicationAutoMapperProfile : Profil IAttributeOptionIdsSerializer attributeOptionIdsSerializer, IOptionsMonitor options) { - CreateMap() + CreateMap() .ForMember(x => x.ProductGroupDisplayName, opt => opt.Ignore()) .AfterMap((src, dest) => { @@ -23,15 +23,15 @@ public class EShopProductsPluginsFlashSalesApplicationAutoMapperProfile : Profil dest.ProductGroupDisplayName = dict[src.ProductGroupName].DisplayName; }) .MapExtraProperties(); - CreateMap() + CreateMap() .ForMember(x => x.AttributeOptionIds, opt => opt.Ignore()) .AfterMap(async (src, dest) => dest.AttributeOptionIds = (await attributeOptionIdsSerializer.DeserializeAsync(src.SerializedAttributeOptionIds)).ToList()) .MapExtraProperties(); - CreateMap() + CreateMap() .MapExtraProperties(); - CreateMap() + CreateMap() .MapExtraProperties(); - CreateMap() + CreateMap() .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSalesReduceInventoryEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs similarity index 73% rename from plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSalesReduceInventoryEventHandler.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs index d5a0375b..0399ce1d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSalesReduceInventoryEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs @@ -1,7 +1,8 @@ using System.Linq; using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; using EasyAbp.EShop.Products.ProductDetails; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; @@ -10,7 +11,7 @@ using Volo.Abp.Uow; namespace EasyAbp.EShop.Products.Products; -public class FlashSalesReduceInventoryEventHandler : IDistributedEventHandler, ITransientDependency +public class FlashSaleReduceInventoryEventHandler : IDistributedEventHandler, ITransientDependency { protected IProductRepository ProductRepository { get; } @@ -22,35 +23,35 @@ public class FlashSalesReduceInventoryEventHandler : IDistributedEventHandler x.Id == eventData.Plan.ProductSkuId); - var hashToken = await FlashSalesPlanHasher.HashAsync(eventData.Plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + var hashToken = await FlashSalePlanHasher.HashAsync(eventData.Plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); if (hashToken != eventData.HashToken) { - await DistributedEventBus.PublishAsync(new CreateFlashSalesOrderCompleteEto() + await DistributedEventBus.PublishAsync(new CreateFlashSaleOrderCompleteEto() { TenantId = eventData.TenantId, PlanId = eventData.PlanId, @@ -59,14 +60,14 @@ public class FlashSalesReduceInventoryEventHandler : IDistributedEventHandler(await ProductDetailRepository.GetAsync(productDetailId.Value)) : + ObjectMapper.Map(await ProductDetailRepository.GetAsync(productDetailId.Value)) : null; - var productEto = ObjectMapper.Map(product); + var productEto = ObjectMapper.Map(product); - var createFlashSalesOrderEto = new CreateFlashSalesOrderEto() + var createFlashSalesOrderEto = new CreateFlashSaleOrderEto() { TenantId = eventData.TenantId, PlanId = eventData.PlanId, diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.Designer.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220706160700_AddedFlashSales.Designer.cs similarity index 99% rename from samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.Designer.cs rename to samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220706160700_AddedFlashSales.Designer.cs index 9463dc56..f80e833e 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.Designer.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220706160700_AddedFlashSales.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace EShopSample.Migrations { [DbContext(typeof(EShopSampleDbContext))] - [Migration("20220626174330_AddedFlashSales")] + [Migration("20220706160700_AddedFlashSales")] partial class AddedFlashSales { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -1024,7 +1024,7 @@ namespace EShopSample.Migrations b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplateScopes", (string)null); }); - modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan", b => + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -1094,10 +1094,10 @@ namespace EShopSample.Migrations b.HasKey("Id"); - b.ToTable("EasyAbpEShopPluginsFlashSalesPlans", (string)null); + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSalePlans", (string)null); }); - modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult", b => + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -1167,7 +1167,7 @@ namespace EShopSample.Migrations b.HasKey("Id"); - b.ToTable("EasyAbpEShopPluginsFlashSalesResults", (string)null); + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSaleResults", (string)null); }); modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220706160700_AddedFlashSales.cs similarity index 92% rename from samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.cs rename to samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220706160700_AddedFlashSales.cs index 9174e969..bb11a583 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220626174330_AddedFlashSales.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220706160700_AddedFlashSales.cs @@ -10,7 +10,7 @@ namespace EShopSample.Migrations protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( - name: "EasyAbpEShopPluginsFlashSalesPlans", + name: "EasyAbpEShopPluginsFlashSalesFlashSalePlans", columns: table => new { Id = table.Column(type: "uniqueidentifier", nullable: false), @@ -33,11 +33,11 @@ namespace EShopSample.Migrations }, constraints: table => { - table.PrimaryKey("PK_EasyAbpEShopPluginsFlashSalesPlans", x => x.Id); + table.PrimaryKey("PK_EasyAbpEShopPluginsFlashSalesFlashSalePlans", x => x.Id); }); migrationBuilder.CreateTable( - name: "EasyAbpEShopPluginsFlashSalesResults", + name: "EasyAbpEShopPluginsFlashSalesFlashSaleResults", columns: table => new { Id = table.Column(type: "uniqueidentifier", nullable: false), @@ -60,17 +60,17 @@ namespace EShopSample.Migrations }, constraints: table => { - table.PrimaryKey("PK_EasyAbpEShopPluginsFlashSalesResults", x => x.Id); + table.PrimaryKey("PK_EasyAbpEShopPluginsFlashSalesFlashSaleResults", x => x.Id); }); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( - name: "EasyAbpEShopPluginsFlashSalesPlans"); + name: "EasyAbpEShopPluginsFlashSalesFlashSalePlans"); migrationBuilder.DropTable( - name: "EasyAbpEShopPluginsFlashSalesResults"); + name: "EasyAbpEShopPluginsFlashSalesFlashSaleResults"); } } } diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs index 63bee2e4..bc37bd1a 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs @@ -1022,7 +1022,7 @@ namespace EShopSample.Migrations b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplateScopes", (string)null); }); - modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.FlashSalesPlan", b => + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -1092,10 +1092,10 @@ namespace EShopSample.Migrations b.HasKey("Id"); - b.ToTable("EasyAbpEShopPluginsFlashSalesPlans", (string)null); + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSalePlans", (string)null); }); - modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.FlashSalesResult", b => + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -1165,7 +1165,7 @@ namespace EShopSample.Migrations b.HasKey("Id"); - b.ToTable("EasyAbpEShopPluginsFlashSalesResults", (string)null); + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSaleResults", (string)null); }); modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => From 5c030de5c78ee902799888caad7d21766ee48eff Mon Sep 17 00:00:00 2001 From: Jadyn Date: Thu, 7 Jul 2022 00:23:37 +0800 Subject: [PATCH 20/97] Remove `Quantity` --- .../EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs | 2 +- .../FlashSales/FlashSalePlans/FlashSalePlanAppService.cs | 1 - .../FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs | 2 -- .../FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs | 2 -- .../Products/Products/FlashSaleReduceInventoryEventHandler.cs | 3 +-- 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index 7866406c..c8ddd87e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -52,7 +52,7 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler Date: Thu, 7 Jul 2022 00:26:46 +0800 Subject: [PATCH 21/97] Improve remove cache item --- .../FlashSalePlans/FlashSalePlanCacheInvalidator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs index 1b56092a..e220c65d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs @@ -22,13 +22,13 @@ public class FlashSalePlanCacheInvalidator : ILocalEventHandler eventData) + public virtual async Task HandleEventAsync(EntityChangedEventData eventData) { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + UnitOfWorkManager.Current.OnCompleted(async () => { await DistributedCache.RemoveAsync(eventData.Entity.Id); }); - - return Task.CompletedTask; } } From e2b43f80a59a6c59e138b66472b84bcc04f7da00 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Thu, 7 Jul 2022 00:37:44 +0800 Subject: [PATCH 22/97] FlashSaleResultAppService use `MultiStoreCrudAppService` replace `CrudAppService` --- .../Dtos/FlashSaleResultDto.cs | 3 ++- .../FlashSalesPermissionDefinitionProvider.cs | 1 + .../Permissions/FlashSalesPermissions.cs | 1 + .../FlashSalePlans/FlashSalePlanAppService.cs | 8 ++++++ .../FlashSaleResultAppService.cs | 25 +++++++++++++------ .../FlashSaleResults/FlashSaleResult.cs | 3 ++- 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs index db177a87..1df7365f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs @@ -1,9 +1,10 @@ using System; +using EasyAbp.EShop.Stores.Stores; using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; -public class FlashSaleResultDto : ExtensibleFullAuditedEntityDto +public class FlashSaleResultDto : ExtensibleFullAuditedEntityDto, IMultiStore { public virtual Guid StoreId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs index fa604608..4a2a7d28 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs @@ -19,6 +19,7 @@ public class FlashSalesPermissionDefinitionProvider : PermissionDefinitionProvid var flashSaleResultPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSaleResult.Default, L("Permission:FlashSaleResult")); flashSaleResultPermission.AddChild(FlashSalesPermissions.FlashSaleResult.Manage, L("Permission:Manage")); + flashSaleResultPermission.AddChild(FlashSalesPermissions.FlashSaleResult.CrossStore, L("Permission:CrossStore")); } private static LocalizableString L(string name) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs index 4259a5f3..b03f5b90 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs @@ -25,5 +25,6 @@ public class FlashSalesPermissions { public const string Default = GroupName + ".FlashSaleResult"; public const string Manage = Default + ".Manage"; + public const string CrossStore = Default + ".CrossStore"; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 8d92fa8e..ee092aaf 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -11,6 +11,7 @@ using EasyAbp.EShop.Stores.Stores; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Caching.Distributed; using Volo.Abp; +using Volo.Abp.Application.Dtos; using Volo.Abp.Caching; using Volo.Abp.Data; using Volo.Abp.DistributedLocking; @@ -84,6 +85,13 @@ public class FlashSalePlanAppService : return await MapToGetOutputDtoAsync(flashSalePlan); } + public override async Task> GetListAsync(FlashSalePlanGetListInput input) + { + await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); + + return await base.GetListAsync(input); + } + public override async Task CreateAsync(FlashSalePlanCreateDto input) { await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index a710c0f4..ea6e6470 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -4,14 +4,16 @@ using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.EShop.Plugins.FlashSales.Permissions; -using Volo.Abp.Application.Services; +using EasyAbp.EShop.Stores.Stores; +using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; public class FlashSaleResultAppService : - ReadOnlyAppService, + MultiStoreCrudAppService, IFlashSaleResultAppService { + protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSaleResult.CrossStore; protected override string GetPolicyName { get; set; } protected override string GetListPolicyName { get; set; } @@ -23,23 +25,30 @@ public class FlashSaleResultAppService : public override async Task GetAsync(Guid id) { - await CheckGetPolicyAsync(); + var flashSalesResult = await GetEntityByIdAsync(id); - var flashSalesPlan = await GetEntityByIdAsync(id); + await CheckMultiStorePolicyAsync(flashSalesResult.StoreId, GetPolicyName); - if (flashSalesPlan.UserId != CurrentUser.Id) + if (flashSalesResult.UserId != CurrentUser.Id) { - await CheckPolicyAsync(FlashSalesPermissions.FlashSaleResult.Manage); + await CheckMultiStorePolicyAsync(flashSalesResult.StoreId, FlashSalesPermissions.FlashSaleResult.Manage); } - return await MapToGetOutputDtoAsync(flashSalesPlan); + return await MapToGetOutputDtoAsync(flashSalesResult); + } + + public override async Task> GetListAsync(FlashSaleResultGetListInput input) + { + await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); + + return await base.GetListAsync(input); } protected override async Task> CreateFilteredQueryAsync(FlashSaleResultGetListInput input) { if (input.UserId != CurrentUser.Id) { - await CheckPolicyAsync(FlashSalesPermissions.FlashSaleResult.Manage); + await CheckMultiStorePolicyAsync(input.StoreId, FlashSalesPermissions.FlashSaleResult.Manage); } return (await base.CreateFilteredQueryAsync(input)) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs index 48f2cdfe..3d90d8ff 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs @@ -1,11 +1,12 @@ using System; +using EasyAbp.EShop.Stores.Stores; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -public class FlashSaleResult : FullAuditedAggregateRoot, IMultiTenant +public class FlashSaleResult : FullAuditedAggregateRoot, IMultiTenant, IMultiStore { public virtual Guid? TenantId { get; protected set; } From e26576b94218d9dcf5792d3a7d01d6dd5997d7d2 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Thu, 7 Jul 2022 00:41:21 +0800 Subject: [PATCH 23/97] Fix `CreateOrderAsync` beginTime check --- .../FlashSales/FlashSalePlans/FlashSalePlanAppService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index ee092aaf..06b0c5e0 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -211,7 +211,7 @@ public class FlashSalePlanAppService : var now = Clock.Now; if (plan.BeginTime > now) { - throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); + throw new BusinessException(FlashSalesErrorCodes.FlashSaleNotStarted); } if (now >= plan.EndTime) From 9aaf5dbbbe39d674dee498bd9cd6d36396856f9d Mon Sep 17 00:00:00 2001 From: Jadyn Date: Thu, 7 Jul 2022 01:04:08 +0800 Subject: [PATCH 24/97] Disable discounts in flash sale --- .../Orders/Orders/CreateFlashSaleOrderEventHandler.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index c8ddd87e..b381f7c0 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -67,8 +67,6 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler productDict) - { - foreach (var provider in OrderDiscountProviders) - { - await provider.DiscountAsync(order, productDict); - } - } } From 28c4b7b6406ca0fba918407d881aa1d636e69c1e Mon Sep 17 00:00:00 2001 From: Jadyn Date: Thu, 7 Jul 2022 01:15:00 +0800 Subject: [PATCH 25/97] Fix the missing part by rename to `FlashSalePlan` and `FlashSaleResult` --- .../CreateFlashSaleOrderEventHandler.cs | 1 - .../FlashSalePlans/FlashSalePlanAppService.cs | 27 +++++++++---------- .../FlashSalePlanCacheInvalidator.cs | 3 +-- .../FlashSalePlans/FlashSalePlanCacheItem.cs | 2 +- .../ProductIsNotInThisStoreException.cs | 2 +- .../ProductSkuIsNotFoundException.cs | 2 +- .../RelatedFlashSaleResultsExistException.cs | 3 +-- .../UnexpectedInventoryStrategyException.cs | 3 ++- .../FlashSaleResultAppService.cs | 15 +++++------ .../FlashSalesApplicationAutoMapperProfile.cs | 1 - .../CreateFlashSaleOrderCompleteEto.cs | 2 +- ...reateFlashSaleOrderCompleteEventHandler.cs | 16 +++++------ .../FlashSalePlans/FlashSalePlan/index.js | 2 +- .../FlashSaleResult/Index.cshtml | 2 +- .../FlashSaleResult/Index.cshtml.cs | 2 +- .../FlashSaleReduceInventoryEventHandler.cs | 1 - 16 files changed, 39 insertions(+), 45 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index b381f7c0..441f4234 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using EasyAbp.EShop.Orders.Orders.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; using EasyAbp.EShop.Products.ProductDetails.Dtos; using EasyAbp.EShop.Products.Products.Dtos; using Volo.Abp.DependencyInjection; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 06b0c5e0..6fb4fa52 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.Permissions; @@ -20,7 +19,7 @@ using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Users; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Authorize] public class FlashSalePlanAppService : @@ -48,7 +47,7 @@ public class FlashSalePlanAppService : protected IAbpDistributedLock DistributedLock { get; } - protected IFlashSalePlanHasher FlashSalesPlanHasher { get; } + protected IFlashSalePlanHasher FlashSalePlanHasher { get; } public FlashSalePlanAppService( IFlashSalePlanRepository flashSalePlanRepository, @@ -58,7 +57,7 @@ public class FlashSalePlanAppService : IDistributedEventBus distributedEventBus, IFlashSaleResultRepository flashSaleResultRepository, IAbpDistributedLock distributedLock, - IFlashSalePlanHasher flashSalesPlanHasher) + IFlashSalePlanHasher flashSalePlanHasher) : base(flashSalePlanRepository) { FlashSalePlanRepository = flashSalePlanRepository; @@ -68,7 +67,7 @@ public class FlashSalePlanAppService : DistributedEventBus = distributedEventBus; FlashSaleResultRepository = flashSaleResultRepository; DistributedLock = distributedLock; - FlashSalesPlanHasher = flashSalesPlanHasher; + FlashSalePlanHasher = flashSalePlanHasher; } public override async Task GetAsync(Guid id) @@ -127,7 +126,7 @@ public class FlashSalePlanAppService : await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, flashSalePlan.StoreId); - if (await ExistRelatedFlashSalesResultsAsync(id) && (input.ProductId != flashSalePlan.ProductId || input.ProductSkuId != flashSalePlan.ProductSkuId)) + if (await ExistRelatedFlashSaleResultsAsync(id) && (input.ProductId != flashSalePlan.ProductId || input.ProductSkuId != flashSalePlan.ProductSkuId)) { throw new RelatedFlashSaleResultsExistException(id); } @@ -149,7 +148,7 @@ public class FlashSalePlanAppService : await CheckMultiStorePolicyAsync(flashSalePlan.StoreId, DeletePolicyName); - if (await ExistRelatedFlashSalesResultsAsync(id)) + if (await ExistRelatedFlashSaleResultsAsync(id)) { throw new RelatedFlashSaleResultsExistException(id); } @@ -229,7 +228,7 @@ public class FlashSalePlanAppService : var userId = CurrentUser.GetId(); - var result = await CreatePendingFlashSalesResultAsync(plan, userId); + var result = await CreatePendingFlashSaleResultAsync(plan, userId); var flashSalesReduceInventoryEto = await PrepareFlashSalesReduceInventoryEtoAsync(plan, result.Id, input, userId, now, cacheHashToken); @@ -276,8 +275,8 @@ public class FlashSalePlanAppService : { return await DistributedCache.GetOrAddAsync(id, async () => { - var flashSalesPlan = await FlashSalePlanRepository.GetAsync(id); - return ObjectMapper.Map(flashSalesPlan); + var flashSalePlan = await FlashSalePlanRepository.GetAsync(id); + return ObjectMapper.Map(flashSalePlan); }); } @@ -298,7 +297,7 @@ public class FlashSalePlanAppService : protected virtual async Task SetCacheHashTokenAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { - var hashToken = await FlashSalesPlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); await TokenDistributedCache.SetStringAsync(await GetCacheKeyAsync(plan), hashToken, new DistributedCacheEntryOptions() { @@ -313,12 +312,12 @@ public class FlashSalePlanAppService : return false; } - var hashToken = await FlashSalesPlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); return cacheHashToken == hashToken; } - protected virtual async Task CreatePendingFlashSalesResultAsync(FlashSalePlanCacheItem plan, Guid userId) + protected virtual async Task CreatePendingFlashSaleResultAsync(FlashSalePlanCacheItem plan, Guid userId) { var lockKey = $"create-flash-sales-order-{plan.Id}-{userId}"; @@ -380,7 +379,7 @@ public class FlashSalePlanAppService : return Task.CompletedTask; } - protected virtual async Task ExistRelatedFlashSalesResultsAsync(Guid planId) + protected virtual async Task ExistRelatedFlashSaleResultsAsync(Guid planId) { return await FlashSaleResultRepository.AnyAsync(x => x.PlanId == planId); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs index e220c65d..7c3c568a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs @@ -1,13 +1,12 @@ using System; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.EventBus; using Volo.Abp.Uow; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; public class FlashSalePlanCacheInvalidator : ILocalEventHandler>, ITransientDependency { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs index 0bb2d31e..da5e41a0 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs @@ -1,7 +1,7 @@ using System; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] public class FlashSalePlanCacheItem : FlashSalePlanDto diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductIsNotInThisStoreException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductIsNotInThisStoreException.cs index b6f7e9f9..3733fb84 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductIsNotInThisStoreException.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductIsNotInThisStoreException.cs @@ -1,7 +1,7 @@ using System; using Volo.Abp; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; public class ProductIsNotInThisStoreException : BusinessException { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductSkuIsNotFoundException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductSkuIsNotFoundException.cs index f3679fe6..f1ab3263 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductSkuIsNotFoundException.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProductSkuIsNotFoundException.cs @@ -1,7 +1,7 @@ using System; using Volo.Abp; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; public class ProductSkuIsNotFoundException : BusinessException { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RelatedFlashSaleResultsExistException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RelatedFlashSaleResultsExistException.cs index e0c9f49f..b50dfeb6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RelatedFlashSaleResultsExistException.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RelatedFlashSaleResultsExistException.cs @@ -1,8 +1,7 @@ using System; -using System.Runtime.Serialization; using Volo.Abp; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] public class RelatedFlashSaleResultsExistException : BusinessException diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/UnexpectedInventoryStrategyException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/UnexpectedInventoryStrategyException.cs index bb2f6508..cc9deae9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/UnexpectedInventoryStrategyException.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/UnexpectedInventoryStrategyException.cs @@ -1,7 +1,8 @@ using EasyAbp.EShop.Products.Products; using Volo.Abp; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + public class UnexpectedInventoryStrategyException : BusinessException { public UnexpectedInventoryStrategyException(InventoryStrategy expectedInventoryStrategy) : base(FlashSalesErrorCodes.UnexpectedInventoryStrategy) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index ea6e6470..7c00f09d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -1,13 +1,12 @@ using System; using System.Linq; using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using EasyAbp.EShop.Stores.Stores; using Volo.Abp.Application.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; public class FlashSaleResultAppService : MultiStoreCrudAppService, @@ -19,22 +18,22 @@ public class FlashSaleResultAppService : protected IFlashSaleResultRepository FlashSaleResultRepository { get; } - public FlashSaleResultAppService(IFlashSaleResultRepository flashSalesResultRepository) : base(flashSalesResultRepository) + public FlashSaleResultAppService(IFlashSaleResultRepository flashSaleResultRepository) : base(flashSaleResultRepository) { } public override async Task GetAsync(Guid id) { - var flashSalesResult = await GetEntityByIdAsync(id); + var flashSaleResult = await GetEntityByIdAsync(id); - await CheckMultiStorePolicyAsync(flashSalesResult.StoreId, GetPolicyName); + await CheckMultiStorePolicyAsync(flashSaleResult.StoreId, GetPolicyName); - if (flashSalesResult.UserId != CurrentUser.Id) + if (flashSaleResult.UserId != CurrentUser.Id) { - await CheckMultiStorePolicyAsync(flashSalesResult.StoreId, FlashSalesPermissions.FlashSaleResult.Manage); + await CheckMultiStorePolicyAsync(flashSaleResult.StoreId, FlashSalesPermissions.FlashSaleResult.Manage); } - return await MapToGetOutputDtoAsync(flashSalesResult); + return await MapToGetOutputDtoAsync(flashSaleResult); } public override async Task> GetListAsync(FlashSaleResultGetListInput input) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs index 51b1f941..3f2a4324 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs @@ -3,7 +3,6 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; namespace EasyAbp.EShop.Plugins.FlashSales; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs index 083afbfb..b5a76b63 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs @@ -2,7 +2,7 @@ using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; public class CreateFlashSaleOrderCompleteEto : ExtensibleObject, IMultiTenant { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs index 297a1342..e4377fcd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs @@ -1,5 +1,5 @@ using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Guids; @@ -9,29 +9,29 @@ namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; public class CreateFlashSaleOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency { - protected IFlashSaleResultRepository FlashSalesResultRepository { get; } + protected IFlashSaleResultRepository FlashSaleResultRepository { get; } protected IGuidGenerator GuidGenerator { get; } - public CreateFlashSaleOrderCompleteEventHandler(IFlashSaleResultRepository flashSalesResultRepository, IGuidGenerator guidGenerator) + public CreateFlashSaleOrderCompleteEventHandler(IFlashSaleResultRepository flashSaleResultRepository, IGuidGenerator guidGenerator) { - FlashSalesResultRepository = flashSalesResultRepository; + FlashSaleResultRepository = flashSaleResultRepository; GuidGenerator = guidGenerator; } [UnitOfWork] public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) { - var flashSalesResult = await FlashSalesResultRepository.GetAsync(eventData.PendingResultId); + var flashSaleResult = await FlashSaleResultRepository.GetAsync(eventData.PendingResultId); if (eventData.Success) { - flashSalesResult.MarkAsSuccessful(eventData.OrderId.Value); + flashSaleResult.MarkAsSuccessful(eventData.OrderId.Value); } else { - flashSalesResult.MarkAsFailed(eventData.Reason); + flashSaleResult.MarkAsFailed(eventData.Reason); } - await FlashSalesResultRepository.UpdateAsync(flashSalesResult, autoSave: true); + await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.js index e9976c18..ff9c2d89 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.js +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlan/index.js @@ -35,7 +35,7 @@ $(function () { text: l('Delete'), visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.FlashSales.FlashSalePlan.Delete'), confirmMessage: function (data) { - return l('FlashSalesPlanDeletionConfirmationMessage', data.record.id); + return l('FlashSalePlanDeletionConfirmationMessage', data.record.id); }, action: function (data) { service.delete(data.record.id) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml index 38c98091..88d70cfa 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml @@ -3,7 +3,7 @@ @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Layout -@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSalesResult +@using EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult @using EasyAbp.EShop.Plugins.FlashSales.Localization @using EasyAbp.EShop.Plugins.FlashSales.Web.Menus diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml.cs index a237d092..def3ff36 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/Index.cshtml.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSalesResult; +namespace EasyAbp.EShop.Plugins.FlashSales.Web.Pages.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult; public class IndexModel : PageModel { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs index f4b1092a..45f6da3c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; using EasyAbp.EShop.Products.ProductDetails; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; From bc5fc8a6ab0c5906b5d6ef945811e9fc7e921a4c Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 9 Jul 2022 23:23:37 +0800 Subject: [PATCH 26/97] Introduce `IFlashSaleInventoryManager` --- EShop.sln | 16 +- .../IProductInventoryProviderResolver.cs | 2 + .../ProductInventoryProviderResolver.cs | 8 +- .../CreateFlashSaleOrderEventHandler.cs | 110 ++++++++--- ...sFlashSalesApplicationAutoMapperProfile.cs | 36 ---- ...Shop.Plugins.FlashSales.Application.csproj | 2 + ...EShopPluginsFlashSalesApplicationModule.cs | 3 + .../FlashSalePlans/FlashSalePlanAppService.cs | 171 +++++++++++------- .../FlashSalePlanTokenCacheItem.cs | 17 ++ .../Products/FlashSaleInventoryManager.cs | 33 ++++ .../FlashSalePlans/CreateFlashSaleOrderEto.cs | 6 +- .../FlashSaleProductAttributeEto.cs | 17 -- .../FlashSaleProductAttributeOptionEto.cs | 14 -- .../FlashSaleProductDetailEto.cs | 14 -- .../FlashSalePlans/FlashSaleProductEto.cs | 44 ----- .../FlashSalePlans/FlashSaleProductSkuEto.cs | 31 ---- .../FlashSaleReduceInventoryEto.cs | 27 --- ...cts.Plugins.FlashSales.Abstractions.csproj | 14 ++ ...ductsPluginsFlashSalesApplicationModule.cs | 11 ++ .../Products/IFlashSaleInventoryManager.cs | 11 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 +++ ...ns.FlashSales.Application.Contracts.csproj | 14 ++ ...insFlashSalesApplicationContractsModule.cs | 10 + ...sFlashSalesPermissionDefinitionProvider.cs | 26 +++ .../ProductsPluginsFlashSalesPermissions.cs | 21 +++ .../Products/Dtos/IncreaseInventoryInput.cs | 37 ++++ .../Products/Dtos/ReduceInventoryInput.cs | 37 ++++ .../Products/IFlashSaleInventoryAppService.cs | 13 ++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 +++ ...ucts.Plugins.FlashSales.Application.csproj | 2 + ...sFlashSalesApplicationAutoMapperProfile.cs | 37 ---- ...ductsPluginsFlashSalesApplicationModule.cs | 20 +- .../Products/FlashSaleInventoryAppService.cs | 45 +++++ .../FlashSaleReduceInventoryEventHandler.cs | 112 ------------ .../ILocalFlashSaleInventoryManager.cs | 12 ++ .../LocalFlashSaleInventoryManager.cs | 33 ++++ 38 files changed, 632 insertions(+), 440 deletions(-) delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeEto.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeOptionEto.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductDetailEto.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductEto.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductSkuEto.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationContractsModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissionDefinitionProvider.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissions.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/IncreaseInventoryInput.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ReduceInventoryInput.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ILocalFlashSaleInventoryManager.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs diff --git a/EShop.sln b/EShop.sln index 44fc2380..88ccbea9 100644 --- a/EShop.sln +++ b/EShop.sln @@ -413,7 +413,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Plugins.Flash EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Orders.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Orders.Plugins.FlashSales.Application\EasyAbp.EShop.Orders.Plugins.FlashSales.Application.csproj", "{5732E880-CB72-49A0-AC4F-A0620F4E4D16}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Application\EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj", "{6AD2F468-D86C-4F9A-B280-3BCC15661C47}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Application\EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj", "{6AD2F468-D86C-4F9A-B280-3BCC15661C47}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions\EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions.csproj", "{C1EB9DC0-F572-41DF-9716-893B154BBB13}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj", "{F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1077,6 +1081,14 @@ Global {6AD2F468-D86C-4F9A-B280-3BCC15661C47}.Debug|Any CPU.Build.0 = Debug|Any CPU {6AD2F468-D86C-4F9A-B280-3BCC15661C47}.Release|Any CPU.ActiveCfg = Release|Any CPU {6AD2F468-D86C-4F9A-B280-3BCC15661C47}.Release|Any CPU.Build.0 = Release|Any CPU + {C1EB9DC0-F572-41DF-9716-893B154BBB13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1EB9DC0-F572-41DF-9716-893B154BBB13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1EB9DC0-F572-41DF-9716-893B154BBB13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1EB9DC0-F572-41DF-9716-893B154BBB13}.Release|Any CPU.Build.0 = Release|Any CPU + {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1284,6 +1296,8 @@ Global {417AB8E2-1488-4814-9699-3B189D1ABA67} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} {5732E880-CB72-49A0-AC4F-A0620F4E4D16} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} {6AD2F468-D86C-4F9A-B280-3BCC15661C47} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {C1EB9DC0-F572-41DF-9716-893B154BBB13} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductInventoryProviderResolver.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductInventoryProviderResolver.cs index 1fd1daca..09ea7ab9 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductInventoryProviderResolver.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductInventoryProviderResolver.cs @@ -9,4 +9,6 @@ public interface IProductInventoryProviderResolver Task ExistProviderAsync([NotNull] string providerName); Task GetAsync(Product product); + + Task GetAsync([NotNull] string providerName); } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs index bd1e4472..89ea20ca 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs @@ -7,6 +7,7 @@ using EasyAbp.EShop.Products.ProductInventories; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp; using Volo.Abp.DependencyInjection; namespace EasyAbp.EShop.Products.Products; @@ -47,6 +48,11 @@ public class ProductInventoryProviderResolver : IProductInventoryProviderResolve return Task.FromResult(GetProviderByName(options.Value.DefaultInventoryProviderName)); } + public virtual Task GetAsync([NotNull] string providerName) + { + return Task.FromResult(GetProviderByName(providerName)); + } + protected virtual IProductInventoryProvider GetProviderByName([CanBeNull] string providerName) { if (providerName.IsNullOrEmpty()) @@ -67,7 +73,7 @@ public class ProductInventoryProviderResolver : IProductInventoryProviderResolve { return; } - + var options = ServiceProvider.GetRequiredService>().Value; foreach (var pair in options.InventoryProviders.GetConfigurationsDictionary()) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index 441f4234..7aab2d4c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -3,7 +3,10 @@ using System.Collections.Generic; using System.Threading.Tasks; using EasyAbp.EShop.Orders.Orders.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Products.ProductDetails; using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; @@ -24,45 +27,59 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler orderDiscountProviders, IOrderRepository orderRepository, - IDistributedEventBus distributedEventBus) + IDistributedEventBus distributedEventBus, + IProductAppService productAppService, + IProductDetailAppService productDetailAppService, + IFlashSalePlanHasher flashSalePlanHasher) { NewOrderGenerator = newOrderGenerator; ObjectMapper = objectMapper; OrderDiscountProviders = orderDiscountProviders; OrderRepository = orderRepository; DistributedEventBus = distributedEventBus; + ProductAppService = productAppService; + ProductDetailAppService = productDetailAppService; + FlashSalePlanHasher = flashSalePlanHasher; } [UnitOfWork(true)] public virtual async Task HandleEventAsync(CreateFlashSaleOrderEto eventData) { - var input = new CreateOrderDto() + var product = await ProductAppService.GetAsync(eventData.Plan.ProductId); + var productSku = product.GetSkuById(eventData.Plan.ProductSkuId); + + if (!await ValidateHashTokenAsync(eventData.Plan, product, productSku, eventData.HashToken)) { - StoreId = eventData.StoreId, - CustomerRemark = eventData.CustomerRemark, - OrderLines = new List() + await DistributedEventBus.PublishAsync(new CreateFlashSaleOrderCompleteEto() { - new CreateOrderLineDto() - { - ProductId = eventData.Plan.ProductId, - ProductSkuId = eventData.Plan.ProductSkuId, - Quantity = 1 - } - } - }; - var productDict = new Dictionary() - { - {eventData.Product.Id, ObjectMapper.Map(eventData.Product)} - }; - var productDetailDict = new Dictionary() - { - {eventData.ProductDetail.Id, ObjectMapper.Map(eventData.ProductDetail)} - }; + TenantId = eventData.TenantId, + PlanId = eventData.PlanId, + OrderId = null, + UserId = eventData.UserId, + StoreId = eventData.StoreId, + PendingResultId = eventData.PendingResultId, + Success = false, + Reason = FlashSaleResultFailedReason.PreOrderExipred + }); + return; + } + + var input = await ConvertToCreateOrderDtoAsync(eventData); + + var productDict = await GetProductDictionaryAsync(product); + + var productDetailDict = await GetProductDetailDictionaryAsync(product, productSku); var order = await NewOrderGenerator.GenerateAsync(eventData.UserId, input, productDict, productDetailDict); @@ -79,4 +96,55 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler> GetProductDictionaryAsync(ProductDto product) + { + var productDict = new Dictionary() + { + {product.Id, product} + }; + + return Task.FromResult(productDict); + } + + protected virtual async Task> GetProductDetailDictionaryAsync(ProductDto product, ProductSkuDto productSku) + { + var dict = new Dictionary(); + + var productDetailId = productSku.ProductDetailId ?? product.ProductDetailId; + + if (productDetailId.HasValue) + { + dict.Add(productDetailId.Value, await ProductDetailAppService.GetAsync(productDetailId.Value)); + } + + return dict; + } + + protected virtual Task ConvertToCreateOrderDtoAsync(CreateFlashSaleOrderEto eventData) + { + var input = new CreateOrderDto() + { + StoreId = eventData.StoreId, + CustomerRemark = eventData.CustomerRemark, + OrderLines = new List() + { + new CreateOrderLineDto() + { + ProductId = eventData.Plan.ProductId, + ProductSkuId = eventData.Plan.ProductSkuId, + Quantity = 1 + } + } + }; + + return Task.FromResult(input); + } + + protected virtual async Task ValidateHashTokenAsync(FlashSalePlanEto plan, ProductDto product, ProductSkuDto productSku, string originHashToken) + { + var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + + return string.Equals(hashToken, originHashToken, StringComparison.InvariantCulture); + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs deleted file mode 100644 index 51e511bb..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs +++ /dev/null @@ -1,36 +0,0 @@ -using AutoMapper; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -using EasyAbp.EShop.Products.ProductDetails.Dtos; -using EasyAbp.EShop.Products.Products.Dtos; -using Volo.Abp.AutoMapper; -using Volo.Abp.DependencyInjection; - -namespace EasyAbp.EShop.Orders.Plugins.FlashSales -{ - public class EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile : Profile - { - public EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile() - { - /* You can configure your AutoMapper mapping configuration here. - * Alternatively, you can split your mapping configurations - * into multiple profile classes for a better organization. */ - CreateMap(MemberList.Destination) - .Ignore(dto => dto.Sold) - .Ignore(dto => dto.MinimumPrice) - .Ignore(dto => dto.MaximumPrice) - .MapExtraProperties(); - CreateMap(MemberList.Destination) - .ForSourceMember(entity => entity.SerializedAttributeOptionIds, opt => opt.DoNotValidate()) - .Ignore(dto => dto.DiscountedPrice) - .Ignore(dto => dto.Inventory) - .Ignore(dto => dto.Sold) - .MapExtraProperties(); - CreateMap(MemberList.Destination) - .MapExtraProperties(); - CreateMap(MemberList.Destination) - .MapExtraProperties(); - CreateMap(MemberList.Destination) - .MapExtraProperties(); - } - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj index 80f4e744..12758834 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp.EShop.Plugins.FlashSales.Application.csproj @@ -16,6 +16,8 @@ + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs index c88bd54a..48e94a13 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationModule.cs @@ -1,4 +1,5 @@ using EasyAbp.EShop.Products; +using EasyAbp.EShop.Products.Plugins.FlashSales; using EasyAbp.EShop.Stores; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Application; @@ -13,6 +14,8 @@ namespace EasyAbp.EShop.Plugins.FlashSales; typeof(EShopPluginsFlashSalesDomainModule), typeof(EShopPluginsFlashSalesApplicationContractsModule), typeof(EShopStoresApplicationSharedModule), + typeof(EShopProductsPluginsFlashSalesAbstractionsModule), + typeof(EShopProductsPluginsFlashSalesApplicationContractsModule), typeof(AbpDddApplicationModule), typeof(AbpAutoMapperModule), typeof(AbpCachingModule) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 6fb4fa52..63bb7c10 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using EasyAbp.Eshop.Products.Products; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.Permissions; @@ -37,9 +38,9 @@ public class FlashSalePlanAppService : protected IProductAppService ProductAppService { get; } - protected IDistributedCache TokenDistributedCache { get; } + protected IDistributedCache PreOrderDistributedCache { get; } - protected IDistributedCache DistributedCache { get; } + protected IDistributedCache PlanDistributedCache { get; } protected IDistributedEventBus DistributedEventBus { get; } @@ -49,25 +50,33 @@ public class FlashSalePlanAppService : protected IFlashSalePlanHasher FlashSalePlanHasher { get; } + protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } + + protected IDistributedCache DistributedCache { get; } + public FlashSalePlanAppService( IFlashSalePlanRepository flashSalePlanRepository, IProductAppService productAppService, - IDistributedCache tokenDistributedCache, - IDistributedCache distributedCache, + IDistributedCache tokenDistributedCache, + IDistributedCache planDistributedCache, IDistributedEventBus distributedEventBus, IFlashSaleResultRepository flashSaleResultRepository, IAbpDistributedLock distributedLock, - IFlashSalePlanHasher flashSalePlanHasher) + IFlashSalePlanHasher flashSalePlanHasher, + IFlashSaleInventoryManager flashSaleInventoryManager, + IDistributedCache distributedCache) : base(flashSalePlanRepository) { FlashSalePlanRepository = flashSalePlanRepository; ProductAppService = productAppService; - TokenDistributedCache = tokenDistributedCache; - DistributedCache = distributedCache; + PreOrderDistributedCache = tokenDistributedCache; + PlanDistributedCache = planDistributedCache; DistributedEventBus = distributedEventBus; FlashSaleResultRepository = flashSaleResultRepository; DistributedLock = distributedLock; FlashSalePlanHasher = flashSalePlanHasher; + FlashSaleInventoryManager = flashSaleInventoryManager; + DistributedCache = distributedCache; } public override async Task GetAsync(Guid id) @@ -180,15 +189,15 @@ public class FlashSalePlanAppService : await ValidatePreOrderAsync(plan, product, productSku); - await SetCacheHashTokenAsync(plan, product, productSku); + await SetPreOrderCacheAsync(plan, product, productSku); } public virtual async Task CheckPreOrderAsync(Guid id) { var plan = await GetFlashSalePlanCacheAsync(id); - var cacheHashToken = await GetCacheHashTokenAsync(plan); - if (cacheHashToken.IsNullOrWhiteSpace()) + var preOrderCache = await GetPreOrderCacheAsync(plan); + if (preOrderCache == null) { throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } @@ -196,7 +205,7 @@ public class FlashSalePlanAppService : var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); - if (!await CompareHashTokenAsync(cacheHashToken, plan, product, productSku)) + if (!await CompareHashTokenAsync(preOrderCache.HashToken, plan, product, productSku)) { throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } @@ -218,39 +227,81 @@ public class FlashSalePlanAppService : throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } - var cacheHashToken = await GetCacheHashTokenAsync(plan); - if (cacheHashToken.IsNullOrWhiteSpace()) + var preOrderCache = await GetPreOrderCacheAsync(plan); + if (preOrderCache == null) { throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); } - await RemoveCacheHashTokenAsync(plan); + await RemovePreOrderCacheAsync(plan); var userId = CurrentUser.GetId(); - var result = await CreatePendingFlashSaleResultAsync(plan, userId); + var key = $"create-flash-sale-order-{plan.Id}-{userId}"; + + await using var handle = await DistributedLock.TryAcquireAsync(key); + + if (handle == null) + { + throw new BusinessException(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); + } + + var userFlashSaleResultCache = await GetUserFlashSaleResultCacheAsync(plan, userId); + if (!userFlashSaleResultCache.IsNullOrWhiteSpace()) + { + throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + } + + if (!await FlashSaleInventoryManager.TryIncreaseInventoryAsync( + plan.TenantId, preOrderCache.InventoryProviderName, + plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) + { + throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); + } - var flashSalesReduceInventoryEto = await PrepareFlashSalesReduceInventoryEtoAsync(plan, result.Id, input, userId, now, cacheHashToken); + // Prevent repeat submit + var existsResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => x.PlanId == plan.Id && x.UserId == userId); - /* - * FlashSalesReduceInventoryEto(success) -> CreateFlashSalesOrderEto -> CreateFlashSalesOrderCompleteEto - * FlashSalesReduceInventoryEto(failed) -> CreateFlashSalesOrderCompleteEto - */ - await DistributedEventBus.PublishAsync(flashSalesReduceInventoryEto); + if (existsResult != null) + { + await SetUserFlashSaleResultCacheAsync(plan, userId, existsResult.Id); + + await FlashSaleInventoryManager.TryIncreaseInventoryAsync( + plan.TenantId, preOrderCache.InventoryProviderName, + plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true + ); + + throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + } + + var result = new FlashSaleResult( + id: GuidGenerator.Create(), + tenantId: CurrentTenant.Id, + storeId: plan.StoreId, + planId: plan.Id, + status: FlashSaleResultStatus.Pending, + reason: null, + userId: userId, + orderId: null + ); + + await FlashSaleResultRepository.InsertAsync(result, autoSave: true); + + await SetUserFlashSaleResultCacheAsync(plan, userId, result.Id); + + var createFlashSaleOrderEto = await PrepareCreateFlashSaleOrderEtoAsync(plan, result.Id, input, userId, now, preOrderCache.HashToken); + + await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); } - protected virtual Task PrepareFlashSalesReduceInventoryEtoAsync( - FlashSalePlanCacheItem plan, - Guid resultId, - CreateOrderInput input, - Guid userId, - DateTime now, - string hashToken) + protected virtual Task PrepareCreateFlashSaleOrderEtoAsync( + FlashSalePlanCacheItem plan, Guid resultId, CreateOrderInput input, + Guid userId, DateTime now, string hashToken) { var planEto = ObjectMapper.Map(plan); planEto.TenantId = CurrentTenant.Id; - var eto = new FlashSaleReduceInventoryEto() + var eto = new CreateFlashSaleOrderEto() { TenantId = CurrentTenant.Id, PlanId = plan.Id, @@ -273,33 +324,40 @@ public class FlashSalePlanAppService : protected virtual async Task GetFlashSalePlanCacheAsync(Guid id) { - return await DistributedCache.GetOrAddAsync(id, async () => + return await PlanDistributedCache.GetOrAddAsync(id, async () => { var flashSalePlan = await FlashSalePlanRepository.GetAsync(id); return ObjectMapper.Map(flashSalePlan); }); } - protected virtual Task GetCacheKeyAsync(FlashSalePlanCacheItem plan) + protected virtual Task GetPreOrderCacheKeyAsync(FlashSalePlanCacheItem plan) { return Task.FromResult($"eshopflashsales_{CurrentTenant.Id}_{CurrentUser.Id}_{plan.ProductSkuId}"); } - protected virtual async Task GetCacheHashTokenAsync(FlashSalePlanCacheItem plan) + protected virtual async Task GetPreOrderCacheAsync(FlashSalePlanCacheItem plan) { - return await TokenDistributedCache.GetStringAsync(await GetCacheKeyAsync(plan)); + return await PreOrderDistributedCache.GetAsync(await GetPreOrderCacheKeyAsync(plan)); } - protected virtual async Task RemoveCacheHashTokenAsync(FlashSalePlanCacheItem plan) + protected virtual async Task RemovePreOrderCacheAsync(FlashSalePlanCacheItem plan) { - await TokenDistributedCache.RemoveAsync(await GetCacheKeyAsync(plan)); + await PreOrderDistributedCache.RemoveAsync(await GetPreOrderCacheKeyAsync(plan)); } - protected virtual async Task SetCacheHashTokenAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + protected virtual async Task SetPreOrderCacheAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); - await TokenDistributedCache.SetStringAsync(await GetCacheKeyAsync(plan), hashToken, new DistributedCacheEntryOptions() + await PreOrderDistributedCache.SetAsync(await GetPreOrderCacheKeyAsync(plan), new FlashSalePlanPreOrderCacheItem() + { + HashToken = hashToken, + PlanId = plan.Id, + ProductId = product.Id, + ProductSkuId = productSku.Id, + InventoryProviderName = product.InventoryProviderName, + }, new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(3) }); @@ -317,36 +375,21 @@ public class FlashSalePlanAppService : return cacheHashToken == hashToken; } - protected virtual async Task CreatePendingFlashSaleResultAsync(FlashSalePlanCacheItem plan, Guid userId) + protected virtual Task GetUserFlashSaleResultCacheKeyAsync(FlashSalePlanCacheItem plan, Guid userId) { - var lockKey = $"create-flash-sales-order-{plan.Id}-{userId}"; - - await using var handle = await DistributedLock.TryAcquireAsync(lockKey); - - if (handle == null) - { - throw new BusinessException(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); - } + return Task.FromResult($"flash-sale-result-{plan.Id}-{userId}"); + } - // Prevent repeat submit - if (await FlashSaleResultRepository.AnyAsync(x => - x.PlanId == plan.Id && x.UserId == userId && (x.Status == FlashSaleResultStatus.Successful || x.Status == FlashSaleResultStatus.Pending)) - ) - { - throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); - } + protected virtual async Task GetUserFlashSaleResultCacheAsync(FlashSalePlanCacheItem plan, Guid userId) + { + var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(plan, userId); + return await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); + } - var result = new FlashSaleResult( - id: GuidGenerator.Create(), - tenantId: CurrentTenant.Id, - storeId: plan.StoreId, - planId: plan.Id, - status: FlashSaleResultStatus.Pending, - reason: null, - userId: userId, - orderId: null - ); - return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); + protected virtual async Task SetUserFlashSaleResultCacheAsync(FlashSalePlanCacheItem plan, Guid userId, Guid resultId) + { + var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(plan, userId); + await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, resultId.ToString()); } protected virtual Task ValidatePreOrderAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs new file mode 100644 index 00000000..4aac4954 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs @@ -0,0 +1,17 @@ +using System; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +[Serializable] +public class FlashSalePlanPreOrderCacheItem +{ + public string HashToken { get; set; } + + public Guid PlanId { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public string InventoryProviderName { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs new file mode 100644 index 00000000..374e15d9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.Eshop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.EShop.Products.Products; + +[ExposeServices(typeof(IFlashSaleInventoryManager), IncludeSelf = true)] +[Dependency(TryRegister = true)] +public class FlashSaleInventoryManager : IFlashSaleInventoryManager, ITransientDependency +{ + protected IFlashSaleInventoryAppService FlashSaleInventoryReducerAppService { get; } + + public FlashSaleInventoryManager(IFlashSaleInventoryAppService flashSaleInventoryReducerAppService) + { + FlashSaleInventoryReducerAppService = flashSaleInventoryReducerAppService; + } + + public virtual async Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool increaseSold) + { + return await FlashSaleInventoryReducerAppService.TryReduceInventoryAsync( + new ReduceInventoryInput(tenantId, providerName, storeId, productId, productSkuId, quantity, increaseSold)); + } + + public virtual async Task TryIncreaseInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool decreaseSold) + { + return await FlashSaleInventoryReducerAppService.TryIncreaseInventoryAsync + (new IncreaseInventoryInput(tenantId, providerName, storeId, productId, productSkuId, quantity, decreaseSold)); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs index af228c85..c17a0f39 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs @@ -21,9 +21,7 @@ public class CreateFlashSaleOrderEto : ExtensibleObject, IMultiTenant public string CustomerRemark { get; set; } - public FlashSaleProductEto Product { get; set; } - - public FlashSaleProductDetailEto ProductDetail { get; set; } - public FlashSalePlanEto Plan { get; set; } + + public string HashToken { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeEto.cs deleted file mode 100644 index 7e9f1e8c..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeEto.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using EasyAbp.EShop.Products.Products; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -[Serializable] -public class FlashSaleProductAttributeEto : FullAuditedEntityEto, IProductAttribute -{ - public string DisplayName { get; set; } - - public string Description { get; set; } - - public int DisplayOrder { get; set; } - - public List ProductAttributeOptions { get; set; } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeOptionEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeOptionEto.cs deleted file mode 100644 index 4548b41c..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductAttributeOptionEto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using EasyAbp.EShop.Products.Products; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -[Serializable] -public class FlashSaleProductAttributeOptionEto : FullAuditedEntityEto, IProductAttributeOption -{ - public string DisplayName { get; set; } - - public string Description { get; set; } - - public int DisplayOrder { get; set; } -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductDetailEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductDetailEto.cs deleted file mode 100644 index 9b2a267d..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductDetailEto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Volo.Abp.MultiTenancy; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -[Serializable] -public class FlashSaleProductDetailEto : FullAuditedEntityEto, IMultiTenant -{ - public Guid? TenantId { get; set; } - - public Guid? StoreId { get; set; } - - public string Description { get; set; } -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductEto.cs deleted file mode 100644 index 6fe3f12c..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductEto.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using EasyAbp.EShop.Products.Products; -using Volo.Abp.MultiTenancy; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -[Serializable] -public class FlashSaleProductEto : FullAuditedEntityEto, IProduct, IMultiTenant -{ - public Guid? TenantId { get; set; } - - public Guid StoreId { get; set; } - - public string ProductGroupName { get; set; } - - public string ProductGroupDisplayName { get; set; } - - public Guid? ProductDetailId { get; set; } - - public string UniqueName { get; set; } - - public string DisplayName { get; set; } - - public InventoryStrategy InventoryStrategy { get; set; } - - public string InventoryProviderName { get; set; } - - public string MediaResources { get; set; } - - public int DisplayOrder { get; set; } - - public bool IsPublished { get; set; } - - public bool IsStatic { get; set; } - - public bool IsHidden { get; set; } - - public TimeSpan? PaymentExpireIn { get; set; } - - public List ProductAttributes { get; set; } - - public List ProductSkus { get; set; } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductSkuEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductSkuEto.cs deleted file mode 100644 index c629db7f..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleProductSkuEto.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using EasyAbp.EShop.Products.Products; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -[Serializable] -public class FlashSaleProductSkuEto : FullAuditedEntityEto, IProductSku -{ - public List AttributeOptionIds { get; set; } - - public string SerializedAttributeOptionIds { get; set; } - - public string Name { get; set; } - - public string Currency { get; set; } - - public decimal? OriginalPrice { get; set; } - - public decimal Price { get; set; } - - public int OrderMinQuantity { get; set; } - - public int OrderMaxQuantity { get; set; } - - public TimeSpan? PaymentExpireIn { get; set; } - - public string MediaResources { get; set; } - - public Guid? ProductDetailId { get; set; } -} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs deleted file mode 100644 index 99beb450..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleReduceInventoryEto.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Volo.Abp.MultiTenancy; -using Volo.Abp.ObjectExtending; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -[Serializable] -public class FlashSaleReduceInventoryEto : ExtensibleObject, IMultiTenant -{ - public Guid? TenantId { get; set; } - - public Guid StoreId { get; set; } - - public Guid PlanId { get; set; } - - public Guid UserId { get; set; } - - public Guid PendingResultId { get; set; } - - public DateTime CreateTime { get; set; } - - public string CustomerRemark { get; set; } - - public FlashSalePlanEto Plan { get; set; } - - public string HashToken { get; set; } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions.csproj new file mode 100644 index 00000000..ceb72923 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions.csproj @@ -0,0 +1,14 @@ + + + + + + netstandard2.0 + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs new file mode 100644 index 00000000..6926ce29 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Products.Plugins.FlashSales; + +[DependsOn( + typeof(EShopProductsApplicationContractsModule) +)] +public class EShopProductsPluginsFlashSalesAbstractionsModule : AbpModule +{ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs new file mode 100644 index 00000000..0896e7d5 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs @@ -0,0 +1,11 @@ +using System; +using System.Threading.Tasks; + +namespace EasyAbp.Eshop.Products.Products; + +public interface IFlashSaleInventoryManager +{ + Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool increaseSold); + + Task TryIncreaseInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold); +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml new file mode 100644 index 00000000..00e1d9a1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xsd new file mode 100644 index 00000000..3f3946e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj new file mode 100644 index 00000000..91c56364 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj @@ -0,0 +1,14 @@ + + + + + + netstandard2.0 + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationContractsModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationContractsModule.cs new file mode 100644 index 00000000..efd5d81b --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationContractsModule.cs @@ -0,0 +1,10 @@ +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Products.Plugins.FlashSales; + +[DependsOn( + typeof(EShopProductsApplicationContractsModule) +)] +public class EShopProductsPluginsFlashSalesApplicationContractsModule : AbpModule +{ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissionDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissionDefinitionProvider.cs new file mode 100644 index 00000000..aedf09da --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissionDefinitionProvider.cs @@ -0,0 +1,26 @@ +using EasyAbp.EShop.Products.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace EasyAbp.EShop.Products.Permissions +{ + public class ProductsPluginsFlashSalesPermissionDefinitionProvider : PermissionDefinitionProvider + { + public override void Define(IPermissionDefinitionContext context) + { + var moduleGroup = context.AddGroup(ProductsPluginsFlashSalesPermissions.GroupName, L("Permission:Products")); + + var flashSaleInventoryPermission = moduleGroup.AddPermission(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Default, L("Permission:FlashSaleInventory")) + .WithProviders(ClientPermissionValueProvider.ProviderName); + flashSaleInventoryPermission.AddChild(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Increase, L("Permission:InventoryIncrease")) + .WithProviders(ClientPermissionValueProvider.ProviderName); + flashSaleInventoryPermission.AddChild(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Reduce, L("Permission:InventoryReduce")) + .WithProviders(ClientPermissionValueProvider.ProviderName); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissions.cs new file mode 100644 index 00000000..66e90962 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Plugins/FlashSales/Permissions/ProductsPluginsFlashSalesPermissions.cs @@ -0,0 +1,21 @@ +using Volo.Abp.Reflection; + +namespace EasyAbp.EShop.Products.Permissions +{ + public class ProductsPluginsFlashSalesPermissions + { + public const string GroupName = "EasyAbp.EShop.Products.Plugins.FlashSales"; + + public class FlashSaleInventory + { + public const string Default = GroupName + ".FlashSaleInventory"; + public const string Reduce = Default + ".Reduce"; + public const string Increase = Default + ".Increase"; + } + + public static string[] GetAll() + { + return ReflectionHelper.GetPublicConstantsRecursively(typeof(ProductsPluginsFlashSalesPermissions)); + } + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/IncreaseInventoryInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/IncreaseInventoryInput.cs new file mode 100644 index 00000000..e520d5bb --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/IncreaseInventoryInput.cs @@ -0,0 +1,37 @@ +using System; +using EasyAbp.EShop.Stores.Stores; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Products.Products.Dtos; + +public class IncreaseInventoryInput : IMultiTenant, IMultiStore +{ + public Guid? TenantId { get; set; } + + public string ProviderName { get; set; } + + public Guid StoreId { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public int Quantity { get; set; } + + public bool ReduceSold { get; set; } + + public IncreaseInventoryInput() + { + } + + public IncreaseInventoryInput(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool reduceSold) + { + TenantId = tenantId; + ProviderName = providerName; + StoreId = storeId; + ProductId = productId; + ProductSkuId = productSkuId; + Quantity = quantity; + ReduceSold = reduceSold; + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ReduceInventoryInput.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ReduceInventoryInput.cs new file mode 100644 index 00000000..fa5ac94c --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ReduceInventoryInput.cs @@ -0,0 +1,37 @@ +using System; +using EasyAbp.EShop.Stores.Stores; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Products.Products.Dtos; + +public class ReduceInventoryInput : IMultiTenant, IMultiStore +{ + public Guid? TenantId { get; set; } + + public string ProviderName { get; set; } + + public Guid StoreId { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + + public int Quantity { get; set; } + + public bool IncreaseSold { get; set; } + + public ReduceInventoryInput() + { + } + + public ReduceInventoryInput(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool increaseSold) + { + TenantId = tenantId; + ProviderName = providerName; + StoreId = storeId; + ProductId = productId; + ProductSkuId = productSkuId; + Quantity = quantity; + IncreaseSold = increaseSold; + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs new file mode 100644 index 00000000..339d2e60 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs @@ -0,0 +1,13 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Products.Dtos; +using Volo.Abp.Application.Services; + +namespace EasyAbp.EShop.Products.Products; + +public interface IFlashSaleInventoryAppService : IApplicationService +{ + Task TryReduceInventoryAsync(ReduceInventoryInput input); + + Task TryIncreaseInventoryAsync(IncreaseInventoryInput input); +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml new file mode 100644 index 00000000..00e1d9a1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd new file mode 100644 index 00000000..3f3946e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj index 308d5504..88afd375 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp.EShop.Products.Plugins.FlashSales.Application.csproj @@ -10,6 +10,8 @@ + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs deleted file mode 100644 index fbb7050b..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationAutoMapperProfile.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Linq; -using AutoMapper; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -using EasyAbp.EShop.Products.Options; -using EasyAbp.EShop.Products.ProductDetails; -using EasyAbp.EShop.Products.Products; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; - -namespace EasyAbp.EShop.Plugins.FlashSales; - -public class EShopProductsPluginsFlashSalesApplicationAutoMapperProfile : Profile, ISingletonDependency -{ - public EShopProductsPluginsFlashSalesApplicationAutoMapperProfile( - IAttributeOptionIdsSerializer attributeOptionIdsSerializer, - IOptionsMonitor options) - { - CreateMap() - .ForMember(x => x.ProductGroupDisplayName, opt => opt.Ignore()) - .AfterMap((src, dest) => - { - var dict = options.CurrentValue.Groups.GetConfigurationsDictionary(); - dest.ProductGroupDisplayName = dict[src.ProductGroupName].DisplayName; - }) - .MapExtraProperties(); - CreateMap() - .ForMember(x => x.AttributeOptionIds, opt => opt.Ignore()) - .AfterMap(async (src, dest) => dest.AttributeOptionIds = (await attributeOptionIdsSerializer.DeserializeAsync(src.SerializedAttributeOptionIds)).ToList()) - .MapExtraProperties(); - CreateMap() - .MapExtraProperties(); - CreateMap() - .MapExtraProperties(); - CreateMap() - .MapExtraProperties(); - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs index a1a599dc..dcee02c4 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesApplicationModule.cs @@ -1,28 +1,14 @@ using EasyAbp.EShop.Plugins.FlashSales; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Products.Plugins.FlashSales; [DependsOn( typeof(EShopProductsApplicationModule), - typeof(EShopPluginsFlashSalesApplicationContractsModule) + typeof(EShopPluginsFlashSalesApplicationContractsModule), + typeof(EShopProductsPluginsFlashSalesApplicationContractsModule), + typeof(EShopProductsPluginsFlashSalesAbstractionsModule) )] public class EShopProductsPluginsFlashSalesApplicationModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddAutoMapperObjectMapper(); - Configure(options => - { - options.Configurators.Add(abpAutoMapperConfigurationContext => - { - var profile = abpAutoMapperConfigurationContext.ServiceProvider - .GetRequiredService(); - - abpAutoMapperConfigurationContext.MapperConfiguration.AddProfile(profile); - }); - }); - } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs new file mode 100644 index 00000000..9a3a56e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs @@ -0,0 +1,45 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Permissions; +using EasyAbp.EShop.Products.Products.Dtos; + +namespace EasyAbp.EShop.Products.Products; + +public class FlashSaleInventoryAppService : ProductsAppService, IFlashSaleInventoryAppService +{ + protected ILocalFlashSaleInventoryManager LocalFlashSaleInventoryReducer { get; } + + public FlashSaleInventoryAppService(ILocalFlashSaleInventoryManager localFlashSaleInventoryReducer) + { + LocalFlashSaleInventoryReducer = localFlashSaleInventoryReducer; + } + + public virtual async Task TryReduceInventoryAsync(ReduceInventoryInput input) + { + await CheckPolicyAsync(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Reduce); + + return await LocalFlashSaleInventoryReducer.TryReduceInventoryAsync( + input.TenantId, + input.ProviderName, + input.StoreId, + input.ProductId, + input.ProductSkuId, + input.Quantity, + input.IncreaseSold + ); + } + + public virtual async Task TryIncreaseInventoryAsync(IncreaseInventoryInput input) + { + await CheckPolicyAsync(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Increase); + + return await LocalFlashSaleInventoryReducer.TryIncreaseInventoryAsync( + input.TenantId, + input.ProviderName, + input.StoreId, + input.ProductId, + input.ProductSkuId, + input.Quantity, + input.ReduceSold + ); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs deleted file mode 100644 index 45f6da3c..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleReduceInventoryEventHandler.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -using EasyAbp.EShop.Products.ProductDetails; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EventBus.Distributed; -using Volo.Abp.ObjectMapping; -using Volo.Abp.Uow; - -namespace EasyAbp.EShop.Products.Products; - -public class FlashSaleReduceInventoryEventHandler : IDistributedEventHandler, ITransientDependency -{ - protected IProductRepository ProductRepository { get; } - - protected IProductDetailRepository ProductDetailRepository { get; } - - protected ProductManager ProductManager { get; } - - protected IDistributedEventBus DistributedEventBus { get; } - - protected IObjectMapper ObjectMapper { get; } - - protected IFlashSalePlanHasher FlashSalePlanHasher { get; } - - public FlashSaleReduceInventoryEventHandler( - IProductRepository productRepository, - IProductDetailRepository productDetailRepository, - ProductManager productManager, - IDistributedEventBus distributedEventBus, - IObjectMapper objectMapper, - IFlashSalePlanHasher flashSalePlanHasher) - { - ProductRepository = productRepository; - ProductDetailRepository = productDetailRepository; - ProductManager = productManager; - DistributedEventBus = distributedEventBus; - ObjectMapper = objectMapper; - FlashSalePlanHasher = flashSalePlanHasher; - } - - [UnitOfWork] - public virtual async Task HandleEventAsync(FlashSaleReduceInventoryEto eventData) - { - var product = await ProductRepository.GetAsync(eventData.Plan.ProductId); - var productSku = product.ProductSkus.Single(x => x.Id == eventData.Plan.ProductSkuId); - - var hashToken = await FlashSalePlanHasher.HashAsync(eventData.Plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); - - if (hashToken != eventData.HashToken) - { - await DistributedEventBus.PublishAsync(new CreateFlashSaleOrderCompleteEto() - { - TenantId = eventData.TenantId, - PlanId = eventData.PlanId, - OrderId = null, - UserId = eventData.UserId, - StoreId = eventData.StoreId, - PendingResultId = eventData.PendingResultId, - Success = false, - Reason = FlashSaleResultFailedReason.PreOrderExipred - }); - return; - } - - if (!await ProductManager.TryReduceInventoryAsync(product, productSku, 1, true)) - { - await DistributedEventBus.PublishAsync(new CreateFlashSaleOrderCompleteEto() - { - TenantId = eventData.TenantId, - PlanId = eventData.PlanId, - OrderId = null, - UserId = eventData.UserId, - StoreId = eventData.StoreId, - PendingResultId = eventData.PendingResultId, - Success = false, - Reason = FlashSaleResultFailedReason.InsufficientInventory - }); - return; - } - - var productDetailId = productSku.ProductDetailId ?? product.ProductDetailId; - - var productDetailEto = productDetailId.HasValue ? - ObjectMapper.Map(await ProductDetailRepository.GetAsync(productDetailId.Value)) : - null; - - var productEto = ObjectMapper.Map(product); - - var createFlashSalesOrderEto = new CreateFlashSaleOrderEto() - { - TenantId = eventData.TenantId, - PlanId = eventData.PlanId, - UserId = eventData.UserId, - PendingResultId = eventData.PendingResultId, - StoreId = eventData.StoreId, - CreateTime = eventData.CreateTime, - CustomerRemark = eventData.CustomerRemark, - Product = productEto, - ProductDetail = productDetailEto, - Plan = eventData.Plan - }; - - foreach (var item in eventData.ExtraProperties) - { - createFlashSalesOrderEto.ExtraProperties.Add(item.Key, item.Value); - } - - await DistributedEventBus.PublishAsync(createFlashSalesOrderEto); - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ILocalFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ILocalFlashSaleInventoryManager.cs new file mode 100644 index 00000000..95982ed4 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ILocalFlashSaleInventoryManager.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using EasyAbp.Eshop.Products.Products; + +namespace EasyAbp.EShop.Products.Products; + +public interface ILocalFlashSaleInventoryManager : IFlashSaleInventoryManager +{ +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs new file mode 100644 index 00000000..f13f758e --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs @@ -0,0 +1,33 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Products.ProductInventories; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.EShop.Products.Products; + +public class LocalFlashSaleInventoryManager : ILocalFlashSaleInventoryManager, ITransientDependency +{ + protected IProductInventoryProviderResolver ProductInventoryProviderResolver { get; } + + public LocalFlashSaleInventoryManager(IProductInventoryProviderResolver productInventoryProviderResolver) + { + ProductInventoryProviderResolver = productInventoryProviderResolver; + } + + public virtual async Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool increaseSold) + { + var model = new InventoryQueryModel(tenantId, storeId, productId, productSkuId); + return await (await ProductInventoryProviderResolver.GetAsync(providerName)) + .TryReduceInventoryAsync(model, quantity, increaseSold); + } + + public virtual async Task TryIncreaseInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool decreaseSold) + { + var model = new InventoryQueryModel(tenantId, storeId, productId, productSkuId); + return await (await ProductInventoryProviderResolver.GetAsync(providerName)) + .TryIncreaseInventoryAsync(model, quantity, decreaseSold); + } +} From fb58762fa9fd9f57c2121b8ba17eefd1b05b523d Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 9 Jul 2022 23:29:17 +0800 Subject: [PATCH 27/97] Introduce `FlashSalesOptions` --- .../FlashSalePlans/FlashSalePlanAppService.cs | 9 +++++++-- .../FlashSales/FlashSalePlans/FlashSalesOptions.cs | 11 +++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 63bb7c10..18b9a9fd 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -10,6 +10,7 @@ using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Stores.Stores; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Options; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Caching; @@ -54,6 +55,8 @@ public class FlashSalePlanAppService : protected IDistributedCache DistributedCache { get; } + protected FlashSalesOptions Options { get; } + public FlashSalePlanAppService( IFlashSalePlanRepository flashSalePlanRepository, IProductAppService productAppService, @@ -64,7 +67,8 @@ public class FlashSalePlanAppService : IAbpDistributedLock distributedLock, IFlashSalePlanHasher flashSalePlanHasher, IFlashSaleInventoryManager flashSaleInventoryManager, - IDistributedCache distributedCache) + IDistributedCache distributedCache, + IOptionsMonitor optionsMonitor) : base(flashSalePlanRepository) { FlashSalePlanRepository = flashSalePlanRepository; @@ -77,6 +81,7 @@ public class FlashSalePlanAppService : FlashSalePlanHasher = flashSalePlanHasher; FlashSaleInventoryManager = flashSaleInventoryManager; DistributedCache = distributedCache; + Options = optionsMonitor.CurrentValue; } public override async Task GetAsync(Guid id) @@ -359,7 +364,7 @@ public class FlashSalePlanAppService : InventoryProviderName = product.InventoryProviderName, }, new DistributedCacheEntryOptions() { - AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(3) + AbsoluteExpirationRelativeToNow = Options.PreOrderExpirationTime }); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs new file mode 100644 index 00000000..a09478dd --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs @@ -0,0 +1,11 @@ +using System; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public class FlashSalesOptions +{ + /// + /// Default: 3 minutes + /// + public TimeSpan PreOrderExpirationTime { get; set; } = TimeSpan.FromMinutes(3); +} From 193896e091061714d4d3c26b240ab15df0d40a23 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 9 Jul 2022 23:42:51 +0800 Subject: [PATCH 28/97] Format `FlashSalePlanAppService` --- .../FlashSalePlans/FlashSalePlanAppService.cs | 135 ++++++++++-------- 1 file changed, 75 insertions(+), 60 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 18b9a9fd..a4c69347 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -242,9 +242,9 @@ public class FlashSalePlanAppService : var userId = CurrentUser.GetId(); - var key = $"create-flash-sale-order-{plan.Id}-{userId}"; + var lockKey = $"create-flash-sale-order-{plan.Id}-{userId}"; - await using var handle = await DistributedLock.TryAcquireAsync(key); + await using var handle = await DistributedLock.TryAcquireAsync(lockKey); if (handle == null) { @@ -264,33 +264,15 @@ public class FlashSalePlanAppService : throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); } - // Prevent repeat submit - var existsResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => x.PlanId == plan.Id && x.UserId == userId); - - if (existsResult != null) + var result = await CreatePendingFlashSaleResultAsync(plan, userId, async (existsResultId) => { - await SetUserFlashSaleResultCacheAsync(plan, userId, existsResult.Id); + await SetUserFlashSaleResultCacheAsync(plan, userId, existsResultId); await FlashSaleInventoryManager.TryIncreaseInventoryAsync( plan.TenantId, preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true ); - - throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); - } - - var result = new FlashSaleResult( - id: GuidGenerator.Create(), - tenantId: CurrentTenant.Id, - storeId: plan.StoreId, - planId: plan.Id, - status: FlashSaleResultStatus.Pending, - reason: null, - userId: userId, - orderId: null - ); - - await FlashSaleResultRepository.InsertAsync(result, autoSave: true); + }); await SetUserFlashSaleResultCacheAsync(plan, userId, result.Id); @@ -299,33 +281,7 @@ public class FlashSalePlanAppService : await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); } - protected virtual Task PrepareCreateFlashSaleOrderEtoAsync( - FlashSalePlanCacheItem plan, Guid resultId, CreateOrderInput input, - Guid userId, DateTime now, string hashToken) - { - var planEto = ObjectMapper.Map(plan); - planEto.TenantId = CurrentTenant.Id; - - var eto = new CreateFlashSaleOrderEto() - { - TenantId = CurrentTenant.Id, - PlanId = plan.Id, - UserId = userId, - PendingResultId = resultId, - StoreId = plan.StoreId, - CreateTime = now, - CustomerRemark = input.CustomerRemark, - Plan = planEto, - HashToken = hashToken - }; - - foreach (var item in input.ExtraProperties) - { - eto.ExtraProperties.Add(item.Key, item.Value); - } - - return Task.FromResult(eto); - } + #region PreOrderCache protected virtual async Task GetFlashSalePlanCacheAsync(Guid id) { @@ -368,17 +324,9 @@ public class FlashSalePlanAppService : }); } - protected virtual async Task CompareHashTokenAsync(string cacheHashToken, FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) - { - if (cacheHashToken.IsNullOrWhiteSpace()) - { - return false; - } - - var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + #endregion - return cacheHashToken == hashToken; - } + #region UserFlashSaleResultCache protected virtual Task GetUserFlashSaleResultCacheKeyAsync(FlashSalePlanCacheItem plan, Guid userId) { @@ -397,6 +345,20 @@ public class FlashSalePlanAppService : await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, resultId.ToString()); } + #endregion + + protected virtual async Task CompareHashTokenAsync(string originHashToken, FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + { + if (originHashToken.IsNullOrWhiteSpace()) + { + return false; + } + + var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); + + return string.Equals(hashToken, originHashToken, StringComparison.InvariantCulture); + } + protected virtual Task ValidatePreOrderAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (!product.IsPublished) @@ -451,4 +413,57 @@ public class FlashSalePlanAppService : return Task.CompletedTask; } + + protected virtual Task PrepareCreateFlashSaleOrderEtoAsync( + FlashSalePlanCacheItem plan, Guid resultId, CreateOrderInput input, + Guid userId, DateTime now, string hashToken) + { + var planEto = ObjectMapper.Map(plan); + planEto.TenantId = CurrentTenant.Id; + + var eto = new CreateFlashSaleOrderEto() + { + TenantId = CurrentTenant.Id, + PlanId = plan.Id, + UserId = userId, + PendingResultId = resultId, + StoreId = plan.StoreId, + CreateTime = now, + CustomerRemark = input.CustomerRemark, + Plan = planEto, + HashToken = hashToken + }; + + foreach (var item in input.ExtraProperties) + { + eto.ExtraProperties.Add(item.Key, item.Value); + } + + return Task.FromResult(eto); + } + + protected virtual async Task CreatePendingFlashSaleResultAsync(FlashSalePlanCacheItem plan, Guid userId, Func existResultPreProcess) + { + // Prevent repeat submit + var existsResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => x.PlanId == plan.Id && x.UserId == userId); + + if (existsResult != null) + { + await existResultPreProcess(existsResult.Id); + throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + } + + var result = new FlashSaleResult( + id: GuidGenerator.Create(), + tenantId: CurrentTenant.Id, + storeId: plan.StoreId, + planId: plan.Id, + status: FlashSaleResultStatus.Pending, + reason: null, + userId: userId, + orderId: null + ); + + return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); + } } From a64dd7ea07b154e0a75e98ce842f8031a56cb6ef Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 10 Jul 2022 11:45:17 +0800 Subject: [PATCH 29/97] Add `FlashSaleInventoryController` --- EShop.sln | 16 +++++++++- .../ProductInventoryProviderResolver.cs | 2 +- .../Products/FlashSaleInventoryManager.cs | 4 +-- .../Products/IFlashSaleInventoryAppService.cs | 4 +-- .../Products/FlashSaleInventoryAppService.cs | 14 ++++----- ...Products.Plugins.FlashSales.HttpApi.csproj | 16 ++++++++++ ...pProductsPluginsFlashSalesHttpApiModule.cs | 19 ++++++++++++ .../Products/FlashSaleInventoryController.cs | 30 +++++++++++++++++++ .../FodyWeavers.xml | 3 ++ .../FodyWeavers.xsd | 30 +++++++++++++++++++ ...ts.Plugins.FlashSales.HttpApiClient.csproj | 23 ++++++++++++++ ...ctsPluginsFlashSalesHttpApiClientModule.cs | 24 +++++++++++++++ .../FodyWeavers.xml | 3 ++ .../FodyWeavers.xsd | 30 +++++++++++++++++++ .../EShopSample.Application.Contracts.csproj | 3 +- .../EShopSampleApplicationContractsModule.cs | 2 ++ .../EShopSample.HttpApi.Client.csproj | 1 + .../EShopSampleHttpApiClientModule.cs | 2 ++ .../EShopSample.HttpApi.csproj | 1 + .../EShopSampleHttpApiModule.cs | 2 ++ 20 files changed, 215 insertions(+), 14 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Products/FlashSaleInventoryController.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xsd create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xsd diff --git a/EShop.sln b/EShop.sln index 88ccbea9..5d6f9872 100644 --- a/EShop.sln +++ b/EShop.sln @@ -417,7 +417,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plug EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions\EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions.csproj", "{C1EB9DC0-F572-41DF-9716-893B154BBB13}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj", "{F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj", "{F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.csproj", "{B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj", "{98786FEE-155D-42D6-B932-D85E24114CFD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1089,6 +1093,14 @@ Global {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}.Debug|Any CPU.Build.0 = Debug|Any CPU {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}.Release|Any CPU.ActiveCfg = Release|Any CPU {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}.Release|Any CPU.Build.0 = Release|Any CPU + {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}.Release|Any CPU.Build.0 = Release|Any CPU + {98786FEE-155D-42D6-B932-D85E24114CFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98786FEE-155D-42D6-B932-D85E24114CFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {98786FEE-155D-42D6-B932-D85E24114CFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {98786FEE-155D-42D6-B932-D85E24114CFD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1298,6 +1310,8 @@ Global {6AD2F468-D86C-4F9A-B280-3BCC15661C47} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} {C1EB9DC0-F572-41DF-9716-893B154BBB13} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {98786FEE-155D-42D6-B932-D85E24114CFD} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs index 89ea20ca..77199c85 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs @@ -48,7 +48,7 @@ public class ProductInventoryProviderResolver : IProductInventoryProviderResolve return Task.FromResult(GetProviderByName(options.Value.DefaultInventoryProviderName)); } - public virtual Task GetAsync([NotNull] string providerName) + public virtual Task GetAsync([CanBeNull] string providerName) { return Task.FromResult(GetProviderByName(providerName)); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs index 374e15d9..0d811476 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs @@ -20,14 +20,14 @@ public class FlashSaleInventoryManager : IFlashSaleInventoryManager, ITransientD public virtual async Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool increaseSold) { - return await FlashSaleInventoryReducerAppService.TryReduceInventoryAsync( + return await FlashSaleInventoryReducerAppService.TryReduceAsync( new ReduceInventoryInput(tenantId, providerName, storeId, productId, productSkuId, quantity, increaseSold)); } public virtual async Task TryIncreaseInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold) { - return await FlashSaleInventoryReducerAppService.TryIncreaseInventoryAsync + return await FlashSaleInventoryReducerAppService.TryIncreaseAsync (new IncreaseInventoryInput(tenantId, providerName, storeId, productId, productSkuId, quantity, decreaseSold)); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs index 339d2e60..5cd43aed 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Products/Products/IFlashSaleInventoryAppService.cs @@ -7,7 +7,7 @@ namespace EasyAbp.EShop.Products.Products; public interface IFlashSaleInventoryAppService : IApplicationService { - Task TryReduceInventoryAsync(ReduceInventoryInput input); + Task TryReduceAsync(ReduceInventoryInput input); - Task TryIncreaseInventoryAsync(IncreaseInventoryInput input); + Task TryIncreaseAsync(IncreaseInventoryInput input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs index 9a3a56e2..b398f4c9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs @@ -6,18 +6,18 @@ namespace EasyAbp.EShop.Products.Products; public class FlashSaleInventoryAppService : ProductsAppService, IFlashSaleInventoryAppService { - protected ILocalFlashSaleInventoryManager LocalFlashSaleInventoryReducer { get; } + protected ILocalFlashSaleInventoryManager LocalFlashSaleInventoryManager { get; } - public FlashSaleInventoryAppService(ILocalFlashSaleInventoryManager localFlashSaleInventoryReducer) + public FlashSaleInventoryAppService(ILocalFlashSaleInventoryManager localFlashSaleInventoryManager) { - LocalFlashSaleInventoryReducer = localFlashSaleInventoryReducer; + LocalFlashSaleInventoryManager = localFlashSaleInventoryManager; } - public virtual async Task TryReduceInventoryAsync(ReduceInventoryInput input) + public virtual async Task TryReduceAsync(ReduceInventoryInput input) { await CheckPolicyAsync(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Reduce); - return await LocalFlashSaleInventoryReducer.TryReduceInventoryAsync( + return await LocalFlashSaleInventoryManager.TryReduceInventoryAsync( input.TenantId, input.ProviderName, input.StoreId, @@ -28,11 +28,11 @@ public class FlashSaleInventoryAppService : ProductsAppService, IFlashSaleInvent ); } - public virtual async Task TryIncreaseInventoryAsync(IncreaseInventoryInput input) + public virtual async Task TryIncreaseAsync(IncreaseInventoryInput input) { await CheckPolicyAsync(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Increase); - return await LocalFlashSaleInventoryReducer.TryIncreaseInventoryAsync( + return await LocalFlashSaleInventoryManager.TryIncreaseInventoryAsync( input.TenantId, input.ProviderName, input.StoreId, diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.csproj new file mode 100644 index 00000000..b96c1c89 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.csproj @@ -0,0 +1,16 @@ + + + + + + net6.0 + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiModule.cs new file mode 100644 index 00000000..3d2bf12d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiModule.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Products.Plugins.FlashSales; + +[DependsOn( + typeof(EShopProductsHttpApiModule), + typeof(EShopProductsPluginsFlashSalesApplicationContractsModule) +)] +public class EShopProductsPluginsFlashSalesHttpApiModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(EShopProductsPluginsFlashSalesHttpApiModule).Assembly); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Products/FlashSaleInventoryController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Products/FlashSaleInventoryController.cs new file mode 100644 index 00000000..4806a4ba --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Products/Products/FlashSaleInventoryController.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Products.Dtos; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; + +namespace EasyAbp.EShop.Products.Products; + +[RemoteService(Name = EShopProductsRemoteServiceConsts.RemoteServiceName)] +[Route("/api/e-shop/products/plugins/flash-sale-inventory")] +public class FlashSaleInventoryController : ProductsController, IFlashSaleInventoryAppService +{ + protected IFlashSaleInventoryAppService AppService { get; } + + public FlashSaleInventoryController(IFlashSaleInventoryAppService appService) + { + AppService = appService; + } + + [HttpPost("try-increase")] + public virtual Task TryIncreaseAsync(IncreaseInventoryInput input) + { + return AppService.TryIncreaseAsync(input); + } + + [HttpPost("try-reduce")] + public virtual Task TryReduceAsync(ReduceInventoryInput input) + { + return AppService.TryReduceAsync(input); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml new file mode 100644 index 00000000..00e1d9a1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xsd new file mode 100644 index 00000000..3f3946e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj new file mode 100644 index 00000000..ef715f1d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj @@ -0,0 +1,23 @@ + + + + + + netstandard2.1 + + + + + + + + + + + + + + + + + diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs new file mode 100644 index 00000000..0268b99a --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace EasyAbp.EShop.Products.Plugins.FlashSales; + +[DependsOn( + typeof(EShopProductsPluginsFlashSalesApplicationContractsModule) +)] +public class EShopProductsPluginsFlashSalesHttpApiClientModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(EShopProductsApplicationContractsModule).Assembly, + EShopProductsRemoteServiceConsts.RemoteServiceName + ); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml new file mode 100644 index 00000000..00e1d9a1 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xsd new file mode 100644 index 00000000..3f3946e2 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj index 4c75b80b..6fc92f3a 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj @@ -1,4 +1,4 @@ - + @@ -12,6 +12,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs index 9a48e836..369fc04b 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs @@ -2,6 +2,7 @@ using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; using EasyAbp.EShop.Plugins.FlashSales; +using EasyAbp.EShop.Products.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -27,6 +28,7 @@ namespace EShopSample typeof(EShopPluginsBasketsApplicationContractsModule), typeof(EShopPluginsCouponsApplicationContractsModule), typeof(EShopPluginsFlashSalesApplicationContractsModule), + typeof(EShopProductsPluginsFlashSalesApplicationContractsModule), typeof(PaymentServiceApplicationContractsModule), typeof(PaymentServiceWeChatPayApplicationContractsModule), typeof(PaymentServicePrepaymentApplicationContractsModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj index a98f9a64..25e41aa4 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj @@ -12,6 +12,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs index f5ca37ee..0d1030a6 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs @@ -2,6 +2,7 @@ using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; using EasyAbp.EShop.Plugins.FlashSales; +using EasyAbp.EShop.Products.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -27,6 +28,7 @@ namespace EShopSample typeof(EShopPluginsBasketsHttpApiClientModule), typeof(EShopPluginsCouponsHttpApiClientModule), typeof(EShopPluginsFlashSalesHttpApiClientModule), + typeof(EShopProductsPluginsFlashSalesHttpApiClientModule), typeof(PaymentServiceHttpApiClientModule), typeof(PaymentServiceWeChatPayHttpApiClientModule), typeof(PaymentServicePrepaymentHttpApiClientModule) diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj index c9446266..35542d0d 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj @@ -12,6 +12,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs index 846adf32..5a945b40 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs @@ -2,6 +2,7 @@ using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Coupons; using EasyAbp.EShop.Plugins.FlashSales; +using EasyAbp.EShop.Products.Plugins.FlashSales; using EasyAbp.PaymentService; using EasyAbp.PaymentService.Prepayment; using EasyAbp.PaymentService.WeChatPay; @@ -25,6 +26,7 @@ namespace EShopSample typeof(EShopPluginsBasketsHttpApiModule), typeof(EShopPluginsCouponsHttpApiModule), typeof(EShopPluginsFlashSalesHttpApiModule), + typeof(EShopProductsPluginsFlashSalesHttpApiModule), typeof(PaymentServiceHttpApiModule), typeof(PaymentServiceWeChatPayHttpApiModule), typeof(PaymentServicePrepaymentHttpApiModule) From 89fcca3bccb6cb41b2f4e1ef3ee6471f0fb42f6c Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 11 Jul 2022 10:01:32 +0800 Subject: [PATCH 30/97] Fix FodyWeavers --- .../FodyWeavers.xml | 2 +- .../FodyWeavers.xml | 2 +- .../FodyWeavers.xml | 2 +- .../FodyWeavers.xml | 2 +- .../FodyWeavers.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml index 00e1d9a1..be0de3a9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/FodyWeavers.xml @@ -1,3 +1,3 @@  - + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml index 00e1d9a1..be0de3a9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts/FodyWeavers.xml @@ -1,3 +1,3 @@  - + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml index 00e1d9a1..be0de3a9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/FodyWeavers.xml @@ -1,3 +1,3 @@  - + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml index 00e1d9a1..be0de3a9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi/FodyWeavers.xml @@ -1,3 +1,3 @@  - + \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml index 00e1d9a1..be0de3a9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml @@ -1,3 +1,3 @@  - + \ No newline at end of file From 43ec4c468c4c96525f804152af5f53ff76716ebf Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 11 Jul 2022 10:02:26 +0800 Subject: [PATCH 31/97] Fix project name --- EShop.sln | 14 +++++++------- ...ducts.Plugins.FlashSales.HttpApi.Client.csproj} | 0 ...ProductsPluginsFlashSalesHttpApiClientModule.cs | 0 .../FodyWeavers.xml | 0 .../FodyWeavers.xsd | 0 .../EShopSample.HttpApi.Client.csproj | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename plugins/FlashSales/src/{EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj => EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj} (100%) rename plugins/FlashSales/src/{EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient => EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client}/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs (100%) rename plugins/FlashSales/src/{EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient => EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client}/FodyWeavers.xml (100%) rename plugins/FlashSales/src/{EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient => EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client}/FodyWeavers.xsd (100%) diff --git a/EShop.sln b/EShop.sln index 5d6f9872..44c76155 100644 --- a/EShop.sln +++ b/EShop.sln @@ -419,9 +419,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plug EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts.csproj", "{F08D9409-4D01-4639-A7B8-A70B7ED8E0F9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.csproj", "{B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.csproj", "{B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj", "{98786FEE-155D-42D6-B932-D85E24114CFD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj", "{274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1097,10 +1097,10 @@ Global {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}.Debug|Any CPU.Build.0 = Debug|Any CPU {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}.Release|Any CPU.ActiveCfg = Release|Any CPU {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7}.Release|Any CPU.Build.0 = Release|Any CPU - {98786FEE-155D-42D6-B932-D85E24114CFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {98786FEE-155D-42D6-B932-D85E24114CFD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {98786FEE-155D-42D6-B932-D85E24114CFD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {98786FEE-155D-42D6-B932-D85E24114CFD}.Release|Any CPU.Build.0 = Release|Any CPU + {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1311,7 +1311,7 @@ Global {C1EB9DC0-F572-41DF-9716-893B154BBB13} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} - {98786FEE-155D-42D6-B932-D85E24114CFD} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient.csproj rename to plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp/EShop/Products/Plugins/FlashSales/EShopProductsPluginsFlashSalesHttpApiClientModule.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xml similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xml rename to plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xml diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xsd b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xsd similarity index 100% rename from plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApiClient/FodyWeavers.xsd rename to plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/FodyWeavers.xsd diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj index 25e41aa4..723cb68c 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj @@ -12,7 +12,7 @@ - + From 1f1d3073435d5ea2a062a3cf2ac3f57546eb6397 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 11 Jul 2022 15:02:50 +0800 Subject: [PATCH 32/97] Improvement FlashSales --- .../CreateFlashSaleOrderEventHandler.cs | 5 +- .../IFlashSalePlanAppService.cs | 4 +- .../FlashSalePlans/FlashSalePlanAppService.cs | 51 ++++---------- .../FlashSalePlans/FlashSalePlanCacheItem.cs | 3 +- ...reateFlashSaleOrderCompleteEventHandler.cs | 69 +++++++++++++++++++ .../FlashSaleResultAppService.cs | 2 - .../Products/FlashSaleInventoryManager.cs | 2 +- .../FlashSaleResultFailedReason.cs | 2 +- .../FlashSalePlans/FlashSalePlanController.cs | 10 +-- .../Products/IFlashSaleInventoryManager.cs | 2 +- .../Products/FlashSaleInventoryAppService.cs | 2 +- .../LocalFlashSaleInventoryManager.cs | 2 +- 12 files changed, 96 insertions(+), 58 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index 7aab2d4c..57d85ec1 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -70,7 +70,7 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler OrderAsync(Guid id, CreateOrderInput input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index a4c69347..02f21d03 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -112,7 +112,7 @@ public class FlashSalePlanAppService : var product = await ProductAppService.GetAsync(input.ProductId); var productSku = product.GetSkuById(input.ProductSkuId); - await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, input.StoreId); + await ValidateProductAsync(input.ProductId, product, input.StoreId); var flashSalePlan = new FlashSalePlan( GuidGenerator.Create(), @@ -120,8 +120,8 @@ public class FlashSalePlanAppService : input.StoreId, input.BeginTime, input.EndTime, - input.ProductId, - input.ProductSkuId, + product.Id, + productSku.Id, input.IsPublished ); @@ -138,7 +138,7 @@ public class FlashSalePlanAppService : await CheckMultiStorePolicyAsync(product.StoreId, UpdatePolicyName); - await ValidateCreateOrUpdateProductAsync(input.ProductId, product, input.ProductSkuId, productSku, flashSalePlan.StoreId); + await ValidateProductAsync(input.ProductId, product, flashSalePlan.StoreId); if (await ExistRelatedFlashSaleResultsAsync(id) && (input.ProductId != flashSalePlan.ProductId || input.ProductSkuId != flashSalePlan.ProductSkuId)) { @@ -146,7 +146,7 @@ public class FlashSalePlanAppService : } flashSalePlan.SetTimeRange(input.BeginTime, input.EndTime); - flashSalePlan.SetProductSku(flashSalePlan.StoreId, input.ProductId, input.ProductSkuId); + flashSalePlan.SetProductSku(flashSalePlan.StoreId, product.Id, productSku.Id); flashSalePlan.SetPublished(input.IsPublished); flashSalePlan.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); @@ -197,28 +197,7 @@ public class FlashSalePlanAppService : await SetPreOrderCacheAsync(plan, product, productSku); } - public virtual async Task CheckPreOrderAsync(Guid id) - { - var plan = await GetFlashSalePlanCacheAsync(id); - - var preOrderCache = await GetPreOrderCacheAsync(plan); - if (preOrderCache == null) - { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); - } - - var product = await ProductAppService.GetAsync(plan.ProductId); - var productSku = product.GetSkuById(plan.ProductSkuId); - - if (!await CompareHashTokenAsync(preOrderCache.HashToken, plan, product, productSku)) - { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); - } - - await ValidatePreOrderAsync(plan, product, productSku); - } - - public virtual async Task CreateOrderAsync(Guid id, CreateOrderInput input) + public virtual async Task OrderAsync(Guid id, CreateOrderInput input) { var plan = await GetFlashSalePlanCacheAsync(id); var now = Clock.Now; @@ -257,18 +236,18 @@ public class FlashSalePlanAppService : throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); } - if (!await FlashSaleInventoryManager.TryIncreaseInventoryAsync( + if (!await FlashSaleInventoryManager.TryReduceInventoryAsync( plan.TenantId, preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) { - throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); + return false; } var result = await CreatePendingFlashSaleResultAsync(plan, userId, async (existsResultId) => { await SetUserFlashSaleResultCacheAsync(plan, userId, existsResultId); - await FlashSaleInventoryManager.TryIncreaseInventoryAsync( + await FlashSaleInventoryManager.TryRollBackInventoryAsync( plan.TenantId, preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true ); @@ -279,6 +258,8 @@ public class FlashSalePlanAppService : var createFlashSaleOrderEto = await PrepareCreateFlashSaleOrderEtoAsync(plan, result.Id, input, userId, now, preOrderCache.HashToken); await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); + + return true; } #region PreOrderCache @@ -394,18 +375,13 @@ public class FlashSalePlanAppService : return await FlashSaleResultRepository.AnyAsync(x => x.PlanId == planId); } - protected virtual Task ValidateCreateOrUpdateProductAsync(Guid productId, ProductDto product, Guid productSkuId, ProductSkuDto productSku, Guid storeId) + protected virtual Task ValidateProductAsync(Guid productId, ProductDto product, Guid storeId) { if (product.StoreId != storeId) { throw new ProductIsNotInThisStoreException(productId, storeId); } - if (productSku == null) - { - throw new ProductSkuIsNotFoundException(productSkuId); - } - if (product.InventoryStrategy != InventoryStrategy.FlashSales) { throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); @@ -445,7 +421,8 @@ public class FlashSalePlanAppService : protected virtual async Task CreatePendingFlashSaleResultAsync(FlashSalePlanCacheItem plan, Guid userId, Func existResultPreProcess) { // Prevent repeat submit - var existsResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => x.PlanId == plan.Id && x.UserId == userId); + var existsResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => + x.PlanId == plan.Id && x.UserId == userId && x.Status != FlashSaleResultStatus.Failed && x.Reason != FlashSaleResultFailedReason.InvalidHashToken); if (existsResult != null) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs index da5e41a0..4aefcbad 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheItem.cs @@ -1,10 +1,11 @@ using System; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalePlanCacheItem : FlashSalePlanDto +public class FlashSalePlanCacheItem : FlashSalePlanDto, IMultiTenant { public Guid? TenantId { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs new file mode 100644 index 00000000..766f5a11 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs @@ -0,0 +1,69 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.Eshop.Products.Products; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Products.Products; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Logging; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency +{ + protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } + protected IDistributedCache DistributedCache { get; } + protected IFlashSalePlanRepository FlashSalePlanRepository { get; } + protected IProductAppService ProductAppService { get; } + protected ILogger Logger { get; } + + public RollBackInventoryCreateFlashSaleOrderCompleteEventHandler( + IFlashSaleInventoryManager flashSaleInventoryManager, + IDistributedCache distributedCache, + IFlashSalePlanRepository flashSalePlanRepository, + IProductAppService productAppService) + { + FlashSaleInventoryManager = flashSaleInventoryManager; + DistributedCache = distributedCache; + FlashSalePlanRepository = flashSalePlanRepository; + ProductAppService = productAppService; + } + + public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) + { + if (eventData.Success) + { + return; + } + + if (eventData.Reason != FlashSaleResultFailedReason.InvalidHashToken) + { + return; + } + + var plan = await FlashSalePlanRepository.GetAsync(eventData.PlanId); + var product = await ProductAppService.GetAsync(plan.ProductId); + + if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync( + plan.TenantId, product.InventoryProviderName, + plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true + )) + { + Logger.LogWarning("Try roll back inventory failed."); + return; + } + + await RemoveUserFlashSaleResultCacheAsync(plan, eventData.UserId); + } + + protected virtual Task GetUserFlashSaleResultCacheKeyAsync(FlashSalePlan plan, Guid userId) + { + return Task.FromResult($"flash-sale-result-{plan.Id}-{userId}"); + } + + protected virtual async Task RemoveUserFlashSaleResultCacheAsync(FlashSalePlan plan, Guid userId) + { + await DistributedCache.RemoveAsync(await GetUserFlashSaleResultCacheKeyAsync(plan, userId)); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index 7c00f09d..20e1a1bc 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -16,8 +16,6 @@ public class FlashSaleResultAppService : protected override string GetPolicyName { get; set; } protected override string GetListPolicyName { get; set; } - protected IFlashSaleResultRepository FlashSaleResultRepository { get; } - public FlashSaleResultAppService(IFlashSaleResultRepository flashSaleResultRepository) : base(flashSaleResultRepository) { } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs index 0d811476..6e6bd678 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs @@ -24,7 +24,7 @@ public class FlashSaleInventoryManager : IFlashSaleInventoryManager, ITransientD new ReduceInventoryInput(tenantId, providerName, storeId, productId, productSkuId, quantity, increaseSold)); } - public virtual async Task TryIncreaseInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + public virtual async Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold) { return await FlashSaleInventoryReducerAppService.TryIncreaseAsync diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs index e18b76cb..7d2891e3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs @@ -4,5 +4,5 @@ public static class FlashSaleResultFailedReason { public const string InsufficientInventory = nameof(InsufficientInventory); - public const string PreOrderExipred = nameof(PreOrderExipred); + public const string InvalidHashToken = nameof(InvalidHashToken); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index 90551b2f..c2c473d6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -57,15 +57,9 @@ public class FlashSalePlanController : return Service.PreOrderAsync(id); } - [HttpGet("{id}/check-pre-order")] - public virtual Task CheckPreOrderAsync(Guid id) - { - return Service.CheckPreOrderAsync(id); - } - [HttpPost("{id}/order")] - public virtual Task CreateOrderAsync(Guid id, CreateOrderInput input) + public virtual Task OrderAsync(Guid id, CreateOrderInput input) { - return Service.CreateOrderAsync(id, input); + return Service.OrderAsync(id, input); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs index 0896e7d5..2fa36304 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs @@ -7,5 +7,5 @@ public interface IFlashSaleInventoryManager { Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool increaseSold); - Task TryIncreaseInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold); + Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs index b398f4c9..cbac9f41 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs @@ -32,7 +32,7 @@ public class FlashSaleInventoryAppService : ProductsAppService, IFlashSaleInvent { await CheckPolicyAsync(ProductsPluginsFlashSalesPermissions.FlashSaleInventory.Increase); - return await LocalFlashSaleInventoryManager.TryIncreaseInventoryAsync( + return await LocalFlashSaleInventoryManager.TryRollBackInventoryAsync( input.TenantId, input.ProviderName, input.StoreId, diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs index f13f758e..093b7ed3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs @@ -23,7 +23,7 @@ public class LocalFlashSaleInventoryManager : ILocalFlashSaleInventoryManager, I .TryReduceInventoryAsync(model, quantity, increaseSold); } - public virtual async Task TryIncreaseInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + public virtual async Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold) { var model = new InventoryQueryModel(tenantId, storeId, productId, productSkuId); From e491387cad906db5e6e285374ac47b9a6334e59a Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 11 Jul 2022 19:11:15 +0800 Subject: [PATCH 33/97] Add pre-order response --- .../Dtos/FlashSalePlanPreOrderDto.cs | 11 +++++++++ .../IFlashSalePlanAppService.cs | 2 +- .../FlashSalePlans/FlashSalePlanAppService.cs | 24 +++++++------------ .../FlashSalePlans/FlashSalesOptions.cs | 2 +- .../FlashSalePlans/FlashSalePlanController.cs | 2 +- 5 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs new file mode 100644 index 00000000..54ffa8f0 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs @@ -0,0 +1,11 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; + +public class FlashSalePlanPreOrderDto : ExtensibleEntityDto +{ + public DateTime ExpiresTime { get; set; } + + public double Expires { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs index 69f34dd6..2d8c7130 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs @@ -13,7 +13,7 @@ public interface IFlashSalePlanAppService : FlashSalePlanCreateDto, FlashSalePlanUpdateDto> { - Task PreOrderAsync(Guid id); + Task PreOrderAsync(Guid id); Task OrderAsync(Guid id, CreateOrderInput input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 02f21d03..50da39eb 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -19,6 +19,7 @@ using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Timing; using Volo.Abp.Users; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; @@ -186,15 +187,18 @@ public class FlashSalePlanAppService : .WhereIf(input.End.HasValue, x => x.BeginTime <= input.End.Value); } - public virtual async Task PreOrderAsync(Guid id) + public virtual async Task PreOrderAsync(Guid id) { var plan = await GetFlashSalePlanCacheAsync(id); var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); + var expiresTime = DateTimeOffset.Now.Add(Options.PreOrderExpires); await ValidatePreOrderAsync(plan, product, productSku); - await SetPreOrderCacheAsync(plan, product, productSku); + await SetPreOrderCacheAsync(plan, product, productSku, expiresTime); + + return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), Expires = Options.PreOrderExpires.TotalSeconds }; } public virtual async Task OrderAsync(Guid id, CreateOrderInput input) @@ -288,7 +292,7 @@ public class FlashSalePlanAppService : await PreOrderDistributedCache.RemoveAsync(await GetPreOrderCacheKeyAsync(plan)); } - protected virtual async Task SetPreOrderCacheAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) + protected virtual async Task SetPreOrderCacheAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku, DateTimeOffset expirationTime) { var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); @@ -301,7 +305,7 @@ public class FlashSalePlanAppService : InventoryProviderName = product.InventoryProviderName, }, new DistributedCacheEntryOptions() { - AbsoluteExpirationRelativeToNow = Options.PreOrderExpirationTime + AbsoluteExpiration = expirationTime }); } @@ -328,18 +332,6 @@ public class FlashSalePlanAppService : #endregion - protected virtual async Task CompareHashTokenAsync(string originHashToken, FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) - { - if (originHashToken.IsNullOrWhiteSpace()) - { - return false; - } - - var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); - - return string.Equals(hashToken, originHashToken, StringComparison.InvariantCulture); - } - protected virtual Task ValidatePreOrderAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (!product.IsPublished) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs index a09478dd..45d94a88 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs @@ -7,5 +7,5 @@ public class FlashSalesOptions /// /// Default: 3 minutes /// - public TimeSpan PreOrderExpirationTime { get; set; } = TimeSpan.FromMinutes(3); + public TimeSpan PreOrderExpires { get; set; } = TimeSpan.FromMinutes(3); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index c2c473d6..868da3ad 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -52,7 +52,7 @@ public class FlashSalePlanController : } [HttpPost("{id}/pre-order")] - public virtual Task PreOrderAsync(Guid id) + public virtual Task PreOrderAsync(Guid id) { return Service.PreOrderAsync(id); } From d29b281c8ecf0a3c3e7f433286acdcdc0a5c09f3 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Mon, 11 Jul 2022 19:12:47 +0800 Subject: [PATCH 34/97] Add `[UnitOfWork]` to HandleEventAsync --- ...RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs index 766f5a11..295b3baf 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Uow; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; @@ -30,6 +31,7 @@ public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandler : IDistri ProductAppService = productAppService; } + [UnitOfWork(true)] public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) { if (eventData.Success) From 6fa62b07204235e6331b1a8d5940756455f9cd56 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Tue, 12 Jul 2022 17:08:58 +0800 Subject: [PATCH 35/97] Improvement FlashSales --- .../FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs | 2 +- .../FlashSales/FlashSalePlans/FlashSalePlanAppService.cs | 2 +- ...llBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs | 1 - .../FlashSaleResults/FlashSaleResultFailedReason.cs | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs index 54ffa8f0..ccfdea14 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSalePlanPreOrderDto.cs @@ -7,5 +7,5 @@ public class FlashSalePlanPreOrderDto : ExtensibleEntityDto { public DateTime ExpiresTime { get; set; } - public double Expires { get; set; } + public double ExpiresInSeconds { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 50da39eb..49d27aee 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -198,7 +198,7 @@ public class FlashSalePlanAppService : await SetPreOrderCacheAsync(plan, product, productSku, expiresTime); - return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), Expires = Options.PreOrderExpires.TotalSeconds }; + return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), ExpiresInSeconds = Options.PreOrderExpires.TotalSeconds }; } public virtual async Task OrderAsync(Guid id, CreateOrderInput input) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs index 295b3baf..42bcfbf4 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs @@ -31,7 +31,6 @@ public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandler : IDistri ProductAppService = productAppService; } - [UnitOfWork(true)] public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) { if (eventData.Success) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs index 7d2891e3..f4ef7845 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs @@ -2,7 +2,7 @@ public static class FlashSaleResultFailedReason { - public const string InsufficientInventory = nameof(InsufficientInventory); + public const string InsufficientInventory = "InsufficientInventory"; - public const string InvalidHashToken = nameof(InvalidHashToken); + public const string InvalidHashToken = "InvalidHashToken"; } From 50b59e6de23b19c2fbe28a60645d26a106690292 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 16 Jul 2022 19:09:30 +0800 Subject: [PATCH 36/97] Improve FlashSales --- ...rdersPluginsFlashSalesApplicationModule.cs | 4 +- .../FlashSalePlans/FlashSalePlanAppService.cs | 66 +++++++++++-------- .../FlashSalePlanTokenCacheItem.cs | 5 +- ...reateFlashSaleOrderCompleteEventHandler.cs | 7 +- .../FlashSalePlans/FlashSalePlanHasher.cs | 2 +- .../FlashSales/FlashSalesErrorCodes.cs | 2 + .../Plugins/FlashSales/Localization/en.json | 1 + .../FlashSales/Localization/zh-Hans.json | 1 + .../FlashSales/Localization/zh-Hant.json | 1 + .../FlashSaleResults/FlashSaleResult.cs | 14 ++-- ...lashSaleResultStatusNotPendingException.cs | 12 ++++ 11 files changed, 76 insertions(+), 39 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatusNotPendingException.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs index 1f38ffa1..6086e4d7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs @@ -1,7 +1,5 @@ -using EasyAbp.EShop.Orders.Orders; -using EasyAbp.EShop.Plugins.FlashSales; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.EShop.Products; -using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 49d27aee..86121c50 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -29,6 +29,21 @@ public class FlashSalePlanAppService : MultiStoreCrudAppService, IFlashSalePlanAppService { + /// + /// The cache key format. + /// {0}: FlashSalePlan ID + /// {1}: User ID + /// + public const string PreOrderCacheKeyFormat = "eshopflashsales_{0}_{1}"; + + /// + /// The cache key format. + /// {0}: Tenant ID + /// {1}: FlashSalePlan ID + /// {2}: User ID + /// + public const string UserFlashSaleResultCacheKeyFormat = "eshopflashsales-result_{0}_{1}_{2}"; + protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.CrossStore; protected override string GetPolicyName { get; set; } protected override string GetListPolicyName { get; set; } @@ -203,6 +218,12 @@ public class FlashSalePlanAppService : public virtual async Task OrderAsync(Guid id, CreateOrderInput input) { + var preOrderCache = await GetPreOrderCacheAsync(id); + if (preOrderCache == null) + { + throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); + } + var plan = await GetFlashSalePlanCacheAsync(id); var now = Clock.Now; if (plan.BeginTime > now) @@ -215,13 +236,7 @@ public class FlashSalePlanAppService : throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } - var preOrderCache = await GetPreOrderCacheAsync(plan); - if (preOrderCache == null) - { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); - } - - await RemovePreOrderCacheAsync(plan); + await RemovePreOrderCacheAsync(id); var userId = CurrentUser.GetId(); @@ -234,7 +249,7 @@ public class FlashSalePlanAppService : throw new BusinessException(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); } - var userFlashSaleResultCache = await GetUserFlashSaleResultCacheAsync(plan, userId); + var userFlashSaleResultCache = await GetUserFlashSaleResultCacheAsync(plan.Id); if (!userFlashSaleResultCache.IsNullOrWhiteSpace()) { throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); @@ -249,7 +264,7 @@ public class FlashSalePlanAppService : var result = await CreatePendingFlashSaleResultAsync(plan, userId, async (existsResultId) => { - await SetUserFlashSaleResultCacheAsync(plan, userId, existsResultId); + await SetUserFlashSaleResultCacheAsync(plan.Id, existsResultId); await FlashSaleInventoryManager.TryRollBackInventoryAsync( plan.TenantId, preOrderCache.InventoryProviderName, @@ -257,7 +272,7 @@ public class FlashSalePlanAppService : ); }); - await SetUserFlashSaleResultCacheAsync(plan, userId, result.Id); + await SetUserFlashSaleResultCacheAsync(plan.Id, result.Id); var createFlashSaleOrderEto = await PrepareCreateFlashSaleOrderEtoAsync(plan, result.Id, input, userId, now, preOrderCache.HashToken); @@ -277,26 +292,26 @@ public class FlashSalePlanAppService : }); } - protected virtual Task GetPreOrderCacheKeyAsync(FlashSalePlanCacheItem plan) + protected virtual Task GetPreOrderCacheKeyAsync(Guid planId) { - return Task.FromResult($"eshopflashsales_{CurrentTenant.Id}_{CurrentUser.Id}_{plan.ProductSkuId}"); + return Task.FromResult(string.Format(PreOrderCacheKeyFormat, planId, CurrentUser.Id)); } - protected virtual async Task GetPreOrderCacheAsync(FlashSalePlanCacheItem plan) + protected virtual async Task GetPreOrderCacheAsync(Guid planId) { - return await PreOrderDistributedCache.GetAsync(await GetPreOrderCacheKeyAsync(plan)); + return await PreOrderDistributedCache.GetAsync(await GetPreOrderCacheKeyAsync(planId)); } - protected virtual async Task RemovePreOrderCacheAsync(FlashSalePlanCacheItem plan) + protected virtual async Task RemovePreOrderCacheAsync(Guid planId) { - await PreOrderDistributedCache.RemoveAsync(await GetPreOrderCacheKeyAsync(plan)); + await PreOrderDistributedCache.RemoveAsync(await GetPreOrderCacheKeyAsync(planId)); } protected virtual async Task SetPreOrderCacheAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku, DateTimeOffset expirationTime) { var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); - await PreOrderDistributedCache.SetAsync(await GetPreOrderCacheKeyAsync(plan), new FlashSalePlanPreOrderCacheItem() + await PreOrderDistributedCache.SetAsync(await GetPreOrderCacheKeyAsync(plan.Id), new FlashSalePlanPreOrderCacheItem() { HashToken = hashToken, PlanId = plan.Id, @@ -313,20 +328,20 @@ public class FlashSalePlanAppService : #region UserFlashSaleResultCache - protected virtual Task GetUserFlashSaleResultCacheKeyAsync(FlashSalePlanCacheItem plan, Guid userId) + protected virtual Task GetUserFlashSaleResultCacheKeyAsync(Guid planId) { - return Task.FromResult($"flash-sale-result-{plan.Id}-{userId}"); + return Task.FromResult(string.Format(UserFlashSaleResultCacheKeyFormat, CurrentTenant.Id, planId, CurrentUser.GetId())); } - protected virtual async Task GetUserFlashSaleResultCacheAsync(FlashSalePlanCacheItem plan, Guid userId) + protected virtual async Task GetUserFlashSaleResultCacheAsync(Guid planId) { - var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(plan, userId); + var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(planId); return await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); } - protected virtual async Task SetUserFlashSaleResultCacheAsync(FlashSalePlanCacheItem plan, Guid userId, Guid resultId) + protected virtual async Task SetUserFlashSaleResultCacheAsync(Guid planId, Guid resultId) { - var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(plan, userId); + var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(planId); await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, resultId.ToString()); } @@ -427,10 +442,7 @@ public class FlashSalePlanAppService : tenantId: CurrentTenant.Id, storeId: plan.StoreId, planId: plan.Id, - status: FlashSaleResultStatus.Pending, - reason: null, - userId: userId, - orderId: null + userId: userId ); return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs index 4aac4954..efaff0e9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTokenCacheItem.cs @@ -1,10 +1,13 @@ using System; +using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; [Serializable] -public class FlashSalePlanPreOrderCacheItem +public class FlashSalePlanPreOrderCacheItem : IMultiTenant { + public Guid? TenantId { get; set; } + public string HashToken { get; set; } public Guid PlanId { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs index 42bcfbf4..6aad2f50 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs @@ -7,7 +7,6 @@ using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; -using Volo.Abp.Uow; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; @@ -23,12 +22,14 @@ public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandler : IDistri IFlashSaleInventoryManager flashSaleInventoryManager, IDistributedCache distributedCache, IFlashSalePlanRepository flashSalePlanRepository, - IProductAppService productAppService) + IProductAppService productAppService, + ILogger logger) { FlashSaleInventoryManager = flashSaleInventoryManager; DistributedCache = distributedCache; FlashSalePlanRepository = flashSalePlanRepository; ProductAppService = productAppService; + Logger = logger; } public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) @@ -60,7 +61,7 @@ public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandler : IDistri protected virtual Task GetUserFlashSaleResultCacheKeyAsync(FlashSalePlan plan, Guid userId) { - return Task.FromResult($"flash-sale-result-{plan.Id}-{userId}"); + return Task.FromResult(string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, userId)); } protected virtual async Task RemoveUserFlashSaleResultCacheAsync(FlashSalePlan plan, Guid userId) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasher.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasher.cs index 8531b8a7..783c44b3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasher.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasher.cs @@ -10,7 +10,7 @@ public class FlashSalePlanHasher : IFlashSalePlanHasher, ITransientDependency { public virtual Task HashAsync(DateTime? planLastModificationTime, DateTime? productLastModificationTime, DateTime? productSkuLastModificationTime) { - var input = $"{planLastModificationTime}|{productLastModificationTime}|{productSkuLastModificationTime}"; + var input = $"{planLastModificationTime?.Ticks}|{productLastModificationTime?.Ticks}|{productSkuLastModificationTime?.Ticks}"; return Task.FromResult(CreateMd5(input)); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index 5857aaba..a38555b3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -27,4 +27,6 @@ public static class FlashSalesErrorCodes public const string DuplicateFlashSalesOrder = $"{Namespace}:{nameof(DuplicateFlashSalesOrder)}"; public const string RelatedFlashSaleResultsExist = $"{Namespace}:{nameof(RelatedFlashSaleResultsExist)}"; + + public const string FlashSaleResultStatusNotPending = $"{Namespace}:{nameof(FlashSaleResultStatusNotPending)}"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json index a0863199..0b5b2c37 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -13,6 +13,7 @@ "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "Busy to create flash-sale order", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "Duplicate flash-sales order", "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "Related flash-sales results exist", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleResultStatusNotPending": "The status of flash-sale result has been changed", "Menu:FlashSalesManagement": "Flash-Sales Management", "Permission:FlashSalePlan": "FlashSale Plan", "Permission:Manage": "Manage", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json index 2327818b..5aa756b8 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -13,6 +13,7 @@ "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "闪购下单繁忙", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重复闪购下单", "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "已存在关联的闪购结果", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleResultStatusNotPending": "闪购结果的状态已经变更", "Menu:FlashSalesManagement": "闪购", "Permission:FlashSalePlan": "闪购计划", "Permission:Manage": "管理", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json index 2b7767ee..6f7a3e84 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -13,6 +13,7 @@ "EasyAbp.EShop.Plugins.FlashSales:BusyToCreateFlashSaleOrder": "閃購下單繁忙", "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重複閃購下單", "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "已存在關聯的閃購結果", + "EasyAbp.EShop.Plugins.FlashSales:FlashSaleResultStatusNotPending": "閃購結果的状态已經變更", "Menu:FlashSalesManagement": "閃購管理", "Permission:FlashSalePlan": "閃購計畫", "Permission:Manage": "管理", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs index 3d90d8ff..2617a14a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs @@ -24,26 +24,32 @@ public class FlashSaleResult : FullAuditedAggregateRoot, IMultiTenant, IMu protected FlashSaleResult() { } - public FlashSaleResult(Guid id, Guid? tenantId, Guid storeId, Guid planId, FlashSaleResultStatus status, string reason, Guid userId, Guid? orderId) + public FlashSaleResult(Guid id, Guid? tenantId, Guid storeId, Guid planId, Guid userId) : base(id) { TenantId = tenantId; StoreId = storeId; PlanId = planId; - Status = status; - Reason = reason; + Status = FlashSaleResultStatus.Pending; UserId = userId; - OrderId = orderId; } public void MarkAsSuccessful(Guid orderId) { + if (Status != FlashSaleResultStatus.Pending) + { + throw new FlashSaleResultStatusNotPendingException(Id); + } Status = FlashSaleResultStatus.Successful; OrderId = orderId; } public void MarkAsFailed(string reason) { + if (Status != FlashSaleResultStatus.Pending) + { + throw new FlashSaleResultStatusNotPendingException(Id); + } Status = FlashSaleResultStatus.Failed; Reason = Check.NotNullOrEmpty(reason, nameof(reason)); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatusNotPendingException.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatusNotPendingException.cs new file mode 100644 index 00000000..9402b683 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultStatusNotPendingException.cs @@ -0,0 +1,12 @@ +using System; +using Volo.Abp; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class FlashSaleResultStatusNotPendingException : BusinessException +{ + public FlashSaleResultStatusNotPendingException(Guid resultId) : base(FlashSalesErrorCodes.FlashSaleResultStatusNotPending) + { + WithData(nameof(resultId), resultId); + } +} From b855e7558851523743d3bf0e245e9b247a19e13a Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 16 Jul 2022 19:10:02 +0800 Subject: [PATCH 37/97] Add UnitTests for FlashSales --- EShop.sln | 7 + ...s.FlashSales.Application.Tests.abppkg.json | 3 + ...lugins.FlashSales.Application.Tests.csproj | 14 + .../CreateFlashSaleOrderEventHandlerTests.cs | 177 +++++++ ...PluginsFlashSalesApplicationTestsModule.cs | 13 + ...ersPluginsFlashSalesApplicationTestBase.cs | 69 +++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ ...lugins.FlashSales.Application.Tests.csproj | 2 +- .../Plugins/FlashSales/CreateTimeRange.cs | 9 + ...PluginsFlashSalesApplicationTestModule.cs} | 4 +- .../FlashSalePlanAppServiceTests.cs | 483 ++++++++++++++++++ ...eFlashSaleOrderCompleteEventHandlerTest.cs | 171 +++++++ .../FlashSalesApplicationTestBase.cs | 144 +++++- .../Products/FakeFlashSaleInventoryManager.cs | 27 + ...EShopPluginsFlashSalesDomainTestModule.cs} | 4 +- .../FlashSalePlanHasherTests.cs | 29 ++ .../FlashSalePlans/FlashSalePlanTests.cs | 114 +++++ ...FlashSaleOrderCompleteEventHandlerTests.cs | 85 +++ .../FlashSaleResults/FlashSaleResultTests.cs | 96 ++++ .../FlashSales/FlashSalesDomainTestBase.cs | 2 +- ...lashSalesEntityFrameworkCoreTestModule.cs} | 4 +- .../FlashSalesEntityFrameworkCoreTestBase.cs | 2 +- .../FlashSales/ConsoleTestAppHostedService.cs | 2 +- ...luginsFlashSalesConsoleApiClientModule.cs} | 2 +- ...ShopPluginsFlashSalesMongoDbTestModule.cs} | 4 +- .../MongoDB/FlashSalesMongoDbTestBase.cs | 2 +- ...> EShopPluginsFlashSalesTestBaseModule.cs} | 2 +- .../Plugins/FlashSales/FlashSalesTestData.cs | 28 + 29 files changed, 1515 insertions(+), 17 deletions(-) create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.abppkg.json create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.csproj create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xml create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/CreateTimeRange.cs rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesApplicationTestModule.cs => EShopPluginsFlashSalesApplicationTestModule.cs} (56%) create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesDomainTestModule.cs => EShopPluginsFlashSalesDomainTestModule.cs} (71%) create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasherTests.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTests.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/{FlashSalesEntityFrameworkCoreTestModule.cs => EShopPluginsFlashSalesEntityFrameworkCoreTestModule.cs} (91%) rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesConsoleApiClientModule.cs => EShopPluginsFlashSalesConsoleApiClientModule.cs} (80%) rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/{FlashSalesMongoDbTestModule.cs => EShopPluginsFlashSalesMongoDbTestModule.cs} (86%) rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/{FlashSalesTestBaseModule.cs => EShopPluginsFlashSalesTestBaseModule.cs} (94%) create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestData.cs diff --git a/EShop.sln b/EShop.sln index 44c76155..9031a10d 100644 --- a/EShop.sln +++ b/EShop.sln @@ -423,6 +423,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plug EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client", "plugins\FlashSales\src\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client\EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj", "{274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests", "plugins\FlashSales\test\EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests\EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.csproj", "{17A3486C-1845-4B4E-B1A6-752106F0C309}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1101,6 +1103,10 @@ Global {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}.Debug|Any CPU.Build.0 = Debug|Any CPU {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}.Release|Any CPU.ActiveCfg = Release|Any CPU {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8}.Release|Any CPU.Build.0 = Release|Any CPU + {17A3486C-1845-4B4E-B1A6-752106F0C309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17A3486C-1845-4B4E-B1A6-752106F0C309}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17A3486C-1845-4B4E-B1A6-752106F0C309}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17A3486C-1845-4B4E-B1A6-752106F0C309}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1312,6 +1318,7 @@ Global {F08D9409-4D01-4639-A7B8-A70B7ED8E0F9} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} {B137BF4B-8C0A-4CE2-AF22-BD9BD29C86B7} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} {274769DC-5DD6-4CFD-8078-5E0E0CE8D6D8} = {F29C5BCD-E6C0-4556-A631-CACA41B1050B} + {17A3486C-1845-4B4E-B1A6-752106F0C309} = {9C180C9E-50E9-4624-BE06-5C8C24A028E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.abppkg.json b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.abppkg.json new file mode 100644 index 00000000..a686451f --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.abppkg.json @@ -0,0 +1,3 @@ +{ + "role": "lib.test" +} \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.csproj new file mode 100644 index 00000000..bd18bfdc --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + + + + + + + + + + diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs new file mode 100644 index 00000000..b7643685 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales; +using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.EShop.Products.ProductDetails; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using NSubstitute; +using Xunit; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using Volo.Abp.Users; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.MultiTenancy; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +namespace EasyAbp.EShop.Orders.Orders; + +public class CreateFlashSaleOrderEventHandlerTests : OrdersPluginsFlashSalesApplicationTestBase +{ + protected CreateFlashSaleOrderEventHandler EventHandler { get; } + + protected ICurrentUser CurrentUser { get; } + + protected ICurrentTenant CurrentTenant { get; } + + protected IDistributedEventBus DistributedEventBus { get; } + + protected IFlashSalePlanHasher FlashSalePlanHasher { get; } + + protected IOrderRepository OrderRepository { get; } + + protected ProductDto Product1 { get; set; } + + public CreateFlashSaleOrderEventHandlerTests() + { + EventHandler = GetRequiredService(); + CurrentUser = GetRequiredService(); + CurrentTenant = GetRequiredService(); + DistributedEventBus = GetRequiredService(); + FlashSalePlanHasher = GetRequiredService(); + OrderRepository = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + Product1 = CreateMockProductDto(); + + var productAppService = Substitute.For(); + productAppService.GetAsync(FlashSalesTestData.Product1Id).Returns(Task.FromResult(Product1)); + services.Replace(ServiceDescriptor.Singleton(productAppService)); + + var productDetailAppService = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(productDetailAppService)); + productDetailAppService.GetAsync(FlashSalesTestData.ProductDetail1Id).Returns(Task.FromResult( + new ProductDetailDto + { + Id = FlashSalesTestData.ProductDetail1Id, + CreationTime = FlashSalesTestData.ProductDetailLastModificationTime, + LastModificationTime = FlashSalesTestData.ProductDetailLastModificationTime, + StoreId = FlashSalesTestData.Store1Id, + Description = "My Details 1" + })); + productDetailAppService.GetAsync(FlashSalesTestData.ProductDetail2Id).Returns(Task.FromResult( + new ProductDetailDto + { + Id = FlashSalesTestData.ProductDetail2Id, + StoreId = FlashSalesTestData.Store1Id, + Description = "My Details 2" + })); + + var distributedEventBus = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(distributedEventBus)); + + var flashSalePlanHasher = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(flashSalePlanHasher)); + + var orderRepository = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(orderRepository)); + + base.AfterAddApplication(services); + } + + [Fact] + public async Task HandleEventAsync() + { + FlashSalePlanHasher.HashAsync(default, default, default) + .ReturnsForAnyArgs("My Hash Token"); + OrderRepository.InsertAsync(default, default, default) + .ReturnsForAnyArgs(callInfo => callInfo.Arg()); + + var createFlashSaleOrderEto = new CreateFlashSaleOrderEto() + { + TenantId = CurrentTenant.Id, + PlanId = FlashSalesTestData.Plan1Id, + StoreId = FlashSalesTestData.Store1Id, + UserId = CurrentUser.GetId(), + PendingResultId = FlashSalesTestData.Result1Id, + CreateTime = DateTime.Now, + CustomerRemark = "My Remark", + HashToken = "My Hash Token", + Plan = new FlashSalePlanEto + { + Id = FlashSalesTestData.Plan1Id, + TenantId = CurrentTenant.Id, + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + } + }; + + await EventHandler.HandleEventAsync(createFlashSaleOrderEto); + + await DistributedEventBus.Received() + .PublishAsync(Arg.Is(eto => + eto.TenantId == CurrentTenant.Id && + eto.PendingResultId == FlashSalesTestData.Result1Id && + eto.Success && + eto.StoreId == FlashSalesTestData.Store1Id && + eto.PlanId == FlashSalesTestData.Plan1Id && + eto.UserId == CurrentUser.GetId() && + eto.OrderId != null && + eto.Reason == null + )); + } + + [Fact] + public async Task HandleEventAsync_Should_Publish_False_When_ValidateHashToken_Failed() + { + FlashSalePlanHasher.HashAsync(default, default, default) + .ReturnsForAnyArgs("My Hash Token"); + + var createFlashSaleOrderEto = new CreateFlashSaleOrderEto() + { + TenantId = CurrentTenant.Id, + PlanId = FlashSalesTestData.Plan1Id, + StoreId = FlashSalesTestData.Store1Id, + UserId = CurrentUser.GetId(), + PendingResultId = FlashSalesTestData.Result1Id, + CreateTime = DateTime.Now, + CustomerRemark = "My Remark", + HashToken = "My Hash Token Failed", + Plan = new FlashSalePlanEto + { + Id = FlashSalesTestData.Plan1Id, + TenantId = CurrentTenant.Id, + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + } + }; + + await EventHandler.HandleEventAsync(createFlashSaleOrderEto); + + await DistributedEventBus.Received() + .PublishAsync(Arg.Is(eto => + eto.TenantId == CurrentTenant.Id && + eto.PendingResultId == FlashSalesTestData.Result1Id && + !eto.Success && + eto.StoreId == FlashSalesTestData.Store1Id && + eto.PlanId == FlashSalesTestData.Plan1Id && + eto.UserId == CurrentUser.GetId() && + eto.OrderId == null && + eto.Reason == FlashSaleResultFailedReason.InvalidHashToken + )); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs new file mode 100644 index 00000000..3ac63e8e --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs @@ -0,0 +1,13 @@ +using EasyAbp.EShop.Orders.Plugins.FlashSales; +using Volo.Abp.Modularity; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +[DependsOn( + typeof(EShopOrdersPluginsFlashSalesApplicationModule), + typeof(EShopPluginsFlashSalesTestBaseModule) + )] +public class EShopOrdersPluginsFlashSalesApplicationTestsModule : AbpModule +{ + +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs new file mode 100644 index 00000000..5abed316 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +/* Inherit from this class for your application layer tests. + * See SampleAppService_Tests for example. + */ +public abstract class OrdersPluginsFlashSalesApplicationTestBase : FlashSalesTestBase +{ + protected virtual ProductDto CreateMockProductDto() + { + return new ProductDto + { + CreationTime = DateTime.Now, + IsPublished = true, + Id = FlashSalesTestData.Product1Id, + StoreId = FlashSalesTestData.Store1Id, + ProductGroupName = "Default", + ProductGroupDisplayName = "Default", + UniqueName = "Pencil", + DisplayName = "Hello pencil", + ProductDetailId = FlashSalesTestData.ProductDetail1Id, + ProductSkus = new List + { + new ProductSkuDto + { + Id = FlashSalesTestData.ProductSku1Id, + Name = "My SKU", + OrderMinQuantity = 0, + OrderMaxQuantity = 100, + AttributeOptionIds = new List(), + Price = 1m, + Currency = "USD", + ProductDetailId = null, + Inventory = 10, + }, + new ProductSkuDto + { + Id = FlashSalesTestData.ProductSku2Id, + Name = "My SKU 2", + OrderMinQuantity = 0, + OrderMaxQuantity = 100, + AttributeOptionIds = new List(), + Price = 2m, + Currency = "USD", + ProductDetailId = FlashSalesTestData.ProductDetail2Id, + Inventory = 0 + }, + new ProductSkuDto + { + Id = FlashSalesTestData.ProductSku3Id, + Name = "My SKU 3", + OrderMinQuantity = 0, + OrderMaxQuantity = 100, + AttributeOptionIds = new List(), + Price = 3m, + Currency = "USD", + ProductDetailId = FlashSalesTestData.ProductDetail2Id, + Inventory = 1 + } + }, + InventoryStrategy = InventoryStrategy.FlashSales, + LastModificationTime = FlashSalesTestData.ProductLastModificationTime + }; + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xml b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xml new file mode 100644 index 00000000..1715698c --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd new file mode 100644 index 00000000..ffa6fc4b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj index d9dbd3e1..0719f417 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp.EShop.Plugins.FlashSales.Application.Tests.csproj @@ -1,4 +1,4 @@ - + net6.0 diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/CreateTimeRange.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/CreateTimeRange.cs new file mode 100644 index 00000000..2dbc3aa4 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/CreateTimeRange.cs @@ -0,0 +1,9 @@ +namespace EasyAbp.EShop.Plugins.FlashSales; + +public enum CreateTimeRange +{ + Starting, + NotStart, + Expired, + WillBeExpired, +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationTestModule.cs similarity index 56% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationTestModule.cs index 3a60972a..cf845dff 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesApplicationTestModule.cs @@ -4,9 +4,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales; [DependsOn( typeof(EShopPluginsFlashSalesApplicationModule), - typeof(FlashSalesDomainTestModule) + typeof(EShopPluginsFlashSalesDomainTestModule) )] -public class FlashSalesApplicationTestModule : AbpModule +public class EShopPluginsFlashSalesApplicationTestModule : AbpModule { } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs new file mode 100644 index 00000000..879eb260 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs @@ -0,0 +1,483 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.Eshop.Products.Products; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; +using NSubstitute; +using Shouldly; +using Volo.Abp; +using Volo.Abp.Caching; +using Volo.Abp.DistributedLocking; +using Volo.Abp.Domain.Entities; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Users; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase +{ + protected IFlashSalePlanAppService AppService { get; } + + protected IDistributedEventBus DistributedEventBus { get; } + + private ProductDto Product1 { get; set; } + + public FlashSalePlanAppServiceTests() + { + AppService = GetRequiredService(); + DistributedEventBus = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + Product1 = CreateMockProductDto(); + + var productAppService = Substitute.For(); + productAppService.GetAsync(FlashSalesTestData.Product1Id).Returns(Task.FromResult(Product1)); + services.Replace(ServiceDescriptor.Singleton(productAppService)); + + services.Replace(ServiceDescriptor.Transient()); + + var distributedEventBus = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(distributedEventBus)); + base.AfterAddApplication(services); + } + + [Fact] + public async Task GetAsync() + { + var returnFlashSalePlan = await CreateFlashSalePlanAsync(); + + var flashSalePlan = await AppService.GetAsync(returnFlashSalePlan.Id); + + flashSalePlan.ShouldNotBeNull(); + flashSalePlan.Id.ShouldBe(returnFlashSalePlan.Id); + flashSalePlan.StoreId.ShouldBe(returnFlashSalePlan.StoreId); + flashSalePlan.BeginTime.ShouldBe(returnFlashSalePlan.BeginTime); + flashSalePlan.EndTime.ShouldBe(returnFlashSalePlan.EndTime); + flashSalePlan.ProductId.ShouldBe(returnFlashSalePlan.ProductId); + flashSalePlan.ProductSkuId.ShouldBe(returnFlashSalePlan.ProductSkuId); + flashSalePlan.IsPublished.ShouldBe(returnFlashSalePlan.IsPublished); + + returnFlashSalePlan = await CreateFlashSalePlanAsync(isPublished: false); + + flashSalePlan = await AppService.GetAsync(returnFlashSalePlan.Id); + + flashSalePlan.ShouldNotBeNull(); + flashSalePlan.Id.ShouldBe(returnFlashSalePlan.Id); + flashSalePlan.StoreId.ShouldBe(returnFlashSalePlan.StoreId); + flashSalePlan.BeginTime.ShouldBe(returnFlashSalePlan.BeginTime); + flashSalePlan.EndTime.ShouldBe(returnFlashSalePlan.EndTime); + flashSalePlan.ProductId.ShouldBe(returnFlashSalePlan.ProductId); + flashSalePlan.ProductSkuId.ShouldBe(returnFlashSalePlan.ProductSkuId); + flashSalePlan.IsPublished.ShouldBe(returnFlashSalePlan.IsPublished); + } + + [Fact] + public async Task GetListAsync() + { + var publishedPlan = await CreateFlashSalePlanAsync(isPublished: true); + var unpublishedPlan = await CreateFlashSalePlanAsync(isPublished: false); + + var allListDto = await AppService.GetListAsync(new FlashSalePlanGetListInput() + { + IncludeUnpublished = true + }); + + allListDto.TotalCount.ShouldBeGreaterThan(0); + allListDto.Items.FirstOrDefault(x => x.Id == publishedPlan.Id) + .ShouldNotBeNull() + .Id.ShouldBe(publishedPlan.Id); + + allListDto.Items.FirstOrDefault(x => x.Id == unpublishedPlan.Id) + .ShouldNotBeNull() + .Id.ShouldBe(unpublishedPlan.Id); + + var publishedListDto = await AppService.GetListAsync(new FlashSalePlanGetListInput()); + + publishedListDto.TotalCount.ShouldBeGreaterThan(0); + publishedListDto.Items.FirstOrDefault(x => x.Id == publishedPlan.Id) + .ShouldNotBeNull() + .Id.ShouldBe(publishedPlan.Id); + + publishedListDto.Items.FirstOrDefault(x => x.Id == unpublishedPlan.Id) + .ShouldBeNull(); + } + + [Fact] + public async Task CreateAsync() + { + var createDto = new FlashSalePlanCreateDto() + { + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }; + var returnFlashSalePlanDto = await AppService.CreateAsync(createDto); + + var flashSalePlan = await AppService.GetAsync(returnFlashSalePlanDto.Id); + + flashSalePlan.Id.ShouldBe(returnFlashSalePlanDto.Id); + flashSalePlan.StoreId.ShouldBe(createDto.StoreId); + flashSalePlan.BeginTime.ShouldBe(createDto.BeginTime); + flashSalePlan.EndTime.ShouldBe(createDto.EndTime); + flashSalePlan.ProductId.ShouldBe(createDto.ProductId); + flashSalePlan.ProductSkuId.ShouldBe(createDto.ProductSkuId); + flashSalePlan.IsPublished.ShouldBe(createDto.IsPublished); + + return flashSalePlan; + } + + [Fact] + public async Task CreateAsync_Should_Throw_Expcetion_When_Validate_Product_Failed() + { + var createDto = new FlashSalePlanCreateDto() + { + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }; + + Product1.StoreId = Guid.NewGuid(); + await AppService.CreateAsync(createDto).ShouldThrowAsync(); + Product1.StoreId = FlashSalesTestData.Store1Id; + + Product1.InventoryStrategy = InventoryStrategy.ReduceAfterPlacing; + await AppService.CreateAsync(createDto).ShouldThrowAsync(); + + Product1.StoreId = FlashSalesTestData.Store1Id; + Product1.InventoryStrategy = InventoryStrategy.FlashSales; + } + + [Fact] + public async Task UpdateAsync() + { + var createDto = new FlashSalePlanCreateDto() + { + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }; + var returnFlashSalePlanDto = await AppService.CreateAsync(createDto); + var updateDto = new FlashSalePlanUpdateDto() + { + BeginTime = DateTime.Now.AddMinutes(30), + EndTime = DateTime.Now.AddMinutes(60), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = false + }; + + var flashSalePlan = await AppService.UpdateAsync(returnFlashSalePlanDto.Id, updateDto); + + flashSalePlan.Id.ShouldBe(returnFlashSalePlanDto.Id); + flashSalePlan.StoreId.ShouldBe(createDto.StoreId); + flashSalePlan.BeginTime.ShouldBe(updateDto.BeginTime); + flashSalePlan.EndTime.ShouldBe(updateDto.EndTime); + flashSalePlan.ProductId.ShouldBe(updateDto.ProductId); + flashSalePlan.ProductSkuId.ShouldBe(updateDto.ProductSkuId); + flashSalePlan.IsPublished.ShouldBe(updateDto.IsPublished); + } + + [Fact] + public async Task UpdateAsync_Should_Throw_Expcetion_When_Validate_Product_Failed() + { + var createDto = new FlashSalePlanCreateDto() + { + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }; + var returnFlashSalePlanDto = await AppService.CreateAsync(createDto); + var updateDto = new FlashSalePlanUpdateDto() + { + BeginTime = DateTime.Now.AddMinutes(30), + EndTime = DateTime.Now.AddMinutes(60), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = false + }; + + Product1.StoreId = Guid.NewGuid(); + await AppService.UpdateAsync(returnFlashSalePlanDto.Id, updateDto).ShouldThrowAsync(); + Product1.StoreId = FlashSalesTestData.Store1Id; + + Product1.InventoryStrategy = InventoryStrategy.ReduceAfterPlacing; + await AppService.UpdateAsync(returnFlashSalePlanDto.Id, updateDto).ShouldThrowAsync(); + + Product1.StoreId = FlashSalesTestData.Store1Id; + Product1.InventoryStrategy = InventoryStrategy.FlashSales; + } + + [Fact] + public async Task UpdateAsync_Should_Throw_Expcetion_When_Has_Result_And_Change_Product() + { + var createDto = new FlashSalePlanCreateDto() + { + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }; + var returnFlashSalePlanDto = await AppService.CreateAsync(createDto); + var updateDto = new FlashSalePlanUpdateDto() + { + BeginTime = DateTime.Now.AddMinutes(30), + EndTime = DateTime.Now.AddMinutes(value: 60), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku2Id, + IsPublished = false + }; + await CreatePendingResultAsync(returnFlashSalePlanDto.Id, returnFlashSalePlanDto.StoreId, Guid.NewGuid()); + + await AppService.UpdateAsync(returnFlashSalePlanDto.Id, updateDto).ShouldThrowAsync(); + } + + [Fact] + public async Task DeleteAsync() + { + var createDto = new FlashSalePlanCreateDto() + { + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }; + var returnFlashSalePlanDto = await AppService.CreateAsync(createDto); + + await AppService.DeleteAsync(returnFlashSalePlanDto.Id); + await AppService.GetAsync(returnFlashSalePlanDto.Id).ShouldThrowAsync(); + } + + [Fact] + public async Task DeleteAsync_Should_Throw_Expcetion_When_Has_Result() + { + var createDto = new FlashSalePlanCreateDto() + { + StoreId = FlashSalesTestData.Store1Id, + BeginTime = DateTime.Now, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }; + var returnFlashSalePlanDto = await AppService.CreateAsync(createDto); + await CreatePendingResultAsync(returnFlashSalePlanDto.Id, returnFlashSalePlanDto.StoreId, Guid.NewGuid()); + + await AppService.DeleteAsync(returnFlashSalePlanDto.Id).ShouldThrowAsync(); + } + + [Fact] + public async Task PreOrderAsync() + { + var options = GetRequiredService>().Value; + var distributedCache = GetRequiredService>(); + var plan = await CreateFlashSalePlanAsync(); + var preOrderCacheKey = string.Format(FlashSalePlanAppService.PreOrderCacheKeyFormat, plan.Id, CurrentUser.Id); + var hashToken = await GetRequiredService() + .HashAsync(plan.LastModificationTime, Product1.LastModificationTime, Product1.GetSkuById(plan.ProductSkuId).LastModificationTime); + + var dto = await AppService.PreOrderAsync(plan.Id); + + dto.ExpiresInSeconds.ShouldBe(options.PreOrderExpires.TotalSeconds); + var preOrderCacheItem = await distributedCache.GetAsync(preOrderCacheKey); + preOrderCacheItem.ShouldNotBeNull(); + preOrderCacheItem.PlanId.ShouldBe(plan.Id); + preOrderCacheItem.TenantId.ShouldBe(plan.TenantId); + preOrderCacheItem.HashToken.ShouldBe(hashToken); + preOrderCacheItem.ProductId.ShouldBe(plan.ProductId); + preOrderCacheItem.ProductSkuId.ShouldBe(plan.ProductSkuId); + preOrderCacheItem.InventoryProviderName = Product1.InventoryProviderName; + } + + [Fact] + public async Task PreOrderAsync_Should_Throw_Exception_When_Validate_PreOrder_Failed() + { + var plan = await CreateFlashSalePlanAsync(); + + Product1.IsPublished = false; + + (await AppService.PreOrderAsync(plan.Id) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.ProductIsNotPublished); + + Product1.IsPublished = true; + + Product1.InventoryStrategy = InventoryStrategy.ReduceAfterPlacing; + + await AppService.PreOrderAsync(plan.Id) + .ShouldThrowAsync(); + + Product1.InventoryStrategy = InventoryStrategy.FlashSales; + + var plan2 = await CreateFlashSalePlanAsync(isPublished: false); + await AppService.PreOrderAsync(plan2.Id) + .ShouldThrowAsync(); + + var plan3 = await CreateFlashSalePlanAsync(timeRange: CreateTimeRange.Expired); + (await AppService.PreOrderAsync(plan3.Id) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver); + + var plan4 = await CreateFlashSalePlanAsync(useSku2: true); + (await AppService.PreOrderAsync(plan4.Id) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.ProductSkuInventoryExceeded); + } + + [Fact] + public async Task OrderAsync() + { + var plan = await CreateFlashSalePlanAsync(); + var hashToken = await GetRequiredService() + .HashAsync(plan.LastModificationTime, Product1.LastModificationTime, Product1.GetSkuById(plan.ProductSkuId).LastModificationTime); + var createOrderInput = new CreateOrderInput() + { + CustomerRemark = "remark1", + ExtraProperties = { { "key1", "value1" } } + }; + await AppService.PreOrderAsync(plan.Id); + + var isSucess = await AppService.OrderAsync(plan.Id, createOrderInput); + + isSucess.ShouldBe(true); + await DistributedEventBus.Received().PublishAsync(Arg.Is(eto => + eto.TenantId == plan.TenantId && + eto.StoreId == plan.StoreId && + eto.PlanId == plan.Id && + eto.UserId == CurrentUser.GetId() && + eto.HashToken == hashToken && + eto.CustomerRemark == createOrderInput.CustomerRemark && + eto.Plan != null && + eto.Plan.TenantId == plan.TenantId && + eto.Plan.StoreId == plan.StoreId && + eto.Plan.BeginTime == plan.BeginTime && + eto.Plan.EndTime == plan.EndTime && + eto.Plan.ProductId == plan.ProductId && + eto.Plan.ProductSkuId == plan.ProductSkuId && + eto.Plan.IsPublished == plan.IsPublished && + eto.ExtraProperties.ContainsKey("key1") && + eto.ExtraProperties["key1"].ToString() == "value1" + )); + } + + [Fact] + public async Task OrderAsync_Throw_Exception_When_Not_PreOrder() + { + var plan = await CreateFlashSalePlanAsync(); + var createOrderInput = new CreateOrderInput(); + + (await AppService.OrderAsync(plan.Id, createOrderInput) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.PreOrderExpired); + } + + [Fact] + public async Task OrderAsync_Throw_Exception_When_FlashSaleNotStarted() + { + var plan = await CreateFlashSalePlanAsync(timeRange: CreateTimeRange.NotStart); + var createOrderInput = new CreateOrderInput(); + await AppService.PreOrderAsync(plan.Id); + + (await AppService.OrderAsync(plan.Id, createOrderInput) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleNotStarted); + } + + [Fact] + public async Task OrderAsync_Throw_Exception_When_FlashSaleIsOver() + { + var plan = await CreateFlashSalePlanAsync(timeRange: CreateTimeRange.WillBeExpired); + var createOrderInput = new CreateOrderInput(); + await AppService.PreOrderAsync(plan.Id); + + await Task.Delay(TimeSpan.FromSeconds(1.2)); + + (await AppService.OrderAsync(plan.Id, createOrderInput) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver); + } + + [Fact] + public async Task OrderAsync_Throw_Exception_When_BusyToCreateFlashSaleOrder() + { + var plan = await CreateFlashSalePlanAsync(); + var createOrderInput = new CreateOrderInput(); + await AppService.PreOrderAsync(plan.Id); + var distributedLock = GetRequiredService(); + var lockKey = $"create-flash-sale-order-{plan.Id}-{CurrentUser.GetId()}"; + + await using var handle = await distributedLock.TryAcquireAsync(lockKey); + + (await AppService.OrderAsync(plan.Id, createOrderInput) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); + } + + [Fact] + public async Task OrderAsync_Throw_Exception_When_Exist_UserFlashSaleResultCache() + { + var plan = await CreateFlashSalePlanAsync(); + var createOrderInput = new CreateOrderInput(); + await AppService.PreOrderAsync(plan.Id); + var distributedCache = GetRequiredService(); + var userId = CurrentUser.GetId(); + var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, userId); + await distributedCache.SetStringAsync(userFlashSaleResultCacheKey, Guid.NewGuid().ToString()); + + (await AppService.OrderAsync(plan.Id, createOrderInput) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + } + + [Fact] + public async Task OrderAsync_Return_False_When_TryReduceInventory_Failed() + { + var plan = await CreateFlashSalePlanAsync(); + var createOrderInput = new CreateOrderInput(); + await AppService.PreOrderAsync(plan.Id); + + FakeFlashSaleInventoryManager.ShouldReduceSuccess = false; + + (await AppService.OrderAsync(plan.Id, createOrderInput)).ShouldBe(false); + } + + [Fact] + public async Task OrderAsync_Return_False_When_Exist_Not_Failed_Result() + { + var plan = await CreateFlashSalePlanAsync(); + var createOrderInput = new CreateOrderInput(); + await AppService.PreOrderAsync(plan.Id); + var userId = GetRequiredService().GetId(); + + await CreatePendingResultAsync(plan.Id, plan.StoreId, userId); + + (await AppService.OrderAsync(plan.Id, createOrderInput) + .ShouldThrowAsync()) + .Code.ShouldBe(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs new file mode 100644 index 00000000..164faa82 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using EasyAbp.Eshop.Products.Products; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using NSubstitute; +using NSubstitute.ReceivedExtensions; +using Shouldly; +using Volo.Abp; +using Volo.Abp.Caching; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Users; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest : FlashSalesApplicationTestBase +{ + protected RollBackInventoryCreateFlashSaleOrderCompleteEventHandler EventHandler { get; } + + protected IDistributedCache DistributedCache { get; } + + protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; set; } + + private ProductDto Product1 { get; set; } + + public RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest() + { + EventHandler = GetRequiredService(); + DistributedCache = GetRequiredService(); + FlashSaleInventoryManager = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + Product1 = CreateMockProductDto(); + + var productAppService = Substitute.For(); + productAppService.GetAsync(FlashSalesTestData.Product1Id).Returns(Task.FromResult(Product1)); + services.Replace(ServiceDescriptor.Singleton(productAppService)); + + FlashSaleInventoryManager = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(FlashSaleInventoryManager)); + base.AfterAddApplication(services); + } + + [Fact] + public async Task HandleEventAsync() + { + var plan = await CreateFlashSalePlanAsync(); + var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); + await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); + var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() + { + TenantId = pendingFlashResult.TenantId, + PendingResultId = pendingFlashResult.Id, + Success = false, + StoreId = pendingFlashResult.StoreId, + PlanId = pendingFlashResult.PlanId, + OrderId = null, + Reason = FlashSaleResultFailedReason.InvalidHashToken, + UserId = pendingFlashResult.UserId + }; + FlashSaleInventoryManager + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .Returns(Task.FromResult(true)); + + await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); + + var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); + userFlashSaleResultCache.ShouldBeNull(); + + await FlashSaleInventoryManager.Received() + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + } + + [Fact] + public async Task HandleEventAsync_Should_Not_Remove_UserFlashSaleResultCache_When_TryRollBackInventory_Failed() + { + var plan = await CreateFlashSalePlanAsync(); + var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); + await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); + var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() + { + TenantId = pendingFlashResult.TenantId, + PendingResultId = pendingFlashResult.Id, + Success = false, + StoreId = pendingFlashResult.StoreId, + PlanId = pendingFlashResult.PlanId, + OrderId = null, + Reason = FlashSaleResultFailedReason.InvalidHashToken, + UserId = pendingFlashResult.UserId + }; + FlashSaleInventoryManager + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .Returns(Task.FromResult(false)); + + await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); + + var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); + userFlashSaleResultCache.ShouldBe(pendingFlashResult.Id.ToString()); + + await FlashSaleInventoryManager.Received() + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + } + + [Fact] + public async Task HandleEventAsync_Should_Ignore_When_Success_Is_True() + { + var plan = await CreateFlashSalePlanAsync(); + var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); + await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); + var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() + { + TenantId = pendingFlashResult.TenantId, + PendingResultId = pendingFlashResult.Id, + Success = true, + StoreId = pendingFlashResult.StoreId, + PlanId = pendingFlashResult.PlanId, + OrderId = Guid.NewGuid(), + Reason = null, + UserId = pendingFlashResult.UserId + }; + + await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); + + var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); + userFlashSaleResultCache.ShouldBe(pendingFlashResult.Id.ToString()); + + await FlashSaleInventoryManager.DidNotReceiveWithAnyArgs() + .TryRollBackInventoryAsync(default, default, Guid.Empty, Guid.Empty, Guid.Empty, default, default); + } + + [Fact] + public async Task HandleEventAsync_Should_Ignore_When_Reason_Not_InvalidHashToken() + { + var plan = await CreateFlashSalePlanAsync(); + var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); + await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); + var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() + { + TenantId = pendingFlashResult.TenantId, + PendingResultId = pendingFlashResult.Id, + Success = false, + StoreId = pendingFlashResult.StoreId, + PlanId = pendingFlashResult.PlanId, + OrderId = null, + Reason = "Other", + UserId = pendingFlashResult.UserId + }; + + await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); + + var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); + userFlashSaleResultCache.ShouldBe(pendingFlashResult.Id.ToString()); + + await FlashSaleInventoryManager.DidNotReceiveWithAnyArgs() + .TryRollBackInventoryAsync(default, default, Guid.Empty, Guid.Empty, Guid.Empty, default, default); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs index 77224ae3..e0877a3d 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs @@ -1,9 +1,149 @@ -namespace EasyAbp.EShop.Plugins.FlashSales; +using System.Threading.Tasks; +using System; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using Volo.Abp; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Timing; +using Volo.Abp.Users; +using EasyAbp.EShop.Products.Products.Dtos; +using EasyAbp.EShop.Products.Products; +using System.Collections.Generic; + +namespace EasyAbp.EShop.Plugins.FlashSales; /* Inherit from this class for your application layer tests. * See SampleAppService_Tests for example. */ -public abstract class FlashSalesApplicationTestBase : FlashSalesTestBase +public abstract class FlashSalesApplicationTestBase : FlashSalesTestBase { + protected IGuidGenerator GuidGenerator { get; } + + protected ICurrentTenant CurrentTenant { get; } + + protected IClock Clock { get; } + + protected ICurrentUser CurrentUser { get; } + + protected IFlashSaleResultRepository FlashSaleResultRepository { get; } + + protected IFlashSalePlanRepository FlashSalePlanRepository { get; } + + protected FlashSalesApplicationTestBase() + { + GuidGenerator = GetRequiredService(); + CurrentTenant = GetRequiredService(); + Clock = GetRequiredService(); + CurrentUser = GetRequiredService(); + FlashSalePlanRepository = GetRequiredService(); + FlashSaleResultRepository = GetRequiredService(); + } + + protected virtual ProductDto CreateMockProductDto() + { + return new ProductDto + { + CreationTime = DateTime.Now, + IsPublished = true, + Id = FlashSalesTestData.Product1Id, + StoreId = FlashSalesTestData.Store1Id, + ProductGroupName = "Default", + ProductGroupDisplayName = "Default", + UniqueName = "Pencil", + DisplayName = "Hello pencil", + ProductDetailId = FlashSalesTestData.ProductDetail1Id, + ProductSkus = new List + { + new ProductSkuDto + { + Id = FlashSalesTestData.ProductSku1Id, + Name = "My SKU", + OrderMinQuantity = 0, + OrderMaxQuantity = 100, + AttributeOptionIds = new List(), + Price = 1m, + Currency = "USD", + ProductDetailId = null, + Inventory = 10, + }, + new ProductSkuDto + { + Id = FlashSalesTestData.ProductSku2Id, + Name = "My SKU 2", + OrderMinQuantity = 0, + OrderMaxQuantity = 100, + AttributeOptionIds = new List(), + Price = 2m, + Currency = "USD", + ProductDetailId = FlashSalesTestData.ProductDetail2Id, + Inventory = 0 + }, + new ProductSkuDto + { + Id = FlashSalesTestData.ProductSku3Id, + Name = "My SKU 3", + OrderMinQuantity = 0, + OrderMaxQuantity = 100, + AttributeOptionIds = new List(), + Price = 3m, + Currency = "USD", + ProductDetailId = FlashSalesTestData.ProductDetail2Id, + Inventory = 1 + } + }, + InventoryStrategy = InventoryStrategy.FlashSales, + LastModificationTime = FlashSalesTestData.ProductLastModificationTime + }; + } + + protected virtual async Task CreatePendingResultAsync(Guid planId, Guid storeId, Guid userId) + { + return await WithUnitOfWorkAsync(async () => + { + return await FlashSaleResultRepository.InsertAsync( + new FlashSaleResult(GuidGenerator.Create(), CurrentTenant.Id, storeId, planId, userId) + ); + }); + } + + protected virtual async Task CreateFlashSalePlanAsync(bool useSku2 = false, CreateTimeRange timeRange = CreateTimeRange.Starting, bool isPublished = true) + { + DateTime beginTime; + DateTime endTime; + + switch (timeRange) + { + case CreateTimeRange.Starting: + beginTime = Clock.Now; + endTime = beginTime.AddMinutes(30); + break; + case CreateTimeRange.NotStart: + beginTime = Clock.Now.AddMinutes(10); + endTime = beginTime.AddMinutes(30); + break; + case CreateTimeRange.Expired: + beginTime = Clock.Now.AddDays(-1); + endTime = beginTime.AddMinutes(30); + break; + case CreateTimeRange.WillBeExpired: + beginTime = Clock.Now.AddDays(-30); + endTime = Clock.Now.AddSeconds(1); + break; + default: + throw new AbpException(); + } + var flashSalePlan = new FlashSalePlan( + GuidGenerator.Create(), + CurrentTenant.Id, + FlashSalesTestData.Store1Id, + beginTime, + endTime, + FlashSalesTestData.Product1Id, + useSku2 ? FlashSalesTestData.ProductSku2Id : FlashSalesTestData.ProductSku1Id, + isPublished + ); + return await WithUnitOfWorkAsync(async () => await FlashSalePlanRepository.InsertAsync(flashSalePlan, autoSave: true)); + } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs new file mode 100644 index 00000000..ff159deb --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs @@ -0,0 +1,27 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.Eshop.Products.Products; + +namespace EasyAbp.EShop.Products.Products; + +public class FakeFlashSaleInventoryManager : IFlashSaleInventoryManager +{ + public static bool ShouldReduceSuccess { get; set; } + + public FakeFlashSaleInventoryManager() + { + ShouldReduceSuccess = true; + } + + public Task TryReduceInventoryAsync( + Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool increaseSold) + { + return Task.FromResult(ShouldReduceSuccess); + } + + public Task TryRollBackInventoryAsync( + Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold) + { + return Task.FromResult(true); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainTestModule.cs similarity index 71% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestModule.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainTestModule.cs index 3a218f7f..3a033be8 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesDomainTestModule.cs @@ -8,9 +8,9 @@ namespace EasyAbp.EShop.Plugins.FlashSales; * database independent anyway. */ [DependsOn( - typeof(FlashSalesEntityFrameworkCoreTestModule) + typeof(EShopPluginsFlashSalesEntityFrameworkCoreTestModule) )] -public class FlashSalesDomainTestModule : AbpModule +public class EShopPluginsFlashSalesDomainTestModule : AbpModule { } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasherTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasherTests.cs new file mode 100644 index 00000000..b0868cd8 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanHasherTests.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +public class FlashSalePlanHasherTests : FlashSalesDomainTestBase +{ + protected IFlashSalePlanHasher FlashSalePlanHasher { get; } + + public FlashSalePlanHasherTests() + { + FlashSalePlanHasher = GetRequiredService(); + } + + [Fact] + public async Task HashAsync() + { + var time1 = DateTime.Now; + var time2 = DateTime.Now.AddTicks(10); + var time3 = DateTime.Now.AddTicks(20); + + (await FlashSalePlanHasher.HashAsync(time1, time2, time3)) + .ShouldBe(await FlashSalePlanHasher.HashAsync(time1, time2, time3)); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTests.cs new file mode 100644 index 00000000..90b7694b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanTests.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public class FlashSalePlanTests +{ + [Fact] + public void Should_Throw_InvalidEndTimeException() + { + Assert.Throws(() => + { + new FlashSalePlan( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + beginTime: DateTime.Now, + endTime: DateTime.Now.AddSeconds(-1), + productId: Guid.NewGuid(), + productSkuId: Guid.NewGuid(), + isPublished: true + ); + }); + } + + [Fact] + public void SetTimeRange() + { + var existPlan = new FlashSalePlan( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + beginTime: DateTime.Now, + endTime: DateTime.Now.AddSeconds(1), + productId: Guid.NewGuid(), + productSkuId: Guid.NewGuid(), + isPublished: true + ); + + var newBeginTime = DateTime.Now; + var newEndTime = newBeginTime.AddMinutes(1); + + existPlan.SetTimeRange(newBeginTime, newEndTime); + + existPlan.BeginTime.ShouldBe(newBeginTime); + existPlan.EndTime.ShouldBe(newEndTime); + } + + [Fact] + public void SetTimeRange_Should_Throw_InvalidEndTimeException_When_Set_InvalidEndTime() + { + var existPlan = new FlashSalePlan( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + beginTime: DateTime.Now, + endTime: DateTime.Now.AddSeconds(1), + productId: Guid.NewGuid(), + productSkuId: Guid.NewGuid(), + isPublished: true + ); + + Assert.Throws(() => existPlan.SetTimeRange(DateTime.Now, DateTime.Now.AddMinutes(-1))); + } + + [Fact] + public void SetProductSku() + { + var existPlan = new FlashSalePlan( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + beginTime: DateTime.Now, + endTime: DateTime.Now.AddSeconds(1), + productId: Guid.NewGuid(), + productSkuId: Guid.NewGuid(), + isPublished: true + ); + + var newStoreId = Guid.NewGuid(); + var newProductId = Guid.NewGuid(); + var newProductSkuId = Guid.NewGuid(); + + existPlan.SetProductSku(newStoreId, newProductId, newProductSkuId); + + existPlan.StoreId.ShouldBe(newStoreId); + existPlan.ProductId.ShouldBe(newProductId); + existPlan.ProductSkuId.ShouldBe(newProductSkuId); + } + + [Fact] + public void SetPublished() + { + var existPlan = new FlashSalePlan( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + beginTime: DateTime.Now, + endTime: DateTime.Now.AddSeconds(1), + productId: Guid.NewGuid(), + productSkuId: Guid.NewGuid(), + isPublished: true + ); + + existPlan.SetPublished(false); + + existPlan.IsPublished.ShouldBe(false); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs new file mode 100644 index 00000000..5172e23f --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs @@ -0,0 +1,85 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using Shouldly; +using Volo.Abp.Guids; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class CreateFlashSaleOrderCompleteEventHandlerTests : FlashSalesDomainTestBase +{ + protected IFlashSaleResultRepository FlashSaleResultRepository { get; } + protected CreateFlashSaleOrderCompleteEventHandler CreateFlashSaleOrderCompleteEventHandler { get; } + protected IGuidGenerator GuidGenerator { get; } + + public CreateFlashSaleOrderCompleteEventHandlerTests() + { + FlashSaleResultRepository = GetRequiredService(); + CreateFlashSaleOrderCompleteEventHandler = GetRequiredService(); + GuidGenerator = GetRequiredService(); + } + + [Fact] + public async Task HandleEventAsync_When_Create_Order_Success() + { + var existFlashResult = await CreateFlashSaleResultAsync(); + var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() + { + TenantId = existFlashResult.TenantId, + PendingResultId = existFlashResult.Id, + Success = true, + StoreId = existFlashResult.StoreId, + PlanId = existFlashResult.PlanId, + OrderId = GuidGenerator.Create(), + Reason = null, + UserId = existFlashResult.UserId, + }; + + await CreateFlashSaleOrderCompleteEventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); + + var flashResult = await FlashSaleResultRepository.GetAsync(existFlashResult.Id); + flashResult.Status.ShouldBe(FlashSaleResultStatus.Successful); + flashResult.OrderId.ShouldBe(createFlashSaleOrderCompleteEto.OrderId); + flashResult.Reason.ShouldBe(null); + } + + [Fact] + public async Task HandleEventAsync_When_Create_Order_Failed() + { + var existFlashResult = await CreateFlashSaleResultAsync(); + var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() + { + TenantId = existFlashResult.TenantId, + PendingResultId = existFlashResult.Id, + Success = false, + StoreId = FlashSalesTestData.Store1Id, + PlanId = existFlashResult.PlanId, + OrderId = null, + Reason = "Failed reason", + UserId = existFlashResult.UserId, + }; + + await CreateFlashSaleOrderCompleteEventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); + + var flashResult = await FlashSaleResultRepository.GetAsync(existFlashResult.Id); + flashResult.Status.ShouldBe(FlashSaleResultStatus.Failed); + flashResult.OrderId.ShouldBe(null); + flashResult.Reason.ShouldBe("Failed reason"); + } + + public async Task CreateFlashSaleResultAsync() + { + return await WithUnitOfWorkAsync(async () => + { + var flashSaleResult = new FlashSaleResult( + GuidGenerator.Create(), + null, + FlashSalesTestData.Store1Id, + FlashSalesTestData.Plan1Id, + GuidGenerator.Create()); + await FlashSaleResultRepository.InsertAsync(flashSaleResult); + + return flashSaleResult; + }); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs new file mode 100644 index 00000000..7464ce4b --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class FlashSaleResultTests +{ + [Fact] + public void MarkAsSuccessful() + { + var flashSaleResult = new FlashSaleResult( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + planId: Guid.NewGuid(), + userId: Guid.NewGuid() + ); + + flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); + + var orderId = Guid.NewGuid(); + flashSaleResult.MarkAsSuccessful(orderId); + + flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Successful); + flashSaleResult.OrderId.ShouldBe(orderId); + } + + [Fact] + public void MarkAsSuccessful_Should_Throw_FlashSaleResultStatusNotPendingException_When_Status_Not_Pending() + { + var flashSaleResult = new FlashSaleResult( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + planId: Guid.NewGuid(), + userId: Guid.NewGuid() + ); + + flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); + + var orderId = Guid.NewGuid(); + flashSaleResult.MarkAsSuccessful(orderId); + flashSaleResult.Reason.ShouldBe(null); + + Assert.Throws(() => + { + flashSaleResult.MarkAsSuccessful(orderId); + }); + } + + [Fact] + public void MarkAsFailed() + { + var flashSaleResult = new FlashSaleResult( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + planId: Guid.NewGuid(), + userId: Guid.NewGuid() + ); + + flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); + + flashSaleResult.MarkAsFailed("reason"); + + flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Failed); + flashSaleResult.OrderId.ShouldBe(null); + flashSaleResult.Reason.ShouldBe("reason"); + } + + [Fact] + public void MarkAsFailed_Should_Throw_FlashSaleResultStatusNotPendingException_When_Status_Not_Pending() + { + var flashSaleResult = new FlashSaleResult( + id: Guid.NewGuid(), + tenantId: null, + storeId: Guid.NewGuid(), + planId: Guid.NewGuid(), + userId: Guid.NewGuid() + ); + + flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); + + flashSaleResult.MarkAsFailed("reason"); + + Assert.Throws(() => + { + flashSaleResult.MarkAsFailed("reason"); + }); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs index 1cb6e93a..58e775a1 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesDomainTestBase.cs @@ -3,7 +3,7 @@ /* Inherit from this class for your domain layer tests. * See SampleManager_Tests for example. */ -public abstract class FlashSalesDomainTestBase : FlashSalesTestBase +public abstract class FlashSalesDomainTestBase : FlashSalesTestBase { } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreTestModule.cs similarity index 91% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreTestModule.cs index fb28fd4a..39b1283c 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/EShopPluginsFlashSalesEntityFrameworkCoreTestModule.cs @@ -9,11 +9,11 @@ using Volo.Abp.Modularity; namespace EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore; [DependsOn( - typeof(FlashSalesTestBaseModule), + typeof(EShopPluginsFlashSalesTestBaseModule), typeof(EShopPluginsFlashSalesEntityFrameworkCoreModule), typeof(AbpEntityFrameworkCoreSqliteModule) )] -public class FlashSalesEntityFrameworkCoreTestModule : AbpModule +public class EShopPluginsFlashSalesEntityFrameworkCoreTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs index 01e83ba7..0ba954e8 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore.Tests/EasyAbp/EShop/Plugins/FlashSales/EntityFrameworkCore/FlashSalesEntityFrameworkCoreTestBase.cs @@ -3,7 +3,7 @@ /* This class can be used as a base class for EF Core integration tests, * while SampleRepository_Tests uses a different approach. */ -public abstract class FlashSalesEntityFrameworkCoreTestBase : FlashSalesTestBase +public abstract class FlashSalesEntityFrameworkCoreTestBase : FlashSalesTestBase { } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs index d9e47d1d..f1d41e9b 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/ConsoleTestAppHostedService.cs @@ -18,7 +18,7 @@ public class ConsoleTestAppHostedService : IHostedService public async Task StartAsync(CancellationToken cancellationToken) { - using (var application = await AbpApplicationFactory.CreateAsync(options => + using (var application = await AbpApplicationFactory.CreateAsync(options => { options.Services.ReplaceConfiguration(_configuration); options.UseAutofac(); diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesConsoleApiClientModule.cs similarity index 80% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesConsoleApiClientModule.cs index 1d081c6c..80a95f2c 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/FlashSalesConsoleApiClientModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client.ConsoleTestApp/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesConsoleApiClientModule.cs @@ -9,7 +9,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales; typeof(EShopPluginsFlashSalesHttpApiClientModule), typeof(AbpHttpClientIdentityModelModule) )] -public class FlashSalesConsoleApiClientModule : AbpModule +public class EShopPluginsFlashSalesConsoleApiClientModule : AbpModule { } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbTestModule.cs similarity index 86% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbTestModule.cs index 2d101fa3..3bc8bcd3 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/EShopPluginsFlashSalesMongoDbTestModule.cs @@ -6,10 +6,10 @@ using Volo.Abp.Uow; namespace EasyAbp.EShop.Plugins.FlashSales.MongoDB; [DependsOn( - typeof(FlashSalesTestBaseModule), + typeof(EShopPluginsFlashSalesTestBaseModule), typeof(EShopPluginsFlashSalesMongoDbModule) )] -public class FlashSalesMongoDbTestModule : AbpModule +public class EShopPluginsFlashSalesMongoDbTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs index 0953ae82..585e5ef6 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.MongoDB.Tests/EasyAbp/EShop/Plugins/FlashSales/MongoDB/FlashSalesMongoDbTestBase.cs @@ -3,7 +3,7 @@ /* This class can be used as a base class for MongoDB integration tests, * while SampleRepository_Tests uses a different approach. */ -public abstract class FlashSalesMongoDbTestBase : FlashSalesTestBase +public abstract class FlashSalesMongoDbTestBase : FlashSalesTestBase { } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesTestBaseModule.cs similarity index 94% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesTestBaseModule.cs index 33ce5497..5bc24871 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestBaseModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/EShopPluginsFlashSalesTestBaseModule.cs @@ -14,7 +14,7 @@ namespace EasyAbp.EShop.Plugins.FlashSales; typeof(AbpAuthorizationModule), typeof(EShopPluginsFlashSalesDomainModule) )] -public class FlashSalesTestBaseModule : AbpModule +public class EShopPluginsFlashSalesTestBaseModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestData.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestData.cs new file mode 100644 index 00000000..baa98bd9 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.TestBase/EasyAbp/EShop/Plugins/FlashSales/FlashSalesTestData.cs @@ -0,0 +1,28 @@ +using System; + +namespace EasyAbp.EShop.Plugins.FlashSales; + +public static class FlashSalesTestData +{ + public static Guid Plan1Id { get; } = Guid.NewGuid(); + + public static Guid Result1Id { get; } = Guid.NewGuid(); + + public static Guid Store1Id { get; } = Guid.NewGuid(); + + public static Guid Product1Id { get; } = Guid.NewGuid(); + + public static Guid ProductSku1Id { get; } = Guid.NewGuid(); + + public static Guid ProductSku2Id { get; } = Guid.NewGuid(); + + public static Guid ProductSku3Id { get; } = Guid.NewGuid(); + + public static Guid ProductDetail1Id { get; } = Guid.NewGuid(); + + public static Guid ProductDetail2Id { get; } = Guid.NewGuid(); + + public static DateTime ProductLastModificationTime { get; } = DateTime.Today; + + public static DateTime ProductDetailLastModificationTime { get; } = DateTime.Today; +} From 4b30e6c0931a5159322c51f6e1f85148fa9c1daf Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 16 Jul 2022 20:06:49 +0800 Subject: [PATCH 38/97] Return `CreateOrderDto` --- .../FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs | 11 +++++++++++ .../FlashSalePlans/IFlashSalePlanAppService.cs | 2 +- .../FlashSalePlans/FlashSalePlanAppService.cs | 6 +++--- .../FlashSalePlans/FlashSalePlanController.cs | 2 +- .../FlashSalePlans/FlashSalePlanAppServiceTests.cs | 7 +++++-- 5 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs new file mode 100644 index 00000000..e3f54829 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs @@ -0,0 +1,11 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; + +public class CreateOrderDto : ExtensibleEntityDto +{ + public bool IsSuccess { get; set; } + + public Guid? FlashSaleResultId { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs index 2d8c7130..55b211ea 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs @@ -15,5 +15,5 @@ public interface IFlashSalePlanAppService : { Task PreOrderAsync(Guid id); - Task OrderAsync(Guid id, CreateOrderInput input); + Task OrderAsync(Guid id, CreateOrderInput input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 86121c50..257d88b1 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -216,7 +216,7 @@ public class FlashSalePlanAppService : return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), ExpiresInSeconds = Options.PreOrderExpires.TotalSeconds }; } - public virtual async Task OrderAsync(Guid id, CreateOrderInput input) + public virtual async Task OrderAsync(Guid id, CreateOrderInput input) { var preOrderCache = await GetPreOrderCacheAsync(id); if (preOrderCache == null) @@ -259,7 +259,7 @@ public class FlashSalePlanAppService : plan.TenantId, preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) { - return false; + return new CreateOrderDto() { IsSuccess = false }; } var result = await CreatePendingFlashSaleResultAsync(plan, userId, async (existsResultId) => @@ -278,7 +278,7 @@ public class FlashSalePlanAppService : await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); - return true; + return new CreateOrderDto() { IsSuccess = true, FlashSaleResultId = result.Id }; } #region PreOrderCache diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index 868da3ad..c0cd3732 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -58,7 +58,7 @@ public class FlashSalePlanController : } [HttpPost("{id}/order")] - public virtual Task OrderAsync(Guid id, CreateOrderInput input) + public virtual Task OrderAsync(Guid id, CreateOrderInput input) { return Service.OrderAsync(id, input); } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs index 879eb260..ccdc05ea 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs @@ -364,7 +364,8 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase var isSucess = await AppService.OrderAsync(plan.Id, createOrderInput); - isSucess.ShouldBe(true); + isSucess.IsSuccess.ShouldBe(true); + isSucess.FlashSaleResultId.ShouldNotBeNull(); await DistributedEventBus.Received().PublishAsync(Arg.Is(eto => eto.TenantId == plan.TenantId && eto.StoreId == plan.StoreId && @@ -463,7 +464,9 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase FakeFlashSaleInventoryManager.ShouldReduceSuccess = false; - (await AppService.OrderAsync(plan.Id, createOrderInput)).ShouldBe(false); + var createOrderDto = await AppService.OrderAsync(plan.Id, createOrderInput); + createOrderDto.IsSuccess.ShouldBe(false); + createOrderDto.FlashSaleResultId.ShouldBeNull(); } [Fact] From 714ad1ff555537afd4fad7fcb87631efaa2e4302 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sat, 16 Jul 2022 20:07:05 +0800 Subject: [PATCH 39/97] Add FlashSales docs --- docs/plugins/flash-sales/README.md | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 docs/plugins/flash-sales/README.md diff --git a/docs/plugins/flash-sales/README.md b/docs/plugins/flash-sales/README.md new file mode 100644 index 00000000..f14a2d7e --- /dev/null +++ b/docs/plugins/flash-sales/README.md @@ -0,0 +1,47 @@ +# EShop.Plugins.FlashSales + +[![ABP version](https://img.shields.io/badge/dynamic/xml?style=flat-square&color=yellow&label=abp&query=%2F%2FProject%2FPropertyGroup%2FAbpVersion&url=https%3A%2F%2Fraw.githubusercontent.com%2FEasyAbp%2FEShop%2Fmaster%2FDirectory.Build.props)](https://abp.io) +[![Discord online](https://badgen.net/discord/online-members/S6QaezrCRq?label=Discord)](https://discord.gg/S6QaezrCRq) +[![GitHub stars](https://img.shields.io/github/stars/EasyAbp/EShop?style=social)](https://www.github.com/EasyAbp/EShop) + +A flash-sales plugin for EShop. + +## Installation + +1. Install the following NuGet packages. ([see how](https://github.com/EasyAbp/EasyAbpGuide/blob/master/docs/How-To.md#add-nuget-packages)) + + * EasyAbp.EShop.Orders.Plugins.FlashSales.Application (install at EasyAbp.EShop.Orders.Application location) + * EasyAbp.EShop.Products.Plugins.FlashSales.Application (install at EasyAbp.EShop.Products.Application location) + * EasyAbp.EShop.Plugins.FlashSales.Application + * EasyAbp.EShop.Plugins.FlashSales.Application.Contracts + * EasyAbp.EShop.Plugins.FlashSales.Domain + * EasyAbp.EShop.Plugins.FlashSales.Domain.Shared + * EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore + * EasyAbp.EShop.Plugins.FlashSales.HttpApi + * EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client + * (Optional) EasyAbp.EShop.Plugins.FlashSales.MongoDB + * (Optional) EasyAbp.EShop.Plugins.FlashSales.Web + * (Special Optional) EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts (install at EasyAbp.EShop.Products.Application.Contracts location) + * (SpecialOptional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi (install at EasyAbp.EShop.Products.HttpApi location) + * (Special Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client (install at EasyAbp.EShop.Products.HttpApi.Client location) + > When you do not open the dynamic API for the `EasyAbp.EShop.Products` module, these `Special Optional` modules must be installed. + +2. Add `DependsOn(typeof(EShopXxxModule))` attribute to configure the module dependencies. ([see how](https://github.com/EasyAbp/EasyAbpGuide/blob/master/docs/How-To.md#add-module-dependencies)) + +3. Add `builder.ConfigureEShopPluginsFlashSales();` to the `OnModelCreating()` method in **MyProjectDbContext.cs**. + +4. Add EF Core migrations and update your database. See: [ABP document](https://docs.abp.io/en/abp/latest/Tutorials/Part-1?UI=MVC&DB=EF#add-database-migration). + +## Usage + +### Admins + +1. Create a published flash-sale plan. + +### Customers + +1. Using `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/pre-order` (POST) to pre-order. It will return the expires time if the flash-sale plan is available. +2. Within the expires time, using `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/order` (POST) to request flash purchase order. +3. Using `/api/e-shop/plugins/flash-sales/flash-sale-result/{resultId}` (GET) to query the result. + + > Continuously pulled until the result is no longer `Pending`. If the status is `Successful`, the order will be included. If the status `Failed`, the reason will be included. From 7e160fa0aaa57f232443780a0e2be16548ec12aa Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 17 Jul 2022 12:23:34 +0800 Subject: [PATCH 40/97] Fix typo --- .../{CreateOrderDto.cs => CreateOrderResultDto.cs} | 2 +- .../FlashSalePlans/IFlashSalePlanAppService.cs | 2 +- .../FlashSalePlans/FlashSalePlanAppService.cs | 6 +++--- ...kenCreateFlashSaleOrderCompleteEventHandler.cs} | 8 ++++---- .../FlashSalePlans/FlashSalePlanController.cs | 2 +- .../FlashSalePlans/FlashSalePlanAppServiceTests.cs | 14 +++++++------- ...reateFlashSaleOrderCompleteEventHandlerTest.cs} | 14 ++++---------- 7 files changed, 21 insertions(+), 27 deletions(-) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/{CreateOrderDto.cs => CreateOrderResultDto.cs} (78%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/{RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs => ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs} (85%) rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/{RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs => ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs} (93%) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderResultDto.cs similarity index 78% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderResultDto.cs index e3f54829..418e04af 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderResultDto.cs @@ -3,7 +3,7 @@ using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; -public class CreateOrderDto : ExtensibleEntityDto +public class CreateOrderResultDto : ExtensibleEntityDto { public bool IsSuccess { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs index 55b211ea..d98fe61f 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs @@ -15,5 +15,5 @@ public interface IFlashSalePlanAppService : { Task PreOrderAsync(Guid id); - Task OrderAsync(Guid id, CreateOrderInput input); + Task OrderAsync(Guid id, CreateOrderInput input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 257d88b1..056b2edf 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -216,7 +216,7 @@ public class FlashSalePlanAppService : return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), ExpiresInSeconds = Options.PreOrderExpires.TotalSeconds }; } - public virtual async Task OrderAsync(Guid id, CreateOrderInput input) + public virtual async Task OrderAsync(Guid id, CreateOrderInput input) { var preOrderCache = await GetPreOrderCacheAsync(id); if (preOrderCache == null) @@ -259,7 +259,7 @@ public class FlashSalePlanAppService : plan.TenantId, preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) { - return new CreateOrderDto() { IsSuccess = false }; + return new CreateOrderResultDto() { IsSuccess = false }; } var result = await CreatePendingFlashSaleResultAsync(plan, userId, async (existsResultId) => @@ -278,7 +278,7 @@ public class FlashSalePlanAppService : await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); - return new CreateOrderDto() { IsSuccess = true, FlashSaleResultId = result.Id }; + return new CreateOrderResultDto() { IsSuccess = true, FlashSaleResultId = result.Id }; } #region PreOrderCache diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs similarity index 85% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs index 6aad2f50..7068b989 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs @@ -10,20 +10,20 @@ using Volo.Abp.EventBus.Distributed; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency +public class ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency { protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } protected IDistributedCache DistributedCache { get; } protected IFlashSalePlanRepository FlashSalePlanRepository { get; } protected IProductAppService ProductAppService { get; } - protected ILogger Logger { get; } + protected ILogger Logger { get; } - public RollBackInventoryCreateFlashSaleOrderCompleteEventHandler( + public ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler( IFlashSaleInventoryManager flashSaleInventoryManager, IDistributedCache distributedCache, IFlashSalePlanRepository flashSalePlanRepository, IProductAppService productAppService, - ILogger logger) + ILogger logger) { FlashSaleInventoryManager = flashSaleInventoryManager; DistributedCache = distributedCache; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index c0cd3732..424f9dc2 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -58,7 +58,7 @@ public class FlashSalePlanController : } [HttpPost("{id}/order")] - public virtual Task OrderAsync(Guid id, CreateOrderInput input) + public virtual Task OrderAsync(Guid id, CreateOrderInput input) { return Service.OrderAsync(id, input); } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs index ccdc05ea..59167758 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs @@ -140,7 +140,7 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase } [Fact] - public async Task CreateAsync_Should_Throw_Expcetion_When_Validate_Product_Failed() + public async Task CreateAsync_Should_Throw_Exception_When_Validate_Product_Failed() { var createDto = new FlashSalePlanCreateDto() { @@ -197,7 +197,7 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase } [Fact] - public async Task UpdateAsync_Should_Throw_Expcetion_When_Validate_Product_Failed() + public async Task UpdateAsync_Should_Throw_Exception_When_Validate_Product_Failed() { var createDto = new FlashSalePlanCreateDto() { @@ -230,7 +230,7 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase } [Fact] - public async Task UpdateAsync_Should_Throw_Expcetion_When_Has_Result_And_Change_Product() + public async Task UpdateAsync_Should_Throw_Exception_When_Has_Result_And_Change_Product() { var createDto = new FlashSalePlanCreateDto() { @@ -274,7 +274,7 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase } [Fact] - public async Task DeleteAsync_Should_Throw_Expcetion_When_Has_Result() + public async Task DeleteAsync_Should_Throw_Exception_When_Has_Result() { var createDto = new FlashSalePlanCreateDto() { @@ -362,10 +362,10 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase }; await AppService.PreOrderAsync(plan.Id); - var isSucess = await AppService.OrderAsync(plan.Id, createOrderInput); + var createOrderDto = await AppService.OrderAsync(plan.Id, createOrderInput); - isSucess.IsSuccess.ShouldBe(true); - isSucess.FlashSaleResultId.ShouldNotBeNull(); + createOrderDto.IsSuccess.ShouldBe(true); + createOrderDto.FlashSaleResultId.ShouldNotBeNull(); await DistributedEventBus.Received().PublishAsync(Arg.Is(eto => eto.TenantId == plan.TenantId && eto.StoreId == plan.StoreId && diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs similarity index 93% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs index 164faa82..e5de418b 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using EasyAbp.Eshop.Products.Products; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; @@ -13,17 +10,14 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using NSubstitute; using NSubstitute.ReceivedExtensions; using Shouldly; -using Volo.Abp; -using Volo.Abp.Caching; -using Volo.Abp.EventBus.Distributed; using Volo.Abp.Users; using Xunit; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest : FlashSalesApplicationTestBase +public class ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest : FlashSalesApplicationTestBase { - protected RollBackInventoryCreateFlashSaleOrderCompleteEventHandler EventHandler { get; } + protected ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler EventHandler { get; } protected IDistributedCache DistributedCache { get; } @@ -31,9 +25,9 @@ public class RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest : Fla private ProductDto Product1 { get; set; } - public RollBackInventoryCreateFlashSaleOrderCompleteEventHandlerTest() + public ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest() { - EventHandler = GetRequiredService(); + EventHandler = GetRequiredService(); DistributedCache = GetRequiredService(); FlashSaleInventoryManager = GetRequiredService(); } From 6cc239b8f286b9b095cb9ed32113cbd80e7de1b3 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 17 Jul 2022 12:41:41 +0800 Subject: [PATCH 41/97] `DefaultProductInventoryProvider` using `DistributedLock` --- .../EasyAbp.EShop.Products.Domain.csproj | 1 + .../DefaultProductInventoryProvider.cs | 41 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp.EShop.Products.Domain.csproj b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp.EShop.Products.Domain.csproj index 2dab26aa..663bb9c9 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp.EShop.Products.Domain.csproj +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp.EShop.Products.Domain.csproj @@ -8,6 +8,7 @@ + diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs index 613a434c..9f420ea2 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using EasyAbp.EShop.Products.ProductInventories; +using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; +using Volo.Abp.DistributedLocking; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; @@ -13,6 +15,14 @@ namespace EasyAbp.EShop.Products.Products { public class DefaultProductInventoryProvider : IProductInventoryProvider, ITransientDependency { + /// + /// The lock key format. + /// {0}: Tenant ID + /// {1}: Product ID + /// {2}: ProductSku ID + /// + public const string DefaultProductInventoryLockKeyFormat = "eshop-product-inventory-{0}-{1}-{2}"; + public static string DefaultProductInventoryProviderName { get; set; } = "Default"; public static string DefaultProductInventoryProviderDisplayName { get; set; } = "Default"; public static string DefaultProductInventoryProviderDescription { get; set; } = "Default"; @@ -24,17 +34,23 @@ namespace EasyAbp.EShop.Products.Products private readonly ICurrentTenant _currentTenant; private readonly IDistributedEventBus _distributedEventBus; private readonly IProductInventoryRepository _productInventoryRepository; + private readonly IAbpDistributedLock _distributedLock; + private readonly ILogger _logger; public DefaultProductInventoryProvider( IGuidGenerator guidGenerator, ICurrentTenant currentTenant, IDistributedEventBus distributedEventBus, - IProductInventoryRepository productInventoryRepository) + IProductInventoryRepository productInventoryRepository, + IAbpDistributedLock distributedLock, + ILogger logger) { _guidGenerator = guidGenerator; _currentTenant = currentTenant; _distributedEventBus = distributedEventBus; _productInventoryRepository = productInventoryRepository; + _distributedLock = distributedLock; + _logger = logger; } [UnitOfWork] @@ -62,6 +78,15 @@ namespace EasyAbp.EShop.Products.Products public virtual async Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, bool decreaseSold) { + await using var handle = await _distributedLock.TryAcquireAsync(await GetLockKeyAsync(model), TimeSpan.FromSeconds(30)); + + if (handle == null) + { + _logger.LogWarning("TryIncreaseInventory failed to acquire lock for product inventory: {TenantId},{ProductId},{ProductSkuId}", + model.TenantId, model.ProductId, model.ProductSkuId); + return false; + } + var productInventory = await GetOrCreateProductInventoryAsync(model.ProductId, model.ProductSkuId); return await TryIncreaseInventoryAsync(model, productInventory, quantity, decreaseSold); @@ -71,6 +96,15 @@ namespace EasyAbp.EShop.Products.Products public virtual async Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold) { + await using var handle = await _distributedLock.TryAcquireAsync(await GetLockKeyAsync(model), TimeSpan.FromSeconds(30)); + + if (handle == null) + { + _logger.LogWarning("TryReduceInventory failed to acquire lock for product inventory: {TenantId},{ProductId},{ProductSkuId}", + model.TenantId, model.ProductId, model.ProductSkuId); + return false; + } + var productInventory = await GetOrCreateProductInventoryAsync(model.ProductId, model.ProductSkuId); return await TryReduceInventoryAsync(model, productInventory, quantity, increaseSold); @@ -158,5 +192,10 @@ namespace EasyAbp.EShop.Products.Products newInventory, sold)); } + + protected virtual Task GetLockKeyAsync(InventoryQueryModel model) + { + return Task.FromResult(string.Format(DefaultProductInventoryLockKeyFormat, model.TenantId, model.ProductId, model.ProductSkuId)); + } } } \ No newline at end of file From a5a4a188a111ff971877241a951b5adf8d3fb3a8 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 17 Jul 2022 12:48:52 +0800 Subject: [PATCH 42/97] Update FlashSales docs --- docs/plugins/flash-sales/README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/plugins/flash-sales/README.md b/docs/plugins/flash-sales/README.md index f14a2d7e..7e970ea8 100644 --- a/docs/plugins/flash-sales/README.md +++ b/docs/plugins/flash-sales/README.md @@ -1,6 +1,8 @@ # EShop.Plugins.FlashSales [![ABP version](https://img.shields.io/badge/dynamic/xml?style=flat-square&color=yellow&label=abp&query=%2F%2FProject%2FPropertyGroup%2FAbpVersion&url=https%3A%2F%2Fraw.githubusercontent.com%2FEasyAbp%2FEShop%2Fmaster%2FDirectory.Build.props)](https://abp.io) +[![NuGet](https://img.shields.io/nuget/v/EasyAbp.EShop.Plugins.FlashSales.Domain.svg?style=flat-square)](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.FlashSales.Domain) +[![NuGet Download](https://img.shields.io/nuget/dt/EasyAbp.EShop.Plugins.FlashSales.Domain.svg?style=flat-square)](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.FlashSales.Domain) [![Discord online](https://badgen.net/discord/online-members/S6QaezrCRq?label=Discord)](https://discord.gg/S6QaezrCRq) [![GitHub stars](https://img.shields.io/github/stars/EasyAbp/EShop?style=social)](https://www.github.com/EasyAbp/EShop) @@ -21,10 +23,9 @@ A flash-sales plugin for EShop. * EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client * (Optional) EasyAbp.EShop.Plugins.FlashSales.MongoDB * (Optional) EasyAbp.EShop.Plugins.FlashSales.Web - * (Special Optional) EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts (install at EasyAbp.EShop.Products.Application.Contracts location) - * (SpecialOptional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi (install at EasyAbp.EShop.Products.HttpApi location) - * (Special Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client (install at EasyAbp.EShop.Products.HttpApi.Client location) - > When you do not open the dynamic API for the `EasyAbp.EShop.Products` module, these `Special Optional` modules must be installed. + * (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts (install at EasyAbp.EShop.Products.Application.Contracts location) + * (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi (install at EasyAbp.EShop.Products.HttpApi location) + * (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client (install at EasyAbp.EShop.Products.HttpApi.Client location) 2. Add `DependsOn(typeof(EShopXxxModule))` attribute to configure the module dependencies. ([see how](https://github.com/EasyAbp/EasyAbpGuide/blob/master/docs/How-To.md#add-module-dependencies)) @@ -40,8 +41,6 @@ A flash-sales plugin for EShop. ### Customers -1. Using `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/pre-order` (POST) to pre-order. It will return the expires time if the flash-sale plan is available. -2. Within the expires time, using `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/order` (POST) to request flash purchase order. -3. Using `/api/e-shop/plugins/flash-sales/flash-sale-result/{resultId}` (GET) to query the result. - - > Continuously pulled until the result is no longer `Pending`. If the status is `Successful`, the order will be included. If the status `Failed`, the reason will be included. +1. Use `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/pre-order` (POST) to pre-order. It will return an expiration time if your pre-order request succeeds. You should re-invoke this API to refresh your request before the expiration time. +2. When the flash sale starts, use `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/order` (POST) to create your order. If you are fast enough, it will occupy the inventory and create an order for you in the background. +3. If you are told that you have succeeded, continuous use `/api/e-shop/plugins/flash-sales/flash-sale-result/{resultId}` (GET) to query the order creation result until it succeeds or fails. From 592799b29bc6cec476529be096b3d171af31803b Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 17 Jul 2022 12:52:08 +0800 Subject: [PATCH 43/97] Rename to `FlashSaleOrderResultDto` --- ...eOrderResultDto.cs => FlashSaleOrderResultDto.cs} | 2 +- .../FlashSalePlans/IFlashSalePlanAppService.cs | 2 +- .../FlashSalePlans/FlashSalePlanAppService.cs | 6 +++--- .../FlashSalePlans/FlashSalePlanController.cs | 2 +- .../FlashSalePlans/FlashSalePlanAppServiceTests.cs | 12 ++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/{CreateOrderResultDto.cs => FlashSaleOrderResultDto.cs} (78%) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderResultDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSaleOrderResultDto.cs similarity index 78% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderResultDto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSaleOrderResultDto.cs index 418e04af..adeec222 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/CreateOrderResultDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/FlashSaleOrderResultDto.cs @@ -3,7 +3,7 @@ using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; -public class CreateOrderResultDto : ExtensibleEntityDto +public class FlashSaleOrderResultDto : ExtensibleEntityDto { public bool IsSuccess { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs index d98fe61f..24cdd447 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/IFlashSalePlanAppService.cs @@ -15,5 +15,5 @@ public interface IFlashSalePlanAppService : { Task PreOrderAsync(Guid id); - Task OrderAsync(Guid id, CreateOrderInput input); + Task OrderAsync(Guid id, CreateOrderInput input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 056b2edf..4bc20ffb 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -216,7 +216,7 @@ public class FlashSalePlanAppService : return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), ExpiresInSeconds = Options.PreOrderExpires.TotalSeconds }; } - public virtual async Task OrderAsync(Guid id, CreateOrderInput input) + public virtual async Task OrderAsync(Guid id, CreateOrderInput input) { var preOrderCache = await GetPreOrderCacheAsync(id); if (preOrderCache == null) @@ -259,7 +259,7 @@ public class FlashSalePlanAppService : plan.TenantId, preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) { - return new CreateOrderResultDto() { IsSuccess = false }; + return new FlashSaleOrderResultDto() { IsSuccess = false }; } var result = await CreatePendingFlashSaleResultAsync(plan, userId, async (existsResultId) => @@ -278,7 +278,7 @@ public class FlashSalePlanAppService : await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); - return new CreateOrderResultDto() { IsSuccess = true, FlashSaleResultId = result.Id }; + return new FlashSaleOrderResultDto() { IsSuccess = true, FlashSaleResultId = result.Id }; } #region PreOrderCache diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index 424f9dc2..bd18e94e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -58,7 +58,7 @@ public class FlashSalePlanController : } [HttpPost("{id}/order")] - public virtual Task OrderAsync(Guid id, CreateOrderInput input) + public virtual Task OrderAsync(Guid id, CreateOrderInput input) { return Service.OrderAsync(id, input); } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs index 59167758..844fe01c 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs @@ -362,10 +362,10 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase }; await AppService.PreOrderAsync(plan.Id); - var createOrderDto = await AppService.OrderAsync(plan.Id, createOrderInput); + var result = await AppService.OrderAsync(plan.Id, createOrderInput); - createOrderDto.IsSuccess.ShouldBe(true); - createOrderDto.FlashSaleResultId.ShouldNotBeNull(); + result.IsSuccess.ShouldBe(true); + result.FlashSaleResultId.ShouldNotBeNull(); await DistributedEventBus.Received().PublishAsync(Arg.Is(eto => eto.TenantId == plan.TenantId && eto.StoreId == plan.StoreId && @@ -464,9 +464,9 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase FakeFlashSaleInventoryManager.ShouldReduceSuccess = false; - var createOrderDto = await AppService.OrderAsync(plan.Id, createOrderInput); - createOrderDto.IsSuccess.ShouldBe(false); - createOrderDto.FlashSaleResultId.ShouldBeNull(); + var result = await AppService.OrderAsync(plan.Id, createOrderInput); + result.IsSuccess.ShouldBe(false); + result.FlashSaleResultId.ShouldBeNull(); } [Fact] From 11c6578ca9c58c1364b5263239087fec60950509 Mon Sep 17 00:00:00 2001 From: Super Date: Tue, 19 Jul 2022 02:26:28 +0800 Subject: [PATCH 44/97] Update README.md --- docs/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 56cb754c..86ee886d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -80,7 +80,7 @@ We have launched an online demo for this module: [https://eshop.samples.easyabp. ## Advanced Usages -We can customize some features to use EShop in complex application scenarios. +We can customize the EShop for complex application scenarios. ### Gift Card Shop @@ -89,8 +89,8 @@ We can customize some features to use EShop in complex application scenarios. * Read the article to learn how to implement it. (todo) ### Paid Knowledge Market -* Also use the [EasyAbp.SharedResources](https://easyabp.io/modules/SharedResources/) module. -* The carrier of knowledge can be articles, pictures, audios, videos, files, streams, etc. +* Install the [EasyAbp.SharedResources](https://easyabp.io/modules/SharedResources/) module. +* The carrier of knowledge can be articles, pictures, audio, videos, files, streams, etc. * When a knowledge order is paid, automatically authorize the customer to access the resources he purchased. * Read the article to learn how to implement it. (todo) From a3cba8f24ef4698311a036b4adf1ad0545028097 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Tue, 19 Jul 2022 09:05:38 +0800 Subject: [PATCH 45/97] Rename to `CreateFlashSaleOrderFailedEventHandler` --- ...ndler.cs => CreateFlashSaleOrderFailedEventHandler.cs} | 8 ++++---- ...t.cs => CreateFlashSaleOrderFailedEventHandlerTest.cs} | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/{ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs => CreateFlashSaleOrderFailedEventHandler.cs} (85%) rename plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/{ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs => CreateFlashSaleOrderFailedEventHandlerTest.cs} (95%) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandler.cs similarity index 85% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandler.cs index 7068b989..7e5f7d89 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandler.cs @@ -10,20 +10,20 @@ using Volo.Abp.EventBus.Distributed; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public class ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency +public class CreateFlashSaleOrderFailedEventHandler : IDistributedEventHandler, ITransientDependency { protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } protected IDistributedCache DistributedCache { get; } protected IFlashSalePlanRepository FlashSalePlanRepository { get; } protected IProductAppService ProductAppService { get; } - protected ILogger Logger { get; } + protected ILogger Logger { get; } - public ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler( + public CreateFlashSaleOrderFailedEventHandler ( IFlashSaleInventoryManager flashSaleInventoryManager, IDistributedCache distributedCache, IFlashSalePlanRepository flashSalePlanRepository, IProductAppService productAppService, - ILogger logger) + ILogger logger) { FlashSaleInventoryManager = flashSaleInventoryManager; DistributedCache = distributedCache; diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandlerTest.cs similarity index 95% rename from plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs rename to plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandlerTest.cs index e5de418b..41e2981f 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandlerTest.cs @@ -15,9 +15,9 @@ using Xunit; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public class ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest : FlashSalesApplicationTestBase +public class CreateFlashSaleOrderFailedEventHandlerTest : FlashSalesApplicationTestBase { - protected ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandler EventHandler { get; } + protected CreateFlashSaleOrderFailedEventHandler EventHandler { get; } protected IDistributedCache DistributedCache { get; } @@ -25,9 +25,9 @@ public class ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest private ProductDto Product1 { get; set; } - public ProcessInvalidHashTokenCreateFlashSaleOrderCompleteEventHandlerTest() + public CreateFlashSaleOrderFailedEventHandlerTest() { - EventHandler = GetRequiredService(); + EventHandler = GetRequiredService(); DistributedCache = GetRequiredService(); FlashSaleInventoryManager = GetRequiredService(); } From b567aab3ded4f2ea5b6f6e23f6a833564396a975 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Tue, 19 Jul 2022 09:05:57 +0800 Subject: [PATCH 46/97] Update FlashSales docs --- docs/plugins/flash-sales/README.md | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/plugins/flash-sales/README.md b/docs/plugins/flash-sales/README.md index 7e970ea8..f29c46e7 100644 --- a/docs/plugins/flash-sales/README.md +++ b/docs/plugins/flash-sales/README.md @@ -1,8 +1,8 @@ # EShop.Plugins.FlashSales [![ABP version](https://img.shields.io/badge/dynamic/xml?style=flat-square&color=yellow&label=abp&query=%2F%2FProject%2FPropertyGroup%2FAbpVersion&url=https%3A%2F%2Fraw.githubusercontent.com%2FEasyAbp%2FEShop%2Fmaster%2FDirectory.Build.props)](https://abp.io) -[![NuGet](https://img.shields.io/nuget/v/EasyAbp.EShop.Plugins.FlashSales.Domain.svg?style=flat-square)](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.FlashSales.Domain) -[![NuGet Download](https://img.shields.io/nuget/dt/EasyAbp.EShop.Plugins.FlashSales.Domain.svg?style=flat-square)](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.FlashSales.Domain) +[![NuGet](https://img.shields.io/nuget/v/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.svg?style=flat-square)](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared) +[![NuGet Download](https://img.shields.io/nuget/dt/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared.svg?style=flat-square)](https://www.nuget.org/packages/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared) [![Discord online](https://badgen.net/discord/online-members/S6QaezrCRq?label=Discord)](https://discord.gg/S6QaezrCRq) [![GitHub stars](https://img.shields.io/github/stars/EasyAbp/EShop?style=social)](https://www.github.com/EasyAbp/EShop) @@ -12,20 +12,20 @@ A flash-sales plugin for EShop. 1. Install the following NuGet packages. ([see how](https://github.com/EasyAbp/EasyAbpGuide/blob/master/docs/How-To.md#add-nuget-packages)) - * EasyAbp.EShop.Orders.Plugins.FlashSales.Application (install at EasyAbp.EShop.Orders.Application location) - * EasyAbp.EShop.Products.Plugins.FlashSales.Application (install at EasyAbp.EShop.Products.Application location) - * EasyAbp.EShop.Plugins.FlashSales.Application - * EasyAbp.EShop.Plugins.FlashSales.Application.Contracts - * EasyAbp.EShop.Plugins.FlashSales.Domain - * EasyAbp.EShop.Plugins.FlashSales.Domain.Shared - * EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore - * EasyAbp.EShop.Plugins.FlashSales.HttpApi - * EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client - * (Optional) EasyAbp.EShop.Plugins.FlashSales.MongoDB - * (Optional) EasyAbp.EShop.Plugins.FlashSales.Web - * (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts (install at EasyAbp.EShop.Products.Application.Contracts location) - * (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi (install at EasyAbp.EShop.Products.HttpApi location) - * (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client (install at EasyAbp.EShop.Products.HttpApi.Client location) + - EasyAbp.EShop.Orders.Plugins.FlashSales.Application (install at EasyAbp.EShop.Orders.Application location) + - EasyAbp.EShop.Products.Plugins.FlashSales.Application (install at EasyAbp.EShop.Products.Application location) + - EasyAbp.EShop.Plugins.FlashSales.Application + - EasyAbp.EShop.Plugins.FlashSales.Application.Contracts + - EasyAbp.EShop.Plugins.FlashSales.Domain + - EasyAbp.EShop.Plugins.FlashSales.Domain.Shared + - EasyAbp.EShop.Plugins.FlashSales.EntityFrameworkCore + - EasyAbp.EShop.Plugins.FlashSales.HttpApi + - EasyAbp.EShop.Plugins.FlashSales.HttpApi.Client + - (Optional) EasyAbp.EShop.Plugins.FlashSales.MongoDB + - (Optional) EasyAbp.EShop.Plugins.FlashSales.Web + - (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.Application.Contracts (install at EasyAbp.EShop.Products.Application.Contracts location) + - (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi (install at EasyAbp.EShop.Products.HttpApi location) + - (Optional) EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client (install at EasyAbp.EShop.Products.HttpApi.Client location) 2. Add `DependsOn(typeof(EShopXxxModule))` attribute to configure the module dependencies. ([see how](https://github.com/EasyAbp/EasyAbpGuide/blob/master/docs/How-To.md#add-module-dependencies)) From 34890c53a662b909da4e2d6dadf452a5412fe1f1 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Tue, 19 Jul 2022 13:41:03 +0800 Subject: [PATCH 47/97] Upgrade PaymentService module to v2.0.15 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 8ebd2c05..ceee74a6 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,7 +3,7 @@ 5.3.1 2.7.1 - 2.0.14 + 2.0.15 1.0.1 0.1.0 1.7.0 From 6f233213d50f7f2b3774e16a889c55914fb1526c Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Tue, 19 Jul 2022 13:41:37 +0800 Subject: [PATCH 48/97] Change version to 3.0.0-preview.3 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 9ea44847..3e437d9e 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.2 + 3.0.0-preview.3 $(NoWarn);CS1591 true EasyAbp Team From c003ef4a3d4979cae1197fbae4b2f7b4c786d60d Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 20 Jul 2022 17:21:32 +0800 Subject: [PATCH 49/97] Fix a validation bug in `CreateUpdateProductDto` Resolve #192 --- .../Products/Dtos/CreateUpdateProductDto.cs | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductDto.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductDto.cs index 6301fa24..0f88780f 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductDto.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/CreateUpdateProductDto.cs @@ -13,23 +13,23 @@ namespace EasyAbp.EShop.Products.Products.Dtos { [DisplayName("ProductStoreId")] public Guid StoreId { get; set; } - + [DisplayName("ProductProductGroupName")] public string ProductGroupName { get; set; } - + [DisplayName("ProductDetailId")] public Guid? ProductDetailId { get; set; } [DisplayName("ProductCategory")] public ICollection CategoryIds { get; set; } - + [DisplayName("ProductUniqueName")] public string UniqueName { get; set; } - + [Required] [DisplayName("ProductDisplayName")] public string DisplayName { get; set; } - + public ICollection ProductAttributes { get; set; } [DisplayName("ProductInventoryStrategy")] @@ -46,10 +46,10 @@ namespace EasyAbp.EShop.Products.Products.Dtos [DisplayName("ProductIsPublished")] public bool IsPublished { get; set; } - + [DisplayName("ProductIsHidden")] public bool IsHidden { get; set; } - + [DisplayName("ProductPaymentExpireIn")] public TimeSpan? PaymentExpireIn { get; set; } @@ -64,7 +64,7 @@ namespace EasyAbp.EShop.Products.Products.Dtos new[] { "PaymentExpireIn" } ); } - + if (ProductAttributes.Select(a => a.DisplayName.Trim()).Distinct().Count() != ProductAttributes.Count) { yield return new ValidationResult( @@ -73,15 +73,17 @@ namespace EasyAbp.EShop.Products.Products.Dtos ); } - var optionNameList = ProductAttributes.SelectMany(a => a.ProductAttributeOptions) - .Select(o => o.DisplayName.Trim()).ToList(); - - if (optionNameList.Distinct().Count() != optionNameList.Count) + foreach (var productAttribute in ProductAttributes) { - yield return new ValidationResult( - "DisplayNames of ProductAttributeOptions should be unique!", - new[] { "ProductAttributeOptions" } - ); + var options = productAttribute.ProductAttributeOptions; + + if (options.Select(o => o.DisplayName.Trim()).Distinct().Count() != options.Count) + { + yield return new ValidationResult( + "DisplayNames of ProductAttributeOptions should be unique!", + new[] { "ProductAttributeOptions" } + ); + } } } } From 091856f69916c219bcdc621969f5d175cbca973c Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 24 Jul 2022 15:25:23 +0800 Subject: [PATCH 50/97] Add FlashSales link in README.md --- docs/README.md | 1 + plugins/FlashSales/README.md | 1 + 2 files changed, 2 insertions(+) create mode 120000 plugins/FlashSales/README.md diff --git a/docs/README.md b/docs/README.md index 86ee886d..5a7805ed 100644 --- a/docs/README.md +++ b/docs/README.md @@ -109,6 +109,7 @@ We can customize the EShop for complex application scenarios. * Inventories * [DaprActors](https://github.com/EasyAbp/EShop/tree/dev/plugins/Inventories/DaprActors) * [OrleansGrains](https://github.com/EasyAbp/EShop/tree/dev/plugins/Inventories/OrleansGrains) + * [FlashSales](https://github.com/EasyAbp/EShop/tree/dev/plugins/FlashSales) * [Booking](https://github.com/EasyAbp/EShop/tree/dev/plugins/Booking) ## Roadmap diff --git a/plugins/FlashSales/README.md b/plugins/FlashSales/README.md new file mode 120000 index 00000000..5cd476be --- /dev/null +++ b/plugins/FlashSales/README.md @@ -0,0 +1 @@ +../../docs/plugins/flash-sales/README.md \ No newline at end of file From 45948df5b64eed5049a01fd8130f6aabe86817ff Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 24 Jul 2022 15:40:05 +0800 Subject: [PATCH 51/97] Downgrade the flash sale http client module to `netstandard2.0` --- ...yAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj index ef715f1d..860bfdaa 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client/EasyAbp.EShop.Products.Plugins.FlashSales.HttpApi.Client.csproj @@ -3,7 +3,7 @@ - netstandard2.1 + netstandard2.0 From 6469f9c0773cc3f22cc0a196262072a405b46242 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sat, 30 Jul 2022 15:09:25 +0800 Subject: [PATCH 52/97] Install BookingService module in the sample app --- Directory.Build.props | 2 +- .../EShopSample.Application.Contracts.csproj | 1 + .../EShopSampleApplicationContractsModule.cs | 6 +- .../EShopSample.Application.csproj | 1 + .../EShopSampleApplicationModule.cs | 6 +- .../EShopSample.Domain.Shared.csproj | 1 + .../EShopSampleDomainSharedModule.cs | 6 +- .../EShopSample.Domain.csproj | 1 + .../EShopSampleDomainModule.cs | 6 +- .../EShopSample.EntityFrameworkCore.csproj | 1 + .../EShopSampleDbContext.cs | 4 +- .../EShopSampleEntityFrameworkCoreModule.cs | 6 +- ..._InstalledBookingServiceModule.Designer.cs | 6165 +++++++++++++++++ ...729153358_InstalledBookingServiceModule.cs | 299 + .../EShopSampleDbContextModelSnapshot.cs | 583 +- .../EShopSample.HttpApi.Client.csproj | 1 + .../EShopSampleHttpApiClientModule.cs | 6 +- .../EShopSample.HttpApi.csproj | 1 + .../EShopSampleHttpApiModule.cs | 6 +- .../EShopSample.Web/EShopSample.Web.csproj | 1 + .../EShopSample.Web/EShopSampleWebModule.cs | 4 +- 21 files changed, 7088 insertions(+), 19 deletions(-) create mode 100644 samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.Designer.cs create mode 100644 samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.cs diff --git a/Directory.Build.props b/Directory.Build.props index ceee74a6..089ab547 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,7 +5,7 @@ 2.7.1 2.0.15 1.0.1 - 0.1.0 + 0.1.1 1.7.0 3.6.2 1.0.5 diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj index 7c4bd05c..d947e429 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSample.Application.Contracts.csproj @@ -21,6 +21,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs index 2d6f4ff4..973038f4 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application.Contracts/EShopSampleApplicationContractsModule.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop; +using EasyAbp.BookingService; +using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Booking; using EasyAbp.EShop.Plugins.Coupons; @@ -33,7 +34,8 @@ namespace EShopSample typeof(EShopProductsPluginsFlashSalesApplicationContractsModule), typeof(PaymentServiceApplicationContractsModule), typeof(PaymentServiceWeChatPayApplicationContractsModule), - typeof(PaymentServicePrepaymentApplicationContractsModule) + typeof(PaymentServicePrepaymentApplicationContractsModule), + typeof(BookingServiceApplicationContractsModule) )] public class EShopSampleApplicationContractsModule : AbpModule { diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj index 567ce31c..4c8eecdd 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSample.Application.csproj @@ -24,6 +24,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs index c731c151..76d72423 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Application/EShopSampleApplicationModule.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop; +using EasyAbp.BookingService; +using EasyAbp.EShop; using EasyAbp.EShop.Orders.Plugins.Coupons; using EasyAbp.EShop.Orders.Plugins.FlashSales; using EasyAbp.EShop.Plugins.Baskets; @@ -37,7 +38,8 @@ namespace EShopSample typeof(EShopProductsPluginsFlashSalesApplicationModule), typeof(PaymentServiceApplicationModule), typeof(PaymentServiceWeChatPayApplicationModule), - typeof(PaymentServicePrepaymentApplicationModule) + typeof(PaymentServicePrepaymentApplicationModule), + typeof(BookingServiceApplicationModule) )] public class EShopSampleApplicationModule : AbpModule { diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj index 765700ae..fc7479f7 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSample.Domain.Shared.csproj @@ -12,6 +12,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs index b5deb325..33840764 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain.Shared/EShopSampleDomainSharedModule.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop; +using EasyAbp.BookingService; +using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Booking; using EasyAbp.EShop.Plugins.Coupons; @@ -38,7 +39,8 @@ namespace EShopSample typeof(EShopPluginsFlashSalesDomainSharedModule), typeof(PaymentServiceDomainSharedModule), typeof(PaymentServiceWeChatPayDomainSharedModule), - typeof(PaymentServicePrepaymentDomainSharedModule) + typeof(PaymentServicePrepaymentDomainSharedModule), + typeof(BookingServiceDomainSharedModule) )] public class EShopSampleDomainSharedModule : AbpModule { diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj index 7d3f9600..99617963 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSample.Domain.csproj @@ -20,6 +20,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs index 0ece9d9c..8f5bab64 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Domain/EShopSampleDomainModule.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop; +using EasyAbp.BookingService; +using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Booking; using EasyAbp.EShop.Plugins.Coupons; @@ -46,7 +47,8 @@ namespace EShopSample typeof(EShopPluginsFlashSalesDomainModule), typeof(PaymentServiceDomainModule), typeof(PaymentServiceWeChatPayDomainModule), - typeof(PaymentServicePrepaymentDomainModule) + typeof(PaymentServicePrepaymentDomainModule), + typeof(BookingServiceDomainModule) )] public class EShopSampleDomainModule : AbpModule { diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj index 391ab2be..161e7465 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EShopSample.EntityFrameworkCore.csproj @@ -17,6 +17,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs index 53fbd9a9..7afda756 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleDbContext.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop.EntityFrameworkCore; +using EasyAbp.BookingService.EntityFrameworkCore; +using EasyAbp.EShop.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore; @@ -88,6 +89,7 @@ namespace EShopSample.EntityFrameworkCore builder.ConfigurePaymentService(); builder.ConfigurePaymentServiceWeChatPay(); builder.ConfigurePaymentServicePrepayment(); + builder.ConfigureBookingService(); /* Configure your own tables/entities inside here */ } diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs index 3f9262a9..eea9ddaa 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/EntityFrameworkCore/EShopSampleEntityFrameworkCoreModule.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop.EntityFrameworkCore; +using EasyAbp.BookingService.EntityFrameworkCore; +using EasyAbp.EShop.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Coupons.EntityFrameworkCore; @@ -39,7 +40,8 @@ namespace EShopSample.EntityFrameworkCore typeof(EShopPluginsFlashSalesEntityFrameworkCoreModule), typeof(PaymentServiceEntityFrameworkCoreModule), typeof(PaymentServiceWeChatPayEntityFrameworkCoreModule), - typeof(PaymentServicePrepaymentEntityFrameworkCoreModule) + typeof(PaymentServicePrepaymentEntityFrameworkCoreModule), + typeof(BookingServiceEntityFrameworkCoreModule) )] public class EShopSampleEntityFrameworkCoreModule : AbpModule { diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.Designer.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.Designer.cs new file mode 100644 index 00000000..940177fc --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.Designer.cs @@ -0,0 +1,6165 @@ +// +using System; +using EShopSample.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace EShopSample.Migrations +{ + [DbContext(typeof(EShopSampleDbContext))] + [Migration("20220729153358_InstalledBookingServiceModule")] + partial class InstalledBookingServiceModule + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpBookingServiceAssetCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancies.AssetOccupancy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OccupierName") + .HasColumnType("nvarchar(max)"); + + b.Property("OccupierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("Date", "OccupierUserId"); + + b.HasIndex("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancies", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancyCounts.AssetOccupancyCount", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancyCounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetPeriodSchemes.AssetPeriodScheme", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Date", "AssetId"); + + b.ToTable("EasyAbpBookingServiceAssetPeriodSchemes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServiceAssets", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodUsable") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Date", "AssetId", "PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServiceAssetSchedules", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.HasKey("Id"); + + b.HasIndex("PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServicePeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServicePeriodSchemes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CancellationReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderNumber") + .HasColumnType("nvarchar(450)"); + + b.Property("OrderStatus") + .HasColumnType("int"); + + b.Property("PaidTime") + .HasColumnType("datetime2"); + + b.Property("PaymentExpiration") + .HasColumnType("datetime2"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("ReducedInventoryAfterPaymentTime") + .HasColumnType("datetime2"); + + b.Property("ReducedInventoryAfterPlacingTime") + .HasColumnType("datetime2"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderNumber") + .IsUnique() + .HasFilter("[OrderNumber] IS NOT NULL"); + + b.ToTable("EasyAbpEShopOrdersOrders", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Key") + .HasColumnType("nvarchar(450)"); + + b.Property("Fee") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("OrderId", "Name", "Key"); + + b.ToTable("EasyAbpEShopOrdersOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("EasyAbpEShopOrdersOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsPayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpEShopPaymentsPaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("OrderLineId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.BasketItems.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BasketName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsInvalid") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpEShopPluginsBasketsBasketItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.ProductUpdates.ProductUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopPluginsBasketsProductUpdates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.GrantedStores.GrantedStore", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowAll") + .HasColumnType("bit"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingGrantedStores", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FromTime") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("ToTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategoryPeriod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductAssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAssetCategoryId"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetCategoryPeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FromTime") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("ToTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssets", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAssetPeriod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductAssetId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAssetId"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetPeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.Coupons.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DiscountedAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("ExpirationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UsedTime") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCoupons", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConditionAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CouponType") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscountAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsUnscoped") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("UsableBeginTime") + .HasColumnType("datetime2"); + + b.Property("UsableDuration") + .HasColumnType("time"); + + b.Property("UsableEndTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CouponTemplateId"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplateScopes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BeginTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSalePlans", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PlanId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSaleResults", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpEShopProductsCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductCategories.ProductCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetailHistories.ProductDetailHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductDetailId"); + + b.ToTable("EasyAbpEShopProductsProductDetailHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetails.ProductDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductDetails", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductHistories.ProductHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductInventories.ProductInventory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopProductsProductInventories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProducts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductAttributes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductAttributeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAttributeId"); + + b.ToTable("EasyAbpEShopProductsProductAttributeOptions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderMaxQuantity") + .HasColumnType("int"); + + b.Property("OrderMinQuantity") + .HasColumnType("int"); + + b.Property("OriginalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedAttributeOptionIds") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductSkus", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductView", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("MaximumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("MinimumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProductViews", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.StoreOwners.StoreOwner", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OwnerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("OwnerUserId", "StoreId") + .IsUnique(); + + b.ToTable("EasyAbpEShopStoresStoreOwners", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Stores.Store", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresStores", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServicePaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Accounts.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Balance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingTopUpPaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingWithdrawalAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingWithdrawalRecordId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentAccounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OriginalBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("AccountUserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRecords.WithdrawalRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("CancellationTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ResultErrorCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ResultErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("WithdrawalMethod") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRequests.WithdrawalRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsApproved") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ReviewTime") + .HasColumnType("datetime2"); + + b.Property("ReviewerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRequests", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServiceRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpPaymentServiceRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.PaymentRecords.PaymentRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("Attach") + .HasColumnType("nvarchar(max)"); + + b.Property("BankType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponCount") + .HasColumnType("int"); + + b.Property("CouponFee") + .HasColumnType("int"); + + b.Property("CouponFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeviceInfo") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCodeDes") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("IsSubscribe") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("Openid") + .HasColumnType("nvarchar(max)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ResultCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TimeEnd") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TradeType") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayPaymentRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.RefundRecords.RefundRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashRefundFee") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponRefundCount") + .HasColumnType("int"); + + b.Property("CouponRefundFee") + .HasColumnType("int"); + + b.Property("CouponRefundFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("OutRefundNo") + .HasColumnType("nvarchar(450)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundFee") + .HasColumnType("int"); + + b.Property("RefundId") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRecvAccout") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRequestSource") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundStatus") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementRefundFee") + .HasColumnType("int"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("SuccessTime") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("OutRefundNo"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayRefundRecords", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasColumnType("nvarchar(max)"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorTenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ImpersonatorTenantName"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("ImpersonatorUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ImpersonatorUserName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("TenantName"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsAbandoned") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("JobArgs") + .IsRequired() + .HasMaxLength(1048576) + .HasColumnType("nvarchar(max)"); + + b.Property("JobName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("LastTryTime") + .HasColumnType("datetime2"); + + b.Property("NextTryTime") + .HasColumnType("datetime2"); + + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint") + .HasDefaultValue((byte)15); + + b.Property("TryCount") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasDefaultValue((short)0); + + b.HasKey("Id"); + + b.HasIndex("IsAbandoned", "NextTryTime"); + + b.ToTable("AbpBackgroundJobs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpFeatureValues", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowedAccessTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Type"); + + b.ToTable("IdentityServerApiResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiResourceId", "Key", "Value"); + + b.ToTable("IdentityServerApiResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Scope"); + + b.ToTable("IdentityServerApiResourceScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ApiResourceId", "Type", "Value"); + + b.ToTable("IdentityServerApiResourceSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiScopeId", "Type"); + + b.ToTable("IdentityServerApiScopeClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiScopeId", "Key", "Value"); + + b.ToTable("IdentityServerApiScopeProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("bit"); + + b.Property("AllowOfflineAccess") + .HasColumnType("bit"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("bit"); + + b.Property("AllowRememberConsent") + .HasColumnType("bit"); + + b.Property("AllowedIdentityTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("bit"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("bit"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("BackChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ClientClaimsPrefix") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LogoUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("PairWiseSubjectSalt") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProtocolType") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("bit"); + + b.Property("RequireConsent") + .HasColumnType("bit"); + + b.Property("RequirePkce") + .HasColumnType("bit"); + + b.Property("RequireRequestObject") + .HasColumnType("bit"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("bit"); + + b.Property("UserCodeType") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("IdentityServerClients", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Origin") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.HasKey("ClientId", "Origin"); + + b.ToTable("IdentityServerClientCorsOrigins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("GrantType") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "GrantType"); + + b.ToTable("IdentityServerClientGrantTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Provider") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Provider"); + + b.ToTable("IdentityServerClientIdPRestrictions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("PostLogoutRedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "PostLogoutRedirectUri"); + + b.ToTable("IdentityServerClientPostLogoutRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "Key", "Value"); + + b.ToTable("IdentityServerClientProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("RedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "RedirectUri"); + + b.ToTable("IdentityServerClientRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Scope"); + + b.ToTable("IdentityServerClientScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Devices.DeviceFlowCodes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("DeviceCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UserCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.HasIndex("UserCode"); + + b.ToTable("IdentityServerDeviceFlowCodes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Grants.PersistedGrant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsumedTime") + .HasColumnType("datetime2"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.HasIndex("SubjectId", "SessionId", "Type"); + + b.ToTable("IdentityServerPersistedGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerIdentityResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("IdentityResourceId", "Type"); + + b.ToTable("IdentityServerIdentityResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("IdentityResourceId", "Key", "Value"); + + b.ToTable("IdentityServerIdentityResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[TenantId] IS NOT NULL"); + + b.ToTable("AbpPermissionGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpSettings", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.HasOne("EasyAbp.BookingService.AssetCategories.AssetCategory", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetCategoryId"); + + b1.ToTable("EasyAbpBookingServiceAssetCategories"); + + b1.WithOwner() + .HasForeignKey("AssetCategoryId"); + }); + + b.Navigation("Parent"); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetId"); + + b1.ToTable("EasyAbpBookingServiceAssets"); + + b1.WithOwner() + .HasForeignKey("AssetId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetScheduleId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetScheduleId"); + + b1.ToTable("EasyAbpBookingServiceAssetSchedules"); + + b1.WithOwner() + .HasForeignKey("AssetScheduleId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.HasOne("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", null) + .WithMany("Periods") + .HasForeignKey("PeriodSchemeId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderExtraFees") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderLines") + .HasForeignKey("OrderId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderExtraFees") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderLines") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategoryPeriod", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", null) + .WithMany("Periods") + .HasForeignKey("ProductAssetCategoryId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAssetPeriod", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", null) + .WithMany("Periods") + .HasForeignKey("ProductAssetId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", null) + .WithMany("Scopes") + .HasForeignKey("CouponTemplateId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.HasOne("EasyAbp.EShop.Products.Categories.Category", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductAttributes") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.ProductAttribute", null) + .WithMany("ProductAttributeOptions") + .HasForeignKey("ProductAttributeId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductSkus") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.PaymentService.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.PaymentService.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("Properties") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Navigation("Scopes"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Navigation("ProductAttributes"); + + b.Navigation("ProductSkus"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Navigation("ProductAttributeOptions"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Navigation("Properties"); + + b.Navigation("Scopes"); + + b.Navigation("Secrets"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Navigation("AllowedCorsOrigins"); + + b.Navigation("AllowedGrantTypes"); + + b.Navigation("AllowedScopes"); + + b.Navigation("Claims"); + + b.Navigation("ClientSecrets"); + + b.Navigation("IdentityProviderRestrictions"); + + b.Navigation("PostLogoutRedirectUris"); + + b.Navigation("Properties"); + + b.Navigation("RedirectUris"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.cs new file mode 100644 index 00000000..1aa04d79 --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220729153358_InstalledBookingServiceModule.cs @@ -0,0 +1,299 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EShopSample.Migrations +{ + public partial class InstalledBookingServiceModule : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "OutRefundNo", + table: "EasyAbpPaymentServiceWeChatPayRefundRecords", + type: "nvarchar(450)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServiceAssetCategories", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + AssetDefinitionName = table.Column(type: "nvarchar(max)", nullable: true), + PeriodSchemeId = table.Column(type: "uniqueidentifier", nullable: true), + DefaultPeriodUsable = table.Column(type: "int", nullable: true), + TimeInAdvance_MaxDaysInAdvance = table.Column(type: "int", nullable: true), + TimeInAdvance_MaxTimespanInAdvance = table.Column(type: "time", nullable: true), + TimeInAdvance_MinDaysInAdvance = table.Column(type: "int", nullable: true), + TimeInAdvance_MinTimespanInAdvance = table.Column(type: "time", nullable: true), + Disabled = table.Column(type: "bit", nullable: false), + Code = table.Column(type: "nvarchar(max)", nullable: true), + Level = table.Column(type: "int", nullable: false), + ParentId = table.Column(type: "uniqueidentifier", nullable: true), + DisplayName = table.Column(type: "nvarchar(max)", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServiceAssetCategories", x => x.Id); + table.ForeignKey( + name: "FK_EasyAbpBookingServiceAssetCategories_EasyAbpBookingServiceAssetCategories_ParentId", + column: x => x.ParentId, + principalTable: "EasyAbpBookingServiceAssetCategories", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServiceAssetOccupancies", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + AssetId = table.Column(type: "uniqueidentifier", nullable: false), + Asset = table.Column(type: "nvarchar(max)", nullable: true), + AssetDefinitionName = table.Column(type: "nvarchar(max)", nullable: true), + Volume = table.Column(type: "int", nullable: false), + Date = table.Column(type: "datetime2", nullable: false), + StartingTime = table.Column(type: "time", nullable: false), + Duration = table.Column(type: "time", nullable: false), + OccupierUserId = table.Column(type: "uniqueidentifier", nullable: true), + OccupierName = table.Column(type: "nvarchar(max)", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServiceAssetOccupancies", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServiceAssetOccupancyCounts", + columns: table => new + { + AssetId = table.Column(type: "uniqueidentifier", nullable: false), + Date = table.Column(type: "datetime2", nullable: false), + StartingTime = table.Column(type: "time", nullable: false), + Duration = table.Column(type: "time", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Asset = table.Column(type: "nvarchar(max)", nullable: true), + Volume = table.Column(type: "int", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServiceAssetOccupancyCounts", x => new { x.Date, x.AssetId, x.StartingTime, x.Duration }); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServiceAssetPeriodSchemes", + columns: table => new + { + AssetId = table.Column(type: "uniqueidentifier", nullable: false), + Date = table.Column(type: "datetime2", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + PeriodSchemeId = table.Column(type: "uniqueidentifier", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServiceAssetPeriodSchemes", x => new { x.Date, x.AssetId }); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServiceAssets", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(max)", nullable: true), + AssetDefinitionName = table.Column(type: "nvarchar(max)", nullable: true), + AssetCategoryId = table.Column(type: "uniqueidentifier", nullable: false), + PeriodSchemeId = table.Column(type: "uniqueidentifier", nullable: true), + DefaultPeriodUsable = table.Column(type: "int", nullable: true), + Volume = table.Column(type: "int", nullable: false), + Priority = table.Column(type: "int", nullable: false), + TimeInAdvance_MaxDaysInAdvance = table.Column(type: "int", nullable: true), + TimeInAdvance_MaxTimespanInAdvance = table.Column(type: "time", nullable: true), + TimeInAdvance_MinDaysInAdvance = table.Column(type: "int", nullable: true), + TimeInAdvance_MinTimespanInAdvance = table.Column(type: "time", nullable: true), + Disabled = table.Column(type: "bit", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServiceAssets", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServiceAssetSchedules", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Date = table.Column(type: "datetime2", nullable: false), + AssetId = table.Column(type: "uniqueidentifier", nullable: false), + PeriodSchemeId = table.Column(type: "uniqueidentifier", nullable: false), + PeriodId = table.Column(type: "uniqueidentifier", nullable: false), + PeriodUsable = table.Column(type: "int", nullable: false), + TimeInAdvance_MaxDaysInAdvance = table.Column(type: "int", nullable: true), + TimeInAdvance_MaxTimespanInAdvance = table.Column(type: "time", nullable: true), + TimeInAdvance_MinDaysInAdvance = table.Column(type: "int", nullable: true), + TimeInAdvance_MinTimespanInAdvance = table.Column(type: "time", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServiceAssetSchedules", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServicePeriodSchemes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(max)", nullable: true), + IsDefault = table.Column(type: "bit", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServicePeriodSchemes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "EasyAbpBookingServicePeriods", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + StartingTime = table.Column(type: "time", nullable: false), + Duration = table.Column(type: "time", nullable: false), + PeriodSchemeId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EasyAbpBookingServicePeriods", x => x.Id); + table.ForeignKey( + name: "FK_EasyAbpBookingServicePeriods_EasyAbpBookingServicePeriodSchemes_PeriodSchemeId", + column: x => x.PeriodSchemeId, + principalTable: "EasyAbpBookingServicePeriodSchemes", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_EasyAbpPaymentServiceWeChatPayRefundRecords_OutRefundNo", + table: "EasyAbpPaymentServiceWeChatPayRefundRecords", + column: "OutRefundNo"); + + migrationBuilder.CreateIndex( + name: "IX_EasyAbpBookingServiceAssetCategories_ParentId", + table: "EasyAbpBookingServiceAssetCategories", + column: "ParentId"); + + migrationBuilder.CreateIndex( + name: "IX_EasyAbpBookingServiceAssetOccupancies_Date_AssetId_StartingTime_Duration", + table: "EasyAbpBookingServiceAssetOccupancies", + columns: new[] { "Date", "AssetId", "StartingTime", "Duration" }); + + migrationBuilder.CreateIndex( + name: "IX_EasyAbpBookingServiceAssetOccupancies_Date_OccupierUserId", + table: "EasyAbpBookingServiceAssetOccupancies", + columns: new[] { "Date", "OccupierUserId" }); + + migrationBuilder.CreateIndex( + name: "IX_EasyAbpBookingServiceAssetSchedules_Date_AssetId_PeriodSchemeId", + table: "EasyAbpBookingServiceAssetSchedules", + columns: new[] { "Date", "AssetId", "PeriodSchemeId" }); + + migrationBuilder.CreateIndex( + name: "IX_EasyAbpBookingServicePeriods_PeriodSchemeId", + table: "EasyAbpBookingServicePeriods", + column: "PeriodSchemeId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "EasyAbpBookingServiceAssetCategories"); + + migrationBuilder.DropTable( + name: "EasyAbpBookingServiceAssetOccupancies"); + + migrationBuilder.DropTable( + name: "EasyAbpBookingServiceAssetOccupancyCounts"); + + migrationBuilder.DropTable( + name: "EasyAbpBookingServiceAssetPeriodSchemes"); + + migrationBuilder.DropTable( + name: "EasyAbpBookingServiceAssets"); + + migrationBuilder.DropTable( + name: "EasyAbpBookingServiceAssetSchedules"); + + migrationBuilder.DropTable( + name: "EasyAbpBookingServicePeriods"); + + migrationBuilder.DropTable( + name: "EasyAbpBookingServicePeriodSchemes"); + + migrationBuilder.DropIndex( + name: "IX_EasyAbpPaymentServiceWeChatPayRefundRecords_OutRefundNo", + table: "EasyAbpPaymentServiceWeChatPayRefundRecords"); + + migrationBuilder.AlterColumn( + name: "OutRefundNo", + table: "EasyAbpPaymentServiceWeChatPayRefundRecords", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(450)", + oldNullable: true); + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs index 64cc3698..84e3eafc 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs @@ -19,11 +19,475 @@ namespace EShopSample.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "6.0.6") + .HasAnnotation("ProductVersion", "6.0.7") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpBookingServiceAssetCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancies.AssetOccupancy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OccupierName") + .HasColumnType("nvarchar(max)"); + + b.Property("OccupierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("Date", "OccupierUserId"); + + b.HasIndex("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancies", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancyCounts.AssetOccupancyCount", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancyCounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetPeriodSchemes.AssetPeriodScheme", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Date", "AssetId"); + + b.ToTable("EasyAbpBookingServiceAssetPeriodSchemes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServiceAssets", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodUsable") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Date", "AssetId", "PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServiceAssetSchedules", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.HasKey("Id"); + + b.HasIndex("PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServicePeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServicePeriodSchemes", (string)null); + }); + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => { b.Property("Id") @@ -3055,7 +3519,7 @@ namespace EShopSample.Migrations .HasColumnType("nvarchar(max)"); b.Property("OutRefundNo") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(450)"); b.Property("OutTradeNo") .HasColumnType("nvarchar(max)"); @@ -3108,6 +3572,8 @@ namespace EShopSample.Migrations b.HasKey("Id"); + b.HasIndex("OutRefundNo"); + b.HasIndex("PaymentId"); b.ToTable("EasyAbpPaymentServiceWeChatPayRefundRecords", (string)null); @@ -5041,6 +5507,109 @@ namespace EShopSample.Migrations b.ToTable("AbpTenantConnectionStrings", (string)null); }); + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.HasOne("EasyAbp.BookingService.AssetCategories.AssetCategory", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetCategoryId"); + + b1.ToTable("EasyAbpBookingServiceAssetCategories"); + + b1.WithOwner() + .HasForeignKey("AssetCategoryId"); + }); + + b.Navigation("Parent"); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetId"); + + b1.ToTable("EasyAbpBookingServiceAssets"); + + b1.WithOwner() + .HasForeignKey("AssetId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetScheduleId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetScheduleId"); + + b1.ToTable("EasyAbpBookingServiceAssetSchedules"); + + b1.WithOwner() + .HasForeignKey("AssetScheduleId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.HasOne("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", null) + .WithMany("Periods") + .HasForeignKey("PeriodSchemeId"); + }); + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => { b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) @@ -5427,6 +5996,16 @@ namespace EShopSample.Migrations .IsRequired(); }); + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Navigation("Periods"); + }); + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => { b.Navigation("OrderExtraFees"); diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj index c9508f1f..8674fdc6 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSample.HttpApi.Client.csproj @@ -21,6 +21,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs index 699547c9..b0909aa3 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi.Client/EShopSampleHttpApiClientModule.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop; +using EasyAbp.BookingService; +using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Booking; using EasyAbp.EShop.Plugins.Coupons; @@ -33,7 +34,8 @@ namespace EShopSample typeof(EShopProductsPluginsFlashSalesHttpApiClientModule), typeof(PaymentServiceHttpApiClientModule), typeof(PaymentServiceWeChatPayHttpApiClientModule), - typeof(PaymentServicePrepaymentHttpApiClientModule) + typeof(PaymentServicePrepaymentHttpApiClientModule), + typeof(BookingServiceHttpApiClientModule) )] public class EShopSampleHttpApiClientModule : AbpModule { diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj index bf8dd050..1779ccea 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSample.HttpApi.csproj @@ -21,6 +21,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs index e818d8d3..8ff8fc33 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.HttpApi/EShopSampleHttpApiModule.cs @@ -1,4 +1,5 @@ -using EasyAbp.EShop; +using EasyAbp.BookingService; +using EasyAbp.EShop; using EasyAbp.EShop.Plugins.Baskets; using EasyAbp.EShop.Plugins.Booking; using EasyAbp.EShop.Plugins.Coupons; @@ -31,7 +32,8 @@ namespace EShopSample typeof(EShopProductsPluginsFlashSalesHttpApiModule), typeof(PaymentServiceHttpApiModule), typeof(PaymentServiceWeChatPayHttpApiModule), - typeof(PaymentServicePrepaymentHttpApiModule) + typeof(PaymentServicePrepaymentHttpApiModule), + typeof(BookingServiceHttpApiModule) )] public class EShopSampleHttpApiModule : AbpModule { diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj index ed0765d8..0102716c 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSample.Web.csproj @@ -49,6 +49,7 @@ + diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs index 8f3f62a6..c69bd88f 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Web/EShopSampleWebModule.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using EasyAbp.BookingService.Web; using EasyAbp.EShop; using EasyAbp.EShop.Plugins; using EasyAbp.EShop.Plugins.Web; @@ -80,7 +81,8 @@ namespace EShopSample.Web typeof(EShopPluginsFlashSalesWebModule), typeof(PaymentServiceWebModule), typeof(PaymentServiceWeChatPayWebModule), - typeof(PaymentServicePrepaymentWebModule) + typeof(PaymentServicePrepaymentWebModule), + typeof(BookingServiceWebModule) )] public class EShopSampleWebModule : AbpModule { From 7720d126c83ac1ce7f0b4b374a5c979586b1dac5 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sat, 6 Aug 2022 17:46:03 +0800 Subject: [PATCH 53/97] Fix authorization in `FlashSalePlanAppService` --- .../FlashSalePlans/FlashSalePlanAppService.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 4bc20ffb..9b3655e3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -19,12 +19,10 @@ using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; -using Volo.Abp.Timing; using Volo.Abp.Users; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -[Authorize] public class FlashSalePlanAppService : MultiStoreCrudAppService, IFlashSalePlanAppService @@ -45,8 +43,8 @@ public class FlashSalePlanAppService : public const string UserFlashSaleResultCacheKeyFormat = "eshopflashsales-result_{0}_{1}_{2}"; protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.CrossStore; - protected override string GetPolicyName { get; set; } - protected override string GetListPolicyName { get; set; } + protected override string GetPolicyName { get; set; } = null; + protected override string GetListPolicyName { get; set; } = null; protected override string CreatePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Create; protected override string UpdatePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Update; protected override string DeletePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Delete; @@ -104,7 +102,10 @@ public class FlashSalePlanAppService : { var flashSalePlan = await GetEntityByIdAsync(id); - await CheckMultiStorePolicyAsync(flashSalePlan.StoreId, GetPolicyName); + if (GetPolicyName is not null) + { + await CheckMultiStorePolicyAsync(flashSalePlan.StoreId, GetPolicyName); + } if (!flashSalePlan.IsPublished) { @@ -116,7 +117,10 @@ public class FlashSalePlanAppService : public override async Task> GetListAsync(FlashSalePlanGetListInput input) { - await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); + if (GetListPolicyName is not null) + { + await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); + } return await base.GetListAsync(input); } @@ -202,6 +206,7 @@ public class FlashSalePlanAppService : .WhereIf(input.End.HasValue, x => x.BeginTime <= input.End.Value); } + [Authorize] public virtual async Task PreOrderAsync(Guid id) { var plan = await GetFlashSalePlanCacheAsync(id); @@ -216,6 +221,7 @@ public class FlashSalePlanAppService : return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), ExpiresInSeconds = Options.PreOrderExpires.TotalSeconds }; } + [Authorize] public virtual async Task OrderAsync(Guid id, CreateOrderInput input) { var preOrderCache = await GetPreOrderCacheAsync(id); From 9513fa9a0cd2c0c34f272408a3497b0de42a6534 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sat, 6 Aug 2022 18:03:32 +0800 Subject: [PATCH 54/97] Change version to 3.0.0-preview.4 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 3e437d9e..1c4787a5 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.3 + 3.0.0-preview.4 $(NoWarn);CS1591 true EasyAbp Team From 929238f634468cf76df8b2511442557af49dbea3 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sat, 6 Aug 2022 22:46:57 +0800 Subject: [PATCH 55/97] Use configured default inventory provider --- .../Products/Products/ProductInventoryProviderResolver.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs index 77199c85..93f85227 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Threading.Tasks; using EasyAbp.EShop.Products.Options; using EasyAbp.EShop.Products.ProductInventories; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using Volo.Abp; using Volo.Abp.DependencyInjection; namespace EasyAbp.EShop.Products.Products; @@ -57,7 +55,8 @@ public class ProductInventoryProviderResolver : IProductInventoryProviderResolve { if (providerName.IsNullOrEmpty()) { - providerName = DefaultProductInventoryProvider.DefaultProductInventoryProviderName; + var options = ServiceProvider.GetRequiredService>(); + providerName = options.Value.DefaultInventoryProviderName; } TryBuildNameToProviderTypeMapping(); From aea554d0907ed66d13335fe2749fef8ce1f2572c Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sat, 6 Aug 2022 22:50:14 +0800 Subject: [PATCH 56/97] Change version to 3.0.0-preview.5 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 1c4787a5..7ec7fec2 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.4 + 3.0.0-preview.5 $(NoWarn);CS1591 true EasyAbp Team From 9bb714e43610211c979bff96ae7f4d02910156e7 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 7 Aug 2022 16:52:18 +0800 Subject: [PATCH 57/97] Make `UserFlashSaleResultCache` have an absolute expiration --- .../FlashSalePlans/FlashSalePlanAppService.cs | 16 +++++++++++----- .../FlashSalePlans/FlashSalesOptions.cs | 5 +++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 9b3655e3..ba76dc98 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -278,10 +278,10 @@ public class FlashSalePlanAppService : ); }); - await SetUserFlashSaleResultCacheAsync(plan.Id, result.Id); - var createFlashSaleOrderEto = await PrepareCreateFlashSaleOrderEtoAsync(plan, result.Id, input, userId, now, preOrderCache.HashToken); + await SetUserFlashSaleResultCacheAsync(plan.Id, result.Id); + await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); return new FlashSaleOrderResultDto() { IsSuccess = true, FlashSaleResultId = result.Id }; @@ -348,7 +348,10 @@ public class FlashSalePlanAppService : protected virtual async Task SetUserFlashSaleResultCacheAsync(Guid planId, Guid resultId) { var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(planId); - await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, resultId.ToString()); + await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, resultId.ToString(), new DistributedCacheEntryOptions() + { + AbsoluteExpiration = DateTimeOffset.Now.Add(Options.UserFlashSaleResultCacheExpires) + }); } #endregion @@ -423,9 +426,12 @@ public class FlashSalePlanAppService : HashToken = hashToken }; - foreach (var item in input.ExtraProperties) + if (input.ExtraProperties != null) { - eto.ExtraProperties.Add(item.Key, item.Value); + foreach (var item in input.ExtraProperties) + { + eto.ExtraProperties.Add(item.Key, item.Value); + } } return Task.FromResult(eto); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs index 45d94a88..e4071710 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs @@ -8,4 +8,9 @@ public class FlashSalesOptions /// Default: 3 minutes /// public TimeSpan PreOrderExpires { get; set; } = TimeSpan.FromMinutes(3); + + /// + /// Default: 5 minutes + /// + public TimeSpan UserFlashSaleResultCacheExpires { get; set; } = TimeSpan.FromMinutes(5); } From cc236820fc3665c731f1f6eb0f77aa81e07d097d Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 7 Aug 2022 16:56:07 +0800 Subject: [PATCH 58/97] Change version to 3.0.0-preview.6 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 7ec7fec2..e83ce0d7 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.5 + 3.0.0-preview.6 $(NoWarn);CS1591 true EasyAbp Team From e9bada97ce7365cdca5e2e6dd2dce1e388080e83 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 7 Aug 2022 17:50:26 +0800 Subject: [PATCH 59/97] Fix authorization in `FlashSaleResultAppService` --- .../FlashSaleResults/FlashSaleResultAppService.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index 20e1a1bc..e9432cf9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -24,7 +24,10 @@ public class FlashSaleResultAppService : { var flashSaleResult = await GetEntityByIdAsync(id); - await CheckMultiStorePolicyAsync(flashSaleResult.StoreId, GetPolicyName); + if (GetPolicyName is not null) + { + await CheckMultiStorePolicyAsync(flashSaleResult.StoreId, GetPolicyName); + } if (flashSaleResult.UserId != CurrentUser.Id) { @@ -36,7 +39,10 @@ public class FlashSaleResultAppService : public override async Task> GetListAsync(FlashSaleResultGetListInput input) { - await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); + if (GetListPolicyName is not null) + { + await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); + } return await base.GetListAsync(input); } From 6c5c96460e740f7363fb090f12916e9104d0a35e Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 7 Aug 2022 17:52:31 +0800 Subject: [PATCH 60/97] Change version to 3.0.0-preview.7 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index e83ce0d7..6524e051 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.6 + 3.0.0-preview.7 $(NoWarn);CS1591 true EasyAbp Team From 961ca1917bfea77f1acdfd24f135eedd21a94594 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 7 Aug 2022 21:02:40 +0800 Subject: [PATCH 61/97] Configure permissions for flash-sales --- .../Permissions/FlashSalesPermissionDefinitionProvider.cs | 1 + .../Plugins/FlashSales/Permissions/FlashSalesPermissions.cs | 1 + .../FlashSales/FlashSalePlans/FlashSalePlanAppService.cs | 3 +++ .../FlashSales/FlashSaleResults/FlashSaleResultAppService.cs | 4 ++-- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs index 4a2a7d28..2f985ef0 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissionDefinitionProvider.cs @@ -16,6 +16,7 @@ public class FlashSalesPermissionDefinitionProvider : PermissionDefinitionProvid flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.Create, L("Permission:Create")); flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.Update, L("Permission:Update")); flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.Delete, L("Permission:Delete")); + flashSalePlanPermission.AddChild(FlashSalesPermissions.FlashSalePlan.PreOrder, L("Permission:PreOrder")); var flashSaleResultPermission = myGroup.AddPermission(FlashSalesPermissions.FlashSaleResult.Default, L("Permission:FlashSaleResult")); flashSaleResultPermission.AddChild(FlashSalesPermissions.FlashSaleResult.Manage, L("Permission:Manage")); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs index b03f5b90..cd4d571a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/Permissions/FlashSalesPermissions.cs @@ -19,6 +19,7 @@ public class FlashSalesPermissions public const string Update = Default + ".Update"; public const string Create = Default + ".Create"; public const string Delete = Default + ".Delete"; + public const string PreOrder = Default + ".PreOrder"; } public class FlashSaleResult diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index ba76dc98..ac0c19b3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -48,6 +48,7 @@ public class FlashSalePlanAppService : protected override string CreatePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Create; protected override string UpdatePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Update; protected override string DeletePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.Delete; + protected virtual string PreOrderPolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.PreOrder; protected IFlashSalePlanRepository FlashSalePlanRepository { get; } @@ -209,6 +210,8 @@ public class FlashSalePlanAppService : [Authorize] public virtual async Task PreOrderAsync(Guid id) { + await CheckPolicyAsync(PreOrderPolicyName); + var plan = await GetFlashSalePlanCacheAsync(id); var product = await ProductAppService.GetAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index e9432cf9..d58f19b0 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -13,8 +13,8 @@ public class FlashSaleResultAppService : IFlashSaleResultAppService { protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSaleResult.CrossStore; - protected override string GetPolicyName { get; set; } - protected override string GetListPolicyName { get; set; } + protected override string GetPolicyName { get; set; } = FlashSalesPermissions.FlashSaleResult.Default; + protected override string GetListPolicyName { get; set; } = FlashSalesPermissions.FlashSaleResult.Default; public FlashSaleResultAppService(IFlashSaleResultRepository flashSaleResultRepository) : base(flashSaleResultRepository) { From 2ac3e22170021d10272b081928fbb2c6ead4e695 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 7 Aug 2022 21:47:27 +0800 Subject: [PATCH 62/97] fix `EShopProductsOptions.DefaultInventoryProviderName` fall back --- .../Products/Products/ProductInventoryProviderResolver.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs index 93f85227..aaf0f227 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs @@ -58,6 +58,10 @@ public class ProductInventoryProviderResolver : IProductInventoryProviderResolve var options = ServiceProvider.GetRequiredService>(); providerName = options.Value.DefaultInventoryProviderName; } + if (providerName.IsNullOrEmpty()) + { + providerName = DefaultProductInventoryProvider.DefaultProductInventoryProviderName; + } TryBuildNameToProviderTypeMapping(); From 360a0b02750d2d3de96e5be74889e7c2b08df576 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 7 Aug 2022 21:57:50 +0800 Subject: [PATCH 63/97] Improve `ProductInventoryProviderResolver.GetProviderByName` --- .../Products/Products/ProductInventoryProviderResolver.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs index aaf0f227..a3b18957 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductInventoryProviderResolver.cs @@ -56,11 +56,7 @@ public class ProductInventoryProviderResolver : IProductInventoryProviderResolve if (providerName.IsNullOrEmpty()) { var options = ServiceProvider.GetRequiredService>(); - providerName = options.Value.DefaultInventoryProviderName; - } - if (providerName.IsNullOrEmpty()) - { - providerName = DefaultProductInventoryProvider.DefaultProductInventoryProviderName; + providerName = options.Value.DefaultInventoryProviderName ?? DefaultProductInventoryProvider.DefaultProductInventoryProviderName; } TryBuildNameToProviderTypeMapping(); From 2fed214b267bb15124f1a00b4f6b999280590130 Mon Sep 17 00:00:00 2001 From: Jadyn Date: Sun, 7 Aug 2022 21:48:08 +0800 Subject: [PATCH 64/97] Use product cache item for flash-sales --- .../FlashSalePlans/FlashSalePlanAppService.cs | 28 ++++++++--- .../FlashSalesApplicationAutoMapperProfile.cs | 5 ++ .../Products/ProductCacheInvalidator.cs | 46 +++++++++++++++++++ .../Products/Products/ProductCacheItem.cs | 10 ++++ .../FlashSalePlanAppServiceTests.cs | 5 -- 5 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index ac0c19b3..14d8e91c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -58,6 +58,8 @@ public class FlashSalePlanAppService : protected IDistributedCache PlanDistributedCache { get; } + protected IDistributedCache ProductDistributedCache { get; } + protected IDistributedEventBus DistributedEventBus { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; } @@ -77,6 +79,7 @@ public class FlashSalePlanAppService : IProductAppService productAppService, IDistributedCache tokenDistributedCache, IDistributedCache planDistributedCache, + IDistributedCache productDistributedCache, IDistributedEventBus distributedEventBus, IFlashSaleResultRepository flashSaleResultRepository, IAbpDistributedLock distributedLock, @@ -90,6 +93,7 @@ public class FlashSalePlanAppService : ProductAppService = productAppService; PreOrderDistributedCache = tokenDistributedCache; PlanDistributedCache = planDistributedCache; + ProductDistributedCache = productDistributedCache; DistributedEventBus = distributedEventBus; FlashSaleResultRepository = flashSaleResultRepository; DistributedLock = distributedLock; @@ -213,7 +217,7 @@ public class FlashSalePlanAppService : await CheckPolicyAsync(PreOrderPolicyName); var plan = await GetFlashSalePlanCacheAsync(id); - var product = await ProductAppService.GetAsync(plan.ProductId); + var product = await GetProductCacheAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); var expiresTime = DateTimeOffset.Now.Add(Options.PreOrderExpires); @@ -381,11 +385,6 @@ public class FlashSalePlanAppService : throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } - if (productSku.Inventory < 1) - { - throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); - } - return Task.CompletedTask; } @@ -462,4 +461,21 @@ public class FlashSalePlanAppService : return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); } + + protected virtual async Task GetProductCacheAsync(Guid productId) + { + return await ProductDistributedCache.GetOrAddAsync(productId, async () => + { + var productDto = await ProductAppService.GetAsync(productId); + + var cacheItem = ObjectMapper.Map(productDto); + + if (cacheItem != null) + { + cacheItem.TenantId = CurrentTenant.Id; + } + + return cacheItem; + }); + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs index 3f2a4324..b66c03f5 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs @@ -3,6 +3,8 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales; @@ -24,5 +26,8 @@ public class FlashSalesApplicationAutoMapperProfile : Profile CreateMap() .MapExtraProperties(); + + CreateMap(MemberList.Source) + .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs new file mode 100644 index 00000000..d9d1ed46 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs @@ -0,0 +1,46 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Products.Products; + +public class ProductCacheInvalidator : + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency +{ + protected IDistributedCache DistributedCache { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + + public ProductCacheInvalidator( + IDistributedCache distributedCache, + IUnitOfWorkManager unitOfWorkManager) + { + DistributedCache = distributedCache; + UnitOfWorkManager = unitOfWorkManager; + } + + public virtual async Task HandleEventAsync(EntityUpdatedEto eventData) + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + + UnitOfWorkManager.Current.OnCompleted(async () => + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + }); + } + + public virtual async Task HandleEventAsync(EntityDeletedEto eventData) + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + + UnitOfWorkManager.Current.OnCompleted(async () => + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs new file mode 100644 index 00000000..0c59d0f7 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs @@ -0,0 +1,10 @@ +using System; +using EasyAbp.EShop.Products.Products.Dtos; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Products.Products; + +public class ProductCacheItem : ProductDto, IMultiTenant +{ + public Guid? TenantId { get; set; } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs index 844fe01c..6fa1d635 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs @@ -342,11 +342,6 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase (await AppService.PreOrderAsync(plan3.Id) .ShouldThrowAsync()) .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver); - - var plan4 = await CreateFlashSalePlanAsync(useSku2: true); - (await AppService.PreOrderAsync(plan4.Id) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.ProductSkuInventoryExceeded); } [Fact] From 664df9f1a2c30df3066e5237936e2f7102db668a Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 7 Aug 2022 22:18:52 +0800 Subject: [PATCH 65/97] Change version to 3.0.0-preview.8 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 6524e051..5d3324d9 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.7 + 3.0.0-preview.8 $(NoWarn);CS1591 true EasyAbp Team From a95b007ec1e4c124b3a0c1a8a29729cded09258d Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 03:14:58 +0800 Subject: [PATCH 66/97] Use warning to log exceptions of inventory operation --- .../DaprActorsInventory/DaprActorsProductInventoryProvider.cs | 4 ++-- .../OrleansGrainsProductInventoryProvider.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs index 86ebb124..73f072fb 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs @@ -67,7 +67,7 @@ public class DaprActorsProductInventoryProvider : IProductInventoryProvider, ITr } catch (Exception e) { - _logger.LogError("Actor threw: {Message}", e.Message); + _logger.LogWarning("Actor threw: {Message}", e.InnerException?.Message ?? e.Message); return false; } @@ -92,7 +92,7 @@ public class DaprActorsProductInventoryProvider : IProductInventoryProvider, ITr } catch (Exception e) { - _logger.LogError("Actor threw: {Message}", e.Message); + _logger.LogWarning("Actor threw: {Message}", e.InnerException?.Message ?? e.Message); return false; } diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs index 19a7edb2..b2b82346 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs @@ -65,7 +65,7 @@ public class OrleansGrainsProductInventoryProvider : IProductInventoryProvider, } catch (Exception e) { - _logger.LogError("Grain threw: {Message}", e.Message); + _logger.LogWarning("Grain threw: {Message}", e.InnerException?.Message ?? e.Message); return false; } @@ -90,7 +90,7 @@ public class OrleansGrainsProductInventoryProvider : IProductInventoryProvider, } catch (Exception e) { - _logger.LogError("Grain threw: {Message}", e.Message); + _logger.LogWarning("Grain threw: {Message}", e.InnerException?.Message ?? e.Message); return false; } From 731020ddfcdcc6497d9c5935199ac034ba170994 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 04:07:00 +0800 Subject: [PATCH 67/97] Inventory actor/grain delay saving to the persistence --- .../IProductInventoryProvider.cs | 6 +- .../DefaultProductInventoryProvider.cs | 4 +- .../EShop/Products/Products/ProductManager.cs | 8 ++- .../FakeProductInventoryProvider.cs | 10 ++-- .../Products/FlashSaleInventoryManager.cs | 18 +++--- .../Products/IFlashSaleInventoryManager.cs | 8 ++- .../LocalFlashSaleInventoryManager.cs | 4 +- .../Products/FakeFlashSaleInventoryManager.cs | 10 ++-- .../Inventories/DaprActors/IInventoryActor.cs | 4 +- ...Shop.Plugins.Inventories.DaprActors.csproj | 1 + ...EShopPluginsInventoriesDaprActorsModule.cs | 2 + .../Inventories/DaprActors/InventoryActor.cs | 60 ++++++++++++++++--- .../DaprActorsProductInventoryProvider.cs | 9 +-- .../FakeInventoryActor.cs | 4 +- .../OrleansGrains/IInventoryGrain.cs | 4 +- ...p.Plugins.Inventories.OrleansGrains.csproj | 1 + ...opPluginsInventoriesOrleansGrainsModule.cs | 2 + .../OrleansGrains/InventoryGrain.cs | 56 +++++++++++++++-- .../OrleansGrainsProductInventoryProvider.cs | 9 +-- .../FakeInventoryGrain.cs | 4 +- 20 files changed, 167 insertions(+), 57 deletions(-) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/IProductInventoryProvider.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/IProductInventoryProvider.cs index eaf89186..981abbed 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/IProductInventoryProvider.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductInventories/IProductInventoryProvider.cs @@ -12,8 +12,10 @@ namespace EasyAbp.EShop.Products.ProductInventories Task> GetSkuIdInventoryDataMappingAsync(IList models); - Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, bool decreaseSold); + Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, bool decreaseSold, + bool isFlashSale = false); - Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold); + Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold, + bool isFlashSale = false); } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs index 9f420ea2..82b9c1a6 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/DefaultProductInventoryProvider.cs @@ -76,7 +76,7 @@ namespace EasyAbp.EShop.Products.Products [UnitOfWork(true)] public virtual async Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, - bool decreaseSold) + bool decreaseSold, bool isFlashSale = false) { await using var handle = await _distributedLock.TryAcquireAsync(await GetLockKeyAsync(model), TimeSpan.FromSeconds(30)); @@ -94,7 +94,7 @@ namespace EasyAbp.EShop.Products.Products [UnitOfWork(true)] public virtual async Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, - bool increaseSold) + bool increaseSold, bool isFlashSale = false) { await using var handle = await _distributedLock.TryAcquireAsync(await GetLockKeyAsync(model), TimeSpan.FromSeconds(30)); diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs index a6f7e35c..ade8db3d 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs @@ -259,8 +259,10 @@ namespace EasyAbp.EShop.Products.Products { var model = new InventoryQueryModel(product.TenantId, product.StoreId, product.Id, productSku.Id); + var isFlashSale = product.InventoryStrategy is InventoryStrategy.FlashSales; + return await (await _productInventoryProviderResolver.GetAsync(product)) - .TryIncreaseInventoryAsync(model, quantity, reduceSold); + .TryIncreaseInventoryAsync(model, quantity, reduceSold, isFlashSale); } public virtual async Task TryReduceInventoryAsync(Product product, ProductSku productSku, int quantity, @@ -268,8 +270,10 @@ namespace EasyAbp.EShop.Products.Products { var model = new InventoryQueryModel(product.TenantId, product.StoreId, product.Id, productSku.Id); + var isFlashSale = product.InventoryStrategy is InventoryStrategy.FlashSales; + return await (await _productInventoryProviderResolver.GetAsync(product)) - .TryReduceInventoryAsync(model, quantity, increaseSold); + .TryReduceInventoryAsync(model, quantity, increaseSold, isFlashSale); } public virtual async Task GetRealPriceAsync(Product product, ProductSku productSku) diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/FakeProductInventoryProvider.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/FakeProductInventoryProvider.cs index e49d2ff2..b5c5ddbb 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/FakeProductInventoryProvider.cs +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.TestBase/FakeProductInventoryProvider.cs @@ -34,10 +34,11 @@ public class FakeProductInventoryProvider : IProductInventoryProvider, ITransien return Task.FromResult(result); } - public Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, bool decreaseSold) + public Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, bool decreaseSold, + bool isFlashSale = false) { Model.Inventory++; - + if (decreaseSold) { Model.Sold--; @@ -46,10 +47,11 @@ public class FakeProductInventoryProvider : IProductInventoryProvider, ITransien return Task.FromResult(true); } - public Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold) + public Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold, + bool isFlashSale = false) { Model.Inventory--; - + if (increaseSold) { Model.Sold++; diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs index 6e6bd678..aaeb31ce 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs @@ -17,17 +17,17 @@ public class FlashSaleInventoryManager : IFlashSaleInventoryManager, ITransientD FlashSaleInventoryReducerAppService = flashSaleInventoryReducerAppService; } - public virtual async Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool increaseSold) + public virtual async Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, + Guid productId, Guid productSkuId, int quantity, bool increaseSold) { - return await FlashSaleInventoryReducerAppService.TryReduceAsync( - new ReduceInventoryInput(tenantId, providerName, storeId, productId, productSkuId, quantity, increaseSold)); + return await FlashSaleInventoryReducerAppService.TryReduceAsync(new ReduceInventoryInput( + tenantId, providerName, storeId, productId, productSkuId, quantity, increaseSold)); } - public virtual async Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool decreaseSold) + public virtual async Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, + Guid productId, Guid productSkuId, int quantity, bool decreaseSold) { - return await FlashSaleInventoryReducerAppService.TryIncreaseAsync - (new IncreaseInventoryInput(tenantId, providerName, storeId, productId, productSkuId, quantity, decreaseSold)); + return await FlashSaleInventoryReducerAppService.TryIncreaseAsync(new IncreaseInventoryInput( + tenantId, providerName, storeId, productId, productSkuId, quantity, decreaseSold)); } -} +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs index 2fa36304..93558adc 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs @@ -5,7 +5,9 @@ namespace EasyAbp.Eshop.Products.Products; public interface IFlashSaleInventoryManager { - Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool increaseSold); + Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool increaseSold); - Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold); -} + Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool decreaseSold); +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs index 093b7ed3..6e38ba04 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs @@ -20,7 +20,7 @@ public class LocalFlashSaleInventoryManager : ILocalFlashSaleInventoryManager, I { var model = new InventoryQueryModel(tenantId, storeId, productId, productSkuId); return await (await ProductInventoryProviderResolver.GetAsync(providerName)) - .TryReduceInventoryAsync(model, quantity, increaseSold); + .TryReduceInventoryAsync(model, quantity, increaseSold, true); } public virtual async Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, @@ -28,6 +28,6 @@ public class LocalFlashSaleInventoryManager : ILocalFlashSaleInventoryManager, I { var model = new InventoryQueryModel(tenantId, storeId, productId, productSkuId); return await (await ProductInventoryProviderResolver.GetAsync(providerName)) - .TryIncreaseInventoryAsync(model, quantity, decreaseSold); + .TryIncreaseInventoryAsync(model, quantity, decreaseSold, true); } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs index ff159deb..866e3b8c 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs @@ -13,15 +13,15 @@ public class FakeFlashSaleInventoryManager : IFlashSaleInventoryManager ShouldReduceSuccess = true; } - public Task TryReduceInventoryAsync( - Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool increaseSold) + public Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool increaseSold) { return Task.FromResult(ShouldReduceSuccess); } - public Task TryRollBackInventoryAsync( - Guid? tenantId, string providerName, Guid storeId, Guid productId, Guid productSkuId, int quantity, bool decreaseSold) + public Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, + Guid productSkuId, int quantity, bool decreaseSold) { return Task.FromResult(true); } -} +} \ No newline at end of file diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/IInventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/IInventoryActor.cs index 714904b5..8a585518 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/IInventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors.Abstractions/EasyAbp/EShop/Plugins/Inventories/DaprActors/IInventoryActor.cs @@ -7,7 +7,7 @@ public interface IInventoryActor : IActor { Task GetInventoryStateAsync(); - Task IncreaseInventoryAsync(int quantity, bool decreaseSold); + Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale); - Task ReduceInventoryAsync(int quantity, bool increaseSold); + Task ReduceInventoryAsync(int quantity, bool increaseSold, bool isFlashSale); } \ No newline at end of file diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj index 4b5cd92d..386df1c6 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj @@ -12,6 +12,7 @@ + diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs index 0b59cb9b..65b224a5 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs @@ -1,8 +1,10 @@ using Volo.Abp.Modularity; +using Volo.Abp.Timing; namespace EasyAbp.EShop.Plugins.Inventories.DaprActors; [DependsOn( + typeof(AbpTimingModule), typeof(EShopPluginsInventoriesDaprActorsAbstractionsModule) )] public class EShopPluginsInventoriesDaprActorsModule : AbpModule diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs index 28457019..3eedce1f 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs @@ -1,6 +1,8 @@ +using System; using System.Threading.Tasks; using Dapr; using Dapr.Actors.Runtime; +using Volo.Abp.Timing; namespace EasyAbp.EShop.Plugins.Inventories.DaprActors; @@ -8,8 +10,13 @@ public class InventoryActor : Actor, IInventoryActor { public static string InventoryStateName { get; set; } = "i"; - public InventoryActor(ActorHost host) : base(host) + protected DateTime? TimeToPersistInventory { get; set; } + + protected IClock Clock { get; } + + public InventoryActor(ActorHost host, IClock clock) : base(host) { + Clock = clock; } protected override async Task OnActivateAsync() @@ -19,25 +26,62 @@ public class InventoryActor : Actor, IInventoryActor public virtual async Task GetInventoryStateAsync() { - return await StateManager.GetStateAsync(InventoryStateName); + var state = await InternalGetInventoryStateAsync(); + + await TrySetInventoryStateAsync(state); + + return state; } - public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold) + public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) { - var state = await GetInventoryStateAsync(); + var state = await InternalGetInventoryStateAsync(); InternalIncreaseInventory(state, quantity, decreaseSold); - await SetInventoryStateAsync(state); + if (!isFlashSale || state.Inventory == 0) + { + await SetInventoryStateAsync(state); + } + else + { + TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + + await TrySetInventoryStateAsync(state); + } } - public async Task ReduceInventoryAsync(int quantity, bool increaseSold) + public virtual async Task ReduceInventoryAsync(int quantity, bool increaseSold, bool isFlashSale) { - var state = await GetInventoryStateAsync(); + var state = await InternalGetInventoryStateAsync(); InternalReduceInventory(state, quantity, increaseSold); - await SetInventoryStateAsync(state); + if (!isFlashSale || state.Inventory == 0) + { + await SetInventoryStateAsync(state); + } + else + { + TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + + await TrySetInventoryStateAsync(state); + } + } + + public virtual Task InternalGetInventoryStateAsync() => + StateManager.GetStateAsync(InventoryStateName); + + public async Task TrySetInventoryStateAsync(InventoryStateModel stateModel) + { + if (!TimeToPersistInventory.HasValue || TimeToPersistInventory.Value < Clock.Now) + { + return false; + } + + await SetInventoryStateAsync(stateModel); + + return true; } protected virtual async Task SetInventoryStateAsync(InventoryStateModel state) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs index 73f072fb..4b496af2 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Products.DaprActorsInventory.Domain/EasyAbp/EShop/Products/DaprActorsInventory/DaprActorsProductInventoryProvider.cs @@ -57,13 +57,13 @@ public class DaprActorsProductInventoryProvider : IProductInventoryProvider, ITr } public virtual async Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, - bool decreaseSold) + bool decreaseSold, bool isFlashSale = false) { var actor = await GetActorAsync(model); try { - await actor.IncreaseInventoryAsync(quantity, decreaseSold); + await actor.IncreaseInventoryAsync(quantity, decreaseSold, isFlashSale); } catch (Exception e) { @@ -75,7 +75,8 @@ public class DaprActorsProductInventoryProvider : IProductInventoryProvider, ITr return true; } - public virtual async Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold) + public virtual async Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold, + bool isFlashSale = false) { var actor = await GetActorAsync(model); @@ -88,7 +89,7 @@ public class DaprActorsProductInventoryProvider : IProductInventoryProvider, ITr try { - await actor.ReduceInventoryAsync(quantity, increaseSold); + await actor.ReduceInventoryAsync(quantity, increaseSold, isFlashSale); } catch (Exception e) { diff --git a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/FakeInventoryActor.cs b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/FakeInventoryActor.cs index 58ae0129..fba881f9 100644 --- a/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/FakeInventoryActor.cs +++ b/plugins/Inventories/DaprActors/test/EasyAbp.EShop.Products.DaprActorsInventory.Domain.Tests/FakeInventoryActor.cs @@ -17,7 +17,7 @@ public class FakeInventoryActor : IInventoryActor, ITransientDependency return Task.FromResult(StateModel); } - public Task IncreaseInventoryAsync(int quantity, bool decreaseSold) + public Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) { StateModel.Inventory += quantity; @@ -29,7 +29,7 @@ public class FakeInventoryActor : IInventoryActor, ITransientDependency return Task.CompletedTask; } - public Task ReduceInventoryAsync(int quantity, bool increaseSold) + public Task ReduceInventoryAsync(int quantity, bool increaseSold, bool isFlashSale) { StateModel.Inventory -= quantity; diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/IInventoryGrain.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/IInventoryGrain.cs index 7deb1fe6..a8f718d9 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/IInventoryGrain.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.Abstractions/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/IInventoryGrain.cs @@ -7,7 +7,7 @@ public interface IInventoryGrain : IGrainWithStringKey { Task GetInventoryStateAsync(); - Task IncreaseInventoryAsync(int quantity, bool decreaseSold); + Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale); - Task ReduceInventoryAsync(int quantity, bool increaseSold); + Task ReduceInventoryAsync(int quantity, bool increaseSold, bool isFlashSale); } \ No newline at end of file diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj index 6e831f2a..2346d462 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj @@ -12,6 +12,7 @@ + all diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs index 087bb7b9..40b6f09d 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs @@ -1,8 +1,10 @@ using Volo.Abp.Modularity; +using Volo.Abp.Timing; namespace EasyAbp.EShop.Plugins.Inventories.OrleansGrains; [DependsOn( + typeof(AbpTimingModule), typeof(EShopPluginsInventoriesOrleansGrainsAbstractionsModule) )] public class EShopPluginsInventoriesOrleansGrainsModule : AbpModule diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs index 454fdb86..06213b69 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs @@ -1,7 +1,9 @@ +using System; using System.Threading.Tasks; using Orleans; using Orleans.Providers; using Orleans.Runtime; +using Volo.Abp.Timing; namespace EasyAbp.EShop.Plugins.Inventories.OrleansGrains; @@ -10,20 +12,66 @@ public class InventoryGrain : Grain, IInventoryGrain { public const string StorageProviderName = "EShopInventoryStorage"; - public virtual Task GetInventoryStateAsync() => Task.FromResult(State); + protected DateTime? TimeToPersistInventory { get; set; } - public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold) + protected IClock Clock { get; } + + public InventoryGrain(IClock clock) + { + Clock = clock; + } + + public virtual async Task GetInventoryStateAsync() + { + var state = State; + + await TryWriteStateAsync(); + + return state; + } + + public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) { InternalIncreaseInventory(quantity, decreaseSold); - await WriteStateAsync(); + if (!isFlashSale || State.Inventory == 0) + { + await WriteStateAsync(); + } + else + { + TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + + await TryWriteStateAsync(); + } } - public async Task ReduceInventoryAsync(int quantity, bool increaseSold) + public virtual async Task ReduceInventoryAsync(int quantity, bool increaseSold, bool isFlashSale) { InternalReduceInventory(quantity, increaseSold); + if (!isFlashSale || State.Inventory == 0) + { + await WriteStateAsync(); + } + else + { + TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + + await TryWriteStateAsync(); + } + } + + public async Task TryWriteStateAsync() + { + if (!TimeToPersistInventory.HasValue || TimeToPersistInventory.Value < Clock.Now) + { + return false; + } + await WriteStateAsync(); + + return true; } protected virtual void InternalIncreaseInventory(int quantity, bool decreaseSold) diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs index b2b82346..f87b08d9 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain/EasyAbp/EShop/Products/OrleansGrainsInventory/OrleansGrainsProductInventoryProvider.cs @@ -55,13 +55,13 @@ public class OrleansGrainsProductInventoryProvider : IProductInventoryProvider, } public virtual async Task TryIncreaseInventoryAsync(InventoryQueryModel model, int quantity, - bool decreaseSold) + bool decreaseSold, bool isFlashSale = false) { var grain = await GetGrainAsync(model); try { - await grain.IncreaseInventoryAsync(quantity, decreaseSold); + await grain.IncreaseInventoryAsync(quantity, decreaseSold, isFlashSale); } catch (Exception e) { @@ -73,7 +73,8 @@ public class OrleansGrainsProductInventoryProvider : IProductInventoryProvider, return true; } - public virtual async Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold) + public virtual async Task TryReduceInventoryAsync(InventoryQueryModel model, int quantity, bool increaseSold, + bool isFlashSale = false) { var grain = await GetGrainAsync(model); @@ -86,7 +87,7 @@ public class OrleansGrainsProductInventoryProvider : IProductInventoryProvider, try { - await grain.ReduceInventoryAsync(quantity, increaseSold); + await grain.ReduceInventoryAsync(quantity, increaseSold, isFlashSale); } catch (Exception e) { diff --git a/plugins/Inventories/OrleansGrains/test/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests/FakeInventoryGrain.cs b/plugins/Inventories/OrleansGrains/test/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests/FakeInventoryGrain.cs index 49f7199a..3520d7a3 100644 --- a/plugins/Inventories/OrleansGrains/test/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests/FakeInventoryGrain.cs +++ b/plugins/Inventories/OrleansGrains/test/EasyAbp.EShop.Products.OrleansGrainsInventory.Domain.Tests/FakeInventoryGrain.cs @@ -17,7 +17,7 @@ public class FakeInventoryGrain : IInventoryGrain, ITransientDependency return Task.FromResult(StateModel); } - public Task IncreaseInventoryAsync(int quantity, bool decreaseSold) + public Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) { StateModel.Inventory += quantity; @@ -29,7 +29,7 @@ public class FakeInventoryGrain : IInventoryGrain, ITransientDependency return Task.CompletedTask; } - public Task ReduceInventoryAsync(int quantity, bool increaseSold) + public Task ReduceInventoryAsync(int quantity, bool increaseSold, bool isFlashSale) { StateModel.Inventory -= quantity; From 2db229450e531977f7a4de5123261bbf6a52fbd8 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 04:10:37 +0800 Subject: [PATCH 68/97] Change version to 3.0.0-preview.9 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 5d3324d9..2ebe1c73 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.8 + 3.0.0-preview.9 $(NoWarn);CS1591 true EasyAbp Team From 4f77f025d9a7b9f2ef944a690f9f0be6eab463fb Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 14:59:44 +0800 Subject: [PATCH 69/97] Add logs for inventory rollback fail --- .../InventoryRollbackOrderCanceledEventHandler.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/InventoryRollbackOrderCanceledEventHandler.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/InventoryRollbackOrderCanceledEventHandler.cs index 6b8f3d70..386575b5 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/InventoryRollbackOrderCanceledEventHandler.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/InventoryRollbackOrderCanceledEventHandler.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Threading.Tasks; using EasyAbp.EShop.Orders.Orders; +using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Uow; @@ -10,13 +11,16 @@ namespace EasyAbp.EShop.Products.Products // see: https://github.com/EasyAbp/EShop/issues/139 public class InventoryRollbackOrderCanceledEventHandler : IDistributedEventHandler, ITransientDependency { + private readonly ILogger _logger; private readonly IProductManager _productManager; private readonly IProductRepository _productRepository; public InventoryRollbackOrderCanceledEventHandler( + ILogger logger, IProductManager productManager, IProductRepository productRepository) { + _logger = logger; _productManager = productManager; _productRepository = productRepository; } @@ -40,7 +44,12 @@ namespace EasyAbp.EShop.Products.Products var productSku = product.ProductSkus.Single(x => x.Id == orderLine.ProductSkuId); - await _productManager.TryIncreaseInventoryAsync(product, productSku, orderLine.Quantity, true); + if (!await _productManager.TryIncreaseInventoryAsync(product, productSku, orderLine.Quantity, true)) + { + _logger.LogWarning( + "InventoryRollbackOrderCanceledEventHandler: inventory rollback failed! productId = {productId}, productSkuId = {productSkuId}, quantity = {quantity}, reduceSold = {reduceSold}", + orderLine.ProductId, orderLine.ProductSkuId, orderLine.Quantity, true); + } } } } From 26221596e193f748bea11a74ec47bbae9b5c0d08 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 15:02:12 +0800 Subject: [PATCH 70/97] Use protected instead of public --- .../EShop/Plugins/Inventories/DaprActors/InventoryActor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs index 3eedce1f..0d9938b0 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs @@ -69,10 +69,10 @@ public class InventoryActor : Actor, IInventoryActor } } - public virtual Task InternalGetInventoryStateAsync() => + protected virtual Task InternalGetInventoryStateAsync() => StateManager.GetStateAsync(InventoryStateName); - public async Task TrySetInventoryStateAsync(InventoryStateModel stateModel) + protected virtual async Task TrySetInventoryStateAsync(InventoryStateModel stateModel) { if (!TimeToPersistInventory.HasValue || TimeToPersistInventory.Value < Clock.Now) { From c7f781f32b4de82981bd2a0aa6d014103363c6f4 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 15:03:11 +0800 Subject: [PATCH 71/97] Change version to 3.0.0-preview.10 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 2ebe1c73..ca95604e 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.9 + 3.0.0-preview.10 $(NoWarn);CS1591 true EasyAbp Team From 6c9aebb24a8c023df2888d693abb1bf1878c81be Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 16:02:46 +0800 Subject: [PATCH 72/97] Use actor timer to persist inventory for flash sales --- ...Shop.Plugins.Inventories.DaprActors.csproj | 1 - ...EShopPluginsInventoriesDaprActorsModule.cs | 2 - .../Inventories/DaprActors/InventoryActor.cs | 53 +++++++++---------- ...p.Plugins.Inventories.OrleansGrains.csproj | 1 - ...opPluginsInventoriesOrleansGrainsModule.cs | 2 - .../OrleansGrains/InventoryGrain.cs | 45 +++++++--------- 6 files changed, 45 insertions(+), 59 deletions(-) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj index 386df1c6..4b5cd92d 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp.EShop.Plugins.Inventories.DaprActors.csproj @@ -12,7 +12,6 @@ - diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs index 65b224a5..0b59cb9b 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/EShopPluginsInventoriesDaprActorsModule.cs @@ -1,10 +1,8 @@ using Volo.Abp.Modularity; -using Volo.Abp.Timing; namespace EasyAbp.EShop.Plugins.Inventories.DaprActors; [DependsOn( - typeof(AbpTimingModule), typeof(EShopPluginsInventoriesDaprActorsAbstractionsModule) )] public class EShopPluginsInventoriesDaprActorsModule : AbpModule diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs index 0d9938b0..b78c33f8 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs @@ -2,7 +2,7 @@ using System; using System.Threading.Tasks; using Dapr; using Dapr.Actors.Runtime; -using Volo.Abp.Timing; +using JetBrains.Annotations; namespace EasyAbp.EShop.Plugins.Inventories.DaprActors; @@ -10,13 +10,13 @@ public class InventoryActor : Actor, IInventoryActor { public static string InventoryStateName { get; set; } = "i"; - protected DateTime? TimeToPersistInventory { get; set; } + protected bool FlashSalesInventoryUpdated { get; set; } - protected IClock Clock { get; } + [CanBeNull] + protected ActorTimer FlashSalesPersistInventoryTimer { get; set; } - public InventoryActor(ActorHost host, IClock clock) : base(host) + public InventoryActor(ActorHost host) : base(host) { - Clock = clock; } protected override async Task OnActivateAsync() @@ -24,64 +24,61 @@ public class InventoryActor : Actor, IInventoryActor await StateManager.TryAddStateAsync(InventoryStateName, new InventoryStateModel()); } - public virtual async Task GetInventoryStateAsync() - { - var state = await InternalGetInventoryStateAsync(); - - await TrySetInventoryStateAsync(state); - - return state; - } + public virtual Task GetInventoryStateAsync() => + StateManager.GetStateAsync(InventoryStateName); public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) { - var state = await InternalGetInventoryStateAsync(); + var state = await GetInventoryStateAsync(); InternalIncreaseInventory(state, quantity, decreaseSold); - if (!isFlashSale || state.Inventory == 0) + if (!isFlashSale) { await SetInventoryStateAsync(state); } else { - TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + FlashSalesInventoryUpdated = true; - await TrySetInventoryStateAsync(state); + await TryRegisterFlashSalesPersistInventoryTimerAsync(); } } public virtual async Task ReduceInventoryAsync(int quantity, bool increaseSold, bool isFlashSale) { - var state = await InternalGetInventoryStateAsync(); + var state = await GetInventoryStateAsync(); InternalReduceInventory(state, quantity, increaseSold); - if (!isFlashSale || state.Inventory == 0) + if (!isFlashSale) { await SetInventoryStateAsync(state); } else { - TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + FlashSalesInventoryUpdated = true; - await TrySetInventoryStateAsync(state); + await TryRegisterFlashSalesPersistInventoryTimerAsync(); } } - protected virtual Task InternalGetInventoryStateAsync() => - StateManager.GetStateAsync(InventoryStateName); + protected virtual async Task TryRegisterFlashSalesPersistInventoryTimerAsync() + { + FlashSalesPersistInventoryTimer ??= await RegisterTimerAsync(null, nameof(PeriodicSetInventoryStateAsync), + null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3)); + } - protected virtual async Task TrySetInventoryStateAsync(InventoryStateModel stateModel) + protected virtual async Task PeriodicSetInventoryStateAsync() { - if (!TimeToPersistInventory.HasValue || TimeToPersistInventory.Value < Clock.Now) + if (!FlashSalesInventoryUpdated) { - return false; + return; } - await SetInventoryStateAsync(stateModel); + await SetInventoryStateAsync(await GetInventoryStateAsync()); - return true; + FlashSalesInventoryUpdated = false; } protected virtual async Task SetInventoryStateAsync(InventoryStateModel state) diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj index 2346d462..6e831f2a 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp.EShop.Plugins.Inventories.OrleansGrains.csproj @@ -12,7 +12,6 @@ - all diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs index 40b6f09d..087bb7b9 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/EShopPluginsInventoriesOrleansGrainsModule.cs @@ -1,10 +1,8 @@ using Volo.Abp.Modularity; -using Volo.Abp.Timing; namespace EasyAbp.EShop.Plugins.Inventories.OrleansGrains; [DependsOn( - typeof(AbpTimingModule), typeof(EShopPluginsInventoriesOrleansGrainsAbstractionsModule) )] public class EShopPluginsInventoriesOrleansGrainsModule : AbpModule diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs index 06213b69..b17aadbc 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs @@ -1,9 +1,9 @@ using System; using System.Threading.Tasks; +using JetBrains.Annotations; using Orleans; using Orleans.Providers; using Orleans.Runtime; -using Volo.Abp.Timing; namespace EasyAbp.EShop.Plugins.Inventories.OrleansGrains; @@ -12,23 +12,12 @@ public class InventoryGrain : Grain, IInventoryGrain { public const string StorageProviderName = "EShopInventoryStorage"; - protected DateTime? TimeToPersistInventory { get; set; } + protected bool FlashSalesInventoryUpdated { get; set; } - protected IClock Clock { get; } + [CanBeNull] + protected IDisposable FlashSalesPersistInventoryTimer { get; set; } - public InventoryGrain(IClock clock) - { - Clock = clock; - } - - public virtual async Task GetInventoryStateAsync() - { - var state = State; - - await TryWriteStateAsync(); - - return state; - } + public virtual Task GetInventoryStateAsync() => Task.FromResult(State); public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) { @@ -40,9 +29,9 @@ public class InventoryGrain : Grain, IInventoryGrain } else { - TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + FlashSalesInventoryUpdated = true; - await TryWriteStateAsync(); + TryRegisterFlashSalesPersistInventoryTimer(); } } @@ -56,22 +45,28 @@ public class InventoryGrain : Grain, IInventoryGrain } else { - TimeToPersistInventory ??= Clock.Now + TimeSpan.FromSeconds(30); + FlashSalesInventoryUpdated = true; - await TryWriteStateAsync(); + TryRegisterFlashSalesPersistInventoryTimer(); } } - - public async Task TryWriteStateAsync() + + protected virtual void TryRegisterFlashSalesPersistInventoryTimer() + { + FlashSalesPersistInventoryTimer ??= RegisterTimer(PeriodicWriteInventoryStateAsync, + new object(), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3)); + } + + protected virtual async Task PeriodicWriteInventoryStateAsync(object obj) { - if (!TimeToPersistInventory.HasValue || TimeToPersistInventory.Value < Clock.Now) + if (!FlashSalesInventoryUpdated) { - return false; + return; } await WriteStateAsync(); - return true; + FlashSalesInventoryUpdated = false; } protected virtual void InternalIncreaseInventory(int quantity, bool decreaseSold) From df6c13631f899a6f5a975384fe855cfe7609429d Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 16:11:07 +0800 Subject: [PATCH 73/97] Persist inventory on deactivate --- .../EShop/Plugins/Inventories/DaprActors/InventoryActor.cs | 6 +++--- .../Plugins/Inventories/OrleansGrains/InventoryGrain.cs | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs index b78c33f8..29f5555e 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs @@ -81,10 +81,10 @@ public class InventoryActor : Actor, IInventoryActor FlashSalesInventoryUpdated = false; } - protected virtual async Task SetInventoryStateAsync(InventoryStateModel state) - { + protected virtual async Task SetInventoryStateAsync(InventoryStateModel state) => await StateManager.SetStateAsync(InventoryStateName, state); - } + + protected override async Task OnDeactivateAsync() => await SetInventoryStateAsync(await GetInventoryStateAsync()); protected virtual void InternalIncreaseInventory(InventoryStateModel stateModel, int quantity, bool decreaseSold) { diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs index b17aadbc..1815bcb3 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs @@ -69,6 +69,8 @@ public class InventoryGrain : Grain, IInventoryGrain FlashSalesInventoryUpdated = false; } + public override Task OnDeactivateAsync() => WriteStateAsync(); + protected virtual void InternalIncreaseInventory(int quantity, bool decreaseSold) { if (quantity < 0) From 8dc2e8a6427f12da29d2a382e77f6fa53f5156fc Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 16:55:40 +0800 Subject: [PATCH 74/97] Improve inventory actor timers --- .../Inventories/DaprActors/InventoryActor.cs | 21 +++++++++---------- .../OrleansGrains/InventoryGrain.cs | 21 +++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs index 29f5555e..ce3ca9b0 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs @@ -2,7 +2,6 @@ using System; using System.Threading.Tasks; using Dapr; using Dapr.Actors.Runtime; -using JetBrains.Annotations; namespace EasyAbp.EShop.Plugins.Inventories.DaprActors; @@ -12,9 +11,6 @@ public class InventoryActor : Actor, IInventoryActor protected bool FlashSalesInventoryUpdated { get; set; } - [CanBeNull] - protected ActorTimer FlashSalesPersistInventoryTimer { get; set; } - public InventoryActor(ActorHost host) : base(host) { } @@ -39,8 +35,6 @@ public class InventoryActor : Actor, IInventoryActor } else { - FlashSalesInventoryUpdated = true; - await TryRegisterFlashSalesPersistInventoryTimerAsync(); } } @@ -57,19 +51,24 @@ public class InventoryActor : Actor, IInventoryActor } else { - FlashSalesInventoryUpdated = true; - await TryRegisterFlashSalesPersistInventoryTimerAsync(); } } protected virtual async Task TryRegisterFlashSalesPersistInventoryTimerAsync() { - FlashSalesPersistInventoryTimer ??= await RegisterTimerAsync(null, nameof(PeriodicSetInventoryStateAsync), - null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3)); + if (FlashSalesInventoryUpdated) + { + return; + } + + FlashSalesInventoryUpdated = true; + + await RegisterTimerAsync(null, nameof(TimerSetInventoryStateAsync), null, TimeSpan.FromSeconds(5), + TimeSpan.FromMilliseconds(-1)); } - protected virtual async Task PeriodicSetInventoryStateAsync() + protected virtual async Task TimerSetInventoryStateAsync() { if (!FlashSalesInventoryUpdated) { diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs index 1815bcb3..cb4aa189 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs @@ -1,6 +1,5 @@ using System; using System.Threading.Tasks; -using JetBrains.Annotations; using Orleans; using Orleans.Providers; using Orleans.Runtime; @@ -14,9 +13,6 @@ public class InventoryGrain : Grain, IInventoryGrain protected bool FlashSalesInventoryUpdated { get; set; } - [CanBeNull] - protected IDisposable FlashSalesPersistInventoryTimer { get; set; } - public virtual Task GetInventoryStateAsync() => Task.FromResult(State); public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) @@ -29,8 +25,6 @@ public class InventoryGrain : Grain, IInventoryGrain } else { - FlashSalesInventoryUpdated = true; - TryRegisterFlashSalesPersistInventoryTimer(); } } @@ -45,19 +39,24 @@ public class InventoryGrain : Grain, IInventoryGrain } else { - FlashSalesInventoryUpdated = true; - TryRegisterFlashSalesPersistInventoryTimer(); } } protected virtual void TryRegisterFlashSalesPersistInventoryTimer() { - FlashSalesPersistInventoryTimer ??= RegisterTimer(PeriodicWriteInventoryStateAsync, - new object(), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3)); + if (FlashSalesInventoryUpdated) + { + return; + } + + FlashSalesInventoryUpdated = true; + + RegisterTimer(TimerWriteInventoryStateAsync, new object(), TimeSpan.FromSeconds(5), + TimeSpan.FromMilliseconds(-1)); } - protected virtual async Task PeriodicWriteInventoryStateAsync(object obj) + protected virtual async Task TimerWriteInventoryStateAsync(object obj) { if (!FlashSalesInventoryUpdated) { From 94746c4fc30446088bcc368a9f4cca4a08046aee Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 16:57:52 +0800 Subject: [PATCH 75/97] Change version to 3.0.0-preview.11 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index ca95604e..df4910c4 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.10 + 3.0.0-preview.11 $(NoWarn);CS1591 true EasyAbp Team From 703acd195204bd6eb6005e3fa2ca13bdc0cf8ea7 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 19:54:07 +0800 Subject: [PATCH 76/97] Fix a state bug in `InventoryActor` --- .../Plugins/Inventories/DaprActors/InventoryActor.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs index ce3ca9b0..73f8963c 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; using Dapr; using Dapr.Actors.Runtime; +using JetBrains.Annotations; namespace EasyAbp.EShop.Plugins.Inventories.DaprActors; @@ -11,6 +12,9 @@ public class InventoryActor : Actor, IInventoryActor protected bool FlashSalesInventoryUpdated { get; set; } + [CanBeNull] + protected InventoryStateModel State { get; set; } + public InventoryActor(ActorHost host) : base(host) { } @@ -20,8 +24,8 @@ public class InventoryActor : Actor, IInventoryActor await StateManager.TryAddStateAsync(InventoryStateName, new InventoryStateModel()); } - public virtual Task GetInventoryStateAsync() => - StateManager.GetStateAsync(InventoryStateName); + public virtual async Task GetInventoryStateAsync() => + State ??= await StateManager.GetStateAsync(InventoryStateName); public virtual async Task IncreaseInventoryAsync(int quantity, bool decreaseSold, bool isFlashSale) { From e68aa54bd969b732790c8cd648b248c11c53e7eb Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 8 Aug 2022 20:24:14 +0800 Subject: [PATCH 77/97] Change version to 3.0.0-preview.12 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index df4910c4..6d13ef79 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.11 + 3.0.0-preview.12 $(NoWarn);CS1591 true EasyAbp Team From 22a4d0dbce111943c0993050b19c7bf715051ea4 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Tue, 9 Aug 2022 13:49:02 +0800 Subject: [PATCH 78/97] Fix authorization of flash sales module --- .../FlashSalePlans/FlashSalePlanAppService.cs | 10 ++-------- .../FlashSaleResultAppService.cs | 19 +++++++++---------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 14d8e91c..2eb6b92d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -107,10 +107,7 @@ public class FlashSalePlanAppService : { var flashSalePlan = await GetEntityByIdAsync(id); - if (GetPolicyName is not null) - { - await CheckMultiStorePolicyAsync(flashSalePlan.StoreId, GetPolicyName); - } + await CheckGetPolicyAsync(); if (!flashSalePlan.IsPublished) { @@ -122,10 +119,7 @@ public class FlashSalePlanAppService : public override async Task> GetListAsync(FlashSalePlanGetListInput input) { - if (GetListPolicyName is not null) - { - await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); - } + await CheckGetListPolicyAsync(); return await base.GetListAsync(input); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index d58f19b0..c9034bb9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -5,6 +5,7 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using EasyAbp.EShop.Stores.Stores; using Volo.Abp.Application.Dtos; +using Volo.Abp.Users; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; @@ -24,12 +25,11 @@ public class FlashSaleResultAppService : { var flashSaleResult = await GetEntityByIdAsync(id); - if (GetPolicyName is not null) + if (flashSaleResult.UserId == CurrentUser.Id) { - await CheckMultiStorePolicyAsync(flashSaleResult.StoreId, GetPolicyName); + await CheckGetPolicyAsync(); } - - if (flashSaleResult.UserId != CurrentUser.Id) + else { await CheckMultiStorePolicyAsync(flashSaleResult.StoreId, FlashSalesPermissions.FlashSaleResult.Manage); } @@ -39,7 +39,11 @@ public class FlashSaleResultAppService : public override async Task> GetListAsync(FlashSaleResultGetListInput input) { - if (GetListPolicyName is not null) + if (input.UserId.HasValue && input.UserId == CurrentUser.Id) + { + await CheckGetListPolicyAsync(); + } + else { await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName); } @@ -49,11 +53,6 @@ public class FlashSaleResultAppService : protected override async Task> CreateFilteredQueryAsync(FlashSaleResultGetListInput input) { - if (input.UserId != CurrentUser.Id) - { - await CheckMultiStorePolicyAsync(input.StoreId, FlashSalesPermissions.FlashSaleResult.Manage); - } - return (await base.CreateFilteredQueryAsync(input)) .WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId.Value) .WhereIf(input.PlanId.HasValue, x => x.PlanId == input.PlanId.Value) From 2177adec7bc191f161fb793663a5e5109264d5ee Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Tue, 9 Aug 2022 13:51:03 +0800 Subject: [PATCH 79/97] Fix `FlashSalePlanAppService.CreateFilteredQueryAsync` method --- .../FlashSalePlans/FlashSalePlanAppService.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 2eb6b92d..b61b3a50 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -121,6 +121,11 @@ public class FlashSalePlanAppService : { await CheckGetListPolicyAsync(); + if (input.IncludeUnpublished) + { + await CheckMultiStorePolicyAsync(input.StoreId, FlashSalesPermissions.FlashSalePlan.Manage); + } + return await base.GetListAsync(input); } @@ -191,11 +196,6 @@ public class FlashSalePlanAppService : protected override async Task> CreateFilteredQueryAsync(FlashSalePlanGetListInput input) { - if (input.IncludeUnpublished) - { - await CheckMultiStorePolicyAsync(input.StoreId, FlashSalesPermissions.FlashSalePlan.Manage); - } - return (await base.CreateFilteredQueryAsync(input)) .WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId.Value) .WhereIf(input.ProductId.HasValue, x => x.ProductId == input.ProductId.Value) From f38aca1088548d2622b1a95e76f0ac947ba4e1f1 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Tue, 9 Aug 2022 13:53:36 +0800 Subject: [PATCH 80/97] Change version to 3.0.0-preview.13 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 6d13ef79..47c1e2be 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.12 + 3.0.0-preview.13 $(NoWarn);CS1591 true EasyAbp Team From 7f86174fcf56af88a6ef2b2f1a45c682a7930c37 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 14 Aug 2022 17:12:39 +0800 Subject: [PATCH 81/97] Update sample app Program.cs --- .../src/EShopSample.Web/Program.cs | 24 ++++++++++--------- .../src/EShopSample.Web/Startup.cs | 18 -------------- 2 files changed, 13 insertions(+), 29 deletions(-) delete mode 100644 samples/EShopSample/aspnet-core/src/EShopSample.Web/Startup.cs diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs index 9a93944d..a0ff483d 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.Web/Program.cs @@ -1,5 +1,8 @@ using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -8,7 +11,7 @@ namespace EShopSample.Web { public class Program { - public static int Main(string[] args) + public static async Task Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG @@ -27,7 +30,15 @@ namespace EShopSample.Web try { Log.Information("Starting web host."); - CreateHostBuilder(args).Build().Run(); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + app.MapGet("ping", () => "pong"); + await app.RunAsync(); return 0; } catch (Exception ex) @@ -40,14 +51,5 @@ namespace EShopSample.Web Log.CloseAndFlush(); } } - - internal static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .UseAutofac() - .UseSerilog(); } } diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Startup.cs b/samples/EShopSample/aspnet-core/src/EShopSample.Web/Startup.cs deleted file mode 100644 index 288c6529..00000000 --- a/samples/EShopSample/aspnet-core/src/EShopSample.Web/Startup.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; - -namespace EShopSample.Web -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - services.AddApplication(); - } - - public void Configure(IApplicationBuilder app) - { - app.InitializeApplication(); - } - } -} From 6be4a0652f9e257d7c9681762a3d13e686b8d72c Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Sun, 14 Aug 2022 17:13:55 +0800 Subject: [PATCH 82/97] Disable auditing of IFlashSalePlanAppService.OrderAsync --- .../FlashSales/FlashSalePlans/FlashSalePlanAppService.cs | 2 ++ .../FlashSales/FlashSalePlans/FlashSalePlanController.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index b61b3a50..084f1f1b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; using Volo.Abp; using Volo.Abp.Application.Dtos; +using Volo.Abp.Auditing; using Volo.Abp.Caching; using Volo.Abp.Data; using Volo.Abp.DistributedLocking; @@ -222,6 +223,7 @@ public class FlashSalePlanAppService : return new FlashSalePlanPreOrderDto { ExpiresTime = Clock.Normalize(expiresTime.LocalDateTime), ExpiresInSeconds = Options.PreOrderExpires.TotalSeconds }; } + [DisableAuditing] [Authorize] public virtual async Task OrderAsync(Guid id, CreateOrderInput input) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index bd18e94e..6ed92500 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -4,6 +4,7 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using Microsoft.AspNetCore.Mvc; using Volo.Abp; using Volo.Abp.Application.Dtos; +using Volo.Abp.Auditing; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; @@ -57,6 +58,7 @@ public class FlashSalePlanController : return Service.PreOrderAsync(id); } + [DisableAuditing] [HttpPost("{id}/order")] public virtual Task OrderAsync(Guid id, CreateOrderInput input) { From 798f1f83a16710da7c659421d64664805095ff21 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Mon, 15 Aug 2022 22:56:50 +0800 Subject: [PATCH 83/97] Refactor the flash sales plugin module --- docs/plugins/flash-sales/README.md | 4 +- .../CreateFlashSaleOrderEventHandler.cs | 27 ++- .../Dtos/FlashSaleOrderResultDto.cs | 10 +- ...derInput.cs => OrderFlashSalePlanInput.cs} | 2 +- .../IFlashSalePlanAppService.cs | 2 +- .../Dtos/FlashSaleResultDto.cs | 14 +- .../IFlashSaleResultAppService.cs | 3 +- .../CreateFlashSaleOrderFailedEventHandler.cs | 71 ------ ...lashSaleOrderCreationResultEventHandler.cs | 93 +++++++ .../FlashSalePlans/FlashSalePlanAppService.cs | 165 ++++++------- .../CreateFlashSaleResultEventHandler.cs | 109 +++++++++ .../FlashSaleCurrentResultCache.cs | 59 +++++ .../FlashSaleCurrentResultCacheItem.cs | 13 + .../FlashSaleResultAppService.cs | 45 +++- .../IFlashSaleCurrentResultCache.cs | 13 + .../FlashSalesOptions.cs | 4 +- .../FlashSalePlans/CreateFlashSaleOrderEto.cs | 8 +- ....cs => FlashSaleOrderCreationResultEto.cs} | 6 +- .../CreateFlashSaleResultEto.cs | 24 ++ .../FlashSaleResultFailedReason.cs | 2 - .../FlashSales/FlashSalesErrorCodes.cs | 2 + .../Plugins/FlashSales/Localization/en.json | 2 + .../FlashSales/Localization/zh-Hans.json | 2 + .../FlashSales/Localization/zh-Hant.json | 2 + ...reateFlashSaleOrderCompleteEventHandler.cs | 37 --- .../FlashSaleResults/FlashSaleResult.cs | 13 +- .../FlashSaleResults/IFlashSaleResult.cs | 17 ++ .../FlashSalePlans/FlashSalePlanController.cs | 7 +- .../FlashSaleResultController.cs | 6 + .../ViewFlashSaleResultViewModel.cs | 3 + .../FlashSaleResults/FlashSaleResult/index.js | 5 + .../CreateFlashSaleOrderEventHandlerTests.cs | 23 +- ...PluginsFlashSalesApplicationTestsModule.cs | 4 +- ...ersPluginsFlashSalesApplicationTestBase.cs | 3 +- ...ateFlashSaleOrderFailedEventHandlerTest.cs | 165 ------------- ...aleOrderCreationResultEventHandlerTests.cs | 229 ++++++++++++++++++ .../FlashSalePlanAppServiceTests.cs | 119 +++++---- .../CreateFlashSaleResultEventHandlerTests.cs | 122 ++++++++++ .../FlashSalesApplicationTestBase.cs | 9 +- ...FlashSaleOrderCompleteEventHandlerTests.cs | 85 ------- .../FlashSaleResults/FlashSaleResultTests.cs | 12 +- 41 files changed, 961 insertions(+), 580 deletions(-) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/Dtos/{CreateOrderInput.cs => OrderFlashSalePlanInput.cs} (72%) delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCache.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCacheItem.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleCurrentResultCache.cs rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/{FlashSalePlans => Options}/FlashSalesOptions.cs (63%) rename plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/{CreateFlashSaleOrderCompleteEto.cs => FlashSaleOrderCreationResultEto.cs} (74%) create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs delete mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs create mode 100644 plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResult.cs delete mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandlerTest.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs create mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs delete mode 100644 plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs diff --git a/docs/plugins/flash-sales/README.md b/docs/plugins/flash-sales/README.md index f29c46e7..9b2896a5 100644 --- a/docs/plugins/flash-sales/README.md +++ b/docs/plugins/flash-sales/README.md @@ -41,6 +41,6 @@ A flash-sales plugin for EShop. ### Customers -1. Use `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/pre-order` (POST) to pre-order. It will return an expiration time if your pre-order request succeeds. You should re-invoke this API to refresh your request before the expiration time. +1. Use `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/pre-order` (POST) to pre-order. It will return an expiration time if your pre-order request succeeds. Don't forget to re-invoke this API to refresh your request before the expiration time. 2. When the flash sale starts, use `/api/e-shop/plugins/flash-sales/flash-sale-plan/{planId}/order` (POST) to create your order. If you are fast enough, it will occupy the inventory and create an order for you in the background. -3. If you are told that you have succeeded, continuous use `/api/e-shop/plugins/flash-sales/flash-sale-result/{resultId}` (GET) to query the order creation result until it succeeds or fails. +3. If you are told that you have succeeded, continuous use `/api/e-shop/plugins/flash-sales/flash-sale-result/current/{planId}` (GET) to query the order creation result until it succeeds or fails. diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index 57d85ec1..be794301 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -10,6 +10,7 @@ using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; +using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectMapping; using Volo.Abp.Uow; @@ -61,16 +62,17 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler() { @@ -139,6 +142,8 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler PreOrderAsync(Guid id); - Task OrderAsync(Guid id, CreateOrderInput input); + Task OrderAsync(Guid id, OrderFlashSalePlanInput flashSalePlanInput); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs index 1df7365f..46c19205 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/Dtos/FlashSaleResultDto.cs @@ -6,15 +6,17 @@ namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; public class FlashSaleResultDto : ExtensibleFullAuditedEntityDto, IMultiStore { - public virtual Guid StoreId { get; set; } + public Guid StoreId { get; set; } - public virtual Guid PlanId { get; set; } + public Guid PlanId { get; set; } - public virtual FlashSaleResultStatus Status { get; set; } + public FlashSaleResultStatus Status { get; set; } - public virtual string Reason { get; set; } + public string Reason { get; set; } - public virtual Guid UserId { get; set; } + public Guid UserId { get; set; } - public virtual Guid? OrderId { get; set; } + public Guid? OrderId { get; set; } + + public DateTime ReducedInventoryTime { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs index 3c1bce94..4b95c6a5 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application.Contracts/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResultAppService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using Volo.Abp.Application.Services; @@ -10,5 +11,5 @@ public interface IFlashSaleResultAppService : Guid, FlashSaleResultGetListInput> { - + Task GetCurrentAsync(Guid planId); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandler.cs deleted file mode 100644 index 7e5f7d89..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandler.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Threading.Tasks; -using EasyAbp.Eshop.Products.Products; -using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -using EasyAbp.EShop.Products.Products; -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Logging; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EventBus.Distributed; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -public class CreateFlashSaleOrderFailedEventHandler : IDistributedEventHandler, ITransientDependency -{ - protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } - protected IDistributedCache DistributedCache { get; } - protected IFlashSalePlanRepository FlashSalePlanRepository { get; } - protected IProductAppService ProductAppService { get; } - protected ILogger Logger { get; } - - public CreateFlashSaleOrderFailedEventHandler ( - IFlashSaleInventoryManager flashSaleInventoryManager, - IDistributedCache distributedCache, - IFlashSalePlanRepository flashSalePlanRepository, - IProductAppService productAppService, - ILogger logger) - { - FlashSaleInventoryManager = flashSaleInventoryManager; - DistributedCache = distributedCache; - FlashSalePlanRepository = flashSalePlanRepository; - ProductAppService = productAppService; - Logger = logger; - } - - public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) - { - if (eventData.Success) - { - return; - } - - if (eventData.Reason != FlashSaleResultFailedReason.InvalidHashToken) - { - return; - } - - var plan = await FlashSalePlanRepository.GetAsync(eventData.PlanId); - var product = await ProductAppService.GetAsync(plan.ProductId); - - if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync( - plan.TenantId, product.InventoryProviderName, - plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true - )) - { - Logger.LogWarning("Try roll back inventory failed."); - return; - } - - await RemoveUserFlashSaleResultCacheAsync(plan, eventData.UserId); - } - - protected virtual Task GetUserFlashSaleResultCacheKeyAsync(FlashSalePlan plan, Guid userId) - { - return Task.FromResult(string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, userId)); - } - - protected virtual async Task RemoveUserFlashSaleResultCacheAsync(FlashSalePlan plan, Guid userId) - { - await DistributedCache.RemoveAsync(await GetUserFlashSaleResultCacheKeyAsync(plan, userId)); - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs new file mode 100644 index 00000000..c626ef58 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs @@ -0,0 +1,93 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.Eshop.Products.Products; +using EasyAbp.EShop.Products.Products; +using Microsoft.Extensions.Logging; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler, + ITransientDependency +{ + protected ILogger Logger { get; } + protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } + protected IFlashSalePlanRepository FlashSalePlanRepository { get; } + protected IProductAppService ProductAppService { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + protected IObjectMapper ObjectMapper { get; } + protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } + protected IFlashSaleResultRepository FlashSaleResultRepository { get; } + + public FlashSaleOrderCreationResultEventHandler( + ILogger logger, + IFlashSaleInventoryManager flashSaleInventoryManager, + IFlashSalePlanRepository flashSalePlanRepository, + IProductAppService productAppService, + IUnitOfWorkManager unitOfWorkManager, + IObjectMapper objectMapper, + IFlashSaleCurrentResultCache flashSaleCurrentResultCache, + IFlashSaleResultRepository flashSaleResultRepository) + { + Logger = logger; + FlashSaleInventoryManager = flashSaleInventoryManager; + FlashSalePlanRepository = flashSalePlanRepository; + ProductAppService = productAppService; + UnitOfWorkManager = unitOfWorkManager; + ObjectMapper = objectMapper; + FlashSaleCurrentResultCache = flashSaleCurrentResultCache; + FlashSaleResultRepository = flashSaleResultRepository; + } + + [UnitOfWork] + public virtual async Task HandleEventAsync(FlashSaleOrderCreationResultEto eventData) + { + var flashSaleResult = await FlashSaleResultRepository.GetAsync(eventData.ResultId); + + if (eventData.Success) + { + flashSaleResult.MarkAsSuccessful(eventData.OrderId!.Value); + + await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true); + } + else + { + var plan = await FlashSalePlanRepository.GetAsync(eventData.PlanId); + var product = await ProductAppService.GetAsync(plan.ProductId); + + flashSaleResult.MarkAsFailed(eventData.Reason); + + await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true); + + if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync( + plan.TenantId, product.InventoryProviderName, + plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true + )) + { + Logger.LogWarning("Try roll back inventory failed."); + return; // Avoid to remove cache on the UOW completed. + } + } + + UnitOfWorkManager.Current.OnCompleted(async () => + { + if (flashSaleResult.Status is FlashSaleResultStatus.Failed && eventData.AllowToTryAgain) + { + await FlashSaleCurrentResultCache.RemoveAsync(flashSaleResult.PlanId, flashSaleResult.UserId); + } + else + { + await FlashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, + new FlashSaleCurrentResultCacheItem + { + TenantId = flashSaleResult.TenantId, + ResultDto = ObjectMapper.Map(flashSaleResult) + }); + } + }); + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 084f1f1b..7fd09c35 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -4,12 +4,15 @@ using System.Threading.Tasks; using EasyAbp.Eshop.Products.Products; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Options; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Stores.Stores; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp; using Volo.Abp.Application.Dtos; @@ -20,6 +23,8 @@ using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Uow; using Volo.Abp.Users; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; @@ -35,14 +40,6 @@ public class FlashSalePlanAppService : /// public const string PreOrderCacheKeyFormat = "eshopflashsales_{0}_{1}"; - /// - /// The cache key format. - /// {0}: Tenant ID - /// {1}: FlashSalePlan ID - /// {2}: User ID - /// - public const string UserFlashSaleResultCacheKeyFormat = "eshopflashsales-result_{0}_{1}_{2}"; - protected override string CrossStorePolicyName { get; set; } = FlashSalesPermissions.FlashSalePlan.CrossStore; protected override string GetPolicyName { get; set; } = null; protected override string GetListPolicyName { get; set; } = null; @@ -71,7 +68,7 @@ public class FlashSalePlanAppService : protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } - protected IDistributedCache DistributedCache { get; } + protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } protected FlashSalesOptions Options { get; } @@ -86,8 +83,8 @@ public class FlashSalePlanAppService : IAbpDistributedLock distributedLock, IFlashSalePlanHasher flashSalePlanHasher, IFlashSaleInventoryManager flashSaleInventoryManager, - IDistributedCache distributedCache, - IOptionsMonitor optionsMonitor) + IFlashSaleCurrentResultCache flashSaleCurrentResultCache, + IOptions options) : base(flashSalePlanRepository) { FlashSalePlanRepository = flashSalePlanRepository; @@ -100,8 +97,8 @@ public class FlashSalePlanAppService : DistributedLock = distributedLock; FlashSalePlanHasher = flashSalePlanHasher; FlashSaleInventoryManager = flashSaleInventoryManager; - DistributedCache = distributedCache; - Options = optionsMonitor.CurrentValue; + FlashSaleCurrentResultCache = flashSaleCurrentResultCache; + Options = options.Value; } public override async Task GetAsync(Guid id) @@ -207,6 +204,7 @@ public class FlashSalePlanAppService : } [Authorize] + [UnitOfWork(IsDisabled = true)] public virtual async Task PreOrderAsync(Guid id) { await CheckPolicyAsync(PreOrderPolicyName); @@ -224,25 +222,26 @@ public class FlashSalePlanAppService : } [DisableAuditing] + [UnitOfWork(IsDisabled = true)] [Authorize] - public virtual async Task OrderAsync(Guid id, CreateOrderInput input) + public virtual async Task OrderAsync(Guid id, OrderFlashSalePlanInput flashSalePlanInput) { var preOrderCache = await GetPreOrderCacheAsync(id); if (preOrderCache == null) { - throw new BusinessException(FlashSalesErrorCodes.PreOrderExpired); + return CreateFailureResultDto(FlashSalesErrorCodes.PreOrderExpired); } var plan = await GetFlashSalePlanCacheAsync(id); var now = Clock.Now; if (plan.BeginTime > now) { - throw new BusinessException(FlashSalesErrorCodes.FlashSaleNotStarted); + return CreateFailureResultDto(FlashSalesErrorCodes.FlashSaleNotStarted); } if (now >= plan.EndTime) { - throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); + return CreateFailureResultDto(FlashSalesErrorCodes.FlashSaleIsOver); } await RemovePreOrderCacheAsync(id); @@ -255,39 +254,69 @@ public class FlashSalePlanAppService : if (handle == null) { - throw new BusinessException(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); + return CreateFailureResultDto(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); } - var userFlashSaleResultCache = await GetUserFlashSaleResultCacheAsync(plan.Id); - if (!userFlashSaleResultCache.IsNullOrWhiteSpace()) + if (await FlashSaleCurrentResultCache.GetAsync(plan.Id, CurrentUser.GetId()) is not null) { - throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + return CreateFailureResultDto(FlashSalesErrorCodes.DuplicateFlashSalesOrder); } if (!await FlashSaleInventoryManager.TryReduceInventoryAsync( - plan.TenantId, preOrderCache.InventoryProviderName, - plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) + plan.TenantId, preOrderCache.InventoryProviderName, + plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) { - return new FlashSaleOrderResultDto() { IsSuccess = false }; + await FlashSaleCurrentResultCache.RemoveAsync(plan.Id, CurrentUser.GetId()); + return CreateFailureResultDto(FlashSalesErrorCodes.ProductSkuInventoryExceeded); } - var result = await CreatePendingFlashSaleResultAsync(plan, userId, async (existsResultId) => + try { - await SetUserFlashSaleResultCacheAsync(plan.Id, existsResultId); + var createFlashSaleResultEto = + await PrepareCreateFlashSaleResultEtoAsync(plan, flashSalePlanInput, userId, Clock.Now, preOrderCache.HashToken); + await FlashSaleCurrentResultCache.SetAsync(plan.Id, CurrentUser.GetId(), new FlashSaleCurrentResultCacheItem + { + TenantId = CurrentTenant.Id, + ResultDto = new FlashSaleResultDto + { + Id = createFlashSaleResultEto.ResultId, + StoreId = createFlashSaleResultEto.Plan.StoreId, + PlanId = createFlashSaleResultEto.Plan.Id, + UserId = createFlashSaleResultEto.UserId + } + }); + + await DistributedEventBus.PublishAsync(createFlashSaleResultEto, false, false); + + return new FlashSaleOrderResultDto + { + IsSuccess = true + }; + } + catch (Exception e) + { + Logger.LogWarning("Failed to publish the CreateFlashSaleOrderEto event!"); + Logger.LogException(e, LogLevel.Warning); + await FlashSaleInventoryManager.TryRollBackInventoryAsync( plan.TenantId, preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true ); - }); - - var createFlashSaleOrderEto = await PrepareCreateFlashSaleOrderEtoAsync(plan, result.Id, input, userId, now, preOrderCache.HashToken); - await SetUserFlashSaleResultCacheAsync(plan.Id, result.Id); - - await DistributedEventBus.PublishAsync(createFlashSaleOrderEto); + await FlashSaleCurrentResultCache.RemoveAsync(plan.Id, CurrentUser.GetId()); + return CreateFailureResultDto(FlashSalesErrorCodes.DistributedEventBusUnavailable); + } + } - return new FlashSaleOrderResultDto() { IsSuccess = true, FlashSaleResultId = result.Id }; + protected virtual FlashSaleOrderResultDto CreateFailureResultDto(string errorCode) + { + return new FlashSaleOrderResultDto + { + IsSuccess = false, + ErrorCode = errorCode, + ErrorMessage = L[errorCode] + }; } #region PreOrderCache @@ -335,30 +364,6 @@ public class FlashSalePlanAppService : #endregion - #region UserFlashSaleResultCache - - protected virtual Task GetUserFlashSaleResultCacheKeyAsync(Guid planId) - { - return Task.FromResult(string.Format(UserFlashSaleResultCacheKeyFormat, CurrentTenant.Id, planId, CurrentUser.GetId())); - } - - protected virtual async Task GetUserFlashSaleResultCacheAsync(Guid planId) - { - var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(planId); - return await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); - } - - protected virtual async Task SetUserFlashSaleResultCacheAsync(Guid planId, Guid resultId) - { - var userFlashSaleResultCacheKey = await GetUserFlashSaleResultCacheKeyAsync(planId); - await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, resultId.ToString(), new DistributedCacheEntryOptions() - { - AbsoluteExpiration = DateTimeOffset.Now.Add(Options.UserFlashSaleResultCacheExpires) - }); - } - - #endregion - protected virtual Task ValidatePreOrderAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (!product.IsPublished) @@ -404,60 +409,32 @@ public class FlashSalePlanAppService : return Task.CompletedTask; } - protected virtual Task PrepareCreateFlashSaleOrderEtoAsync( - FlashSalePlanCacheItem plan, Guid resultId, CreateOrderInput input, - Guid userId, DateTime now, string hashToken) + protected virtual Task PrepareCreateFlashSaleResultEtoAsync( + FlashSalePlanCacheItem plan, OrderFlashSalePlanInput flashSalePlanInput, + Guid userId, DateTime reducedInventoryTime, string hashToken) { var planEto = ObjectMapper.Map(plan); planEto.TenantId = CurrentTenant.Id; - var eto = new CreateFlashSaleOrderEto() + var eto = new CreateFlashSaleResultEto { TenantId = CurrentTenant.Id, - PlanId = plan.Id, UserId = userId, - PendingResultId = resultId, - StoreId = plan.StoreId, - CreateTime = now, - CustomerRemark = input.CustomerRemark, + ResultId = GuidGenerator.Create(), + ReducedInventoryTime = reducedInventoryTime, + CustomerRemark = flashSalePlanInput.CustomerRemark, Plan = planEto, HashToken = hashToken }; - if (input.ExtraProperties != null) + if (flashSalePlanInput.ExtraProperties != null) { - foreach (var item in input.ExtraProperties) - { - eto.ExtraProperties.Add(item.Key, item.Value); - } + flashSalePlanInput.MapExtraPropertiesTo(eto, MappingPropertyDefinitionChecks.Source); } return Task.FromResult(eto); } - protected virtual async Task CreatePendingFlashSaleResultAsync(FlashSalePlanCacheItem plan, Guid userId, Func existResultPreProcess) - { - // Prevent repeat submit - var existsResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => - x.PlanId == plan.Id && x.UserId == userId && x.Status != FlashSaleResultStatus.Failed && x.Reason != FlashSaleResultFailedReason.InvalidHashToken); - - if (existsResult != null) - { - await existResultPreProcess(existsResult.Id); - throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); - } - - var result = new FlashSaleResult( - id: GuidGenerator.Create(), - tenantId: CurrentTenant.Id, - storeId: plan.StoreId, - planId: plan.Id, - userId: userId - ); - - return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); - } - protected virtual async Task GetProductCacheAsync(Guid productId) { return await ProductDistributedCache.GetOrAddAsync(productId, async () => diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs new file mode 100644 index 00000000..26a05647 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs @@ -0,0 +1,109 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using Microsoft.Extensions.Logging; +using Volo.Abp; +using Volo.Abp.DependencyInjection; +using Volo.Abp.DistributedLocking; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectExtending; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class CreateFlashSaleResultEventHandler : IDistributedEventHandler, + ITransientDependency +{ + protected IObjectMapper ObjectMapper { get; } + protected IGuidGenerator GuidGenerator { get; } + protected ICurrentTenant CurrentTenant { get; } + protected ILogger Logger { get; } + protected IAbpDistributedLock AbpDistributedLock { get; } + protected IDistributedEventBus DistributedEventBus { get; } + protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } + protected IFlashSaleResultRepository FlashSaleResultRepository { get; } + + public CreateFlashSaleResultEventHandler( + IObjectMapper objectMapper, + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant, + ILogger logger, + IAbpDistributedLock abpDistributedLock, + IDistributedEventBus distributedEventBus, + IFlashSaleCurrentResultCache flashSaleCurrentResultCache, + IFlashSaleResultRepository flashSaleResultRepository) + { + ObjectMapper = objectMapper; + GuidGenerator = guidGenerator; + CurrentTenant = currentTenant; + Logger = logger; + AbpDistributedLock = abpDistributedLock; + DistributedEventBus = distributedEventBus; + FlashSaleCurrentResultCache = flashSaleCurrentResultCache; + FlashSaleResultRepository = flashSaleResultRepository; + } + + [UnitOfWork(true)] + public virtual async Task HandleEventAsync(CreateFlashSaleResultEto eventData) + { + await using var handle = await AbpDistributedLock.TryAcquireAsync(await GetLockKeyAsync(eventData)); + + if (handle is null) + { + throw new AbpException("Concurrent flash sale result creation"); + } + + var ongoingResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => + x.PlanId == eventData.Plan.Id && + x.UserId == eventData.UserId && + x.Status != FlashSaleResultStatus.Failed); + + if (ongoingResult is not null) + { + Logger.LogWarning("Duplicate ongoing flash sale result creation"); + + await FlashSaleCurrentResultCache.SetAsync(eventData.Plan.Id, eventData.UserId, + new FlashSaleCurrentResultCacheItem + { + TenantId = ongoingResult.TenantId, + ResultDto = ObjectMapper.Map(ongoingResult) + }); + + return; + } + + var result = new FlashSaleResult( + id: eventData.ResultId, + tenantId: CurrentTenant.Id, + storeId: eventData.Plan.StoreId, + planId: eventData.Plan.Id, + userId: eventData.UserId, + reducedInventoryTime: eventData.ReducedInventoryTime + ); + + var eto = new CreateFlashSaleOrderEto + { + TenantId = eventData.TenantId, + ResultId = eventData.ResultId, + UserId = eventData.UserId, + CustomerRemark = eventData.CustomerRemark, + Plan = eventData.Plan, + HashToken = eventData.HashToken + }; + + eventData.MapExtraPropertiesTo(eto, MappingPropertyDefinitionChecks.None); + + await DistributedEventBus.PublishAsync(eto); + + await FlashSaleResultRepository.InsertAsync(result, autoSave: true); + } + + protected virtual Task GetLockKeyAsync(CreateFlashSaleResultEto eventData) + { + return Task.FromResult($"eshopflashsales-creating-result_{eventData.Plan.Id}-{eventData.UserId}"); + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCache.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCache.cs new file mode 100644 index 00000000..f88863a5 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCache.cs @@ -0,0 +1,59 @@ +using System; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.Options; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Options; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class FlashSaleCurrentResultCache : IFlashSaleCurrentResultCache, ITransientDependency +{ + /// + /// The cache key format. + /// {0}: FlashSalePlan ID + /// {1}: User ID + /// + public const string FlashSaleCurrentResultCacheKeyFormat = "eshopflashsales-current-result_{0}_{1}"; + + protected IDistributedCache Cache { get; } + protected FlashSalesOptions Options { get; } + + public FlashSaleCurrentResultCache( + IDistributedCache cache, + IOptions options) + { + Cache = cache; + Options = options.Value; + } + + public virtual async Task GetAsync(Guid planId, Guid userId) + { + var flashSaleCurrentResultCacheKey = await GetKeyAsync(planId, userId); + return await Cache.GetAsync(flashSaleCurrentResultCacheKey); + } + + public virtual async Task SetAsync(Guid planId, Guid userId, FlashSaleCurrentResultCacheItem cacheItem) + { + var flashSaleCurrentResultCacheKey = await GetKeyAsync(planId, userId); + + await Cache.SetAsync(flashSaleCurrentResultCacheKey, cacheItem, + new DistributedCacheEntryOptions + { + AbsoluteExpiration = DateTimeOffset.Now.Add(Options.FlashSaleCurrentResultCacheExpires) + }); + } + + public virtual async Task RemoveAsync(Guid planId, Guid userId) + { + var flashSaleCurrentResultCacheKey = await GetKeyAsync(planId, userId); + + await Cache.RemoveAsync(flashSaleCurrentResultCacheKey); + } + + protected virtual Task GetKeyAsync(Guid planId, Guid userId) + { + return Task.FromResult(string.Format(FlashSaleCurrentResultCacheKeyFormat, planId, userId)); + } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCacheItem.cs new file mode 100644 index 00000000..032c129a --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleCurrentResultCacheItem.cs @@ -0,0 +1,13 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +[Serializable] +public class FlashSaleCurrentResultCacheItem : IMultiTenant +{ + public Guid? TenantId { get; set; } + + public FlashSaleResultDto ResultDto { get; set; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs index c9034bb9..205b8eed 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultAppService.cs @@ -4,7 +4,9 @@ using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.EShop.Plugins.FlashSales.Permissions; using EasyAbp.EShop.Stores.Stores; +using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; +using Volo.Abp.Domain.Entities; using Volo.Abp.Users; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; @@ -17,24 +19,46 @@ public class FlashSaleResultAppService : protected override string GetPolicyName { get; set; } = FlashSalesPermissions.FlashSaleResult.Default; protected override string GetListPolicyName { get; set; } = FlashSalesPermissions.FlashSaleResult.Default; - public FlashSaleResultAppService(IFlashSaleResultRepository flashSaleResultRepository) : base(flashSaleResultRepository) + protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } + + public FlashSaleResultAppService( + IFlashSaleCurrentResultCache flashSaleCurrentResultCache, + IFlashSaleResultRepository flashSaleResultRepository) : base(flashSaleResultRepository) { + FlashSaleCurrentResultCache = flashSaleCurrentResultCache; } - public override async Task GetAsync(Guid id) + [Authorize] + public override Task GetAsync(Guid id) { - var flashSaleResult = await GetEntityByIdAsync(id); + throw new NotSupportedException(); + } + + public virtual async Task GetCurrentAsync(Guid planId) + { + await CheckGetPolicyAsync(); + + var cache = await FlashSaleCurrentResultCache.GetAsync(planId, CurrentUser.GetId()); - if (flashSaleResult.UserId == CurrentUser.Id) + if (cache is not null) { - await CheckGetPolicyAsync(); + return cache.ResultDto; } - else + + var list = await GetListAsync(new FlashSaleResultGetListInput + { + MaxResultCount = 1, + Sorting = "Status ASC, CreationTime DESC", + PlanId = planId, + UserId = CurrentUser.GetId() + }); + + if (list.TotalCount == 0) { - await CheckMultiStorePolicyAsync(flashSaleResult.StoreId, FlashSalesPermissions.FlashSaleResult.Manage); + throw new EntityNotFoundException(typeof(FlashSaleResult)); } - return await MapToGetOutputDtoAsync(flashSaleResult); + return list.Items[0]; } public override async Task> GetListAsync(FlashSaleResultGetListInput input) @@ -51,7 +75,8 @@ public class FlashSaleResultAppService : return await base.GetListAsync(input); } - protected override async Task> CreateFilteredQueryAsync(FlashSaleResultGetListInput input) + protected override async Task> CreateFilteredQueryAsync( + FlashSaleResultGetListInput input) { return (await base.CreateFilteredQueryAsync(input)) .WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId.Value) @@ -60,4 +85,4 @@ public class FlashSaleResultAppService : .WhereIf(input.UserId.HasValue, x => x.UserId == input.UserId.Value) .WhereIf(input.OrderId.HasValue, x => x.OrderId == input.OrderId.Value); } -} +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleCurrentResultCache.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleCurrentResultCache.cs new file mode 100644 index 00000000..e6b63e7d --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleCurrentResultCache.cs @@ -0,0 +1,13 @@ +using System; +using System.Threading.Tasks; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public interface IFlashSaleCurrentResultCache +{ + Task GetAsync(Guid planId, Guid userId); + + Task SetAsync(Guid planId, Guid userId, FlashSaleCurrentResultCacheItem cacheItem); + + Task RemoveAsync(Guid planId, Guid userId); +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/Options/FlashSalesOptions.cs similarity index 63% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/Options/FlashSalesOptions.cs index e4071710..cb677006 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalesOptions.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/Options/FlashSalesOptions.cs @@ -1,6 +1,6 @@ using System; -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +namespace EasyAbp.EShop.Plugins.FlashSales.Options; public class FlashSalesOptions { @@ -12,5 +12,5 @@ public class FlashSalesOptions /// /// Default: 5 minutes /// - public TimeSpan UserFlashSaleResultCacheExpires { get; set; } = TimeSpan.FromMinutes(5); + public TimeSpan FlashSaleCurrentResultCacheExpires { get; set; } = TimeSpan.FromMinutes(5); } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs index c17a0f39..4f50a1d3 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderEto.cs @@ -9,16 +9,10 @@ public class CreateFlashSaleOrderEto : ExtensibleObject, IMultiTenant { public Guid? TenantId { get; set; } - public Guid StoreId { get; set; } - - public Guid PlanId { get; set; } + public Guid ResultId { get; set; } public Guid UserId { get; set; } - public Guid PendingResultId { get; set; } - - public DateTime CreateTime { get; set; } - public string CustomerRemark { get; set; } public FlashSalePlanEto Plan { get; set; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEto.cs similarity index 74% rename from plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs rename to plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEto.cs index b5a76b63..4c581f2a 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderCompleteEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEto.cs @@ -4,11 +4,11 @@ using Volo.Abp.ObjectExtending; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -public class CreateFlashSaleOrderCompleteEto : ExtensibleObject, IMultiTenant +public class FlashSaleOrderCreationResultEto : ExtensibleObject, IMultiTenant { public Guid? TenantId { get; set; } - public Guid PendingResultId { get; set; } + public Guid ResultId { get; set; } public bool Success { get; set; } @@ -21,4 +21,6 @@ public class CreateFlashSaleOrderCompleteEto : ExtensibleObject, IMultiTenant public Guid UserId { get; set; } public Guid? OrderId { get; set; } + + public bool AllowToTryAgain { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs new file mode 100644 index 00000000..c4558072 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs @@ -0,0 +1,24 @@ +using System; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using Volo.Abp.MultiTenancy; +using Volo.Abp.ObjectExtending; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +[Serializable] +public class CreateFlashSaleResultEto : ExtensibleObject, IMultiTenant +{ + public Guid? TenantId { get; set; } + + public Guid ResultId { get; set; } + + public Guid UserId { get; set; } + + public DateTime ReducedInventoryTime { get; set; } + + public string CustomerRemark { get; set; } + + public FlashSalePlanEto Plan { get; set; } + + public string HashToken { get; set; } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs index f4ef7845..d02bcc8d 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultFailedReason.cs @@ -2,7 +2,5 @@ public static class FlashSaleResultFailedReason { - public const string InsufficientInventory = "InsufficientInventory"; - public const string InvalidHashToken = "InvalidHashToken"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs index a38555b3..94479a94 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalesErrorCodes.cs @@ -29,4 +29,6 @@ public static class FlashSalesErrorCodes public const string RelatedFlashSaleResultsExist = $"{Namespace}:{nameof(RelatedFlashSaleResultsExist)}"; public const string FlashSaleResultStatusNotPending = $"{Namespace}:{nameof(FlashSaleResultStatusNotPending)}"; + + public const string DistributedEventBusUnavailable = $"{Namespace}:{nameof(DistributedEventBusUnavailable)}"; } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json index 0b5b2c37..a090db59 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/en.json @@ -14,6 +14,7 @@ "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "Duplicate flash-sales order", "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "Related flash-sales results exist", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleResultStatusNotPending": "The status of flash-sale result has been changed", + "EasyAbp.EShop.Plugins.FlashSales:Menu:DistributedEventBusUnavailable": "The distributed event bus is unavailable", "Menu:FlashSalesManagement": "Flash-Sales Management", "Permission:FlashSalePlan": "FlashSale Plan", "Permission:Manage": "Manage", @@ -41,6 +42,7 @@ "FlashSaleResultReason": "Reason", "FlashSaleResultUserId": "User ID", "FlashSaleResultOrderId": "Order ID", + "FlashSaleResultReducedInventoryTime": "Inventory Reduction Time", "FlashSaleResultCreationTime": "Creation Time", "ViewFlashSaleResult": "View", "Enum:FlashSaleResultStatus.Pending": "Pending", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json index 5aa756b8..2a5a34e8 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hans.json @@ -14,6 +14,7 @@ "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重复闪购下单", "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "已存在关联的闪购结果", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleResultStatusNotPending": "闪购结果的状态已经变更", + "EasyAbp.EShop.Plugins.FlashSales:Menu:DistributedEventBusUnavailable": "分布式事件总线不可用", "Menu:FlashSalesManagement": "闪购", "Permission:FlashSalePlan": "闪购计划", "Permission:Manage": "管理", @@ -41,6 +42,7 @@ "FlashSaleResultReason": "原因", "FlashSaleResultUserId": "用户 ID", "FlashSaleResultOrderId": "订单 ID", + "FlashSaleResultReducedInventoryTime": "扣库存时间", "FlashSaleResultCreationTime": "创建时间", "ViewFlashSaleResult": "查看", "Enum:FlashSaleResultStatus.Pending": "等待中", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json index 6f7a3e84..91ad46ab 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/Localization/zh-Hant.json @@ -14,6 +14,7 @@ "EasyAbp.EShop.Plugins.FlashSales:DuplicateFlashSalesOrder": "重複閃購下單", "EasyAbp.EShop.Plugins.FlashSales:RelatedFlashSaleResultsExist": "已存在關聯的閃購結果", "EasyAbp.EShop.Plugins.FlashSales:FlashSaleResultStatusNotPending": "閃購結果的状态已經變更", + "EasyAbp.EShop.Plugins.FlashSales:Menu:DistributedEventBusUnavailable": "分佈式事件總線不可用", "Menu:FlashSalesManagement": "閃購管理", "Permission:FlashSalePlan": "閃購計畫", "Permission:Manage": "管理", @@ -41,6 +42,7 @@ "FlashSaleResultReason": "原因", "FlashSaleResultUserId": "用戶 ID", "FlashSaleResultOrderId": "訂單 ID", + "FlashSaleResultReducedInventoryTime": "扣庫存時間", "FlashSaleResultCreationTime": "創建時間", "ViewFlashSaleResult": "查看", "Enum:FlashSaleResultStatus.Pending": "等待中", diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs deleted file mode 100644 index e4377fcd..00000000 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandler.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EventBus.Distributed; -using Volo.Abp.Guids; -using Volo.Abp.Uow; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; - -public class CreateFlashSaleOrderCompleteEventHandler : IDistributedEventHandler, ITransientDependency -{ - protected IFlashSaleResultRepository FlashSaleResultRepository { get; } - protected IGuidGenerator GuidGenerator { get; } - - public CreateFlashSaleOrderCompleteEventHandler(IFlashSaleResultRepository flashSaleResultRepository, IGuidGenerator guidGenerator) - { - FlashSaleResultRepository = flashSaleResultRepository; - GuidGenerator = guidGenerator; - } - - [UnitOfWork] - public virtual async Task HandleEventAsync(CreateFlashSaleOrderCompleteEto eventData) - { - var flashSaleResult = await FlashSaleResultRepository.GetAsync(eventData.PendingResultId); - - if (eventData.Success) - { - flashSaleResult.MarkAsSuccessful(eventData.OrderId.Value); - } - else - { - flashSaleResult.MarkAsFailed(eventData.Reason); - } - - await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true); - } -} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs index 2617a14a..a1a25619 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult.cs @@ -1,12 +1,12 @@ using System; -using EasyAbp.EShop.Stores.Stores; +using JetBrains.Annotations; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -public class FlashSaleResult : FullAuditedAggregateRoot, IMultiTenant, IMultiStore +public class FlashSaleResult : FullAuditedAggregateRoot, IFlashSaleResult, IMultiTenant { public virtual Guid? TenantId { get; protected set; } @@ -22,16 +22,19 @@ public class FlashSaleResult : FullAuditedAggregateRoot, IMultiTenant, IMu public virtual Guid? OrderId { get; protected set; } + public virtual DateTime ReducedInventoryTime { get; protected set; } + protected FlashSaleResult() { } - public FlashSaleResult(Guid id, Guid? tenantId, Guid storeId, Guid planId, Guid userId) - : base(id) + public FlashSaleResult( + Guid id, Guid? tenantId, Guid storeId, Guid planId, Guid userId, DateTime reducedInventoryTime) : base(id) { TenantId = tenantId; StoreId = storeId; PlanId = planId; Status = FlashSaleResultStatus.Pending; UserId = userId; + ReducedInventoryTime = reducedInventoryTime; } public void MarkAsSuccessful(Guid orderId) @@ -44,7 +47,7 @@ public class FlashSaleResult : FullAuditedAggregateRoot, IMultiTenant, IMu OrderId = orderId; } - public void MarkAsFailed(string reason) + public void MarkAsFailed([NotNull] string reason) { if (Status != FlashSaleResultStatus.Pending) { diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResult.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResult.cs new file mode 100644 index 00000000..967485f9 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/IFlashSaleResult.cs @@ -0,0 +1,17 @@ +using System; +using EasyAbp.EShop.Stores.Stores; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public interface IFlashSaleResult : IMultiStore +{ + Guid PlanId { get; } + + FlashSaleResultStatus Status { get; } + + string Reason { get; } + + Guid UserId { get; } + + Guid? OrderId { get; } +} \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs index 6ed92500..8dc38783 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanController.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Auditing; +using Volo.Abp.Uow; namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; @@ -52,6 +53,7 @@ public class FlashSalePlanController : return Service.DeleteAsync(id); } + [UnitOfWork(IsDisabled = true)] [HttpPost("{id}/pre-order")] public virtual Task PreOrderAsync(Guid id) { @@ -59,9 +61,10 @@ public class FlashSalePlanController : } [DisableAuditing] + [UnitOfWork(IsDisabled = true)] [HttpPost("{id}/order")] - public virtual Task OrderAsync(Guid id, CreateOrderInput input) + public virtual Task OrderAsync(Guid id, OrderFlashSalePlanInput flashSalePlanInput) { - return Service.OrderAsync(id, input); + return Service.OrderAsync(id, flashSalePlanInput); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs index b0095dcc..0f6c1707 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.HttpApi/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultController.cs @@ -30,4 +30,10 @@ public class FlashSaleResultController : FlashSalesController, IFlashSaleResultA { return Service.GetListAsync(input); } + + [HttpGet("current/{planId}")] + public virtual Task GetCurrentAsync(Guid planId) + { + return Service.GetCurrentAsync(planId); + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs index 49b9aae1..88ab34ec 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/ViewModels/ViewFlashSaleResultViewModel.cs @@ -23,4 +23,7 @@ public class ViewFlashSaleResultViewModel [Display(Name = "FlashSaleResultOrderId")] public Guid? OrderId { get; set; } + + [Display(Name = "FlashSaleResultReducedInventoryTime")] + public DateTime ReducedInventoryTime { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.js b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.js index aac69835..f94b74e6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.js +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Web/Pages/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResult/index.js @@ -60,6 +60,11 @@ $(function () { data: "creationTime", dataFormat: 'datetime' }, + { + title: l('FlashSaleResultReducedInventoryTime'), + data: "reducedInventoryTime", + dataFormat: 'datetime' + }, ] })); diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs index b7643685..1305861f 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandlerTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using EasyAbp.EShop.Orders.Plugins.FlashSales; using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.EShop.Products.ProductDetails.Dtos; using EasyAbp.EShop.Products.ProductDetails; @@ -93,14 +94,11 @@ public class CreateFlashSaleOrderEventHandlerTests : OrdersPluginsFlashSalesAppl OrderRepository.InsertAsync(default, default, default) .ReturnsForAnyArgs(callInfo => callInfo.Arg()); - var createFlashSaleOrderEto = new CreateFlashSaleOrderEto() + var createFlashSaleOrderEto = new CreateFlashSaleOrderEto { TenantId = CurrentTenant.Id, - PlanId = FlashSalesTestData.Plan1Id, - StoreId = FlashSalesTestData.Store1Id, UserId = CurrentUser.GetId(), - PendingResultId = FlashSalesTestData.Result1Id, - CreateTime = DateTime.Now, + ResultId = FlashSalesTestData.Result1Id, CustomerRemark = "My Remark", HashToken = "My Hash Token", Plan = new FlashSalePlanEto @@ -119,9 +117,9 @@ public class CreateFlashSaleOrderEventHandlerTests : OrdersPluginsFlashSalesAppl await EventHandler.HandleEventAsync(createFlashSaleOrderEto); await DistributedEventBus.Received() - .PublishAsync(Arg.Is(eto => + .PublishAsync(Arg.Is(eto => eto.TenantId == CurrentTenant.Id && - eto.PendingResultId == FlashSalesTestData.Result1Id && + eto.ResultId == FlashSalesTestData.Result1Id && eto.Success && eto.StoreId == FlashSalesTestData.Store1Id && eto.PlanId == FlashSalesTestData.Plan1Id && @@ -137,14 +135,11 @@ public class CreateFlashSaleOrderEventHandlerTests : OrdersPluginsFlashSalesAppl FlashSalePlanHasher.HashAsync(default, default, default) .ReturnsForAnyArgs("My Hash Token"); - var createFlashSaleOrderEto = new CreateFlashSaleOrderEto() + var createFlashSaleOrderEto = new CreateFlashSaleOrderEto { TenantId = CurrentTenant.Id, - PlanId = FlashSalesTestData.Plan1Id, - StoreId = FlashSalesTestData.Store1Id, UserId = CurrentUser.GetId(), - PendingResultId = FlashSalesTestData.Result1Id, - CreateTime = DateTime.Now, + ResultId = FlashSalesTestData.Result1Id, CustomerRemark = "My Remark", HashToken = "My Hash Token Failed", Plan = new FlashSalePlanEto @@ -163,9 +158,9 @@ public class CreateFlashSaleOrderEventHandlerTests : OrdersPluginsFlashSalesAppl await EventHandler.HandleEventAsync(createFlashSaleOrderEto); await DistributedEventBus.Received() - .PublishAsync(Arg.Is(eto => + .PublishAsync(Arg.Is(eto => eto.TenantId == CurrentTenant.Id && - eto.PendingResultId == FlashSalesTestData.Result1Id && + eto.ResultId == FlashSalesTestData.Result1Id && !eto.Success && eto.StoreId == FlashSalesTestData.Store1Id && eto.PlanId == FlashSalesTestData.Plan1Id && diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs index 3ac63e8e..fa4d143e 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationTestsModule.cs @@ -1,7 +1,7 @@ -using EasyAbp.EShop.Orders.Plugins.FlashSales; +using EasyAbp.EShop.Plugins.FlashSales; using Volo.Abp.Modularity; -namespace EasyAbp.EShop.Plugins.FlashSales; +namespace EasyAbp.EShop.Orders.Plugins.FlashSales; [DependsOn( typeof(EShopOrdersPluginsFlashSalesApplicationModule), diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs index 5abed316..a055ca98 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Orders.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Orders/Plugins/FlashSales/OrdersPluginsFlashSalesApplicationTestBase.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; +using EasyAbp.EShop.Plugins.FlashSales; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; -namespace EasyAbp.EShop.Plugins.FlashSales; +namespace EasyAbp.EShop.Orders.Plugins.FlashSales; /* Inherit from this class for your application layer tests. * See SampleAppService_Tests for example. diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandlerTest.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandlerTest.cs deleted file mode 100644 index 41e2981f..00000000 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/CreateFlashSaleOrderFailedEventHandlerTest.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Threading.Tasks; -using EasyAbp.Eshop.Products.Products; -using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; -using EasyAbp.EShop.Products.Products; -using EasyAbp.EShop.Products.Products.Dtos; -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using NSubstitute; -using NSubstitute.ReceivedExtensions; -using Shouldly; -using Volo.Abp.Users; -using Xunit; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; - -public class CreateFlashSaleOrderFailedEventHandlerTest : FlashSalesApplicationTestBase -{ - protected CreateFlashSaleOrderFailedEventHandler EventHandler { get; } - - protected IDistributedCache DistributedCache { get; } - - protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; set; } - - private ProductDto Product1 { get; set; } - - public CreateFlashSaleOrderFailedEventHandlerTest() - { - EventHandler = GetRequiredService(); - DistributedCache = GetRequiredService(); - FlashSaleInventoryManager = GetRequiredService(); - } - - protected override void AfterAddApplication(IServiceCollection services) - { - Product1 = CreateMockProductDto(); - - var productAppService = Substitute.For(); - productAppService.GetAsync(FlashSalesTestData.Product1Id).Returns(Task.FromResult(Product1)); - services.Replace(ServiceDescriptor.Singleton(productAppService)); - - FlashSaleInventoryManager = Substitute.For(); - services.Replace(ServiceDescriptor.Singleton(FlashSaleInventoryManager)); - base.AfterAddApplication(services); - } - - [Fact] - public async Task HandleEventAsync() - { - var plan = await CreateFlashSalePlanAsync(); - var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); - var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); - await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); - var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() - { - TenantId = pendingFlashResult.TenantId, - PendingResultId = pendingFlashResult.Id, - Success = false, - StoreId = pendingFlashResult.StoreId, - PlanId = pendingFlashResult.PlanId, - OrderId = null, - Reason = FlashSaleResultFailedReason.InvalidHashToken, - UserId = pendingFlashResult.UserId - }; - FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) - .Returns(Task.FromResult(true)); - - await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); - - var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); - userFlashSaleResultCache.ShouldBeNull(); - - await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); - } - - [Fact] - public async Task HandleEventAsync_Should_Not_Remove_UserFlashSaleResultCache_When_TryRollBackInventory_Failed() - { - var plan = await CreateFlashSalePlanAsync(); - var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); - var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); - await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); - var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() - { - TenantId = pendingFlashResult.TenantId, - PendingResultId = pendingFlashResult.Id, - Success = false, - StoreId = pendingFlashResult.StoreId, - PlanId = pendingFlashResult.PlanId, - OrderId = null, - Reason = FlashSaleResultFailedReason.InvalidHashToken, - UserId = pendingFlashResult.UserId - }; - FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) - .Returns(Task.FromResult(false)); - - await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); - - var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); - userFlashSaleResultCache.ShouldBe(pendingFlashResult.Id.ToString()); - - await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); - } - - [Fact] - public async Task HandleEventAsync_Should_Ignore_When_Success_Is_True() - { - var plan = await CreateFlashSalePlanAsync(); - var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); - var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); - await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); - var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() - { - TenantId = pendingFlashResult.TenantId, - PendingResultId = pendingFlashResult.Id, - Success = true, - StoreId = pendingFlashResult.StoreId, - PlanId = pendingFlashResult.PlanId, - OrderId = Guid.NewGuid(), - Reason = null, - UserId = pendingFlashResult.UserId - }; - - await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); - - var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); - userFlashSaleResultCache.ShouldBe(pendingFlashResult.Id.ToString()); - - await FlashSaleInventoryManager.DidNotReceiveWithAnyArgs() - .TryRollBackInventoryAsync(default, default, Guid.Empty, Guid.Empty, Guid.Empty, default, default); - } - - [Fact] - public async Task HandleEventAsync_Should_Ignore_When_Reason_Not_InvalidHashToken() - { - var plan = await CreateFlashSalePlanAsync(); - var pendingFlashResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); - var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, CurrentUser.GetId()); - await DistributedCache.SetStringAsync(userFlashSaleResultCacheKey, pendingFlashResult.Id.ToString()); - var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() - { - TenantId = pendingFlashResult.TenantId, - PendingResultId = pendingFlashResult.Id, - Success = false, - StoreId = pendingFlashResult.StoreId, - PlanId = pendingFlashResult.PlanId, - OrderId = null, - Reason = "Other", - UserId = pendingFlashResult.UserId - }; - - await EventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); - - var userFlashSaleResultCache = await DistributedCache.GetStringAsync(userFlashSaleResultCacheKey); - userFlashSaleResultCache.ShouldBe(pendingFlashResult.Id.ToString()); - - await FlashSaleInventoryManager.DidNotReceiveWithAnyArgs() - .TryRollBackInventoryAsync(default, default, Guid.Empty, Guid.Empty, Guid.Empty, default, default); - } -} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs new file mode 100644 index 00000000..b526b164 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs @@ -0,0 +1,229 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.EShop.Products.ProductDetails; +using EasyAbp.EShop.Products.ProductDetails.Dtos; +using EasyAbp.Eshop.Products.Products; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using NSubstitute; +using Shouldly; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Users; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; + +public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicationTestBase +{ + protected IObjectMapper ObjectMapper { get; } + protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } + protected FlashSaleOrderCreationResultEventHandler FlashSaleOrderCreationResultEventHandler { get; } + protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; set; } + + private ProductDto Product1 { get; set; } + + public FlashSaleOrderCreationResultEventHandlerTests() + { + ObjectMapper = GetRequiredService(); + FlashSaleCurrentResultCache = GetRequiredService(); + FlashSaleOrderCreationResultEventHandler = GetRequiredService(); + FlashSaleInventoryManager = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + Product1 = CreateMockProductDto(); + + var productAppService = Substitute.For(); + productAppService.GetAsync(FlashSalesTestData.Product1Id).Returns(Task.FromResult(Product1)); + services.Replace(ServiceDescriptor.Singleton(productAppService)); + + var productDetailAppService = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(productDetailAppService)); + productDetailAppService.GetAsync(FlashSalesTestData.ProductDetail1Id).Returns(Task.FromResult( + new ProductDetailDto + { + Id = FlashSalesTestData.ProductDetail1Id, + CreationTime = FlashSalesTestData.ProductDetailLastModificationTime, + LastModificationTime = FlashSalesTestData.ProductDetailLastModificationTime, + StoreId = FlashSalesTestData.Store1Id, + Description = "My Details 1" + })); + productDetailAppService.GetAsync(FlashSalesTestData.ProductDetail2Id).Returns(Task.FromResult( + new ProductDetailDto + { + Id = FlashSalesTestData.ProductDetail2Id, + StoreId = FlashSalesTestData.Store1Id, + Description = "My Details 2" + })); + + var flashSaleInventoryManager = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(flashSaleInventoryManager)); + + base.AfterAddApplication(services); + } + + protected async Task SetFlashSaleCurrentResultCacheAsync(FlashSaleResult flashSaleResult) + { + await FlashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, + new FlashSaleCurrentResultCacheItem + { + TenantId = CurrentTenant.Id, + ResultDto = ObjectMapper.Map(flashSaleResult) + }); + } + + [Fact] + public async Task HandleEventAsync_When_Create_Order_Success() + { + var plan = await CreateFlashSalePlanAsync(); + var flashSaleResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + await SetFlashSaleCurrentResultCacheAsync(flashSaleResult); + + var flashSaleOrderCreationResultEto = new FlashSaleOrderCreationResultEto + { + TenantId = flashSaleResult.TenantId, + ResultId = flashSaleResult.Id, + Success = true, + StoreId = flashSaleResult.StoreId, + PlanId = flashSaleResult.PlanId, + OrderId = GuidGenerator.Create(), + Reason = null, + UserId = flashSaleResult.UserId, + AllowToTryAgain = false + }; + + FlashSaleInventoryManager + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .Returns(Task.FromResult(true)); + + await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); + + var flashResult = await FlashSaleResultRepository.GetAsync(flashSaleResult.Id); + flashResult.Status.ShouldBe(FlashSaleResultStatus.Successful); + flashResult.OrderId.ShouldBe(flashSaleOrderCreationResultEto.OrderId); + flashResult.Reason.ShouldBe(null); + + var flashSaleCurrentResultCache = await FlashSaleCurrentResultCache.GetAsync(flashResult.PlanId, flashResult.UserId); + flashSaleCurrentResultCache.ShouldNotBeNull(); + flashSaleCurrentResultCache.ResultDto.Id.ShouldBe(flashSaleResult.Id); + flashSaleCurrentResultCache.ResultDto.Status.ShouldBe(FlashSaleResultStatus.Successful); + + await FlashSaleInventoryManager.DidNotReceive() + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + } + + [Fact] + public async Task HandleEventAsync_When_Create_Order_Failed_And_Not_Allow_To_Try_Again() + { + var plan = await CreateFlashSalePlanAsync(); + var flashSaleResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + await SetFlashSaleCurrentResultCacheAsync(flashSaleResult); + + var flashSaleOrderCreationResultEto = new FlashSaleOrderCreationResultEto + { + TenantId = flashSaleResult.TenantId, + ResultId = flashSaleResult.Id, + Success = false, + StoreId = FlashSalesTestData.Store1Id, + PlanId = flashSaleResult.PlanId, + OrderId = null, + Reason = "Failed reason", + UserId = flashSaleResult.UserId, + AllowToTryAgain = false + }; + + FlashSaleInventoryManager + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .Returns(Task.FromResult(true)); + + await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); + + var flashResult = await FlashSaleResultRepository.GetAsync(flashSaleResult.Id); + flashResult.Status.ShouldBe(FlashSaleResultStatus.Failed); + flashResult.OrderId.ShouldBe(null); + flashResult.Reason.ShouldBe("Failed reason"); + + var flashSaleCurrentResultCache = await FlashSaleCurrentResultCache.GetAsync(flashResult.PlanId, flashResult.UserId); + flashSaleCurrentResultCache.ShouldNotBeNull(); + flashSaleCurrentResultCache.ResultDto.Id.ShouldBe(flashSaleResult.Id); + flashSaleCurrentResultCache.ResultDto.Status.ShouldBe(FlashSaleResultStatus.Failed); + + await FlashSaleInventoryManager.Received() + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + } + + [Fact] + public async Task HandleEventAsync_When_Create_Order_Failed_And_Allow_To_Try_Again() + { + var plan = await CreateFlashSalePlanAsync(); + var flashSaleResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + await SetFlashSaleCurrentResultCacheAsync(flashSaleResult); + + var flashSaleOrderCreationResultEto = new FlashSaleOrderCreationResultEto + { + TenantId = flashSaleResult.TenantId, + ResultId = flashSaleResult.Id, + Success = false, + StoreId = FlashSalesTestData.Store1Id, + PlanId = flashSaleResult.PlanId, + OrderId = null, + Reason = "Failed reason", + UserId = flashSaleResult.UserId, + AllowToTryAgain = true + }; + + FlashSaleInventoryManager + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .Returns(Task.FromResult(true)); + + await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); + + var flashResult = await FlashSaleResultRepository.GetAsync(flashSaleResult.Id); + flashResult.Status.ShouldBe(FlashSaleResultStatus.Failed); + flashResult.OrderId.ShouldBe(null); + flashResult.Reason.ShouldBe("Failed reason"); + + var flashSaleCurrentResultCache = await FlashSaleCurrentResultCache.GetAsync(flashResult.PlanId, flashResult.UserId); + flashSaleCurrentResultCache.ShouldBeNull(); + + await FlashSaleInventoryManager.Received() + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + } + + [Fact] + public async Task Should_Not_Remove_FlashSaleCurrentResultCache_When_TryRollBackInventory_Failed() + { + var plan = await CreateFlashSalePlanAsync(); + var flashSaleResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, CurrentUser.GetId()); + await SetFlashSaleCurrentResultCacheAsync(flashSaleResult); + + var flashSaleOrderCreationResultEto = new FlashSaleOrderCreationResultEto + { + TenantId = flashSaleResult.TenantId, + ResultId = flashSaleResult.Id, + Success = false, + StoreId = flashSaleResult.StoreId, + PlanId = flashSaleResult.PlanId, + OrderId = null, + Reason = FlashSaleResultFailedReason.InvalidHashToken, + UserId = flashSaleResult.UserId, + AllowToTryAgain = true + }; + + FlashSaleInventoryManager + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .Returns(Task.FromResult(false)); + + await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); + + var flashSaleCurrentResultCache = await FlashSaleCurrentResultCache.GetAsync(plan.Id, CurrentUser.GetId()); + flashSaleCurrentResultCache.ShouldNotBeNull(); + + await FlashSaleInventoryManager.Received() + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs index 6fa1d635..0b748d20 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs @@ -1,13 +1,13 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using EasyAbp.Eshop.Products.Products; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; +using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.EShop.Plugins.FlashSales.Options; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; -using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; @@ -15,9 +15,11 @@ using NSubstitute; using Shouldly; using Volo.Abp; using Volo.Abp.Caching; +using Volo.Abp.Data; using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities; using Volo.Abp.EventBus.Distributed; +using Volo.Abp.ObjectExtending; using Volo.Abp.Users; using Xunit; @@ -28,12 +30,15 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase protected IDistributedEventBus DistributedEventBus { get; } + protected IDistributedCache ProductDistributedCache { get; } + private ProductDto Product1 { get; set; } public FlashSalePlanAppServiceTests() { AppService = GetRequiredService(); DistributedEventBus = GetRequiredService(); + ProductDistributedCache = GetRequiredService>(); } protected override void AfterAddApplication(IServiceCollection services) @@ -48,6 +53,12 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase var distributedEventBus = Substitute.For(); services.Replace(ServiceDescriptor.Singleton(distributedEventBus)); + + ObjectExtensionManager.Instance.AddOrUpdate(info => + { + info.AddOrUpdateProperty("key1"); + }); + base.AfterAddApplication(services); } @@ -326,13 +337,14 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase .Code.ShouldBe(FlashSalesErrorCodes.ProductIsNotPublished); Product1.IsPublished = true; - Product1.InventoryStrategy = InventoryStrategy.ReduceAfterPlacing; + await ProductDistributedCache.RemoveAsync(Product1.Id); await AppService.PreOrderAsync(plan.Id) .ShouldThrowAsync(); Product1.InventoryStrategy = InventoryStrategy.FlashSales; + await ProductDistributedCache.RemoveAsync(Product1.Id); var plan2 = await CreateFlashSalePlanAsync(isPublished: false); await AppService.PreOrderAsync(plan2.Id) @@ -350,25 +362,23 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase var plan = await CreateFlashSalePlanAsync(); var hashToken = await GetRequiredService() .HashAsync(plan.LastModificationTime, Product1.LastModificationTime, Product1.GetSkuById(plan.ProductSkuId).LastModificationTime); - var createOrderInput = new CreateOrderInput() + var orderFlashSalePlanInput = new OrderFlashSalePlanInput { - CustomerRemark = "remark1", - ExtraProperties = { { "key1", "value1" } } + CustomerRemark = "remark1" }; + orderFlashSalePlanInput.SetProperty("key1", "value1"); await AppService.PreOrderAsync(plan.Id); - var result = await AppService.OrderAsync(plan.Id, createOrderInput); + var result = await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput); result.IsSuccess.ShouldBe(true); - result.FlashSaleResultId.ShouldNotBeNull(); - await DistributedEventBus.Received().PublishAsync(Arg.Is(eto => + await DistributedEventBus.Received().PublishAsync(Arg.Is(eto => eto.TenantId == plan.TenantId && - eto.StoreId == plan.StoreId && - eto.PlanId == plan.Id && eto.UserId == CurrentUser.GetId() && eto.HashToken == hashToken && - eto.CustomerRemark == createOrderInput.CustomerRemark && + eto.CustomerRemark == orderFlashSalePlanInput.CustomerRemark && eto.Plan != null && + eto.Plan.Id == plan.Id && eto.Plan.TenantId == plan.TenantId && eto.Plan.StoreId == plan.StoreId && eto.Plan.BeginTime == plan.BeginTime && @@ -378,104 +388,121 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase eto.Plan.IsPublished == plan.IsPublished && eto.ExtraProperties.ContainsKey("key1") && eto.ExtraProperties["key1"].ToString() == "value1" - )); + ), false, false); } [Fact] public async Task OrderAsync_Throw_Exception_When_Not_PreOrder() { var plan = await CreateFlashSalePlanAsync(); - var createOrderInput = new CreateOrderInput(); + var orderFlashSalePlanInput = new OrderFlashSalePlanInput(); - (await AppService.OrderAsync(plan.Id, createOrderInput) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.PreOrderExpired); + (await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput)).ErrorCode + .ShouldBe(FlashSalesErrorCodes.PreOrderExpired); } [Fact] public async Task OrderAsync_Throw_Exception_When_FlashSaleNotStarted() { var plan = await CreateFlashSalePlanAsync(timeRange: CreateTimeRange.NotStart); - var createOrderInput = new CreateOrderInput(); + var orderFlashSalePlanInput = new OrderFlashSalePlanInput(); await AppService.PreOrderAsync(plan.Id); - (await AppService.OrderAsync(plan.Id, createOrderInput) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleNotStarted); + (await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput)) + .ErrorCode.ShouldBe(FlashSalesErrorCodes.FlashSaleNotStarted); } [Fact] public async Task OrderAsync_Throw_Exception_When_FlashSaleIsOver() { var plan = await CreateFlashSalePlanAsync(timeRange: CreateTimeRange.WillBeExpired); - var createOrderInput = new CreateOrderInput(); + var orderFlashSalePlanInput = new OrderFlashSalePlanInput(); await AppService.PreOrderAsync(plan.Id); await Task.Delay(TimeSpan.FromSeconds(1.2)); - (await AppService.OrderAsync(plan.Id, createOrderInput) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver); + (await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput)) + .ErrorCode.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver); } [Fact] public async Task OrderAsync_Throw_Exception_When_BusyToCreateFlashSaleOrder() { var plan = await CreateFlashSalePlanAsync(); - var createOrderInput = new CreateOrderInput(); + var orderFlashSalePlanInput = new OrderFlashSalePlanInput(); await AppService.PreOrderAsync(plan.Id); var distributedLock = GetRequiredService(); var lockKey = $"create-flash-sale-order-{plan.Id}-{CurrentUser.GetId()}"; await using var handle = await distributedLock.TryAcquireAsync(lockKey); - (await AppService.OrderAsync(plan.Id, createOrderInput) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); + (await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput)) + .ErrorCode.ShouldBe(FlashSalesErrorCodes.BusyToCreateFlashSaleOrder); } [Fact] - public async Task OrderAsync_Throw_Exception_When_Exist_UserFlashSaleResultCache() + public async Task OrderAsync_Throw_Exception_When_Exist_FlashSaleCurrentResultCache() { var plan = await CreateFlashSalePlanAsync(); - var createOrderInput = new CreateOrderInput(); + var orderFlashSalePlanInput = new OrderFlashSalePlanInput(); await AppService.PreOrderAsync(plan.Id); - var distributedCache = GetRequiredService(); + var flashSaleCurrentResultCache = GetRequiredService(); var userId = CurrentUser.GetId(); - var userFlashSaleResultCacheKey = string.Format(FlashSalePlanAppService.UserFlashSaleResultCacheKeyFormat, plan.TenantId, plan.Id, userId); - await distributedCache.SetStringAsync(userFlashSaleResultCacheKey, Guid.NewGuid().ToString()); - - (await AppService.OrderAsync(plan.Id, createOrderInput) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + await flashSaleCurrentResultCache.SetAsync(plan.Id, userId, + new FlashSaleCurrentResultCacheItem + { + TenantId = CurrentTenant.Id, + ResultDto = new FlashSaleResultDto + { + Id = Guid.NewGuid(), + StoreId = plan.StoreId, + PlanId = plan.Id, + UserId = userId + } + }); + + (await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput)) + .ErrorCode.ShouldBe(FlashSalesErrorCodes.DuplicateFlashSalesOrder); } [Fact] public async Task OrderAsync_Return_False_When_TryReduceInventory_Failed() { var plan = await CreateFlashSalePlanAsync(); - var createOrderInput = new CreateOrderInput(); + var orderFlashSalePlanInput = new OrderFlashSalePlanInput(); await AppService.PreOrderAsync(plan.Id); FakeFlashSaleInventoryManager.ShouldReduceSuccess = false; - var result = await AppService.OrderAsync(plan.Id, createOrderInput); + var result = await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput); result.IsSuccess.ShouldBe(false); - result.FlashSaleResultId.ShouldBeNull(); } [Fact] public async Task OrderAsync_Return_False_When_Exist_Not_Failed_Result() { var plan = await CreateFlashSalePlanAsync(); - var createOrderInput = new CreateOrderInput(); + var orderFlashSalePlanInput = new OrderFlashSalePlanInput(); await AppService.PreOrderAsync(plan.Id); var userId = GetRequiredService().GetId(); - await CreatePendingResultAsync(plan.Id, plan.StoreId, userId); + var existingResult = await CreatePendingResultAsync(plan.Id, plan.StoreId, userId); - (await AppService.OrderAsync(plan.Id, createOrderInput) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.DuplicateFlashSalesOrder); + Guid? newResultId = null; + DistributedEventBus.PublishAsync(null, false, false).ReturnsForAnyArgs(async info => + { + var eto = info.Arg(); + newResultId = eto.ResultId; + var handler = ServiceProvider.GetRequiredService(); + await handler.HandleEventAsync(eto); + }); + + await AppService.OrderAsync(plan.Id, orderFlashSalePlanInput); + + await DistributedEventBus.Received() + .PublishAsync(Arg.Is(eto => eto.ResultId == newResultId), false, false); + + var flashSaleResultAppService = ServiceProvider.GetRequiredService(); + (await flashSaleResultAppService.GetCurrentAsync(plan.Id)).Id.ShouldBe(existingResult.Id); } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs new file mode 100644 index 00000000..a45d4c84 --- /dev/null +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs @@ -0,0 +1,122 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using Shouldly; +using Volo.Abp.Users; +using Xunit; + +namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; + +public class CreateFlashSaleResultEventHandlerTests : FlashSalesApplicationTestBase +{ + protected IFlashSaleResultAppService FlashSaleResultAppService { get; } + protected CreateFlashSaleResultEventHandler CreateFlashSaleResultEventHandler { get; } + + public CreateFlashSaleResultEventHandlerTests() + { + FlashSaleResultAppService = GetRequiredService(); + CreateFlashSaleResultEventHandler = GetRequiredService(); + } + + [Fact] + public async Task Should_Create_Result() + { + var reducedInventoryTime = DateTime.Now; + var createFlashSaleResultEto = await CreateCreateFlashSaleResultEtoAsync(reducedInventoryTime); + + await CreateFlashSaleResultEventHandler.HandleEventAsync(createFlashSaleResultEto); + + var flashResult = await FlashSaleResultRepository.GetAsync(FlashSalesTestData.Result1Id); + flashResult.Status.ShouldBe(FlashSaleResultStatus.Pending); + flashResult.OrderId.ShouldBeNull(); + flashResult.Reason.ShouldBe(null); + flashResult.ReducedInventoryTime.ShouldBe(reducedInventoryTime); + + (await FlashSaleResultAppService.GetCurrentAsync(createFlashSaleResultEto.Plan.Id)).Id.ShouldBe(flashResult.Id); + } + + [Fact] + public async Task Should_Not_Create_Result_If_Duplicate() + { + var existFlashResult1 = await CreateFlashSaleResultAsync(); + var createFlashSaleResultEto1 = await CreateCreateFlashSaleResultEtoAsync(DateTime.Now); + var planId = createFlashSaleResultEto1.Plan.Id; + + existFlashResult1.MarkAsFailed("some reason"); + await FlashSaleResultRepository.UpdateAsync(existFlashResult1, true); + + (await FlashSaleResultAppService.GetCurrentAsync(planId)).Id.ShouldBe(existFlashResult1.Id); + + await CreateFlashSaleResultEventHandler.HandleEventAsync(createFlashSaleResultEto1); + + var flashResultList = await FlashSaleResultRepository.GetListAsync(); + flashResultList.Count.ShouldBe(2); + flashResultList.ShouldContain(x => x.Id == existFlashResult1.Id); + + (await FlashSaleResultAppService.GetCurrentAsync(planId)).Id.ShouldNotBe(existFlashResult1.Id); + + var existFlashResult2 = flashResultList.First(x => x.Id != existFlashResult1.Id); + var createFlashSaleResultEto2 = await CreateCreateFlashSaleResultEtoAsync(DateTime.Now); + + await CreateFlashSaleResultEventHandler.HandleEventAsync(createFlashSaleResultEto2); + + flashResultList = await FlashSaleResultRepository.GetListAsync(); + flashResultList.Count.ShouldBe(2); + flashResultList.ShouldContain(x => x.Id == existFlashResult1.Id); + flashResultList.ShouldContain(x => x.Id == existFlashResult2.Id); + + (await FlashSaleResultAppService.GetCurrentAsync(planId)).Id.ShouldBe(existFlashResult2.Id); + + existFlashResult2.MarkAsSuccessful(GuidGenerator.Create()); + await FlashSaleResultRepository.UpdateAsync(existFlashResult2, true); + + await CreateFlashSaleResultEventHandler.HandleEventAsync(createFlashSaleResultEto2); + + flashResultList = await FlashSaleResultRepository.GetListAsync(); + flashResultList.Count.ShouldBe(2); + flashResultList.ShouldContain(x => x.Id == existFlashResult1.Id); + flashResultList.ShouldContain(x => x.Id == existFlashResult2.Id); + + (await FlashSaleResultAppService.GetCurrentAsync(planId)).Id.ShouldBe(existFlashResult2.Id); + } + + public Task CreateCreateFlashSaleResultEtoAsync(DateTime reducedInventoryTime) + { + return Task.FromResult(new CreateFlashSaleResultEto + { + ResultId = FlashSalesTestData.Result1Id, + UserId = CurrentUser.GetId(), + ReducedInventoryTime = reducedInventoryTime, + Plan = new FlashSalePlanEto + { + Id = FlashSalesTestData.Plan1Id, + TenantId = null, + StoreId = FlashSalesTestData.Store1Id, + BeginTime = reducedInventoryTime, + EndTime = DateTime.Now.AddMinutes(30), + ProductId = FlashSalesTestData.Product1Id, + ProductSkuId = FlashSalesTestData.ProductSku1Id, + IsPublished = true + }, + HashToken = "My Hash Token" + }); + } + + public async Task CreateFlashSaleResultAsync() + { + return await WithUnitOfWorkAsync(async () => + { + var flashSaleResult = new FlashSaleResult( + GuidGenerator.Create(), + null, + FlashSalesTestData.Store1Id, + FlashSalesTestData.Plan1Id, + CurrentUser.GetId(), + DateTime.Now); + await FlashSaleResultRepository.InsertAsync(flashSaleResult); + + return flashSaleResult; + }); + } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs index e0877a3d..d31baa83 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationTestBase.cs @@ -99,12 +99,9 @@ public abstract class FlashSalesApplicationTestBase : FlashSalesTestBase CreatePendingResultAsync(Guid planId, Guid storeId, Guid userId) { - return await WithUnitOfWorkAsync(async () => - { - return await FlashSaleResultRepository.InsertAsync( - new FlashSaleResult(GuidGenerator.Create(), CurrentTenant.Id, storeId, planId, userId) - ); - }); + return await WithUnitOfWorkAsync(async () => await FlashSaleResultRepository.InsertAsync( + new FlashSaleResult(GuidGenerator.Create(), CurrentTenant.Id, storeId, planId, userId, DateTime.Now) + )); } protected virtual async Task CreateFlashSalePlanAsync(bool useSku2 = false, CreateTimeRange timeRange = CreateTimeRange.Starting, bool isPublished = true) diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs deleted file mode 100644 index 5172e23f..00000000 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleOrderCompleteEventHandlerTests.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Threading.Tasks; -using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; -using Shouldly; -using Volo.Abp.Guids; -using Xunit; - -namespace EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; - -public class CreateFlashSaleOrderCompleteEventHandlerTests : FlashSalesDomainTestBase -{ - protected IFlashSaleResultRepository FlashSaleResultRepository { get; } - protected CreateFlashSaleOrderCompleteEventHandler CreateFlashSaleOrderCompleteEventHandler { get; } - protected IGuidGenerator GuidGenerator { get; } - - public CreateFlashSaleOrderCompleteEventHandlerTests() - { - FlashSaleResultRepository = GetRequiredService(); - CreateFlashSaleOrderCompleteEventHandler = GetRequiredService(); - GuidGenerator = GetRequiredService(); - } - - [Fact] - public async Task HandleEventAsync_When_Create_Order_Success() - { - var existFlashResult = await CreateFlashSaleResultAsync(); - var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() - { - TenantId = existFlashResult.TenantId, - PendingResultId = existFlashResult.Id, - Success = true, - StoreId = existFlashResult.StoreId, - PlanId = existFlashResult.PlanId, - OrderId = GuidGenerator.Create(), - Reason = null, - UserId = existFlashResult.UserId, - }; - - await CreateFlashSaleOrderCompleteEventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); - - var flashResult = await FlashSaleResultRepository.GetAsync(existFlashResult.Id); - flashResult.Status.ShouldBe(FlashSaleResultStatus.Successful); - flashResult.OrderId.ShouldBe(createFlashSaleOrderCompleteEto.OrderId); - flashResult.Reason.ShouldBe(null); - } - - [Fact] - public async Task HandleEventAsync_When_Create_Order_Failed() - { - var existFlashResult = await CreateFlashSaleResultAsync(); - var createFlashSaleOrderCompleteEto = new CreateFlashSaleOrderCompleteEto() - { - TenantId = existFlashResult.TenantId, - PendingResultId = existFlashResult.Id, - Success = false, - StoreId = FlashSalesTestData.Store1Id, - PlanId = existFlashResult.PlanId, - OrderId = null, - Reason = "Failed reason", - UserId = existFlashResult.UserId, - }; - - await CreateFlashSaleOrderCompleteEventHandler.HandleEventAsync(createFlashSaleOrderCompleteEto); - - var flashResult = await FlashSaleResultRepository.GetAsync(existFlashResult.Id); - flashResult.Status.ShouldBe(FlashSaleResultStatus.Failed); - flashResult.OrderId.ShouldBe(null); - flashResult.Reason.ShouldBe("Failed reason"); - } - - public async Task CreateFlashSaleResultAsync() - { - return await WithUnitOfWorkAsync(async () => - { - var flashSaleResult = new FlashSaleResult( - GuidGenerator.Create(), - null, - FlashSalesTestData.Store1Id, - FlashSalesTestData.Plan1Id, - GuidGenerator.Create()); - await FlashSaleResultRepository.InsertAsync(flashSaleResult); - - return flashSaleResult; - }); - } -} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs index 7464ce4b..db1466ec 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Domain.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/FlashSaleResultTests.cs @@ -18,7 +18,8 @@ public class FlashSaleResultTests tenantId: null, storeId: Guid.NewGuid(), planId: Guid.NewGuid(), - userId: Guid.NewGuid() + userId: Guid.NewGuid(), + DateTime.Now ); flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); @@ -38,7 +39,8 @@ public class FlashSaleResultTests tenantId: null, storeId: Guid.NewGuid(), planId: Guid.NewGuid(), - userId: Guid.NewGuid() + userId: Guid.NewGuid(), + DateTime.Now ); flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); @@ -61,7 +63,8 @@ public class FlashSaleResultTests tenantId: null, storeId: Guid.NewGuid(), planId: Guid.NewGuid(), - userId: Guid.NewGuid() + userId: Guid.NewGuid(), + DateTime.Now ); flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); @@ -81,7 +84,8 @@ public class FlashSaleResultTests tenantId: null, storeId: Guid.NewGuid(), planId: Guid.NewGuid(), - userId: Guid.NewGuid() + userId: Guid.NewGuid(), + DateTime.Now ); flashSaleResult.Status.ShouldBe(FlashSaleResultStatus.Pending); From 490c38dc5f4aa1f495e76ede7ed8a95cb1d36568 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Tue, 16 Aug 2022 13:37:11 +0800 Subject: [PATCH 84/97] Simplify methods of `IFlashSaleInventoryManager` --- .../FlashSaleOrderCreationResultEventHandler.cs | 6 ++---- .../FlashSalePlans/FlashSalePlanAppService.cs | 13 +++++-------- .../Products/FlashSaleInventoryManager.cs | 8 ++++---- .../Products/IFlashSaleInventoryManager.cs | 4 ++-- .../Products/FlashSaleInventoryAppService.cs | 8 ++------ .../Products/LocalFlashSaleInventoryManager.cs | 8 ++++---- ...shSaleOrderCreationResultEventHandlerTests.cs | 16 ++++++++-------- .../Products/FakeFlashSaleInventoryManager.cs | 4 ++-- 8 files changed, 29 insertions(+), 38 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs index c626ef58..fc067341 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs @@ -63,10 +63,8 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true); - if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync( - plan.TenantId, product.InventoryProviderName, - plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true - )) + if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync(plan.TenantId, product.InventoryProviderName, + plan.StoreId, plan.ProductId, plan.ProductSkuId)) { Logger.LogWarning("Try roll back inventory failed."); return; // Avoid to remove cache on the UOW completed. diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 7fd09c35..1c73d4a4 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -262,9 +262,8 @@ public class FlashSalePlanAppService : return CreateFailureResultDto(FlashSalesErrorCodes.DuplicateFlashSalesOrder); } - if (!await FlashSaleInventoryManager.TryReduceInventoryAsync( - plan.TenantId, preOrderCache.InventoryProviderName, - plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true)) + if (!await FlashSaleInventoryManager.TryReduceInventoryAsync(plan.TenantId, preOrderCache.InventoryProviderName, + plan.StoreId, plan.ProductId, plan.ProductSkuId)) { await FlashSaleCurrentResultCache.RemoveAsync(plan.Id, CurrentUser.GetId()); return CreateFailureResultDto(FlashSalesErrorCodes.ProductSkuInventoryExceeded); @@ -298,11 +297,9 @@ public class FlashSalePlanAppService : { Logger.LogWarning("Failed to publish the CreateFlashSaleOrderEto event!"); Logger.LogException(e, LogLevel.Warning); - - await FlashSaleInventoryManager.TryRollBackInventoryAsync( - plan.TenantId, preOrderCache.InventoryProviderName, - plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true - ); + + await FlashSaleInventoryManager.TryRollBackInventoryAsync(plan.TenantId, + preOrderCache.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); await FlashSaleCurrentResultCache.RemoveAsync(plan.Id, CurrentUser.GetId()); return CreateFailureResultDto(FlashSalesErrorCodes.DistributedEventBusUnavailable); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs index aaeb31ce..41ad7ee8 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryManager.cs @@ -18,16 +18,16 @@ public class FlashSaleInventoryManager : IFlashSaleInventoryManager, ITransientD } public virtual async Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, - Guid productId, Guid productSkuId, int quantity, bool increaseSold) + Guid productId, Guid productSkuId) { return await FlashSaleInventoryReducerAppService.TryReduceAsync(new ReduceInventoryInput( - tenantId, providerName, storeId, productId, productSkuId, quantity, increaseSold)); + tenantId, providerName, storeId, productId, productSkuId, 1, true)); } public virtual async Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, - Guid productId, Guid productSkuId, int quantity, bool decreaseSold) + Guid productId, Guid productSkuId) { return await FlashSaleInventoryReducerAppService.TryIncreaseAsync(new IncreaseInventoryInput( - tenantId, providerName, storeId, productId, productSkuId, quantity, decreaseSold)); + tenantId, providerName, storeId, productId, productSkuId, 1, true)); } } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs index 93558adc..8041e743 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Abstractions/EasyAbp/Eshop/Products/Products/IFlashSaleInventoryManager.cs @@ -6,8 +6,8 @@ namespace EasyAbp.Eshop.Products.Products; public interface IFlashSaleInventoryManager { Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool increaseSold); + Guid productSkuId); Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool decreaseSold); + Guid productSkuId); } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs index cbac9f41..3b03efb6 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/FlashSaleInventoryAppService.cs @@ -22,9 +22,7 @@ public class FlashSaleInventoryAppService : ProductsAppService, IFlashSaleInvent input.ProviderName, input.StoreId, input.ProductId, - input.ProductSkuId, - input.Quantity, - input.IncreaseSold + input.ProductSkuId ); } @@ -37,9 +35,7 @@ public class FlashSaleInventoryAppService : ProductsAppService, IFlashSaleInvent input.ProviderName, input.StoreId, input.ProductId, - input.ProductSkuId, - input.Quantity, - input.ReduceSold + input.ProductSkuId ); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs index 6e38ba04..aae7dad0 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Products.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/LocalFlashSaleInventoryManager.cs @@ -16,18 +16,18 @@ public class LocalFlashSaleInventoryManager : ILocalFlashSaleInventoryManager, I } public virtual async Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool increaseSold) + Guid productSkuId) { var model = new InventoryQueryModel(tenantId, storeId, productId, productSkuId); return await (await ProductInventoryProviderResolver.GetAsync(providerName)) - .TryReduceInventoryAsync(model, quantity, increaseSold, true); + .TryReduceInventoryAsync(model, 1, true, true); } public virtual async Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool decreaseSold) + Guid productSkuId) { var model = new InventoryQueryModel(tenantId, storeId, productId, productSkuId); return await (await ProductInventoryProviderResolver.GetAsync(providerName)) - .TryIncreaseInventoryAsync(model, quantity, decreaseSold, true); + .TryIncreaseInventoryAsync(model, 1, true, true); } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs index b526b164..bf9e63eb 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs @@ -97,7 +97,7 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) .Returns(Task.FromResult(true)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -113,7 +113,7 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ResultDto.Status.ShouldBe(FlashSaleResultStatus.Successful); await FlashSaleInventoryManager.DidNotReceive() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); } [Fact] @@ -137,7 +137,7 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) .Returns(Task.FromResult(true)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -153,7 +153,7 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ResultDto.Status.ShouldBe(FlashSaleResultStatus.Failed); await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); } [Fact] @@ -177,7 +177,7 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) .Returns(Task.FromResult(true)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -191,7 +191,7 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ShouldBeNull(); await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); } [Fact] @@ -215,7 +215,7 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true) + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) .Returns(Task.FromResult(false)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -224,6 +224,6 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ShouldNotBeNull(); await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId, 1, true); + .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs index 866e3b8c..faf0f706 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Products/Products/FakeFlashSaleInventoryManager.cs @@ -14,13 +14,13 @@ public class FakeFlashSaleInventoryManager : IFlashSaleInventoryManager } public Task TryReduceInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool increaseSold) + Guid productSkuId) { return Task.FromResult(ShouldReduceSuccess); } public Task TryRollBackInventoryAsync(Guid? tenantId, string providerName, Guid storeId, Guid productId, - Guid productSkuId, int quantity, bool decreaseSold) + Guid productSkuId) { return Task.FromResult(true); } From 6cb670c0fbb2f094d6ee2342e8d567fb33a2ed06 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 17 Aug 2022 02:24:47 +0800 Subject: [PATCH 85/97] Improve flash sales inventory rollback --- .../CreateFlashSaleOrderEventHandler.cs | 6 ++ ...lashSaleOrderCreationResultEventHandler.cs | 55 ++++++++++--------- .../FlashSalePlans/FlashSalePlanAppService.cs | 9 +-- .../CreateFlashSaleResultEventHandler.cs | 25 +++++++-- .../FlashSaleOrderCreationResultEto.cs | 6 ++ .../CreateFlashSaleResultEto.cs | 2 + ...aleOrderCreationResultEventHandlerTests.cs | 44 ++++++++++++--- .../CreateFlashSaleResultEventHandlerTests.cs | 33 ++++++++++- 8 files changed, 136 insertions(+), 44 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs index be794301..9c0c7ddb 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Orders/CreateFlashSaleOrderEventHandler.cs @@ -72,6 +72,9 @@ public class CreateFlashSaleOrderEventHandler : IDistributedEventHandler Logger { get; } protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } - protected IFlashSalePlanRepository FlashSalePlanRepository { get; } - protected IProductAppService ProductAppService { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; } protected IObjectMapper ObjectMapper { get; } protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } @@ -26,8 +23,6 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler public FlashSaleOrderCreationResultEventHandler( ILogger logger, IFlashSaleInventoryManager flashSaleInventoryManager, - IFlashSalePlanRepository flashSalePlanRepository, - IProductAppService productAppService, IUnitOfWorkManager unitOfWorkManager, IObjectMapper objectMapper, IFlashSaleCurrentResultCache flashSaleCurrentResultCache, @@ -35,8 +30,6 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler { Logger = logger; FlashSaleInventoryManager = flashSaleInventoryManager; - FlashSalePlanRepository = flashSalePlanRepository; - ProductAppService = productAppService; UnitOfWorkManager = unitOfWorkManager; ObjectMapper = objectMapper; FlashSaleCurrentResultCache = flashSaleCurrentResultCache; @@ -56,36 +49,48 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler } else { - var plan = await FlashSalePlanRepository.GetAsync(eventData.PlanId); - var product = await ProductAppService.GetAsync(plan.ProductId); - flashSaleResult.MarkAsFailed(eventData.Reason); await FlashSaleResultRepository.UpdateAsync(flashSaleResult, autoSave: true); - - if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync(plan.TenantId, product.InventoryProviderName, - plan.StoreId, plan.ProductId, plan.ProductSkuId)) - { - Logger.LogWarning("Try roll back inventory failed."); - return; // Avoid to remove cache on the UOW completed. - } } UnitOfWorkManager.Current.OnCompleted(async () => { - if (flashSaleResult.Status is FlashSaleResultStatus.Failed && eventData.AllowToTryAgain) + if (eventData.Success) { - await FlashSaleCurrentResultCache.RemoveAsync(flashSaleResult.PlanId, flashSaleResult.UserId); + await ResetFlashSaleCurrentResultCacheAsync(flashSaleResult); } else { - await FlashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, - new FlashSaleCurrentResultCacheItem - { - TenantId = flashSaleResult.TenantId, - ResultDto = ObjectMapper.Map(flashSaleResult) - }); + // try to roll back the inventory. + if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync( + eventData.TenantId, eventData.ProductInventoryProviderName, eventData.StoreId, + eventData.ProductId, eventData.ProductSkuId)) + { + Logger.LogWarning("Failed to roll back the flash sale inventory."); + return; // avoid to remove cache if the rollback failed. + } + + // remove the cache so the user can try to order again. + if (eventData.AllowToTryAgain) + { + await FlashSaleCurrentResultCache.RemoveAsync(flashSaleResult.PlanId, flashSaleResult.UserId); + } + else + { + await ResetFlashSaleCurrentResultCacheAsync(flashSaleResult); + } } }); } + + protected virtual async Task ResetFlashSaleCurrentResultCacheAsync(FlashSaleResult flashSaleResult) + { + await FlashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, + new FlashSaleCurrentResultCacheItem + { + TenantId = flashSaleResult.TenantId, + ResultDto = ObjectMapper.Map(flashSaleResult) + }); + } } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index 1c73d4a4..ab38c192 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -272,7 +272,7 @@ public class FlashSalePlanAppService : try { var createFlashSaleResultEto = - await PrepareCreateFlashSaleResultEtoAsync(plan, flashSalePlanInput, userId, Clock.Now, preOrderCache.HashToken); + await PrepareCreateFlashSaleResultEtoAsync(plan, flashSalePlanInput, userId, Clock.Now, preOrderCache); await FlashSaleCurrentResultCache.SetAsync(plan.Id, CurrentUser.GetId(), new FlashSaleCurrentResultCacheItem { @@ -407,8 +407,8 @@ public class FlashSalePlanAppService : } protected virtual Task PrepareCreateFlashSaleResultEtoAsync( - FlashSalePlanCacheItem plan, OrderFlashSalePlanInput flashSalePlanInput, - Guid userId, DateTime reducedInventoryTime, string hashToken) + FlashSalePlanCacheItem plan, OrderFlashSalePlanInput flashSalePlanInput, Guid userId, + DateTime reducedInventoryTime, FlashSalePlanPreOrderCacheItem preOrderCacheItem) { var planEto = ObjectMapper.Map(plan); planEto.TenantId = CurrentTenant.Id; @@ -421,7 +421,8 @@ public class FlashSalePlanAppService : ReducedInventoryTime = reducedInventoryTime, CustomerRemark = flashSalePlanInput.CustomerRemark, Plan = planEto, - HashToken = hashToken + ProductInventoryProviderName = preOrderCacheItem.InventoryProviderName, + HashToken = preOrderCacheItem.HashToken }; if (flashSalePlanInput.ExtraProperties != null) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs index 26a05647..e691edd7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs @@ -1,13 +1,14 @@ using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.Eshop.Products.Products; +using EasyAbp.EShop.Products.Products; using Microsoft.Extensions.Logging; using Volo.Abp; using Volo.Abp.DependencyInjection; using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; -using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectMapping; @@ -19,30 +20,33 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler Logger { get; } protected IAbpDistributedLock AbpDistributedLock { get; } protected IDistributedEventBus DistributedEventBus { get; } + protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; } public CreateFlashSaleResultEventHandler( IObjectMapper objectMapper, - IGuidGenerator guidGenerator, ICurrentTenant currentTenant, + IUnitOfWorkManager unitOfWorkManager, ILogger logger, IAbpDistributedLock abpDistributedLock, IDistributedEventBus distributedEventBus, + IFlashSaleInventoryManager flashSaleInventoryManager, IFlashSaleCurrentResultCache flashSaleCurrentResultCache, IFlashSaleResultRepository flashSaleResultRepository) { ObjectMapper = objectMapper; - GuidGenerator = guidGenerator; CurrentTenant = currentTenant; + UnitOfWorkManager = unitOfWorkManager; Logger = logger; AbpDistributedLock = abpDistributedLock; DistributedEventBus = distributedEventBus; + FlashSaleInventoryManager = flashSaleInventoryManager; FlashSaleCurrentResultCache = flashSaleCurrentResultCache; FlashSaleResultRepository = flashSaleResultRepository; } @@ -73,7 +77,18 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler(ongoingResult) }); - return; + // try to roll back the inventory. + UnitOfWorkManager.Current.OnCompleted(async () => + { + if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync(eventData.TenantId, + eventData.ProductInventoryProviderName, eventData.Plan.StoreId, + eventData.Plan.ProductId, eventData.Plan.ProductSkuId)) + { + Logger.LogWarning("Failed to roll back the flash sale inventory."); + } + }); + + return; // avoid to create a result entity and an order. } var result = new FlashSaleResult( diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEto.cs index 4c581f2a..88ce602b 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEto.cs @@ -22,5 +22,11 @@ public class FlashSaleOrderCreationResultEto : ExtensibleObject, IMultiTenant public Guid? OrderId { get; set; } + public string ProductInventoryProviderName { get; set; } + + public Guid ProductId { get; set; } + + public Guid ProductSkuId { get; set; } + public bool AllowToTryAgain { get; set; } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs index c4558072..b37298ba 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Domain.Shared/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEto.cs @@ -20,5 +20,7 @@ public class CreateFlashSaleResultEto : ExtensibleObject, IMultiTenant public FlashSalePlanEto Plan { get; set; } + public string ProductInventoryProviderName { get; set; } + public string HashToken { get; set; } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs index bf9e63eb..75a081b2 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandlerTests.cs @@ -93,11 +93,16 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati OrderId = GuidGenerator.Create(), Reason = null, UserId = flashSaleResult.UserId, + ProductInventoryProviderName = Product1.InventoryProviderName, + ProductId = plan.ProductId, + ProductSkuId = plan.ProductSkuId, AllowToTryAgain = false }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId) .Returns(Task.FromResult(true)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -113,7 +118,9 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ResultDto.Status.ShouldBe(FlashSaleResultStatus.Successful); await FlashSaleInventoryManager.DidNotReceive() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId); } [Fact] @@ -133,11 +140,16 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati OrderId = null, Reason = "Failed reason", UserId = flashSaleResult.UserId, + ProductInventoryProviderName = Product1.InventoryProviderName, + ProductId = plan.ProductId, + ProductSkuId = plan.ProductSkuId, AllowToTryAgain = false }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId) .Returns(Task.FromResult(true)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -153,7 +165,9 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ResultDto.Status.ShouldBe(FlashSaleResultStatus.Failed); await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId); } [Fact] @@ -173,11 +187,16 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati OrderId = null, Reason = "Failed reason", UserId = flashSaleResult.UserId, + ProductInventoryProviderName = Product1.InventoryProviderName, + ProductId = plan.ProductId, + ProductSkuId = plan.ProductSkuId, AllowToTryAgain = true }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId) .Returns(Task.FromResult(true)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -191,7 +210,9 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ShouldBeNull(); await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId); } [Fact] @@ -211,11 +232,16 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati OrderId = null, Reason = FlashSaleResultFailedReason.InvalidHashToken, UserId = flashSaleResult.UserId, + ProductInventoryProviderName = Product1.InventoryProviderName, + ProductId = plan.ProductId, + ProductSkuId = plan.ProductSkuId, AllowToTryAgain = true }; FlashSaleInventoryManager - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId) + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId) .Returns(Task.FromResult(false)); await FlashSaleOrderCreationResultEventHandler.HandleEventAsync(flashSaleOrderCreationResultEto); @@ -224,6 +250,8 @@ public class FlashSaleOrderCreationResultEventHandlerTests : FlashSalesApplicati flashSaleCurrentResultCache.ShouldNotBeNull(); await FlashSaleInventoryManager.Received() - .TryRollBackInventoryAsync(plan.TenantId, Product1.InventoryProviderName, plan.StoreId, plan.ProductId, plan.ProductSkuId); + .TryRollBackInventoryAsync(flashSaleOrderCreationResultEto.TenantId, + flashSaleOrderCreationResultEto.ProductInventoryProviderName, flashSaleOrderCreationResultEto.StoreId, + flashSaleOrderCreationResultEto.ProductId, flashSaleOrderCreationResultEto.ProductSkuId); } } diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs index a45d4c84..c3234074 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandlerTests.cs @@ -2,6 +2,10 @@ using System.Linq; using System.Threading.Tasks; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; +using EasyAbp.Eshop.Products.Products; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using NSubstitute; using Shouldly; using Volo.Abp.Users; using Xunit; @@ -12,11 +16,21 @@ public class CreateFlashSaleResultEventHandlerTests : FlashSalesApplicationTestB { protected IFlashSaleResultAppService FlashSaleResultAppService { get; } protected CreateFlashSaleResultEventHandler CreateFlashSaleResultEventHandler { get; } + protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } public CreateFlashSaleResultEventHandlerTests() { FlashSaleResultAppService = GetRequiredService(); CreateFlashSaleResultEventHandler = GetRequiredService(); + FlashSaleInventoryManager = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + var flashSaleInventoryManager = Substitute.For(); + services.Replace(ServiceDescriptor.Singleton(flashSaleInventoryManager)); + + base.AfterAddApplication(services); } [Fact] @@ -50,6 +64,11 @@ public class CreateFlashSaleResultEventHandlerTests : FlashSalesApplicationTestB await CreateFlashSaleResultEventHandler.HandleEventAsync(createFlashSaleResultEto1); + await FlashSaleInventoryManager.DidNotReceive() + .TryRollBackInventoryAsync(createFlashSaleResultEto1.TenantId, + createFlashSaleResultEto1.ProductInventoryProviderName, createFlashSaleResultEto1.Plan.StoreId, + createFlashSaleResultEto1.Plan.ProductId, createFlashSaleResultEto1.Plan.ProductSkuId); + var flashResultList = await FlashSaleResultRepository.GetListAsync(); flashResultList.Count.ShouldBe(2); flashResultList.ShouldContain(x => x.Id == existFlashResult1.Id); @@ -61,6 +80,11 @@ public class CreateFlashSaleResultEventHandlerTests : FlashSalesApplicationTestB await CreateFlashSaleResultEventHandler.HandleEventAsync(createFlashSaleResultEto2); + await FlashSaleInventoryManager.Received() + .TryRollBackInventoryAsync(createFlashSaleResultEto2.TenantId, + createFlashSaleResultEto2.ProductInventoryProviderName, createFlashSaleResultEto2.Plan.StoreId, + createFlashSaleResultEto2.Plan.ProductId, createFlashSaleResultEto2.Plan.ProductSkuId); + flashResultList = await FlashSaleResultRepository.GetListAsync(); flashResultList.Count.ShouldBe(2); flashResultList.ShouldContain(x => x.Id == existFlashResult1.Id); @@ -73,6 +97,11 @@ public class CreateFlashSaleResultEventHandlerTests : FlashSalesApplicationTestB await CreateFlashSaleResultEventHandler.HandleEventAsync(createFlashSaleResultEto2); + await FlashSaleInventoryManager.Received() + .TryRollBackInventoryAsync(createFlashSaleResultEto2.TenantId, + createFlashSaleResultEto2.ProductInventoryProviderName, createFlashSaleResultEto2.Plan.StoreId, + createFlashSaleResultEto2.Plan.ProductId, createFlashSaleResultEto2.Plan.ProductSkuId); + flashResultList = await FlashSaleResultRepository.GetListAsync(); flashResultList.Count.ShouldBe(2); flashResultList.ShouldContain(x => x.Id == existFlashResult1.Id); @@ -81,7 +110,7 @@ public class CreateFlashSaleResultEventHandlerTests : FlashSalesApplicationTestB (await FlashSaleResultAppService.GetCurrentAsync(planId)).Id.ShouldBe(existFlashResult2.Id); } - public Task CreateCreateFlashSaleResultEtoAsync(DateTime reducedInventoryTime) + protected Task CreateCreateFlashSaleResultEtoAsync(DateTime reducedInventoryTime) { return Task.FromResult(new CreateFlashSaleResultEto { @@ -103,7 +132,7 @@ public class CreateFlashSaleResultEventHandlerTests : FlashSalesApplicationTestB }); } - public async Task CreateFlashSaleResultAsync() + protected async Task CreateFlashSaleResultAsync() { return await WithUnitOfWorkAsync(async () => { From 4da2f678b0858bc0c90eed1a36f541f046490485 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 17 Aug 2022 13:01:06 +0800 Subject: [PATCH 86/97] Change version to 3.0.0-preview.14 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 47c1e2be..5ba4f510 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.13 + 3.0.0-preview.14 $(NoWarn);CS1591 true EasyAbp Team From acecaed2a36c578be745e25659086b06e182be02 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 17 Aug 2022 17:30:45 +0800 Subject: [PATCH 87/97] Fix UOW OnCompleted usage --- .../FlashSaleOrderCreationResultEventHandler.cs | 16 +++++++++++----- .../CreateFlashSaleResultEventHandler.cs | 10 +++++++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs index 852d3fa9..ba59e962 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs @@ -2,6 +2,7 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.Eshop.Products.Products; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; @@ -16,7 +17,7 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler protected ILogger Logger { get; } protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; } - protected IObjectMapper ObjectMapper { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; } @@ -24,14 +25,14 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler ILogger logger, IFlashSaleInventoryManager flashSaleInventoryManager, IUnitOfWorkManager unitOfWorkManager, - IObjectMapper objectMapper, + IServiceScopeFactory serviceScopeFactory, IFlashSaleCurrentResultCache flashSaleCurrentResultCache, IFlashSaleResultRepository flashSaleResultRepository) { Logger = logger; FlashSaleInventoryManager = flashSaleInventoryManager; UnitOfWorkManager = unitOfWorkManager; - ObjectMapper = objectMapper; + ServiceScopeFactory = serviceScopeFactory; FlashSaleCurrentResultCache = flashSaleCurrentResultCache; FlashSaleResultRepository = flashSaleResultRepository; } @@ -86,11 +87,16 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler protected virtual async Task ResetFlashSaleCurrentResultCacheAsync(FlashSaleResult flashSaleResult) { - await FlashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, + using var scope = ServiceScopeFactory.CreateScope(); + + var objectMapper = scope.ServiceProvider.GetRequiredService(); + var flashSaleCurrentResultCache = scope.ServiceProvider.GetRequiredService(); + + await flashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, new FlashSaleCurrentResultCacheItem { TenantId = flashSaleResult.TenantId, - ResultDto = ObjectMapper.Map(flashSaleResult) + ResultDto = objectMapper.Map(flashSaleResult) }); } } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs index e691edd7..ef53a8d7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs @@ -3,6 +3,7 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.Eshop.Products.Products; using EasyAbp.EShop.Products.Products; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp; using Volo.Abp.DependencyInjection; @@ -22,6 +23,7 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler Logger { get; } protected IAbpDistributedLock AbpDistributedLock { get; } protected IDistributedEventBus DistributedEventBus { get; } @@ -33,6 +35,7 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler logger, IAbpDistributedLock abpDistributedLock, IDistributedEventBus distributedEventBus, @@ -43,6 +46,7 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler { - if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync(eventData.TenantId, + using var scope = ServiceScopeFactory.CreateScope(); + + var flashSaleInventoryManager = scope.ServiceProvider.GetRequiredService(); + + if (!await flashSaleInventoryManager.TryRollBackInventoryAsync(eventData.TenantId, eventData.ProductInventoryProviderName, eventData.Plan.StoreId, eventData.Plan.ProductId, eventData.Plan.ProductSkuId)) { From 2ef3d30c30f0486838285a7bdcfff528b16ac3b4 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 17 Aug 2022 17:37:16 +0800 Subject: [PATCH 88/97] Change version to 3.0.0-preview.15 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 5ba4f510..45bcc1fb 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.14 + 3.0.0-preview.15 $(NoWarn);CS1591 true EasyAbp Team From 8f344e6189d7cf074ee0c2775a8da57339de260f Mon Sep 17 00:00:00 2001 From: Super <47396430@qq.com> Date: Wed, 17 Aug 2022 20:23:56 +0800 Subject: [PATCH 89/97] Revert "Fix UOW OnCompleted usage" --- .../FlashSaleOrderCreationResultEventHandler.cs | 16 +++++----------- .../CreateFlashSaleResultEventHandler.cs | 10 +--------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs index ba59e962..852d3fa9 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs @@ -2,7 +2,6 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.Eshop.Products.Products; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; @@ -17,7 +16,7 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler protected ILogger Logger { get; } protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; } - protected IServiceScopeFactory ServiceScopeFactory { get; } + protected IObjectMapper ObjectMapper { get; } protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; } @@ -25,14 +24,14 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler ILogger logger, IFlashSaleInventoryManager flashSaleInventoryManager, IUnitOfWorkManager unitOfWorkManager, - IServiceScopeFactory serviceScopeFactory, + IObjectMapper objectMapper, IFlashSaleCurrentResultCache flashSaleCurrentResultCache, IFlashSaleResultRepository flashSaleResultRepository) { Logger = logger; FlashSaleInventoryManager = flashSaleInventoryManager; UnitOfWorkManager = unitOfWorkManager; - ServiceScopeFactory = serviceScopeFactory; + ObjectMapper = objectMapper; FlashSaleCurrentResultCache = flashSaleCurrentResultCache; FlashSaleResultRepository = flashSaleResultRepository; } @@ -87,16 +86,11 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler protected virtual async Task ResetFlashSaleCurrentResultCacheAsync(FlashSaleResult flashSaleResult) { - using var scope = ServiceScopeFactory.CreateScope(); - - var objectMapper = scope.ServiceProvider.GetRequiredService(); - var flashSaleCurrentResultCache = scope.ServiceProvider.GetRequiredService(); - - await flashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, + await FlashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, new FlashSaleCurrentResultCacheItem { TenantId = flashSaleResult.TenantId, - ResultDto = objectMapper.Map(flashSaleResult) + ResultDto = ObjectMapper.Map(flashSaleResult) }); } } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs index ef53a8d7..e691edd7 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs @@ -3,7 +3,6 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.Eshop.Products.Products; using EasyAbp.EShop.Products.Products; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp; using Volo.Abp.DependencyInjection; @@ -23,7 +22,6 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler Logger { get; } protected IAbpDistributedLock AbpDistributedLock { get; } protected IDistributedEventBus DistributedEventBus { get; } @@ -35,7 +33,6 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler logger, IAbpDistributedLock abpDistributedLock, IDistributedEventBus distributedEventBus, @@ -46,7 +43,6 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler { - using var scope = ServiceScopeFactory.CreateScope(); - - var flashSaleInventoryManager = scope.ServiceProvider.GetRequiredService(); - - if (!await flashSaleInventoryManager.TryRollBackInventoryAsync(eventData.TenantId, + if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync(eventData.TenantId, eventData.ProductInventoryProviderName, eventData.Plan.StoreId, eventData.Plan.ProductId, eventData.Plan.ProductSkuId)) { From 41aad42052dab5644f32b98309856d7f12385a52 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 17 Aug 2022 22:48:52 +0800 Subject: [PATCH 90/97] Fix UOW OnCompleted usage with `IAbpApplication` --- .../FlashSaleOrderCreationResultEventHandler.cs | 14 ++++++++++++-- .../CreateFlashSaleResultEventHandler.cs | 10 +++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs index 852d3fa9..f337268e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSaleOrderCreationResultEventHandler.cs @@ -2,7 +2,9 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.Eshop.Products.Products; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Volo.Abp; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; using Volo.Abp.ObjectMapping; @@ -17,6 +19,7 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; } protected IObjectMapper ObjectMapper { get; } + protected IAbpApplication AbpApplication { get; } protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; } @@ -25,6 +28,7 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler IFlashSaleInventoryManager flashSaleInventoryManager, IUnitOfWorkManager unitOfWorkManager, IObjectMapper objectMapper, + IAbpApplication abpApplication, IFlashSaleCurrentResultCache flashSaleCurrentResultCache, IFlashSaleResultRepository flashSaleResultRepository) { @@ -32,6 +36,7 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler FlashSaleInventoryManager = flashSaleInventoryManager; UnitOfWorkManager = unitOfWorkManager; ObjectMapper = objectMapper; + AbpApplication = abpApplication; FlashSaleCurrentResultCache = flashSaleCurrentResultCache; FlashSaleResultRepository = flashSaleResultRepository; } @@ -86,11 +91,16 @@ public class FlashSaleOrderCreationResultEventHandler : IDistributedEventHandler protected virtual async Task ResetFlashSaleCurrentResultCacheAsync(FlashSaleResult flashSaleResult) { - await FlashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, + using var scope = AbpApplication.ServiceProvider.CreateScope(); + + var objectMapper = scope.ServiceProvider.GetRequiredService(); + var flashSaleCurrentResultCache = scope.ServiceProvider.GetRequiredService(); + + await flashSaleCurrentResultCache.SetAsync(flashSaleResult.PlanId, flashSaleResult.UserId, new FlashSaleCurrentResultCacheItem { TenantId = flashSaleResult.TenantId, - ResultDto = ObjectMapper.Map(flashSaleResult) + ResultDto = objectMapper.Map(flashSaleResult) }); } } \ No newline at end of file diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs index e691edd7..2244db6e 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSaleResults/CreateFlashSaleResultEventHandler.cs @@ -3,6 +3,7 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.Eshop.Products.Products; using EasyAbp.EShop.Products.Products; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Volo.Abp; using Volo.Abp.DependencyInjection; @@ -25,6 +26,7 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler Logger { get; } protected IAbpDistributedLock AbpDistributedLock { get; } protected IDistributedEventBus DistributedEventBus { get; } + protected IAbpApplication AbpApplication { get; } protected IFlashSaleInventoryManager FlashSaleInventoryManager { get; } protected IFlashSaleCurrentResultCache FlashSaleCurrentResultCache { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; } @@ -36,6 +38,7 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler logger, IAbpDistributedLock abpDistributedLock, IDistributedEventBus distributedEventBus, + IAbpApplication abpApplication, IFlashSaleInventoryManager flashSaleInventoryManager, IFlashSaleCurrentResultCache flashSaleCurrentResultCache, IFlashSaleResultRepository flashSaleResultRepository) @@ -46,6 +49,7 @@ public class CreateFlashSaleResultEventHandler : IDistributedEventHandler { - if (!await FlashSaleInventoryManager.TryRollBackInventoryAsync(eventData.TenantId, + using var scope = AbpApplication.ServiceProvider.CreateScope(); + + var flashSaleInventoryManager = scope.ServiceProvider.GetRequiredService(); + + if (!await flashSaleInventoryManager.TryRollBackInventoryAsync(eventData.TenantId, eventData.ProductInventoryProviderName, eventData.Plan.StoreId, eventData.Plan.ProductId, eventData.Plan.ProductSkuId)) { From e04ac28451099b99d355d94e898c4dfbc951aeda Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Wed, 17 Aug 2022 22:51:51 +0800 Subject: [PATCH 91/97] Change version to 3.0.0-preview.16 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 45bcc1fb..920fb43c 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.15 + 3.0.0-preview.16 $(NoWarn);CS1591 true EasyAbp Team From 3a5060fb38fac949caf8a2e4d32c65d4c52f80a5 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Thu, 18 Aug 2022 18:51:48 +0800 Subject: [PATCH 92/97] Record InventoryStrategy in OrderLine Resolve #215 --- .../EShop/Orders/Orders/Dtos/OrderLineDto.cs | 5 +- .../EShop/Orders/Orders/NewOrderGenerator.cs | 1 + .../EasyAbp.EShop.Orders.Domain.Shared.csproj | 1 + .../Orders/EShopOrdersDomainSharedModule.cs | 4 +- .../EShop/Orders/Localization/Orders/en.json | 1 + .../Orders/Localization/Orders/zh-Hans.json | 1 + .../Orders/Localization/Orders/zh-Hant.json | 1 + .../EasyAbp/EShop/Orders/Orders/IOrderLine.cs | 41 +- .../EShop/Orders/Orders/OrderLineEto.cs | 5 +- .../EasyAbp/EShop/Orders/Orders/OrderLine.cs | 8 +- .../Orders/InventoryReductionResultTests.cs | 1 + .../Orders/OrderDomainTests.cs | 2 + ...oductInventoryStrategyProperty.Designer.cs | 6171 +++++++++++++++++ ...9_AddedProductInventoryStrategyProperty.cs | 37 + .../EShopSampleDbContextModelSnapshot.cs | 8 +- 15 files changed, 6264 insertions(+), 23 deletions(-) create mode 100644 samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.Designer.cs create mode 100644 samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.cs diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/OrderLineDto.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/OrderLineDto.cs index 143f4b10..1927d372 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/OrderLineDto.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application.Contracts/EasyAbp/EShop/Orders/Orders/Dtos/OrderLineDto.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text.Json.Serialization; +using EasyAbp.EShop.Products.Products; using Volo.Abp.Application.Dtos; using Volo.Abp.Data; @@ -26,7 +27,9 @@ namespace EasyAbp.EShop.Orders.Orders.Dtos public string ProductUniqueName { get; set; } public string ProductDisplayName { get; set; } - + + public InventoryStrategy? ProductInventoryStrategy { get; set; } + public string SkuName { get; set; } public string SkuDescription { get; set; } diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs index 495930c8..be1225ae 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs @@ -148,6 +148,7 @@ namespace EasyAbp.EShop.Orders.Orders productGroupDisplayName: product.ProductGroupDisplayName, productUniqueName: product.UniqueName, productDisplayName: product.DisplayName, + productInventoryStrategy: product.InventoryStrategy, skuName: productSku.Name, skuDescription: await _productSkuDescriptionProvider.GenerateAsync(product, productSku), mediaResources: product.MediaResources, diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp.EShop.Orders.Domain.Shared.csproj b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp.EShop.Orders.Domain.Shared.csproj index cee825f5..de525f48 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp.EShop.Orders.Domain.Shared.csproj +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp.EShop.Orders.Domain.Shared.csproj @@ -12,6 +12,7 @@ + diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/EShopOrdersDomainSharedModule.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/EShopOrdersDomainSharedModule.cs index 2bf5fdd1..f05614f7 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/EShopOrdersDomainSharedModule.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/EShopOrdersDomainSharedModule.cs @@ -2,6 +2,7 @@ using Volo.Abp.Localization; using EasyAbp.EShop.Orders.Localization; using EasyAbp.EShop.Payments; +using EasyAbp.EShop.Products; using EasyAbp.EShop.Stores; using Volo.Abp.Auditing; using Volo.Abp.Localization.ExceptionHandling; @@ -15,7 +16,8 @@ namespace EasyAbp.EShop.Orders typeof(AbpValidationModule), typeof(AbpAuditingContractsModule), typeof(EShopStoresDomainSharedModule), - typeof(EShopPaymentsDomainSharedModule) + typeof(EShopPaymentsDomainSharedModule), + typeof(EShopProductsDomainSharedModule) )] public class EShopOrdersDomainSharedModule : AbpModule { diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json index 67aa9901..6240dc00 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json @@ -35,6 +35,7 @@ "OrderLineProductGroupDisplayName": "Product group", "OrderLineProductUniqueName": "Product unique name", "OrderLineProductDisplayName": "Product display name", + "OrderLineProductInventoryStrategy": "Product inventory strategy", "OrderLineSkuName": "SKU name", "OrderLineSkuDescription": "SKU description", "OrderLineMediaResources": "Media resources", diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hans.json b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hans.json index 00245f2f..a4f962f4 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hans.json +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hans.json @@ -35,6 +35,7 @@ "OrderLineProductGroupDisplayName": "商品组名称", "OrderLineProductUniqueName": "商品编号", "OrderLineProductDisplayName": "商品名称", + "OrderLineProductInventoryStrategy": "商品库存策略", "OrderLineSkuName": "SKU 编号", "OrderLineSkuDescription": "SKU 描述", "OrderLineMediaResources": "多媒体资源", diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hant.json b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hant.json index 6529af18..7db41b9f 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hant.json +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/zh-Hant.json @@ -35,6 +35,7 @@ "OrderLineProductGroupDisplayName": "商品組名稱", "OrderLineProductUniqueName": "商品編號", "OrderLineProductDisplayName": "商品名稱", + "OrderLineProductInventoryStrategy": "商品庫存策略", "OrderLineSkuName": "SKU 編號", "OrderLineSkuDescription": "SKU 描述", "OrderLineMediaResources": "多媒體資源", diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/IOrderLine.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/IOrderLine.cs index feadc7e2..f63f14a3 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/IOrderLine.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/IOrderLine.cs @@ -1,4 +1,5 @@ using System; +using EasyAbp.EShop.Products.Products; using Volo.Abp.Data; namespace EasyAbp.EShop.Orders.Orders @@ -6,44 +7,50 @@ namespace EasyAbp.EShop.Orders.Orders public interface IOrderLine : IHasExtraProperties { Guid ProductId { get; } - + Guid ProductSkuId { get; } - + Guid? ProductDetailId { get; } - + DateTime ProductModificationTime { get; } - + DateTime? ProductDetailModificationTime { get; } - + string ProductGroupName { get; } - + string ProductGroupDisplayName { get; } - + string ProductUniqueName { get; } - + string ProductDisplayName { get; } - + + /// + /// If it is null, should get the from the Product entity. + /// See https://github.com/EasyAbp/EShop/issues/215 + /// + InventoryStrategy? ProductInventoryStrategy { get; } + string SkuName { get; } - + string SkuDescription { get; } - + string MediaResources { get; } - + string Currency { get; } - + decimal UnitPrice { get; } - + decimal TotalPrice { get; } - + decimal TotalDiscount { get; } - + /// /// ActualTotalPrice = TotalPrice - TotalDiscount /// decimal ActualTotalPrice { get; } int Quantity { get; } - + int RefundedQuantity { get; } decimal RefundAmount { get; } diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/OrderLineEto.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/OrderLineEto.cs index 7698bc53..6bce13d7 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/OrderLineEto.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/OrderLineEto.cs @@ -1,4 +1,5 @@ using System; +using EasyAbp.EShop.Products.Products; using Volo.Abp.Data; using Volo.Abp.ObjectExtending; @@ -25,7 +26,9 @@ namespace EasyAbp.EShop.Orders.Orders public string ProductUniqueName { get; set; } public string ProductDisplayName { get; set; } - + + public InventoryStrategy? ProductInventoryStrategy { get; set; } + public string SkuName { get; set; } public string SkuDescription { get; set; } diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderLine.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderLine.cs index 9967f0d2..e8b84996 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderLine.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderLine.cs @@ -1,6 +1,6 @@ using System; -using System.Collections.Generic; using System.Text.Json.Serialization; +using EasyAbp.EShop.Products.Products; using JetBrains.Annotations; using Volo.Abp.Data; using Volo.Abp.Domain.Entities.Auditing; @@ -30,7 +30,9 @@ namespace EasyAbp.EShop.Orders.Orders [NotNull] public virtual string ProductDisplayName { get; protected set; } - + + public virtual InventoryStrategy? ProductInventoryStrategy { get; protected set; } + [CanBeNull] public virtual string SkuName { get; protected set; } @@ -77,6 +79,7 @@ namespace EasyAbp.EShop.Orders.Orders [NotNull] string productGroupDisplayName, [CanBeNull] string productUniqueName, [NotNull] string productDisplayName, + InventoryStrategy productInventoryStrategy, [CanBeNull] string skuName, [CanBeNull] string skuDescription, [CanBeNull] string mediaResources, @@ -96,6 +99,7 @@ namespace EasyAbp.EShop.Orders.Orders ProductGroupDisplayName = productGroupDisplayName; ProductUniqueName = productUniqueName; ProductDisplayName = productDisplayName; + ProductInventoryStrategy = productInventoryStrategy; SkuName = skuName; SkuDescription = skuDescription; MediaResources = mediaResources; diff --git a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/InventoryReductionResultTests.cs b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/InventoryReductionResultTests.cs index c20476dc..13806a0e 100644 --- a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/InventoryReductionResultTests.cs +++ b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/InventoryReductionResultTests.cs @@ -38,6 +38,7 @@ public class InventoryReductionResultTests : OrdersDomainTestBase "Default", null, "Product 1", + InventoryStrategy.NoNeed, null, null, null, diff --git a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/OrderDomainTests.cs b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/OrderDomainTests.cs index 4a4a61f1..e28f5e3c 100644 --- a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/OrderDomainTests.cs +++ b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Domain.Tests/Orders/OrderDomainTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using EasyAbp.EShop.Payments.Refunds; +using EasyAbp.EShop.Products.Products; using Microsoft.Extensions.DependencyInjection; using NSubstitute; using Shouldly; @@ -46,6 +47,7 @@ namespace EasyAbp.EShop.Orders.Orders "Default", null, "Product 1", + InventoryStrategy.NoNeed, null, null, null, diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.Designer.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.Designer.cs new file mode 100644 index 00000000..23aac55e --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.Designer.cs @@ -0,0 +1,6171 @@ +// +using System; +using EShopSample.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace EShopSample.Migrations +{ + [DbContext(typeof(EShopSampleDbContext))] + [Migration("20220818075709_AddedProductInventoryStrategyProperty")] + partial class AddedProductInventoryStrategyProperty + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("ProductVersion", "6.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpBookingServiceAssetCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancies.AssetOccupancy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OccupierName") + .HasColumnType("nvarchar(max)"); + + b.Property("OccupierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("Date", "OccupierUserId"); + + b.HasIndex("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancies", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancyCounts.AssetOccupancyCount", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancyCounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetPeriodSchemes.AssetPeriodScheme", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Date", "AssetId"); + + b.ToTable("EasyAbpBookingServiceAssetPeriodSchemes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServiceAssets", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodUsable") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Date", "AssetId", "PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServiceAssetSchedules", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.HasKey("Id"); + + b.HasIndex("PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServicePeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServicePeriodSchemes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CancellationReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderNumber") + .HasColumnType("nvarchar(450)"); + + b.Property("OrderStatus") + .HasColumnType("int"); + + b.Property("PaidTime") + .HasColumnType("datetime2"); + + b.Property("PaymentExpiration") + .HasColumnType("datetime2"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("ReducedInventoryAfterPaymentTime") + .HasColumnType("datetime2"); + + b.Property("ReducedInventoryAfterPlacingTime") + .HasColumnType("datetime2"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderNumber") + .IsUnique() + .HasFilter("[OrderNumber] IS NOT NULL"); + + b.ToTable("EasyAbpEShopOrdersOrders", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Key") + .HasColumnType("nvarchar(450)"); + + b.Property("Fee") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("OrderId", "Name", "Key"); + + b.ToTable("EasyAbpEShopOrdersOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductInventoryStrategy") + .HasColumnType("int"); + + b.Property("ProductModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("EasyAbpEShopOrdersOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsPayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpEShopPaymentsPaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("OrderLineId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.BasketItems.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BasketName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsInvalid") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpEShopPluginsBasketsBasketItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.ProductUpdates.ProductUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopPluginsBasketsProductUpdates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.GrantedStores.GrantedStore", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowAll") + .HasColumnType("bit"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingGrantedStores", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FromTime") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("ToTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategoryPeriod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductAssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAssetCategoryId"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetCategoryPeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FromTime") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("ToTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssets", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAssetPeriod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductAssetId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAssetId"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetPeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.Coupons.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DiscountedAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("ExpirationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UsedTime") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCoupons", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConditionAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CouponType") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscountAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsUnscoped") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("UsableBeginTime") + .HasColumnType("datetime2"); + + b.Property("UsableDuration") + .HasColumnType("time"); + + b.Property("UsableEndTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CouponTemplateId"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplateScopes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BeginTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSalePlans", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PlanId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasColumnType("nvarchar(max)"); + + b.Property("ReducedInventoryTime") + .HasColumnType("datetime2"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSaleResults", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpEShopProductsCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductCategories.ProductCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetailHistories.ProductDetailHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductDetailId"); + + b.ToTable("EasyAbpEShopProductsProductDetailHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetails.ProductDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductDetails", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductHistories.ProductHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductInventories.ProductInventory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopProductsProductInventories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProducts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductAttributes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductAttributeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAttributeId"); + + b.ToTable("EasyAbpEShopProductsProductAttributeOptions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderMaxQuantity") + .HasColumnType("int"); + + b.Property("OrderMinQuantity") + .HasColumnType("int"); + + b.Property("OriginalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedAttributeOptionIds") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductSkus", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductView", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("MaximumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("MinimumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProductViews", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.StoreOwners.StoreOwner", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OwnerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("OwnerUserId", "StoreId") + .IsUnique(); + + b.ToTable("EasyAbpEShopStoresStoreOwners", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Stores.Store", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresStores", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServicePaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Accounts.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Balance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingTopUpPaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingWithdrawalAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingWithdrawalRecordId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentAccounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OriginalBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("AccountUserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRecords.WithdrawalRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("CancellationTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ResultErrorCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ResultErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("WithdrawalMethod") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRequests.WithdrawalRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsApproved") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ReviewTime") + .HasColumnType("datetime2"); + + b.Property("ReviewerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRequests", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServiceRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpPaymentServiceRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.PaymentRecords.PaymentRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("Attach") + .HasColumnType("nvarchar(max)"); + + b.Property("BankType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponCount") + .HasColumnType("int"); + + b.Property("CouponFee") + .HasColumnType("int"); + + b.Property("CouponFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeviceInfo") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCodeDes") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("IsSubscribe") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("Openid") + .HasColumnType("nvarchar(max)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ResultCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TimeEnd") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TradeType") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayPaymentRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.RefundRecords.RefundRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashRefundFee") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponRefundCount") + .HasColumnType("int"); + + b.Property("CouponRefundFee") + .HasColumnType("int"); + + b.Property("CouponRefundFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("OutRefundNo") + .HasColumnType("nvarchar(450)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundFee") + .HasColumnType("int"); + + b.Property("RefundId") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRecvAccout") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRequestSource") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundStatus") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementRefundFee") + .HasColumnType("int"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("SuccessTime") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("OutRefundNo"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayRefundRecords", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasColumnType("nvarchar(max)"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorTenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ImpersonatorTenantName"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("ImpersonatorUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ImpersonatorUserName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("TenantName"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsAbandoned") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("JobArgs") + .IsRequired() + .HasMaxLength(1048576) + .HasColumnType("nvarchar(max)"); + + b.Property("JobName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("LastTryTime") + .HasColumnType("datetime2"); + + b.Property("NextTryTime") + .HasColumnType("datetime2"); + + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint") + .HasDefaultValue((byte)15); + + b.Property("TryCount") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasDefaultValue((short)0); + + b.HasKey("Id"); + + b.HasIndex("IsAbandoned", "NextTryTime"); + + b.ToTable("AbpBackgroundJobs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpFeatureValues", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowedAccessTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Type"); + + b.ToTable("IdentityServerApiResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiResourceId", "Key", "Value"); + + b.ToTable("IdentityServerApiResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Scope"); + + b.ToTable("IdentityServerApiResourceScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ApiResourceId", "Type", "Value"); + + b.ToTable("IdentityServerApiResourceSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiScopeId", "Type"); + + b.ToTable("IdentityServerApiScopeClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiScopeId", "Key", "Value"); + + b.ToTable("IdentityServerApiScopeProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("bit"); + + b.Property("AllowOfflineAccess") + .HasColumnType("bit"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("bit"); + + b.Property("AllowRememberConsent") + .HasColumnType("bit"); + + b.Property("AllowedIdentityTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("bit"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("bit"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("BackChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ClientClaimsPrefix") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LogoUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("PairWiseSubjectSalt") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProtocolType") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("bit"); + + b.Property("RequireConsent") + .HasColumnType("bit"); + + b.Property("RequirePkce") + .HasColumnType("bit"); + + b.Property("RequireRequestObject") + .HasColumnType("bit"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("bit"); + + b.Property("UserCodeType") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("IdentityServerClients", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Origin") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.HasKey("ClientId", "Origin"); + + b.ToTable("IdentityServerClientCorsOrigins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("GrantType") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "GrantType"); + + b.ToTable("IdentityServerClientGrantTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Provider") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Provider"); + + b.ToTable("IdentityServerClientIdPRestrictions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("PostLogoutRedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "PostLogoutRedirectUri"); + + b.ToTable("IdentityServerClientPostLogoutRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "Key", "Value"); + + b.ToTable("IdentityServerClientProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("RedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "RedirectUri"); + + b.ToTable("IdentityServerClientRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Scope"); + + b.ToTable("IdentityServerClientScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Devices.DeviceFlowCodes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("DeviceCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UserCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.HasIndex("UserCode"); + + b.ToTable("IdentityServerDeviceFlowCodes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Grants.PersistedGrant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsumedTime") + .HasColumnType("datetime2"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.HasIndex("SubjectId", "SessionId", "Type"); + + b.ToTable("IdentityServerPersistedGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerIdentityResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("IdentityResourceId", "Type"); + + b.ToTable("IdentityServerIdentityResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("IdentityResourceId", "Key", "Value"); + + b.ToTable("IdentityServerIdentityResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[TenantId] IS NOT NULL"); + + b.ToTable("AbpPermissionGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpSettings", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.HasOne("EasyAbp.BookingService.AssetCategories.AssetCategory", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetCategoryId"); + + b1.ToTable("EasyAbpBookingServiceAssetCategories"); + + b1.WithOwner() + .HasForeignKey("AssetCategoryId"); + }); + + b.Navigation("Parent"); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetId"); + + b1.ToTable("EasyAbpBookingServiceAssets"); + + b1.WithOwner() + .HasForeignKey("AssetId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetScheduleId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetScheduleId"); + + b1.ToTable("EasyAbpBookingServiceAssetSchedules"); + + b1.WithOwner() + .HasForeignKey("AssetScheduleId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.HasOne("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", null) + .WithMany("Periods") + .HasForeignKey("PeriodSchemeId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderExtraFees") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderLines") + .HasForeignKey("OrderId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderExtraFees") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderLines") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategoryPeriod", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", null) + .WithMany("Periods") + .HasForeignKey("ProductAssetCategoryId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAssetPeriod", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", null) + .WithMany("Periods") + .HasForeignKey("ProductAssetId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", null) + .WithMany("Scopes") + .HasForeignKey("CouponTemplateId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.HasOne("EasyAbp.EShop.Products.Categories.Category", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductAttributes") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.ProductAttribute", null) + .WithMany("ProductAttributeOptions") + .HasForeignKey("ProductAttributeId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductSkus") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.PaymentService.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.PaymentService.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("Properties") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Navigation("Scopes"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Navigation("ProductAttributes"); + + b.Navigation("ProductSkus"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Navigation("ProductAttributeOptions"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Navigation("Properties"); + + b.Navigation("Scopes"); + + b.Navigation("Secrets"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Navigation("AllowedCorsOrigins"); + + b.Navigation("AllowedGrantTypes"); + + b.Navigation("AllowedScopes"); + + b.Navigation("Claims"); + + b.Navigation("ClientSecrets"); + + b.Navigation("IdentityProviderRestrictions"); + + b.Navigation("PostLogoutRedirectUris"); + + b.Navigation("Properties"); + + b.Navigation("RedirectUris"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.cs new file mode 100644 index 00000000..7fe37d7f --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220818075709_AddedProductInventoryStrategyProperty.cs @@ -0,0 +1,37 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EShopSample.Migrations +{ + public partial class AddedProductInventoryStrategyProperty : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ReducedInventoryTime", + table: "EasyAbpEShopPluginsFlashSalesFlashSaleResults", + type: "datetime2", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "ProductInventoryStrategy", + table: "EasyAbpEShopOrdersOrderLines", + type: "int", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ReducedInventoryTime", + table: "EasyAbpEShopPluginsFlashSalesFlashSaleResults"); + + migrationBuilder.DropColumn( + name: "ProductInventoryStrategy", + table: "EasyAbpEShopOrdersOrderLines"); + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs index 84e3eafc..8395ef4a 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs @@ -19,7 +19,7 @@ namespace EShopSample.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("ProductVersion", "6.0.8") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); @@ -699,6 +699,9 @@ namespace EShopSample.Migrations b.Property("ProductId") .HasColumnType("uniqueidentifier"); + b.Property("ProductInventoryStrategy") + .HasColumnType("int"); + b.Property("ProductModificationTime") .HasColumnType("datetime2"); @@ -1853,6 +1856,9 @@ namespace EShopSample.Migrations b.Property("Reason") .HasColumnType("nvarchar(max)"); + b.Property("ReducedInventoryTime") + .HasColumnType("datetime2"); + b.Property("Status") .HasColumnType("int"); From 6713e473553f21201977ed2f7d5342b1f0a59be6 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Thu, 18 Aug 2022 18:53:55 +0800 Subject: [PATCH 93/97] Set `Order.ReducedInventoryAfterPlacingTime` in advance Resolve #214 --- .../EShop/Orders/Orders/NewOrderGenerator.cs | 7 ++ .../Orders/OrderAppServiceTests.cs | 80 +++++++++++++++++++ .../Orders/OrderCreatedEventHandler.cs | 20 ++++- .../Products/OrderCreatedEventHandler.cs | 21 +++-- .../Products/OrderPaidEventHandler.cs | 12 ++- 5 files changed, 129 insertions(+), 11 deletions(-) diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs index be1225ae..fa253029 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs @@ -93,6 +93,13 @@ namespace EasyAbp.EShop.Orders.Orders order.SetOrderNumber(await _orderNumberGenerator.CreateAsync(order)); + // set ReducedInventoryAfterPlacingTime directly if an order contains no OrderLine with `InventoryStrategy.ReduceAfterPlacing`. + // see https://github.com/EasyAbp/EShop/issues/214 + if (order.OrderLines.All(x => x.ProductInventoryStrategy != InventoryStrategy.ReduceAfterPlacing)) + { + order.SetReducedInventoryAfterPlacingTime(_clock.Now); + } + return order; } diff --git a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs index bc99825f..3da6263f 100644 --- a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs +++ b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderAppServiceTests.cs @@ -591,5 +591,85 @@ namespace EasyAbp.EShop.Orders.Orders throw; } } + + [Fact] + public async Task Should_Set_ReducedInventoryAfterPlacingTime_If_No_ReduceAfterPlacing_OrderLine() + { + var createOrderDto = new CreateOrderDto + { + CustomerRemark = "customer remark", + StoreId = OrderTestData.Store1Id, + OrderLines = new List + { + new CreateOrderLineDto + { + ProductId = OrderTestData.Product1Id, + ProductSkuId = OrderTestData.ProductSku1Id, + Quantity = 10 + }, + new CreateOrderLineDto + { + ProductId = OrderTestData.Product1Id, + ProductSkuId = OrderTestData.ProductSku2Id, + Quantity = 1 + } + } + }; + + OrderDto createResponse = null; + await WithUnitOfWorkAsync(async () => + { + createResponse = await _orderAppService.CreateAsync(createOrderDto); + }); + + var order = await _orderAppService.GetAsync(createResponse.Id); + + // The fake inventory reducer (OrderCreatedEventHandler) should skip handling. + OrderCreatedEventHandler.LastOrderId.ShouldBe(order.Id); + OrderCreatedEventHandler.SkippedHandling.ShouldBeTrue(); + + order.ReducedInventoryAfterPlacingTime.ShouldNotBeNull(); + } + + [Fact] + public async Task Should_Not_Set_ReducedInventoryAfterPlacingTime_If_Contains_ReduceAfterPlacing_OrderLine() + { + Product1.InventoryStrategy = InventoryStrategy.ReduceAfterPlacing; + + var createOrderDto = new CreateOrderDto + { + CustomerRemark = "customer remark", + StoreId = OrderTestData.Store1Id, + OrderLines = new List + { + new CreateOrderLineDto + { + ProductId = OrderTestData.Product1Id, + ProductSkuId = OrderTestData.ProductSku1Id, + Quantity = 10 + }, + new CreateOrderLineDto + { + ProductId = OrderTestData.Product1Id, + ProductSkuId = OrderTestData.ProductSku2Id, + Quantity = 1 + } + } + }; + + OrderDto createResponse = null; + await WithUnitOfWorkAsync(async () => + { + createResponse = await _orderAppService.CreateAsync(createOrderDto); + }); + + var order = await _orderAppService.GetAsync(createResponse.Id); + + // The fake inventory reducer (OrderCreatedEventHandler) should handle it. + OrderCreatedEventHandler.LastOrderId.ShouldBe(order.Id); + OrderCreatedEventHandler.SkippedHandling.ShouldBeFalse(); + + order.ReducedInventoryAfterPlacingTime.ShouldNotBeNull(); + } } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderCreatedEventHandler.cs b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderCreatedEventHandler.cs index ea8e7ae3..da491e8b 100644 --- a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderCreatedEventHandler.cs +++ b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.Application.Tests/Orders/OrderCreatedEventHandler.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using EasyAbp.EShop.Products.Products; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities.Events.Distributed; @@ -9,6 +10,9 @@ namespace EasyAbp.EShop.Orders.Orders { public class OrderCreatedEventHandler : IDistributedEventHandler>, ITransientDependency { + public static Guid LastOrderId { get; set; } + public static bool SkippedHandling { get; set; } + private readonly ICurrentTenant _currentTenant; private readonly IDistributedEventBus _distributedEventBus; @@ -19,9 +23,21 @@ namespace EasyAbp.EShop.Orders.Orders _currentTenant = currentTenant; _distributedEventBus = distributedEventBus; } - + public virtual async Task HandleEventAsync(EntityCreatedEto eventData) { + LastOrderId = eventData.Entity.Id; + + // skip if an order contains no OrderLine with `InventoryStrategy.ReduceAfterPlacing`. + // see https://github.com/EasyAbp/EShop/issues/214 + if (eventData.Entity.ReducedInventoryAfterPlacingTime is not null) + { + SkippedHandling = true; + return; + } + + SkippedHandling = false; + using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId); await _distributedEventBus.PublishAsync(new ProductInventoryReductionAfterOrderPlacedResultEto diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderCreatedEventHandler.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderCreatedEventHandler.cs index 1e16d1ba..c0d80119 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderCreatedEventHandler.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderCreatedEventHandler.cs @@ -39,25 +39,36 @@ namespace EasyAbp.EShop.Products.Products [UnitOfWork(true)] public virtual async Task HandleEventAsync(EntityCreatedEto eventData) { + // skip if an order contains no OrderLine with `InventoryStrategy.ReduceAfterPlacing`. + // see https://github.com/EasyAbp/EShop/issues/214 + if (eventData.Entity.ReducedInventoryAfterPlacingTime is not null) + { + return; + } + using var changeTenant = _currentTenant.Change(eventData.Entity.TenantId); var models = new List(); foreach (var orderLine in eventData.Entity.OrderLines) { - // Todo: Should use ProductHistory. - var product = await _productRepository.FindAsync(orderLine.ProductId); + var inventoryStrategy = orderLine.ProductInventoryStrategy; + if (inventoryStrategy is not null && inventoryStrategy != InventoryStrategy.ReduceAfterPlacing) + { + continue; + } + var product = await _productRepository.FindAsync(orderLine.ProductId); var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId); - if (productSku == null) { await PublishInventoryReductionResultEventAsync(eventData, false); return; } - - if (product.InventoryStrategy != InventoryStrategy.ReduceAfterPlacing) + + inventoryStrategy ??= product.InventoryStrategy; + if (inventoryStrategy != InventoryStrategy.ReduceAfterPlacing) { continue; } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderPaidEventHandler.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderPaidEventHandler.cs index 0d2a82fc..4f3b5140 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderPaidEventHandler.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/OrderPaidEventHandler.cs @@ -44,11 +44,14 @@ namespace EasyAbp.EShop.Products.Products foreach (var orderLine in eventData.Order.OrderLines) { - // Todo: Should use ProductHistory. - var product = await _productRepository.FindAsync(orderLine.ProductId); + var inventoryStrategy = orderLine.ProductInventoryStrategy; + if (inventoryStrategy is not null && inventoryStrategy != InventoryStrategy.ReduceAfterPayment) + { + continue; + } + var product = await _productRepository.FindAsync(orderLine.ProductId); var productSku = product?.ProductSkus.FirstOrDefault(sku => sku.Id == orderLine.ProductSkuId); - if (productSku == null) { await PublishInventoryReductionResultEventAsync(eventData, false); @@ -56,7 +59,8 @@ namespace EasyAbp.EShop.Products.Products return; } - if (product.InventoryStrategy != InventoryStrategy.ReduceAfterPayment) + inventoryStrategy ??= product.InventoryStrategy; + if (inventoryStrategy != InventoryStrategy.ReduceAfterPayment) { continue; } From 5046f27ca8e723aa2c7cca5c4212a1949732f247 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Thu, 18 Aug 2022 21:42:07 +0800 Subject: [PATCH 94/97] Change version to 3.0.0-preview.17 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index 920fb43c..d6a9c29c 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.16 + 3.0.0-preview.17 $(NoWarn);CS1591 true EasyAbp Team From fa6d13e9523840fab501583b140c94c3555f0478 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Fri, 19 Aug 2022 02:34:52 +0800 Subject: [PATCH 95/97] Fix flash sales cache invalidators --- .../FlashSalePlans/FlashSalePlanCacheInvalidator.cs | 2 +- .../EShop/Products/Products/ProductCacheInvalidator.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs index 7c3c568a..d8320613 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanCacheInvalidator.cs @@ -25,7 +25,7 @@ public class FlashSalePlanCacheInvalidator : ILocalEventHandler + UnitOfWorkManager.Current?.OnCompleted(async () => { await DistributedCache.RemoveAsync(eventData.Entity.Id); }); diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs index d9d1ed46..4e975b85 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs @@ -28,7 +28,7 @@ public class ProductCacheInvalidator : { await DistributedCache.RemoveAsync(eventData.Entity.Id); - UnitOfWorkManager.Current.OnCompleted(async () => + UnitOfWorkManager.Current?.OnCompleted(async () => { await DistributedCache.RemoveAsync(eventData.Entity.Id); }); @@ -38,7 +38,7 @@ public class ProductCacheInvalidator : { await DistributedCache.RemoveAsync(eventData.Entity.Id); - UnitOfWorkManager.Current.OnCompleted(async () => + UnitOfWorkManager.Current?.OnCompleted(async () => { await DistributedCache.RemoveAsync(eventData.Entity.Id); }); From 1a05cf4bb156878fd5dfde6678c5e216cae97432 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Fri, 19 Aug 2022 02:35:18 +0800 Subject: [PATCH 96/97] Change version to 3.0.0-preview.18 --- common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.props b/common.props index d6a9c29c..b31780b5 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 3.0.0-preview.17 + 3.0.0-preview.18 $(NoWarn);CS1591 true EasyAbp Team From 2bfadf66550685b9dca87340dd435e17aa4bcd82 Mon Sep 17 00:00:00 2001 From: gdlcf88 Date: Fri, 19 Aug 2022 03:56:16 +0800 Subject: [PATCH 97/97] Persist inventory immediately for the first time invoking --- .../Plugins/Inventories/DaprActors/InventoryActor.cs | 8 +++++--- .../Plugins/Inventories/OrleansGrains/InventoryGrain.cs | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs index 73f8963c..6c777df3 100644 --- a/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs +++ b/plugins/Inventories/DaprActors/src/EasyAbp.EShop.Plugins.Inventories.DaprActors/EasyAbp/EShop/Plugins/Inventories/DaprActors/InventoryActor.cs @@ -39,7 +39,7 @@ public class InventoryActor : Actor, IInventoryActor } else { - await TryRegisterFlashSalesPersistInventoryTimerAsync(); + await TryStartIntervalPersistInventoryAsync(); } } @@ -55,11 +55,11 @@ public class InventoryActor : Actor, IInventoryActor } else { - await TryRegisterFlashSalesPersistInventoryTimerAsync(); + await TryStartIntervalPersistInventoryAsync(); } } - protected virtual async Task TryRegisterFlashSalesPersistInventoryTimerAsync() + protected virtual async Task TryStartIntervalPersistInventoryAsync() { if (FlashSalesInventoryUpdated) { @@ -68,6 +68,8 @@ public class InventoryActor : Actor, IInventoryActor FlashSalesInventoryUpdated = true; + await SetInventoryStateAsync(await GetInventoryStateAsync()); + await RegisterTimerAsync(null, nameof(TimerSetInventoryStateAsync), null, TimeSpan.FromSeconds(5), TimeSpan.FromMilliseconds(-1)); } diff --git a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs index cb4aa189..4c657425 100644 --- a/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs +++ b/plugins/Inventories/OrleansGrains/src/EasyAbp.EShop.Plugins.Inventories.OrleansGrains/EasyAbp/EShop/Plugins/Inventories/OrleansGrains/InventoryGrain.cs @@ -25,7 +25,7 @@ public class InventoryGrain : Grain, IInventoryGrain } else { - TryRegisterFlashSalesPersistInventoryTimer(); + await TryStartIntervalPersistInventoryAsync(); } } @@ -39,11 +39,11 @@ public class InventoryGrain : Grain, IInventoryGrain } else { - TryRegisterFlashSalesPersistInventoryTimer(); + await TryStartIntervalPersistInventoryAsync(); } } - protected virtual void TryRegisterFlashSalesPersistInventoryTimer() + protected virtual async Task TryStartIntervalPersistInventoryAsync() { if (FlashSalesInventoryUpdated) { @@ -52,6 +52,8 @@ public class InventoryGrain : Grain, IInventoryGrain FlashSalesInventoryUpdated = true; + await WriteStateAsync(); + RegisterTimer(TimerWriteInventoryStateAsync, new object(), TimeSpan.FromSeconds(5), TimeSpan.FromMilliseconds(-1)); }