1.新建实体:
在WeifuwuDemo.Product.Domain中新建products文件夹并添加实体:(注意ProductInfoImage继承的类不一样)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Volo.Abp.Domain.Entities.Auditing;
namespace WeifuwuDemo.Product.Products
{
public class ProductInfo:FullAuditedAggregateRoot<Guid>
{
public string ProductCode { set; get; } //商品编码
public string ProductUrl { set; get; } // 商品主图
public string ProductTitle { set; get; } //商品标题
public string ProductDescription { set; get; } // 图文描述
public decimal ProductVirtualprice { set; get; } //商品虚拟价格
public decimal ProductPrice { set; get; } //价格
public int ProductSort { set; get; } //商品序号
public int ProductSold { set; get; } //已售件数
public int ProductStock { set; get; } //商品库存
public string ProductStatus { set; get; } // 商品状态
public virtual ICollection<ProductInfoImage> ProductImages { get; set; }
/*public string VirturePrice { set; get; } // 虚拟价格
public string ProductSort { set; get; } // 商品排序*/
public ProductInfo()
{
ProductImages = new Collection<ProductInfoImage>();
}
public ProductInfo(Guid id) : base(id)
{
ProductImages = new Collection<ProductInfoImage>();
}
public ProductInfo(Guid id, Guid? tenantId) : base(id)
{
ProductImages = new Collection<ProductInfoImage>();
}
public ProductInfo(string ProductTitle)
{
// 业务规则:ProductTitle名称不能为空
if (ProductTitle == null)
{
throw new Exception("商品名称不能为空");
}
ProductImages = new Collection<ProductInfoImage>();
}
/// <summary>
/// 添加商品图片
/// </summary>
public void AddProductImage(Guid ImageId, string ImageUrl)
{
// 1、创建一个商品图片
ProductInfoImage productImage = new ProductInfoImage(ImageId);
productImage.ImageUrl = ImageUrl;
// 2、添加到集合中
ProductImages.Add(productImage);
}
/// <summary>
/// 添加商品图片
/// </summary>
public void RemoveProductImage(Guid productImageId)
{
// 1、判断guid ,然后删除指定商品
// 2、添加到集合中
// ProductImages.Remove(productImage);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.Domain.Entities.Auditing;
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoImage:FullAuditedEntity<Guid>
{
public Guid ProductId { set; get; } // 商品编号
public int ImageSort { set; get; } // 排序
public string ImageStatus { set; get; } // 状态(1:启用,2:禁用)
public string ImageUrl { set; get; } // 图片url
public ProductInfoImage()
{
}
public ProductInfoImage(Guid id) : base(id)
{
}
}
}
2.表迁移:在WeifuwuDemo.Product.EntityFrameworkCore中ProductDbContextModelCreatingExtensions添加:
builder.Entity<ProductInfo>(b =>
{
b.ConfigureByConvention();
b.HasMany(u => u.ProductImages).WithOne().HasForeignKey(ur => ur.ProductId).IsRequired();
});
在ProductDbContext中添加:
namespace WeifuwuDemo.Product.EntityFrameworkCore;
[ConnectionStringName(ProductDbProperties.ConnectionStringName)]
public class ProductDbContext : AbpDbContext<ProductDbContext>, IProductDbContext
{
/* Add DbSet for each Aggregate Root here. Example:
* public DbSet<Question> Questions { get; set; }
*/
public DbSet<ProductInfo> ProductInfo { get; set; }
public ProductDbContext(DbContextOptions<ProductDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureProduct();
}
}
执行迁移命令
dotnet ef migrations add productInfo
和
dotnet ef database update
3.创建仓储层和实现层:
在WeifuwuDemo.Product.Domain中products文件夹创建仓储接口:
namespace WeifuwuDemo.Product.Products
{
public interface IProductInfoAbpRepository:IRepository<ProductInfo,Guid>
{
ProductInfo GetProductByName(string ProductName);
/// <summary>
/// 查询和图片
/// </summary>
/// <returns></returns>
public IEnumerable<ProductInfo> GetProductAndImages();
}
}
在WeifuwuDemo.Product.EntityFrameworkCore中文件夹products中创建仓储实现类:
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoAbpRepository:EfCoreRepository<ProductDbContext,ProductInfo,Guid>,IProductInfoAbpRepository
{
public ProductInfoAbpRepository(IDbContextProvider<ProductDbContext> dbContextProvider):base(dbContextProvider)
{
}
public override async Task<ProductInfo> GetAsync(Guid id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
DbSet<ProductInfo> products = await GetDbSetAsync();
return products.Include(p => p.ProductImages).Where(p => p.Id == id).FirstOrDefault();
}
public IEnumerable<ProductInfo> GetProductAndImages()
{
DbSet<ProductInfo> products = GetDbSetAsync().Result;
return products.Include(product => product.ProductImages).ToList();
}
/// <summary>
/// 根据商品名称,查询商品
/// </summary>
/// <param name="ProductName"></param>
/// <returns></returns>
public ProductInfo GetProductByName(string ProductName)
{
// 1、第一种实现
//EBusinessDbContext eBusinessDbContext = GetDbContextAsync().Result;
// 2、第二种实现,根据名称获取商品
DbSet<ProductInfo> products = GetDbSetAsync().Result;
return products.Where(product => product.ProductTitle == ProductName).FirstOrDefault();
}
}
}
在WeifuwuDemo.Product.Application.Contracts中新建products文件夹并创建service接口及dto:
namespace WeifuwuDemo.Product.Products
{
public interface IProductInfoAbpService:ICrudAppService<ProductInfoDto,Guid,PagedAndSortedResultRequestDto,CreateProductInfoDto,UpdateProductInfoDto>
{
}
}
namespace WeifuwuDemo.Product.Products
{
public class CreateProductInfoDto
{
public string ProductUrl { set; get; } // 商品主图
/*[Required]
[StringLength(10)]*/
//[ProductName]
//[Range(3, 10)]
// 规则3:商品名称长度不能大于10
// 规则4:商品名称不能有数字
public string ProductTitle { set; get; } //商品标题
public string ProductDescription { set; get; } // 图文描述
public decimal ProductVirtualprice { set; get; } //商品虚拟价格
public decimal ProductPrice { set; get; } //价格
public ProductInfoImageCreateDto[] ProductImages { set; get; } // 商品图片集合
}
public class ProductInfoImageCreateDto
{
public string ImageUrl { set; get; } // 图片url
public string ImageStatus { set; get; } // 图片状态
}
}
namespace WeifuwuDemo.Product.Products
{
public class DeleteProductInfoDto
{
public string ProductUrl { set; get; } // 商品主图
public string ProductTitle { set; get; } //商品标题
public string ProductDescription { set; get; } // 图文描述
public decimal ProductVirtualprice { set; get; } //商品虚拟价格
public decimal ProductPrice { set; get; } //价格
}
public class DeleteProductInfoImageDto
{
public Guid ProductImageId { set; get; } // 商品图片
}
}
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoAttrQueryDto
{
public string productName { set; get; }
}
}
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoDto:EntityDto<Guid>
{
public string ProductCode { set; get; } //商品编码
public string ProductUrl { set; get; } // 商品主图
public string ProductTitle { set; get; } //商品标题
public string ProductDescription { set; get; } // 图文描述
public decimal ProductVirtualprice { set; get; } //商品虚拟价格
public decimal ProductPrice { set; get; } //价格
public int ProductSort { set; get; } //商品序号
public int ProductSold { set; get; } //已售件数
public int ProductStock { set; get; } //商品库存
public string ProductStatus { set; get; } // 商品状态
public ProductInfoImageDto[] ProductImages { set; get; }// 商品图片
}
public class ProductInfoImageDto
{
public string ImageUrl { set; get; } // 图片url
}
}
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoNameQueryDto:PagedAndSortedResultRequestDto
{
public string ProductName { set; get; }
}
}
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoQueryDto
{
}
}
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoTotaLDto
{
}
}}
}
namespace WeifuwuDemo.Product.Products
{
/// <summary>
/// 更新商品Dto
/// </summary>
public class UpdateProductInfoDto
{
public string ProductUrl { set; get; } // 商品主图
public string ProductTitle { set; get; } //商品标题
public string ProductDescription { set; get; } // 图文描述
public decimal ProductVirtualprice { set; get; } //商品虚拟价格
public decimal ProductPrice { set; get; } //价格
public int ProductStock { set; get; } //商品库存
}
}
namespace WeifuwuDemo.Product.Products
{
/// <summary>
/// 更新商品库存Dto
/// </summary>
public class UpdateProductInfoStockDto
{
// 商品编号
public Guid ProductId { set; get; }
// 商品数量
public int ProductCount { set; get; }
}
}
在WeifuwuDemo.Product.Application中新建文件夹并实现service接口:
namespace WeifuwuDemo.Product.Products
{
public class ProductInfoAbpService:CrudAppService<ProductInfo,ProductInfoDto,Guid,PagedAndSortedResultRequestDto,CreateProductInfoDto,UpdateProductInfoDto>,IProductInfoAbpService
{
private readonly IProductInfoAbpRepository _productInfoAbpRepository;
public ProductInfoAbpService(IProductInfoAbpRepository productInfoAbpRepository):base(productInfoAbpRepository)
{
_productInfoAbpRepository = productInfoAbpRepository;
}
}
}
在ProductApplicationAutoMapperProfile中添加dto和实体的映射:
CreateMap<ProductInfo, ProductInfoDto>();
CreateMap<PagedAndSortedResultRequestDto, ProductInfo>();
CreateMap<CreateProductInfoDto, ProductInfo>();
CreateMap<UpdateProductInfoDto, ProductInfo>();
CreateMap<ProductInfoAttrQueryDto, ProductInfo>();
CreateMap<ProductInfoImageDto, ProductInfoImage>();
CreateMap<ProductInfoImage, ProductInfoImageDto>();
CreateMap<ProductInfoImageCreateDto, ProductInfoImage>();
在ProductApplicationModule中将验证实体和dto差异改为false
public class ProductApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<ProductApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<ProductApplicationModule>(validate: false);
});
}
}
在WeifuwuDemo.Product.HttpApi中新建products文件夹,并创建ProductInfoController:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp;
namespace WeifuwuDemo.Product.Products
{
[ApiController]
[Route("api/[controller]/[action]")]
public class ProductInfoController:ProductController,IProductInfoAbpService
{
private readonly IProductInfoAbpService _productInfoAbpService;
public ProductInfoController(IProductInfoAbpService productInfoAbpService)
{
_productInfoAbpService = productInfoAbpService;
}
/// <summary>
/// 查询商品列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
public async Task<PagedResultDto<ProductInfoDto>> GetListAsync([FromQuery] PagedAndSortedResultRequestDto input)
{
return await _productInfoAbpService.GetListAsync(input);
}
/// <summary>
/// 查询单个商品
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}")]
public async Task<ProductInfoDto> GetAsync(Guid id)
{
var product = await _productInfoAbpService.GetAsync(id);
return product;
}
/// <summary>
/// 更新商品
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task<ProductInfoDto> UpdateAsync(Guid id, UpdateProductInfoDto input)
{
return await _productInfoAbpService.UpdateAsync(id, input);
}
/// <summary>
/// 更新秒杀商品库存
/// </summary>
/// <param name="id"></param>
/// <param name="product"></param>
/// <returns></returns>
[HttpPut("{id}/UpdateProductStock")]
public async Task<IActionResult> PutProductStock(Guid id, UpdateProductInfoStockDto updateProductStockDto)
{
if (!id.Equals(updateProductStockDto.ProductId))
{
return BadRequest();
}
// 1、查询商品
ProductInfoDto product = await _productInfoAbpService.GetAsync(updateProductStockDto.ProductId);
// 2、判断商品库存是否完成
if (product.ProductStock <= 0)
{
throw new AbpException("库存完了");
}
// 3、扣减商品库存
product.ProductStock = product.ProductStock - updateProductStockDto.ProductCount;
// 4、更新商品库存
UpdateProductInfoDto updateProductDto = new UpdateProductInfoDto();
updateProductDto.ProductStock = product.ProductStock;
await _productInfoAbpService.UpdateAsync(updateProductStockDto.ProductId, updateProductDto);
return Ok("更新库存成功");
}
/// <summary>
/// 异步更新秒杀商品库存
/// </summary>
/// <param name="id"></param>
/// <param name="productVo"></param>
/// <returns></returns>
[NonAction]
//[CapSubscribe("product.stock")]
public async Task<IActionResult> SetProductStock(UpdateProductInfoStockDto updateProductStockDto)
{
// 1、查询商品
ProductInfoDto product = await _productInfoAbpService.GetAsync(updateProductStockDto.ProductId);
// 2、判断商品库存是否完成
if (product.ProductStock <= 0)
{
throw new AbpException("库存完了");
}
// 3、扣减商品库存
product.ProductStock = product.ProductStock - updateProductStockDto.ProductCount;
// 4、更新商品库存
UpdateProductInfoDto updateProductDto = new UpdateProductInfoDto();
updateProductDto.ProductStock = product.ProductStock;
await _productInfoAbpService.UpdateAsync(updateProductStockDto.ProductId, updateProductDto);
return Ok("更新库存成功");
}
/// <summary>
/// 创建商品
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<ProductInfoDto> CreateAsync(CreateProductInfoDto input)
{
return await _productInfoAbpService.CreateAsync(input);
}
/// <summary>
/// 删除商品
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task DeleteAsync(Guid id)
{
await _productInfoAbpService.DeleteAsync(id);
}
}
}