mirror of https://github.com/EasyAbp/EShop.git
128 changed files with 8227 additions and 198 deletions
@ -0,0 +1,13 @@ |
|||
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}") |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
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); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,9 +1,14 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public interface IProductRepository : IRepository<Product, Guid> |
|||
{ |
|||
IQueryable<Product> GetQueryable(Guid storeId, Guid categoryId); |
|||
|
|||
IQueryable<Product> GetQueryable(Guid storeId); |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +1,30 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Stores.Stores; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace EasyAbp.EShop.Products.Web.Pages.EShop.Products.Products.Product |
|||
{ |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,23 @@ |
|||
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
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
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
|
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
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; } |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Stores.Stores.Dtos |
|||
{ |
|||
public class StoreDto : FullAuditedEntityDto<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
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(); |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
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()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"ManageYourProfile": "Manage your profile" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "pl", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"ManageYourProfile": "Upravljajte svojim profilom" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"ManageYourProfile": "Profil yönetimi" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"ManageYourProfile": "管理个人资料" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"ManageYourProfile": "管理個人資料" |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
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); |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace EasyAbp.EShop.Stores.Stores |
|||
{ |
|||
public class Store : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace EasyAbp.EShop.Stores.Stores |
|||
{ |
|||
public class Store : FullAuditedAggregateRoot<Guid>, IMultiTenant |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
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); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue