mirror of https://github.com/EasyAbp/EShop.git
32 changed files with 441 additions and 129 deletions
33
plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs → plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs
33
plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs → plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile.cs
@ -1,34 +1,35 @@ |
|||||
using System.Collections.Generic; |
using AutoMapper; |
||||
using System; |
|
||||
using AutoMapper; |
|
||||
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; |
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; |
||||
using EasyAbp.EShop.Products.ProductDetails.Dtos; |
using EasyAbp.EShop.Products.ProductDetails.Dtos; |
||||
using EasyAbp.EShop.Products.Products; |
|
||||
using EasyAbp.EShop.Products.Products.Dtos; |
using EasyAbp.EShop.Products.Products.Dtos; |
||||
|
using Volo.Abp.AutoMapper; |
||||
using Volo.Abp.DependencyInjection; |
using Volo.Abp.DependencyInjection; |
||||
using Volo.Abp.Json; |
|
||||
|
|
||||
namespace EasyAbp.EShop.Orders |
namespace EasyAbp.EShop.Orders.Plugins.FlashSales |
||||
{ |
{ |
||||
public class EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile : Profile, ISingletonDependency |
public class EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile : Profile |
||||
{ |
{ |
||||
public EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile(IJsonSerializer jsonSerializer) |
public EShopOrdersPluginsFlashSalesApplicationAutoMapperProfile() |
||||
{ |
{ |
||||
/* You can configure your AutoMapper mapping configuration here. |
/* You can configure your AutoMapper mapping configuration here. |
||||
* Alternatively, you can split your mapping configurations |
* Alternatively, you can split your mapping configurations |
||||
* into multiple profile classes for a better organization. */ |
* into multiple profile classes for a better organization. */ |
||||
CreateMap<FlashSalesProductEto, ProductDto>(MemberList.Source) |
CreateMap<FlashSalesProductEto, ProductDto>(MemberList.Destination) |
||||
.ForSourceMember(x => x.TenantId, opt => opt.DoNotValidate()) |
.Ignore(dto => dto.Sold) |
||||
|
.Ignore(dto => dto.MinimumPrice) |
||||
|
.Ignore(dto => dto.MaximumPrice) |
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
CreateMap<FlashSalesProductSkuEto, ProductSkuDto>(MemberList.Source) |
CreateMap<FlashSalesProductSkuEto, ProductSkuDto>(MemberList.Destination) |
||||
.ForMember(x => x.AttributeOptionIds, opt => opt.Ignore()) |
.ForSourceMember(entity => entity.SerializedAttributeOptionIds, opt => opt.DoNotValidate()) |
||||
.AfterMap((src, dest) => dest.AttributeOptionIds = jsonSerializer.Deserialize<List<Guid>>(src.SerializedAttributeOptionIds)) |
.Ignore(dto => dto.DiscountedPrice) |
||||
|
.Ignore(dto => dto.Inventory) |
||||
|
.Ignore(dto => dto.Sold) |
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
CreateMap<FlashSalesProductAttributeEto, ProductAttributeDto>(MemberList.Source) |
CreateMap<FlashSalesProductAttributeEto, ProductAttributeDto>(MemberList.Destination) |
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
CreateMap<FlashSalesProductAttributeOptionEto, ProductAttributeOptionDto>(MemberList.Source) |
CreateMap<FlashSalesProductAttributeOptionEto, ProductAttributeOptionDto>(MemberList.Destination) |
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
CreateMap<FlashSalesProductDetailEto, ProductDetailDto>(MemberList.Source) |
CreateMap<FlashSalesProductDetailEto, ProductDetailDto>(MemberList.Destination) |
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
} |
} |
||||
} |
} |
||||
16
plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs → plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs
16
plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs → plugins/FlashSales/src/EasyAbp.EShop.Orders.Plugins.FlashSales.Application/EasyAbp/EShop/Orders/Plugins/FlashSales/EShopOrdersPluginsFlashSalesApplicationModule.cs
@ -1,48 +1,28 @@ |
|||||
using System.Linq; |
|
||||
using AutoMapper; |
using AutoMapper; |
||||
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; |
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; |
||||
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; |
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans.Dtos; |
||||
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; |
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults; |
||||
using EasyAbp.EShop.Plugins.FlashSales.FlashSalesResults.Dtos; |
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; |
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. |
/* You can configure your AutoMapper mapping configuration here. |
||||
* Alternatively, you can split your mapping configurations |
* Alternatively, you can split your mapping configurations |
||||
* into multiple profile classes for a better organization. */ |
* into multiple profile classes for a better organization. */ |
||||
CreateMap<FlashSalesPlan, FlashSalesPlanDto>() |
CreateMap<FlashSalesPlan, FlashSalesPlanDto>() |
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
CreateMap<FlashSalesPlanDto, FlashSalesPlanEto>() |
|
||||
.ForMember(x => x.TenantId, opt => opt.Ignore()) |
|
||||
.MapExtraProperties(); |
|
||||
CreateMap<FlashSalesPlanCreateDto, FlashSalesPlan>(MemberList.Source); |
CreateMap<FlashSalesPlanCreateDto, FlashSalesPlan>(MemberList.Source); |
||||
CreateMap<FlashSalesPlanUpdateDto, FlashSalesPlan>(MemberList.Source); |
CreateMap<FlashSalesPlanUpdateDto, FlashSalesPlan>(MemberList.Source); |
||||
CreateMap<FlashSalesPlan, FlashSalesPlanCacheItem>() |
CreateMap<FlashSalesPlan, FlashSalesPlanCacheItem>() |
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
|
CreateMap<FlashSalesPlanCacheItem, FlashSalesPlanEto>() |
||||
CreateMap<FlashSalesResult, FlashSalesResultDto>() |
|
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
|
|
||||
CreateMap<ProductDto, FlashSalesProductEto>() |
CreateMap<FlashSalesResult, FlashSalesResultDto>() |
||||
.ForMember(x => x.TenantId, opt => opt.Ignore()) |
|
||||
.MapExtraProperties(); |
|
||||
CreateMap<ProductSkuDto, FlashSalesProductSkuEto>() |
|
||||
.ForMember(x => x.SerializedAttributeOptionIds, opt => opt.Ignore()) |
|
||||
.AfterMap((src, dest) => dest.SerializedAttributeOptionIds = jsonSerializer.Serialize(src.AttributeOptionIds.OrderBy(x => x))) |
|
||||
.MapExtraProperties(); |
|
||||
CreateMap<ProductAttributeDto, FlashSalesProductAttributeEto>() |
|
||||
.MapExtraProperties(); |
|
||||
CreateMap<ProductAttributeOptionDto, FlashSalesProductAttributeOptionEto>() |
|
||||
.MapExtraProperties(); |
|
||||
CreateMap<ProductDetailDto, FlashSalesProductDetailEto>() |
|
||||
.MapExtraProperties(); |
.MapExtraProperties(); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -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<string> 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(); |
||||
|
} |
||||
|
} |
||||
@ -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; } |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; |
||||
|
|
||||
|
public interface IFlashSalesPlanHasher |
||||
|
{ |
||||
|
Task<string> HashAsync(DateTime? planLastModificationTime, DateTime? productLastModificationTime, DateTime? productSkuLastModificationTime); |
||||
|
} |
||||
@ -1,9 +1,13 @@ |
|||||
using System; |
using System; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; |
namespace EasyAbp.EShop.Plugins.FlashSales.FlashSalesPlans; |
||||
|
|
||||
public class FlashSalesProductDetailEto : FullAuditedEntityEto<Guid> |
[Serializable] |
||||
|
public class FlashSalesProductDetailEto : FullAuditedEntityEto<Guid>, IMultiTenant |
||||
{ |
{ |
||||
|
public Guid? TenantId { get; set; } |
||||
|
|
||||
public Guid? StoreId { get; set; } |
public Guid? StoreId { get; set; } |
||||
|
|
||||
public string Description { get; set; } |
public string Description { get; set; } |
||||
|
|||||
@ -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); |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Products\src\EasyAbp.EShop.Products.Application\EasyAbp.EShop.Products.Application.csproj" /> |
||||
|
<ProjectReference Include="..\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts\EasyAbp.EShop.Plugins.FlashSales.Application.Contracts.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -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<EShopProductsOptions> options) |
||||
|
{ |
||||
|
CreateMap<Product, FlashSalesProductEto>() |
||||
|
.ForMember(x => x.ProductGroupDisplayName, opt => opt.Ignore()) |
||||
|
.AfterMap((src, dest) => |
||||
|
{ |
||||
|
var dict = options.CurrentValue.Groups.GetConfigurationsDictionary(); |
||||
|
dest.ProductGroupDisplayName = dict[src.ProductGroupName].DisplayName; |
||||
|
}) |
||||
|
.MapExtraProperties(); |
||||
|
CreateMap<ProductSku, FlashSalesProductSkuEto>() |
||||
|
.ForMember(x => x.AttributeOptionIds, opt => opt.Ignore()) |
||||
|
.AfterMap(async (src, dest) => dest.AttributeOptionIds = (await attributeOptionIdsSerializer.DeserializeAsync(src.SerializedAttributeOptionIds)).ToList()) |
||||
|
.MapExtraProperties(); |
||||
|
CreateMap<ProductAttribute, FlashSalesProductAttributeEto>() |
||||
|
.MapExtraProperties(); |
||||
|
CreateMap<ProductAttributeOption, FlashSalesProductAttributeOptionEto>() |
||||
|
.MapExtraProperties(); |
||||
|
CreateMap<ProductDetail, FlashSalesProductDetailEto>() |
||||
|
.MapExtraProperties(); |
||||
|
} |
||||
|
} |
||||
@ -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<EShopProductsPluginsFlashSalesApplicationModule>(); |
||||
|
Configure<AbpAutoMapperOptions>(options => |
||||
|
{ |
||||
|
options.Configurators.Add(abpAutoMapperConfigurationContext => |
||||
|
{ |
||||
|
var profile = abpAutoMapperConfigurationContext.ServiceProvider |
||||
|
.GetRequiredService<EShopProductsPluginsFlashSalesApplicationAutoMapperProfile>(); |
||||
|
|
||||
|
abpAutoMapperConfigurationContext.MapperConfiguration.AddProfile(profile); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -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<FlashSalesReduceInventoryEto>, 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<ProductDetail, FlashSalesProductDetailEto>(await ProductDetailRepository.GetAsync(productDetailId.Value)) : |
||||
|
null; |
||||
|
|
||||
|
var productEto = ObjectMapper.Map<Product, FlashSalesProductEto>(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); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
Loading…
Reference in new issue