Commit 581cf178 authored by gdlcf88's avatar gdlcf88

Completed ProductStore feature, close #2

Completed store management
parent 2737922c
...@@ -6,9 +6,6 @@ namespace EasyAbp.EShop.Products.ProductCategories.Dtos ...@@ -6,9 +6,6 @@ namespace EasyAbp.EShop.Products.ProductCategories.Dtos
{ {
public class CreateUpdateProductCategoryDto public class CreateUpdateProductCategoryDto
{ {
[DisplayName("ProductCategoryStoreId")]
public Guid StoreId { get; set; }
[Required] [Required]
[DisplayName("ProductCategoryCategoryId")] [DisplayName("ProductCategoryCategoryId")]
public Guid CategoryId { get; set; } public Guid CategoryId { get; set; }
......
...@@ -5,8 +5,6 @@ namespace EasyAbp.EShop.Products.ProductCategories.Dtos ...@@ -5,8 +5,6 @@ namespace EasyAbp.EShop.Products.ProductCategories.Dtos
{ {
public class ProductCategoryDto : AuditedEntityDto<Guid> public class ProductCategoryDto : AuditedEntityDto<Guid>
{ {
public Guid StoreId { get; set; }
public Guid CategoryId { get; set; } public Guid CategoryId { get; set; }
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
......
...@@ -8,12 +8,15 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -8,12 +8,15 @@ namespace EasyAbp.EShop.Products.Products.Dtos
{ {
public class CreateUpdateProductDto : IValidatableObject public class CreateUpdateProductDto : IValidatableObject
{ {
[DisplayName("ProductStoreId")]
public Guid StoreId { get; set; }
[Required] [Required]
[DisplayName("ProductProductTypeId")] [DisplayName("ProductProductTypeId")]
public Guid ProductTypeId { get; set; } public Guid ProductTypeId { get; set; }
/// <summary>
/// This property is set for adding the store to ProductStore in creation, or for permission checking in update.
/// </summary>
[DisplayName("ProductStoreId")]
public Guid StoreId { get; set; }
[DisplayName("ProductCategory")] [DisplayName("ProductCategory")]
public ICollection<Guid> CategoryIds { get; set; } public ICollection<Guid> CategoryIds { get; set; }
......
...@@ -6,10 +6,10 @@ namespace EasyAbp.EShop.Products.Products.Dtos ...@@ -6,10 +6,10 @@ namespace EasyAbp.EShop.Products.Products.Dtos
{ {
public class ProductDto : FullAuditedEntityDto<Guid> public class ProductDto : FullAuditedEntityDto<Guid>
{ {
public Guid StoreId { get; set; }
public Guid ProductTypeId { get; set; } public Guid ProductTypeId { get; set; }
public ICollection<Guid> CategoryIds { get; set; }
public string DisplayName { get; set; } public string DisplayName { get; set; }
public InventoryStrategy InventoryStrategy { get; set; } public InventoryStrategy InventoryStrategy { get; set; }
......
using System; using System;
using System.Threading.Tasks;
using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Products.Products.Dtos;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
...@@ -13,6 +14,6 @@ namespace EasyAbp.EShop.Products.Products ...@@ -13,6 +14,6 @@ namespace EasyAbp.EShop.Products.Products
CreateUpdateProductDto, CreateUpdateProductDto,
CreateUpdateProductDto> CreateUpdateProductDto>
{ {
Task DeleteAsync(Guid id, Guid storeId);
} }
} }
\ No newline at end of file
...@@ -5,9 +5,9 @@ using System.Threading.Tasks; ...@@ -5,9 +5,9 @@ using System.Threading.Tasks;
using EasyAbp.EShop.Products.Authorization; using EasyAbp.EShop.Products.Authorization;
using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.ProductCategories;
using EasyAbp.EShop.Products.Products.Dtos; using EasyAbp.EShop.Products.Products.Dtos;
using Volo.Abp.Application.Dtos; using EasyAbp.EShop.Products.ProductStores;
using Volo.Abp;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Threading;
namespace EasyAbp.EShop.Products.Products namespace EasyAbp.EShop.Products.Products
{ {
...@@ -20,33 +20,25 @@ namespace EasyAbp.EShop.Products.Products ...@@ -20,33 +20,25 @@ namespace EasyAbp.EShop.Products.Products
protected override string GetPolicyName { get; set; } = ProductsPermissions.Products.Default; protected override string GetPolicyName { get; set; } = ProductsPermissions.Products.Default;
protected override string GetListPolicyName { get; set; } = ProductsPermissions.Products.Default; protected override string GetListPolicyName { get; set; } = ProductsPermissions.Products.Default;
private readonly IProductStoreRepository _productStoreRepository;
private readonly IProductCategoryRepository _productCategoryRepository; private readonly IProductCategoryRepository _productCategoryRepository;
private readonly IProductRepository _repository; private readonly IProductRepository _repository;
public ProductAppService( public ProductAppService(
IProductStoreRepository productStoreRepository,
IProductCategoryRepository productCategoryRepository, IProductCategoryRepository productCategoryRepository,
IProductRepository repository) : base(repository) IProductRepository repository) : base(repository)
{ {
_productStoreRepository = productStoreRepository;
_productCategoryRepository = productCategoryRepository; _productCategoryRepository = productCategoryRepository;
_repository = repository; _repository = repository;
} }
protected override IQueryable<Product> CreateFilteredQuery(GetProductListDto input) protected override IQueryable<Product> CreateFilteredQuery(GetProductListDto input)
{ {
var query = base.CreateFilteredQuery(input); return input.CategoryId.HasValue
? _repository.GetQueryable(input.StoreId, input.CategoryId.Value)
if (input.CategoryId.HasValue) : _repository.GetQueryable(input.StoreId);
{
var productIds = AsyncHelper
.RunSync(() => _productCategoryRepository.GetListByCategoryId(input.CategoryId.Value, input.StoreId))
.Select(pc => pc.ProductId).ToList();
query = query.Where(p => productIds.Contains(p.Id));
}
query = query.Where(p => p.StoreId == input.StoreId);
return query;
} }
public override async Task<ProductDto> CreateAsync(CreateUpdateProductDto input) public override async Task<ProductDto> CreateAsync(CreateUpdateProductDto input)
...@@ -60,16 +52,26 @@ namespace EasyAbp.EShop.Products.Products ...@@ -60,16 +52,26 @@ namespace EasyAbp.EShop.Products.Products
await UpdateProductAttributesAsync(product, input); await UpdateProductAttributesAsync(product, input);
await Repository.InsertAsync(product, autoSave: true); await Repository.InsertAsync(product, autoSave: true);
await AddProductToStoreAsync(product.Id, input.StoreId);
await UpdateProductCategoriesAsync(product.Id, product.StoreId, input.CategoryIds); await UpdateProductCategoriesAsync(product.Id, input.CategoryIds);
return MapToGetOutputDto(product); return MapToGetOutputDto(product);
} }
protected virtual async Task AddProductToStoreAsync(Guid productId, Guid storeId)
{
await _productStoreRepository.InsertAsync(new ProductStore(GuidGenerator.Create(), CurrentTenant.Id,
storeId, productId, true), true);
}
public override async Task<ProductDto> UpdateAsync(Guid id, CreateUpdateProductDto input) public override async Task<ProductDto> UpdateAsync(Guid id, CreateUpdateProductDto input)
{ {
await CheckUpdatePolicyAsync(); await CheckUpdatePolicyAsync();
await CheckStoreIsProductOwnerAsync(id, input.StoreId);
var product = await GetEntityByIdAsync(id); var product = await GetEntityByIdAsync(id);
MapToEntity(input, product); MapToEntity(input, product);
...@@ -78,12 +80,22 @@ namespace EasyAbp.EShop.Products.Products ...@@ -78,12 +80,22 @@ namespace EasyAbp.EShop.Products.Products
await Repository.UpdateAsync(product, autoSave: true); await Repository.UpdateAsync(product, autoSave: true);
await UpdateProductCategoriesAsync(product.Id, product.StoreId, input.CategoryIds); await UpdateProductCategoriesAsync(product.Id, input.CategoryIds);
return MapToGetOutputDto(product); return MapToGetOutputDto(product);
} }
private async Task UpdateProductAttributesAsync(Product product, CreateUpdateProductDto input) protected virtual async Task CheckStoreIsProductOwnerAsync(Guid id, Guid storeId)
{
var productStore = await _productStoreRepository.GetAsync(id, storeId);
if (!productStore.IsOwner)
{
throw new StoreIsNotProductOwnerException(id, storeId);
}
}
protected virtual async Task UpdateProductAttributesAsync(Product product, CreateUpdateProductDto input)
{ {
foreach (var attributeDto in input.ProductAttributes) foreach (var attributeDto in input.ProductAttributes)
{ {
...@@ -122,21 +134,39 @@ namespace EasyAbp.EShop.Products.Products ...@@ -122,21 +134,39 @@ namespace EasyAbp.EShop.Products.Products
product.ProductAttributes.RemoveAll(a => exceptAttributeNames.Contains(a.DisplayName)); product.ProductAttributes.RemoveAll(a => exceptAttributeNames.Contains(a.DisplayName));
} }
[RemoteService(IsMetadataEnabled = false)]
public override async Task DeleteAsync(Guid id) public override async Task DeleteAsync(Guid id)
{
throw new NotImplementedException();
}
public override async Task<ProductDto> GetAsync(Guid id)
{
var dto = await base.GetAsync(id);
dto.CategoryIds = (await _productCategoryRepository.GetListByProductIdAsync(dto.Id))
.Select(x => x.CategoryId).ToList();
return dto;
}
public async Task DeleteAsync(Guid id, Guid storeId)
{ {
await _productCategoryRepository.DeleteAsync(x => x.ProductId.Equals(id)); await _productCategoryRepository.DeleteAsync(x => x.ProductId.Equals(id));
await CheckStoreIsProductOwnerAsync(id, storeId);
await base.DeleteAsync(id); await base.DeleteAsync(id);
} }
protected virtual async Task UpdateProductCategoriesAsync(Guid productId, Guid storeId, IEnumerable<Guid> categoryIds) protected virtual async Task UpdateProductCategoriesAsync(Guid productId, IEnumerable<Guid> categoryIds)
{ {
await _productCategoryRepository.DeleteAsync(x => x.ProductId.Equals(productId)); await _productCategoryRepository.DeleteAsync(x => x.ProductId.Equals(productId));
foreach (var categoryId in categoryIds) foreach (var categoryId in categoryIds)
{ {
await _productCategoryRepository.InsertAsync(new ProductCategory(GuidGenerator.Create(), await _productCategoryRepository.InsertAsync(
CurrentTenant.Id, storeId, categoryId, productId)); new ProductCategory(GuidGenerator.Create(), CurrentTenant.Id, categoryId, productId), true);
} }
} }
} }
......
using System;
using Volo.Abp;
namespace EasyAbp.EShop.Products.Products
{
public class StoreIsNotProductOwnerException : BusinessException
{
public StoreIsNotProductOwnerException(Guid productId, Guid storeId) : base(
message: $"Store {storeId} is not a owner of the product {productId}")
{
}
}
}
\ No newline at end of file
...@@ -18,12 +18,14 @@ namespace EasyAbp.EShop.Products ...@@ -18,12 +18,14 @@ namespace EasyAbp.EShop.Products
/* 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<Product, ProductDto>(); CreateMap<Product, ProductDto>()
.Ignore(dto => dto.CategoryIds);
CreateMap<ProductDetail, ProductDetailDto>(); CreateMap<ProductDetail, ProductDetailDto>();
CreateMap<ProductAttribute, ProductAttributeDto>(); CreateMap<ProductAttribute, ProductAttributeDto>();
CreateMap<ProductAttributeOption, ProductAttributeOptionDto>(); CreateMap<ProductAttributeOption, ProductAttributeOptionDto>();
CreateMap<ProductSku, ProductSkuDto>(); CreateMap<ProductSku, ProductSkuDto>();
CreateMap<CreateUpdateProductDto, Product>(MemberList.Source) CreateMap<CreateUpdateProductDto, Product>(MemberList.Source)
.ForSourceMember(dto => dto.StoreId, opt => opt.DoNotValidate())
.ForSourceMember(dto => dto.CategoryIds, opt => opt.DoNotValidate()) .ForSourceMember(dto => dto.CategoryIds, opt => opt.DoNotValidate())
.Ignore(p => p.ProductAttributes) .Ignore(p => p.ProductAttributes)
.Ignore(p => p.ProductSkus); .Ignore(p => p.ProductSkus);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -46,7 +48,6 @@ ...@@ -46,7 +48,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -47,7 +49,6 @@ ...@@ -47,7 +49,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -46,7 +48,6 @@ ...@@ -46,7 +48,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -46,7 +48,6 @@ ...@@ -46,7 +48,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -47,7 +49,6 @@ ...@@ -47,7 +49,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -47,7 +49,6 @@ ...@@ -47,7 +49,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -46,7 +48,6 @@ ...@@ -46,7 +48,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -47,7 +49,6 @@ ...@@ -47,7 +49,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
"Menu:Product": "MenuProduct", "Menu:Product": "MenuProduct",
"Product": "Product", "Product": "Product",
"ProductStore": "ProductStore", "ProductStore": "ProductStore",
"ProductProductTypeId": "ProductProductTypeId",
"ProductProductStoreId": "ProductProductStoreId",
"ProductDisplayName": "ProductDisplayName", "ProductDisplayName": "ProductDisplayName",
"ProductDetailDescription": "ProductDetailDescription", "ProductDetailDescription": "ProductDetailDescription",
"ProductDetailDisplayOrder": "ProductDetailDisplayOrder", "ProductDetailDisplayOrder": "ProductDetailDisplayOrder",
...@@ -47,7 +49,6 @@ ...@@ -47,7 +49,6 @@
"Menu:ProductCategory": "MenuProductCategory", "Menu:ProductCategory": "MenuProductCategory",
"ProductCategory": "ProductCategory", "ProductCategory": "ProductCategory",
"ProductCategoryTenantId": "ProductCategoryTenantId", "ProductCategoryTenantId": "ProductCategoryTenantId",
"ProductCategoryStoreId": "ProductCategoryStoreId",
"ProductCategoryCategoryId": "ProductCategoryCategoryId", "ProductCategoryCategoryId": "ProductCategoryCategoryId",
"ProductCategoryProductId": "ProductCategoryProductId", "ProductCategoryProductId": "ProductCategoryProductId",
"ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder", "ProductCategoryDisplayOrder": "ProductCategoryDisplayOrder",
......
...@@ -8,8 +8,8 @@ namespace EasyAbp.EShop.Products.ProductCategories ...@@ -8,8 +8,8 @@ namespace EasyAbp.EShop.Products.ProductCategories
{ {
public interface IProductCategoryRepository : IRepository<ProductCategory, Guid> public interface IProductCategoryRepository : IRepository<ProductCategory, Guid>
{ {
Task<List<ProductCategory>> GetListByCategoryId(Guid categoryId, Guid storeId, CancellationToken cancellationToken = default); Task<List<ProductCategory>> GetListByCategoryIdAsync(Guid categoryId, CancellationToken cancellationToken = default);
Task<List<ProductCategory>> GetListByProductId(Guid productId, Guid storeId, CancellationToken cancellationToken = default); Task<List<ProductCategory>> GetListByProductIdAsync(Guid productId, CancellationToken cancellationToken = default);
} }
} }
\ No newline at end of file
...@@ -5,12 +5,10 @@ using Volo.Abp.MultiTenancy; ...@@ -5,12 +5,10 @@ using Volo.Abp.MultiTenancy;
namespace EasyAbp.EShop.Products.ProductCategories namespace EasyAbp.EShop.Products.ProductCategories
{ {
public class ProductCategory : AuditedAggregateRoot<Guid>, IMultiTenant, IMultiStore public class ProductCategory : AuditedAggregateRoot<Guid>, IMultiTenant
{ {
public virtual Guid? TenantId { get; protected set; } public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid CategoryId { get; protected set; } public virtual Guid CategoryId { get; protected set; }
public virtual Guid ProductId { get; protected set; } public virtual Guid ProductId { get; protected set; }
...@@ -24,14 +22,12 @@ namespace EasyAbp.EShop.Products.ProductCategories ...@@ -24,14 +22,12 @@ namespace EasyAbp.EShop.Products.ProductCategories
public ProductCategory( public ProductCategory(
Guid id, Guid id,
Guid? tenantId, Guid? tenantId,
Guid storeId,
Guid categoryId, Guid categoryId,
Guid productId, Guid productId,
int displayOrder = 0 int displayOrder = 0
) :base(id) ) :base(id)
{ {
TenantId = tenantId; TenantId = tenantId;
StoreId = storeId;
CategoryId = categoryId; CategoryId = categoryId;
ProductId = productId; ProductId = productId;
DisplayOrder = displayOrder; DisplayOrder = displayOrder;
......
using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Products.ProductStores
{
public interface IProductStoreRepository : IRepository<ProductStore, Guid>
{
Task<ProductStore> GetAsync(Guid productId, Guid storeId, CancellationToken cancellationToken = default);
}
}
\ No newline at end of file
using System;
using EasyAbp.EShop.Stores.Stores;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace EasyAbp.EShop.Products.ProductStores
{
public class ProductStore : FullAuditedAggregateRoot<Guid>, IMultiTenant, IMultiStore
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid ProductId { get; protected set; }
public virtual bool IsOwner { get; protected set; }
protected ProductStore() {}
public ProductStore(
Guid id,
Guid? tenantId,
Guid storeId,
Guid productId,
bool isOwner) : base(id)
{
TenantId = tenantId;
StoreId = storeId;
ProductId = productId;
IsOwner = isOwner;
}
}
}
\ No newline at end of file
using System; using System;
using System.Linq;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Products.Products namespace EasyAbp.EShop.Products.Products
{ {
public interface IProductRepository : IRepository<Product, Guid> public interface IProductRepository : IRepository<Product, Guid>
{ {
IQueryable<Product> GetQueryable(Guid storeId, Guid categoryId);
IQueryable<Product> GetQueryable(Guid storeId);
} }
} }
\ No newline at end of file
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using EasyAbp.EShop.Stores.Stores;
using JetBrains.Annotations; using JetBrains.Annotations;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace EasyAbp.EShop.Products.Products namespace EasyAbp.EShop.Products.Products
{ {
public class Product : FullAuditedAggregateRoot<Guid>, IMultiTenant, IMultiStore public class Product : FullAuditedAggregateRoot<Guid>
{ {
public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid ProductTypeId { get; protected set; } public virtual Guid ProductTypeId { get; protected set; }
[NotNull] [NotNull]
...@@ -41,8 +35,6 @@ namespace EasyAbp.EShop.Products.Products ...@@ -41,8 +35,6 @@ namespace EasyAbp.EShop.Products.Products
public Product( public Product(
Guid id, Guid id,
Guid? tenantId,
Guid storeId,
Guid productTypeId, Guid productTypeId,
string displayName, string displayName,
InventoryStrategy inventoryStrategy, InventoryStrategy inventoryStrategy,
...@@ -51,8 +43,6 @@ namespace EasyAbp.EShop.Products.Products ...@@ -51,8 +43,6 @@ namespace EasyAbp.EShop.Products.Products
int displayOrder int displayOrder
) :base(id) ) :base(id)
{ {
TenantId = tenantId;
StoreId = storeId;
ProductTypeId = productTypeId; ProductTypeId = productTypeId;
DisplayName = displayName; DisplayName = displayName;
InventoryStrategy = inventoryStrategy; InventoryStrategy = inventoryStrategy;
......
using EasyAbp.EShop.Products.ProductStores;
using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.ProductCategories;
using EasyAbp.EShop.Products.ProductTypes; using EasyAbp.EShop.Products.ProductTypes;
using EasyAbp.EShop.Products.Categories; using EasyAbp.EShop.Products.Categories;
...@@ -25,6 +26,7 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore ...@@ -25,6 +26,7 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore
options.AddRepository<Category, CategoryRepository>(); options.AddRepository<Category, CategoryRepository>();
options.AddRepository<ProductType, ProductTypeRepository>(); options.AddRepository<ProductType, ProductTypeRepository>();
options.AddRepository<ProductCategory, ProductCategoryRepository>(); options.AddRepository<ProductCategory, ProductCategoryRepository>();
options.AddRepository<ProductStore, ProductStoreRepository>();
}); });
} }
} }
......
...@@ -5,6 +5,7 @@ using EasyAbp.EShop.Products.Products; ...@@ -5,6 +5,7 @@ using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Categories; using EasyAbp.EShop.Products.Categories;
using EasyAbp.EShop.Products.ProductTypes; using EasyAbp.EShop.Products.ProductTypes;
using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.ProductCategories;
using EasyAbp.EShop.Products.ProductStores;
namespace EasyAbp.EShop.Products.EntityFrameworkCore namespace EasyAbp.EShop.Products.EntityFrameworkCore
{ {
...@@ -22,5 +23,6 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore ...@@ -22,5 +23,6 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore
DbSet<Category> Categories { get; set; } DbSet<Category> Categories { get; set; }
DbSet<ProductType> ProductTypes { get; set; } DbSet<ProductType> ProductTypes { get; set; }
DbSet<ProductCategory> ProductCategories { get; set; } DbSet<ProductCategory> ProductCategories { get; set; }
DbSet<ProductStore> ProductStores { get; set; }
} }
} }
...@@ -5,6 +5,7 @@ using EasyAbp.EShop.Products.Products; ...@@ -5,6 +5,7 @@ using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Categories; using EasyAbp.EShop.Products.Categories;
using EasyAbp.EShop.Products.ProductTypes; using EasyAbp.EShop.Products.ProductTypes;
using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.ProductCategories;
using EasyAbp.EShop.Products.ProductStores;
namespace EasyAbp.EShop.Products.EntityFrameworkCore namespace EasyAbp.EShop.Products.EntityFrameworkCore
{ {
...@@ -22,6 +23,7 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore ...@@ -22,6 +23,7 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore
public DbSet<Category> Categories { get; set; } public DbSet<Category> Categories { get; set; }
public DbSet<ProductType> ProductTypes { get; set; } public DbSet<ProductType> ProductTypes { get; set; }
public DbSet<ProductCategory> ProductCategories { get; set; } public DbSet<ProductCategory> ProductCategories { get; set; }
public DbSet<ProductStore> ProductStores { get; set; }
public ProductsDbContext(DbContextOptions<ProductsDbContext> options) public ProductsDbContext(DbContextOptions<ProductsDbContext> options)
: base(options) : base(options)
......
using EasyAbp.EShop.Products.ProductStores;
using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.ProductCategories;
using EasyAbp.EShop.Products.ProductTypes; using EasyAbp.EShop.Products.ProductTypes;
using EasyAbp.EShop.Products.Categories; using EasyAbp.EShop.Products.Categories;
...@@ -102,6 +103,13 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore ...@@ -102,6 +103,13 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore
b.ConfigureByConvention(); b.ConfigureByConvention();
/* Configure more properties here */ /* Configure more properties here */
}); });
builder.Entity<ProductStore>(b =>
{
b.ToTable(options.TablePrefix + "ProductStores", options.Schema);
b.ConfigureByConvention();
/* Configure more properties here */
});
} }
} }
} }
...@@ -16,18 +16,16 @@ namespace EasyAbp.EShop.Products.ProductCategories ...@@ -16,18 +16,16 @@ namespace EasyAbp.EShop.Products.ProductCategories
{ {
} }
public virtual async Task<List<ProductCategory>> GetListByCategoryId(Guid categoryId, Guid storeId, public virtual async Task<List<ProductCategory>> GetListByCategoryIdAsync(Guid categoryId,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
return await GetQueryable().Where(pc => pc.CategoryId == categoryId && pc.StoreId == storeId) return await GetQueryable().Where(pc => pc.CategoryId == categoryId).ToListAsync(cancellationToken);
.ToListAsync(cancellationToken);
} }
public virtual async Task<List<ProductCategory>> GetListByProductId(Guid productId, Guid storeId, public virtual async Task<List<ProductCategory>> GetListByProductIdAsync(Guid productId,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
return await GetQueryable().Where(pc => pc.ProductId == productId && pc.StoreId == storeId) return await GetQueryable().Where(pc => pc.ProductId == productId).ToListAsync(cancellationToken);
.ToListAsync(cancellationToken);
} }
} }
} }
\ No newline at end of file
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using EasyAbp.EShop.Products.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace EasyAbp.EShop.Products.ProductStores
{
public class ProductStoreRepository : EfCoreRepository<ProductsDbContext, ProductStore, Guid>, IProductStoreRepository
{
public ProductStoreRepository(IDbContextProvider<ProductsDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public virtual async Task<ProductStore> GetAsync(Guid productId, Guid storeId, CancellationToken cancellationToken = default)
{
var entity = await GetQueryable().Where(x => x.ProductId == productId && x.StoreId == storeId)
.FirstOrDefaultAsync(cancellationToken);
if (entity == null)
{
throw new EntityNotFoundException(typeof(ProductStore), new {ProductId = productId, StoreId = storeId});
}
return entity;
}
}
}
\ No newline at end of file
...@@ -20,5 +20,22 @@ namespace EasyAbp.EShop.Products.Products ...@@ -20,5 +20,22 @@ namespace EasyAbp.EShop.Products.Products
.Include(x => x.ProductAttributes).ThenInclude(x => x.ProductAttributeOptions) .Include(x => x.ProductAttributes).ThenInclude(x => x.ProductAttributeOptions)
.Include(x => x.ProductSkus); .Include(x => x.ProductSkus);
} }
public IQueryable<Product> GetQueryable(Guid storeId, Guid categoryId)
{
return from product in DbContext.Products
join productStore in DbContext.ProductStores on product.Id equals productStore.ProductId
join productCategory in DbContext.ProductCategories on product.Id equals productCategory.ProductId
where productStore.StoreId == storeId && productCategory.CategoryId == categoryId
select product;
}
public IQueryable<Product> GetQueryable(Guid storeId)
{
return from product in DbContext.Products
join productStore in DbContext.ProductStores on product.Id equals productStore.ProductId
where productStore.StoreId == storeId
select product;
}
} }
} }
\ No newline at end of file
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\EasyAbp.EShop.Stores\src\EasyAbp.EShop.Stores.Application.Contracts\EasyAbp.EShop.Stores.Application.Contracts.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Products.HttpApi\EasyAbp.EShop.Products.HttpApi.csproj" /> <ProjectReference Include="..\EasyAbp.EShop.Products.HttpApi\EasyAbp.EShop.Products.HttpApi.csproj" />
</ItemGroup> </ItemGroup>
......
...@@ -17,7 +17,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -17,7 +17,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
public class CreateModalModel : ProductsPageModel public class CreateModalModel : ProductsPageModel
{ {
[BindProperty] [BindProperty]
public CreateUpdateProductViewModel Product { get; set; } public CreateEditProductViewModel Product { get; set; }
public ICollection<SelectListItem> ProductTypes { get; set; } public ICollection<SelectListItem> ProductTypes { get; set; }
...@@ -37,7 +37,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -37,7 +37,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
_service = service; _service = service;
} }
public async Task OnGetAsync(Guid storeId) public virtual async Task OnGetAsync(Guid storeId, Guid? categoryId)
{ {
ProductTypes = ProductTypes =
(await _productTypeAppService.GetListAsync(new PagedAndSortedResultRequestDto (await _productTypeAppService.GetListAsync(new PagedAndSortedResultRequestDto
...@@ -49,15 +49,20 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -49,15 +49,20 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
{MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount}))?.Items {MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount}))?.Items
.Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList(); .Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList();
Product = new CreateUpdateProductViewModel Product = new CreateEditProductViewModel
{ {
StoreId = storeId StoreId = storeId
}; };
if (categoryId.HasValue)
{
Product.CategoryIds = new List<Guid>(new[] {categoryId.Value});
}
} }
public async Task<IActionResult> OnPostAsync() public virtual async Task<IActionResult> OnPostAsync()
{ {
await _service.CreateAsync(ObjectMapper.Map<CreateUpdateProductViewModel, CreateUpdateProductDto>(Product)); await _service.CreateAsync(ObjectMapper.Map<CreateEditProductViewModel, CreateUpdateProductDto>(Product));
return NoContent(); return NoContent();
} }
} }
......
...@@ -20,7 +20,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -20,7 +20,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
public Guid Id { get; set; } public Guid Id { get; set; }
[BindProperty] [BindProperty]
public CreateUpdateProductViewModel Product { get; set; } public CreateEditProductViewModel Product { get; set; }
public ICollection<SelectListItem> ProductTypes { get; set; } public ICollection<SelectListItem> ProductTypes { get; set; }
...@@ -40,7 +40,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -40,7 +40,7 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
_service = service; _service = service;
} }
public async Task OnGetAsync() public virtual async Task OnGetAsync(Guid storeId)
{ {
ProductTypes = ProductTypes =
(await _productTypeAppService.GetListAsync(new PagedAndSortedResultRequestDto (await _productTypeAppService.GetListAsync(new PagedAndSortedResultRequestDto
...@@ -53,13 +53,16 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product ...@@ -53,13 +53,16 @@ namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
.Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList(); .Select(dto => new SelectListItem(dto.DisplayName, dto.Id.ToString())).ToList();
var productDto = await _service.GetAsync(Id); var productDto = await _service.GetAsync(Id);
Product = ObjectMapper.Map<ProductDto, CreateUpdateProductViewModel>(productDto);
Product = ObjectMapper.Map<ProductDto, CreateEditProductViewModel>(productDto);
Product.StoreId = storeId;
} }
public async Task<IActionResult> OnPostAsync() public virtual async Task<IActionResult> OnPostAsync()
{ {
await _service.UpdateAsync(Id, await _service.UpdateAsync(Id,
ObjectMapper.Map<CreateUpdateProductViewModel, CreateUpdateProductDto>(Product)); ObjectMapper.Map<CreateEditProductViewModel, CreateUpdateProductDto>(Product));
return NoContent(); return NoContent();
} }
} }
......
...@@ -18,12 +18,16 @@ ...@@ -18,12 +18,16 @@
{ {
<abp-style src="/Pages/EShop/Products/Products/Product/index.css"/> <abp-style src="/Pages/EShop/Products/Products/Product/index.css"/>
} }
<script>
let storeId = '@Model.StoreId';
let categoryId = '@Model.CategoryId';
</script>
<abp-card> <abp-card>
<abp-card-header> <abp-card-header>
<abp-row> <abp-row>
<abp-column size-md="_6"> <abp-column size-md="_6">
<abp-card-title>@L["Product"]</abp-card-title> <abp-card-title>@L["Product"] - @Model.StoreName</abp-card-title>
</abp-column> </abp-column>
<abp-column size-md="_6" class="text-right"> <abp-column size-md="_6" class="text-right">
<abp-button id="NewProductButton" <abp-button id="NewProductButton"
...@@ -38,7 +42,6 @@ ...@@ -38,7 +42,6 @@
<thead> <thead>
<tr> <tr>
<th>@L["Actions"]</th> <th>@L["Actions"]</th>
<th>@L["ProductStoreId"]</th>
<th>@L["ProductProductTypeId"]</th> <th>@L["ProductProductTypeId"]</th>
<th>@L["ProductDisplayName"]</th> <th>@L["ProductDisplayName"]</th>
<th>@L["ProductInventoryStrategy"]</th> <th>@L["ProductInventoryStrategy"]</th>
......
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Stores.Stores;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product
{ {
public class IndexModel : ProductsPageModel public class IndexModel : ProductsPageModel
{ {
public async Task OnGetAsync() private readonly IStoreAppService _storeAppService;
[BindProperty(SupportsGet = true)]
public Guid StoreId { get; set; }
[BindProperty(SupportsGet = true)]
public Guid? CategoryId { get; set; }
public string StoreName { get; set; }
public IndexModel(IStoreAppService storeAppService)
{
_storeAppService = storeAppService;
}
public virtual async Task OnGetAsync()
{ {
await Task.CompletedTask; StoreName = (await _storeAppService.GetAsync(StoreId)).Name;
} }
} }
} }
...@@ -9,7 +9,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; ...@@ -9,7 +9,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product.ViewModels
{ {
public class CreateUpdateProductViewModel public class CreateEditProductViewModel
{ {
[HiddenInput] [HiddenInput]
[Display(Name = "ProductStore")] [Display(Name = "ProductStore")]
......
...@@ -14,7 +14,9 @@ $(function () { ...@@ -14,7 +14,9 @@ $(function () {
autoWidth: false, autoWidth: false,
scrollCollapse: true, scrollCollapse: true,
order: [[1, "asc"]], order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(service.getList), ajax: abp.libs.datatables.createAjax(service.getList, function () {
return { storeId: storeId, categoryId: categoryId }
}),
columnDefs: [ columnDefs: [
{ {
rowAction: { rowAction: {
...@@ -23,7 +25,7 @@ $(function () { ...@@ -23,7 +25,7 @@ $(function () {
{ {
text: l('Edit'), text: l('Edit'),
action: function (data) { action: function (data) {
editModal.open({ id: data.record.id }); editModal.open({ id: data.record.id, storeId: storeId });
} }
}, },
{ {
...@@ -32,7 +34,7 @@ $(function () { ...@@ -32,7 +34,7 @@ $(function () {
return l('ProductDeletionConfirmationMessage', data.record.id); return l('ProductDeletionConfirmationMessage', data.record.id);
}, },
action: function (data) { action: function (data) {
service.delete(data.record.id) service.delete({ id: data.record.id, storeId: storeId })
.then(function () { .then(function () {
abp.notify.info(l('SuccessfullyDeleted')); abp.notify.info(l('SuccessfullyDeleted'));
dataTable.ajax.reload(); dataTable.ajax.reload();
...@@ -42,7 +44,6 @@ $(function () { ...@@ -42,7 +44,6 @@ $(function () {
] ]
} }
}, },
{ data: "storeId" },
{ data: "productTypeId" }, { data: "productTypeId" },
{ data: "displayName" }, { data: "displayName" },
{ data: "inventoryStrategy" }, { data: "inventoryStrategy" },
...@@ -61,6 +62,6 @@ $(function () { ...@@ -61,6 +62,6 @@ $(function () {
$('#NewProductButton').click(function (e) { $('#NewProductButton').click(function (e) {
e.preventDefault(); e.preventDefault();
createModal.open(); createModal.open({ storeId: storeId, categoryId: categoryId });
}); });
}); });
\ No newline at end of file
...@@ -10,6 +10,7 @@ using EasyAbp.EShop.Products.Localization; ...@@ -10,6 +10,7 @@ using EasyAbp.EShop.Products.Localization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using EasyAbp.EShop.Products.Localization; using EasyAbp.EShop.Products.Localization;
using EasyAbp.EShop.Stores.Stores;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation;
...@@ -17,7 +18,7 @@ namespace EasyAbp.EShop.Products.Web ...@@ -17,7 +18,7 @@ namespace EasyAbp.EShop.Products.Web
{ {
public class ProductsMenuContributor : IMenuContributor public class ProductsMenuContributor : IMenuContributor
{ {
public async Task ConfigureMenuAsync(MenuConfigurationContext context) public virtual async Task ConfigureMenuAsync(MenuConfigurationContext context)
{ {
if (context.Menu.Name == StandardMenus.Main) if (context.Menu.Name == StandardMenus.Main)
{ {
...@@ -49,8 +50,12 @@ namespace EasyAbp.EShop.Products.Web ...@@ -49,8 +50,12 @@ namespace EasyAbp.EShop.Products.Web
if (await authorizationService.IsGrantedAsync(ProductsPermissions.Products.Default)) if (await authorizationService.IsGrantedAsync(ProductsPermissions.Products.Default))
{ {
var storeAppService = context.ServiceProvider.GetRequiredService<IStoreAppService>();
var defaultStore = (await storeAppService.GetDefaultAsync())?.Id;
productManagementMenuItem.AddItem( productManagementMenuItem.AddItem(
new ApplicationMenuItem("Product", l["Menu:Product"], "/EShop/Products/Products/Product") new ApplicationMenuItem("Product", l["Menu:Product"], "/EShop/Products/Products/Product?storeId=" + defaultStore)
); );
} }
......
...@@ -17,7 +17,8 @@ namespace EasyAbp.EShop.Products.Web ...@@ -17,7 +17,8 @@ namespace EasyAbp.EShop.Products.Web
/* 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<ProductDto, CreateUpdateProductViewModel>() CreateMap<ProductDto, CreateEditProductViewModel>()
.Ignore(dto => dto.StoreId)
// .Ignore(x => x.ProductAttributes); // .Ignore(x => x.ProductAttributes);
.ForMember(dest => dest.ProductAttributeNames, .ForMember(dest => dest.ProductAttributeNames,
opt => opt.MapFrom(source => opt => opt.MapFrom(source =>
...@@ -27,7 +28,7 @@ namespace EasyAbp.EShop.Products.Web ...@@ -27,7 +28,7 @@ namespace EasyAbp.EShop.Products.Web
x.ProductAttributes x.ProductAttributes
.Select(a => a.ProductAttributeOptions.Select(o => o.DisplayName).JoinAsString(",")) .Select(a => a.ProductAttributeOptions.Select(o => o.DisplayName).JoinAsString(","))
.JoinAsString(Environment.NewLine))); .JoinAsString(Environment.NewLine)));
CreateMap<CreateUpdateProductViewModel, CreateUpdateProductDto>() CreateMap<CreateEditProductViewModel, CreateUpdateProductDto>()
.ForMember(dest => dest.ProductAttributes, .ForMember(dest => dest.ProductAttributes,
opt => opt.MapFrom(x => opt => opt.MapFrom(x =>
x.ProductAttributeNames.Split(",", StringSplitOptions.RemoveEmptyEntries).Select((s, i) => x.ProductAttributeNames.Split(",", StringSplitOptions.RemoveEmptyEntries).Select((s, i) =>
......
using System.Threading.Tasks;
using Shouldly;
using Xunit;
namespace EasyAbp.EShop.Products.ProductStores
{
public class ProductStoreDomainTests : ProductsDomainTestBase
{
public ProductStoreDomainTests()
{
}
[Fact]
public async Task Test1()
{
// Arrange
// Assert
// Assert
}
}
}
using System;
using System.Threading.Tasks;
using EasyAbp.EShop.Products.ProductStores;
using Volo.Abp.Domain.Repositories;
using Xunit;
namespace EasyAbp.EShop.Products.EntityFrameworkCore.ProductStores
{
public class ProductStoreRepositoryTests : ProductsEntityFrameworkCoreTestBase
{
private readonly IRepository<ProductStore, Guid> _productStoreRepository;
public ProductStoreRepositoryTests()
{
_productStoreRepository = GetRequiredService<IRepository<ProductStore, Guid>>();
}
[Fact]
public async Task Test1()
{
await WithUnitOfWorkAsync(async () =>
{
// Arrange
// Act
//Assert
});
}
}
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
...@@ -8,7 +8,12 @@ namespace EasyAbp.EShop.Stores.Authorization ...@@ -8,7 +8,12 @@ namespace EasyAbp.EShop.Stores.Authorization
{ {
public override void Define(IPermissionDefinitionContext context) public override void Define(IPermissionDefinitionContext context)
{ {
//var moduleGroup = context.AddGroup(StoresPermissions.GroupName, L("Permission:Stores")); var moduleGroup = context.AddGroup(StoresPermissions.GroupName, L("Permission:Stores"));
var stores = moduleGroup.AddPermission(StoresPermissions.Stores.Default, L("Permission:Store"));
stores.AddChild(StoresPermissions.Stores.Create, L("Permission:Create"));
stores.AddChild(StoresPermissions.Stores.Update, L("Permission:Update"));
stores.AddChild(StoresPermissions.Stores.Delete, L("Permission:Delete"));
} }
private static LocalizableString L(string name) private static LocalizableString L(string name)
......
...@@ -10,5 +10,13 @@ namespace EasyAbp.EShop.Stores.Authorization ...@@ -10,5 +10,13 @@ namespace EasyAbp.EShop.Stores.Authorization
{ {
return ReflectionHelper.GetPublicConstantsRecursively(typeof(StoresPermissions)); return ReflectionHelper.GetPublicConstantsRecursively(typeof(StoresPermissions));
} }
public class Stores
{
public const string Default = GroupName + ".Store";
public const string Delete = Default + ".Delete";
public const string Update = Default + ".Update";
public const string Create = Default + ".Create";
}
} }
} }
\ No newline at end of file
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace EasyAbp.EShop.Stores.Stores.Dtos
{
public class CreateUpdateStoreDto
{
[Required]
[DisplayName("StoreName")]
public string Name { get; set; }
}
}
\ No newline at end of file
using System;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Stores.Stores.Dtos
{
public class StoreDto : FullAuditedEntityDto<Guid>
{
public string Name { get; set; }
}
}
\ No newline at end of file
using System;
using System.Threading.Tasks;
using EasyAbp.EShop.Stores.Stores.Dtos;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Stores.Stores
{
public interface IStoreAppService :
ICrudAppService<
StoreDto,
Guid,
PagedAndSortedResultRequestDto,
CreateUpdateStoreDto,
CreateUpdateStoreDto>
{
Task<StoreDto> GetDefaultAsync();
}
}
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
using System;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Stores.Stores.Dtos;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Stores.Stores
{
public class StoreAppService : CrudAppService<Store, StoreDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateStoreDto, CreateUpdateStoreDto>,
IStoreAppService
{
private readonly IStoreRepository _repository;
public StoreAppService(IStoreRepository repository) : base(repository)
{
_repository = repository;
}
public async Task<StoreDto> GetDefaultAsync()
{
// Todo: need to be improved
return ObjectMapper.Map<Store, StoreDto>(await _repository.FirstOrDefaultAsync());
}
}
}
\ No newline at end of file
using AutoMapper; using EasyAbp.EShop.Stores.Stores;
using EasyAbp.EShop.Stores.Stores.Dtos;
using AutoMapper;
namespace EasyAbp.EShop.Stores namespace EasyAbp.EShop.Stores
{ {
...@@ -9,6 +11,8 @@ namespace EasyAbp.EShop.Stores ...@@ -9,6 +11,8 @@ namespace EasyAbp.EShop.Stores
/* 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<Store, StoreDto>();
CreateMap<CreateUpdateStoreDto, Store>(MemberList.Source);
} }
} }
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Localization\Stores\*.json" /> <EmbeddedResource Include="EasyAbp\EShop\Stores\Localization\Stores\*.json" />
<Content Remove="Localization\Stores\*.json" /> <Content Remove="EasyAbp\EShop\Stores\Localization\Stores\*.json" />
</ItemGroup> </ItemGroup>
</Project> </Project>
...@@ -17,7 +17,7 @@ namespace EasyAbp.EShop.Stores ...@@ -17,7 +17,7 @@ namespace EasyAbp.EShop.Stores
{ {
Configure<AbpVirtualFileSystemOptions>(options => Configure<AbpVirtualFileSystemOptions>(options =>
{ {
options.FileSets.AddEmbedded<EShopStoresDomainSharedModule>("EasyAbp.EShop.Stores"); options.FileSets.AddEmbedded<EShopStoresDomainSharedModule>();
}); });
Configure<AbpLocalizationOptions>(options => Configure<AbpLocalizationOptions>(options =>
...@@ -25,12 +25,12 @@ namespace EasyAbp.EShop.Stores ...@@ -25,12 +25,12 @@ namespace EasyAbp.EShop.Stores
options.Resources options.Resources
.Add<StoresResource>("en") .Add<StoresResource>("en")
.AddBaseTypes(typeof(AbpValidationResource)) .AddBaseTypes(typeof(AbpValidationResource))
.AddVirtualJson("/Localization/Stores"); .AddVirtualJson("/EasyAbp/EShop/Stores/Localization/Stores");
}); });
Configure<AbpExceptionLocalizationOptions>(options => Configure<AbpExceptionLocalizationOptions>(options =>
{ {
options.MapCodeNamespace("Stores", typeof(StoresResource)); options.MapCodeNamespace("EasyAbp.EShop.Stores", typeof(StoresResource));
}); });
} }
} }
......
{
"culture": "cs",
"texts": {
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "en",
"texts": {
"ManageYourProfile": "Manage your profile",
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "pl",
"texts": {
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "pt-BR",
"texts": {
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "sl",
"texts": {
"ManageYourProfile": "Upravljajte svojim profilom",
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "tr",
"texts": {
"ManageYourProfile": "Profil y�netimi",
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "vi",
"texts": {
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "zh-Hans",
"texts": {
"ManageYourProfile": "管理个人资料",
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "zh-Hant",
"texts": {
"ManageYourProfile": "管理個人資料",
"Menu:Store": "MenuStore",
"Store": "Store",
"StoreName": "StoreName",
"CreateStore": "CreateStore",
"EditStore": "EditStore",
"StoreDeletionConfirmationMessage": "Are you sure to delete the store {0}?",
"SuccessfullyDeleted": "Successfully deleted"
}
}
\ No newline at end of file
{
"culture": "en",
"texts": {
"ManageYourProfile": "Manage your profile"
}
}
\ No newline at end of file
{
"culture": "sl",
"texts": {
"ManageYourProfile": "Upravljajte svojim profilom"
}
}
\ No newline at end of file
{
"culture": "tr",
"texts": {
"ManageYourProfile": "Profil ynetimi"
}
}
\ No newline at end of file
{
"culture": "zh-Hans",
"texts": {
"ManageYourProfile": "管理个人资料"
}
}
\ No newline at end of file
{
"culture": "zh-Hant",
"texts": {
"ManageYourProfile": "管理個人資料"
}
}
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Stores.Stores
{
public interface IStoreRepository : IRepository<Store, Guid>
{
Task<Store> FirstOrDefaultAsync(CancellationToken cancellationToken = default);
}
}
\ No newline at end of file
using System; using System;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
...@@ -7,5 +8,19 @@ namespace EasyAbp.EShop.Stores.Stores ...@@ -7,5 +8,19 @@ namespace EasyAbp.EShop.Stores.Stores
public class Store : FullAuditedAggregateRoot<Guid>, IMultiTenant public class Store : FullAuditedAggregateRoot<Guid>, IMultiTenant
{ {
public virtual Guid? TenantId { get; protected set; } public virtual Guid? TenantId { get; protected set; }
[NotNull]
public virtual string Name { get; protected set; }
// Todo: more properties.
protected Store() {}
public Store(
Guid id,
[NotNull] string name) : base(id)
{
Name = name;
}
} }
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
...@@ -12,4 +12,8 @@ ...@@ -12,4 +12,8 @@
<ProjectReference Include="..\EasyAbp.EShop.Stores.Domain\EasyAbp.EShop.Stores.Domain.csproj" /> <ProjectReference Include="..\EasyAbp.EShop.Stores.Domain\EasyAbp.EShop.Stores.Domain.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="EasyAbp\EShop\Stores" />
</ItemGroup>
</Project> </Project>
using Microsoft.Extensions.DependencyInjection; using EasyAbp.EShop.Stores.Stores;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
...@@ -17,7 +18,8 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore ...@@ -17,7 +18,8 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore
/* Add custom repositories here. Example: /* Add custom repositories here. Example:
* options.AddRepository<Question, EfCoreQuestionRepository>(); * options.AddRepository<Question, EfCoreQuestionRepository>();
*/ */
options.AddRepository<Store, StoreRepository>();
}); });
} }
} }
} }
\ No newline at end of file
using Volo.Abp.Data; using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using EasyAbp.EShop.Stores.Stores;
namespace EasyAbp.EShop.Stores.EntityFrameworkCore namespace EasyAbp.EShop.Stores.EntityFrameworkCore
{ {
...@@ -9,5 +11,6 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore ...@@ -9,5 +11,6 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore
/* Add DbSet for each Aggregate Root here. Example: /* Add DbSet for each Aggregate Root here. Example:
* DbSet<Question> Questions { get; } * DbSet<Question> Questions { get; }
*/ */
DbSet<Store> Stores { get; set; }
} }
} }
\ No newline at end of file
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using EasyAbp.EShop.Stores.Stores;
namespace EasyAbp.EShop.Stores.EntityFrameworkCore namespace EasyAbp.EShop.Stores.EntityFrameworkCore
{ {
...@@ -10,6 +11,7 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore ...@@ -10,6 +11,7 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore
/* Add DbSet for each Aggregate Root here. Example: /* Add DbSet for each Aggregate Root here. Example:
* public DbSet<Question> Questions { get; set; } * public DbSet<Question> Questions { get; set; }
*/ */
public DbSet<Store> Stores { get; set; }
public StoresDbContext(DbContextOptions<StoresDbContext> options) public StoresDbContext(DbContextOptions<StoresDbContext> options)
: base(options) : base(options)
...@@ -24,4 +26,4 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore ...@@ -24,4 +26,4 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore
builder.ConfigureStores(); builder.ConfigureStores();
} }
} }
} }
\ No newline at end of file
using System; using EasyAbp.EShop.Stores.Stores;
using System;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace EasyAbp.EShop.Stores.EntityFrameworkCore namespace EasyAbp.EShop.Stores.EntityFrameworkCore
{ {
...@@ -38,6 +40,13 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore ...@@ -38,6 +40,13 @@ namespace EasyAbp.EShop.Stores.EntityFrameworkCore
b.HasIndex(q => q.CreationTime); b.HasIndex(q => q.CreationTime);
}); });
*/ */
builder.Entity<Store>(b =>
{
b.ToTable(options.TablePrefix + "Stores", options.Schema);
b.ConfigureByConvention();
/* Configure more properties here */
});
} }
} }
} }
\ No newline at end of file
using System;
using System.Threading;
using System.Threading.Tasks;
using EasyAbp.EShop.Stores.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace EasyAbp.EShop.Stores.Stores
{
public class StoreRepository : EfCoreRepository<StoresDbContext, Store, Guid>, IStoreRepository
{
public StoreRepository(IDbContextProvider<StoresDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<Store> FirstOrDefaultAsync(CancellationToken cancellationToken = default)
{
return await WithDetails().FirstOrDefaultAsync(cancellationToken: cancellationToken);
}
}
}
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>EasyAbp.EShop.Stores</RootNamespace> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
...@@ -12,4 +12,8 @@ ...@@ -12,4 +12,8 @@
<ProjectReference Include="..\EasyAbp.EShop.Stores.Domain\EasyAbp.EShop.Stores.Domain.csproj" /> <ProjectReference Include="..\EasyAbp.EShop.Stores.Domain\EasyAbp.EShop.Stores.Domain.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="EasyAbp\EShop\Stores" />
</ItemGroup>
</Project> </Project>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment