【愚公系列】2022年02月 .NET架构班 006-ABP vNext 电商项目架构设计
一、电商系统分析
1.电商项目分析
电商项目开发前提:项目的需求点有
1、卖商品
2、管理消费者
3、记录订单
4、管理支付
所以可以分为以下四个领域
1、商品领域
2、消费者(用户)领域
3、订单领域
4、支付(领域)
2.电商项目落地
环境准备:
1、.NET6
2、DDD
3、ABP vNext 5.1.3
4、ABP CLI
5、Mysql 8.0.27
二、电商系统创建步骤
1.创建项目
先通过ABP CLI创建电商webapi项目
abp new XT.EBusiness --dbms mysql -u none -o C:\Users\Happy\CS_BS_PROJECT\XT.EBusiness
2.引入项目
使用vs2022打开项目
3.创建实体
3.1 条件
XT.EBusiness.Domain
3.2 步骤
领域层创建实体:
商品实体,订单实体,用户实体,支付实体
/// <summary>
/// 用户模型
/// </summary>
public class User
{
public int Id { set; get; } // 主键
public string UserName { set; get; } // 用户名
public string Password { set; get; }// 密码
public string UserNickname { set; get; } // 用户昵称
public string UserQQ { set; get; } // 用户QQ
public DateTime CreateTime { set; get; } // 创建时间
public string UserPhone { set; get; }// 用户手机号
}
/// <summary>
/// 支付模型
/// </summary>
public class Payment
{
[Key]
public int Id { set; get; } // '支付编号',
public string PaymentPrice { set; get; } // '支付金额',
public string PaymentStatus { set; get; } // '支付状态',
public int OrderId { set; get; } // '订单号',
public int PaymentType { set; get; }// 支付类型
public string PaymentMethod { set; get; } // '支付方式',
public DateTime Createtime { set; get; } // '支付创建时间',
public DateTime Updatetime { set; get; } // '支付更新时间',
public string PaymentRemark { set; get; } // '支付备注',
public string PaymentUrl { set; get; } // '支付url',
public string PaymentReturnUrl { set; get; } // '支付回调url',
public string PaymentCode { set; get; }// '支付单号',
public string UserId { set; get; } // '用户Id',
public string PaymentErrorNo { set; get; } // '支付错误编号',
public string PaymentErrorInfo { set; get; } // '支付错误信息',
}
/// <summary>
/// 订单模型
/// </summary>
public class Order
{
[Key]
public int Id { set; get; } // 主键
public string OrderType { set; get; } // 订单类型
// public string OrderFlag { set; get; } // 订单标志
public int UserId { set; get; } // 用户Id
public string OrderSn { set; get; }// 订单号
public string OrderTotalPrice { set; get; } // 订单总价
public DateTime Createtime { set; get; } // 创建时间
public DateTime Updatetime { set; get; } // 更新时间
public DateTime Paytime { set; get; }// 支付时间
public DateTime Sendtime { set; get; }// 发货时间
public DateTime Successtime { set; get; }// 订单完成时间
public int OrderStatus { set; get; } // 订单状态
public string OrderName { set; get; } // 订单名称
public string OrderTel { set; get; } // 订单电话
public string OrderAddress { set; get; } // 订单地址
public string OrderRemark { set; get; }// 订单备注
// 订单项
public List<OrderItem> OrderItems { set; get; }
}
/// <summary>
/// 订单项(记录购买商品信息)
/// </summary>
public class OrderItem
{
[Key]
public int Id { set; get; } // 主键
public int OrderId { set; get; } // 订单编号
public string OrderSn { set; get; } // 订单号
public int ProductId { set; get; } // 商品编号
public string ProductUrl { set; get; } // 商品主图
public string ProductName { set; get; }// 商品名称
public decimal ItemPrice { set; get; } // 订单项单价
public int ItemCount { set; get; } // 订单项数量
public decimal ItemTotalPrice { set; get; } // 订单项总价
}
/// <summary>
/// 商品模型
/// </summary>
public class Product /*FullAudited*//*AggregateRoot<Guid>*/
{
public Guid Id { set; get; } // 商品主键
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<ProductImage> ProductImages { get; set; }
public Product()
{
ProductImages = new Collection<ProductImage>();
}
public Product(string ProductTitle)
{
// 业务规则:ProductTitle名称不能为空
if (ProductTitle == null)
{
throw new Exception("商品名称不能为空");
}
ProductImages = new Collection<ProductImage>();
}
/// <summary>
/// 添加商品图片
/// </summary>
public void AddProductImage(string ImageUrl)
{
// 1、创建一个商品图片
ProductImage productImage = new ProductImage();
productImage.ImageUrl = ImageUrl;
// 2、添加到集合中
ProductImages.Add(productImage);
}
/// <summary>
/// 添加商品图片
/// </summary>
public void RemoveProductImage(Guid ProductImageId)
{
// 1、判断guid ,然后删除指定商品
// 2、添加到集合中
// ProductImages.Remove(productImage);
}
}
/// <summary>
/// 商品图片
/// </summary>
public class ProductImage /*: Entity<int>*/
{
//[Key]
public Guid Id { set; get; } // 主键
public Guid ProductId { set; get; } // 商品编号
public int ImageSort { set; get; } // 排序
public string ImageStatus { set; get; } // 状态(1:启用,2:禁用)
public string ImageUrl { set; get; } // 图片url
}
4.创建数据库和表
4.1 条件
XT.EBusiness.EntityFrameworkCore
XT.EBusiness.DbMigrator
4.2 步骤
在仓储层创建XT.EBusiness.EntityFrameworkCore中EBusinessDbContext类中增加
public class EBusinessDbContext :
AbpDbContext<EBusinessDbContext>,
IIdentityDbContext,
ITenantManagementDbContext
{
/* Add DbSet properties for your Aggregate Roots / Entities here. */
// 1、商品实体
public DbSet<Product> Products { get; set; }
}
然后在XT.EBusiness.DbMigrator中appsettings.json中修改
{
"ConnectionStrings": {
"Default": "Server=localhost;Port=3306;Database=EBusiness;Uid=sa;Pwd=1;"
}
}
然后启动YDT.EBusiness.DbMigrator
5.初始化数据库数据
5.1 条件
IDataSeedContributor
XT.EBusiness.DbMigrator
5.2 步骤
先创建种子数据类
// <summary>
/// 商品数据迁移
/// </summary>
public class ProductDataSeederContributor : IDataSeedContributor, ITransientDependency
{
private readonly IRepository<Product, Guid> _productRepository;
public ProductDataSeederContributor(IRepository<Product, Guid> productRepository)
{
_productRepository = productRepository;
}
public async Task SeedAsync(DataSeedContext context)
{
if (await _productRepository.GetCountAsync() <= 0)
{
await _productRepository.InsertAsync(
new Product
{
ProductTitle="iphone12",
ProductPrice=12,
ProductVirtualprice=12,
ProductSold=1,
ProductStatus="1",
ProductStock=1,
ProductDescription="手机非常好",
ProductSort=1,
ProductUrl="23232313"
},
autoSave: true
);
await _productRepository.InsertAsync(
new Product
{
ProductTitle = "iphone13",
ProductPrice = 24,
ProductVirtualprice = 24,
ProductSold = 1,
ProductStatus = "1",
ProductStock = 1,
ProductDescription = "手机非常好",
ProductSort = 1,
ProductUrl = "23232313"
},
autoSave: true
);
}
}
}
然后再次启动XT.EBusiness.DbMigrator项目,数据添加到数据库中
6.领域层和基础设施层设计
6.1 条件
XT.EBusiness.Domain
XT.EBusiness.EntityFrameworkCore
6.2 步骤
在XT.EBusiness.Domain创建IProductRepository接口
/// <summary>
/// 商品仓储
/// </summary>
public interface IProductRepository
{
IEnumerable<Product> GetProducts();
Product GetProductById(Guid id);
void Create(Product Product);
void Update(Product Product);
void Delete(Product Product);
bool ProductExists(Guid id);
}
然后再XT.EBusiness.EntityFrameworkCore实现IProductRepository接口
/// <summary>
/// 商品仓储实现
/// </summary>
[Dependency(ServiceLifetime.Transient)]
public class ProductRepository : IProductRepository
{
public EBusinessDbContext _eBusinessDbContext;
public ProductRepository(EBusinessDbContext eBusinessDbContext)
{
this._eBusinessDbContext = eBusinessDbContext;
}
public void Create(Product Product)
{
_eBusinessDbContext.Products.Add(Product);
_eBusinessDbContext.SaveChanges();
}
public void Delete(Product Product)
{
_eBusinessDbContext.Products.Remove(Product);
_eBusinessDbContext.SaveChanges();
}
public Product GetProductById(Guid id)
{
return _eBusinessDbContext.Products.Find(id);
}
public IEnumerable<Product> GetProducts()
{
return _eBusinessDbContext.Products.ToList();
}
public void Update(Product Product)
{
_eBusinessDbContext.Products.Update(Product);
_eBusinessDbContext.SaveChanges();
}
public bool ProductExists(Guid id)
{
return _eBusinessDbContext.Products.Any(e => e.Id == id);
}
}
7.应用层设计
7.1 条件
XT.EBusiness.Application.Contracts
XT.EBusiness.Application
7.2 步骤
先在XT.EBusiness.Application.Contracts创建商品IProductService
/// <summary>
/// 商品服务
/// </summary>
public interface IProductService
{
IEnumerable<ProductDto> GetProducts();
ProductDto GetProductById(Guid id);
void Create(CreateProductDto createProductDto);
void Update(UpdateProductDto updateProductDto);
void Delete(DeleteProductDto deleteProductDto);
bool ProductExists(Guid id);
}
然后在XT.EBusiness.Application.Contracts中创建增删改查的Dto
CreateProductDto:创建商品Dto
DeleteProductDto:删除商品Dto
UpdateProductDto:更新商品Dto
ProductDto:查询商品Dto
然后在XT.EBusiness.Application中创建IProductService实现类ProductService
/// <summary>
/// 商品服务实现
/// </summary>
[Dependency(ServiceLifetime.Transient)]
public class ProductService : IProductService
{
public readonly IProductRepository _productRepository;
public ProductService(IProductRepository ProductRepository)
{
this._productRepository = ProductRepository;
}
public void Create(CreateProductDto createProductDto)
{
// 1、对象映射
// 2、实体和Dto之间赋值
Product product = new Product();
product.ProductTitle = createProductDto.ProductTitle;
_productRepository.Create(product);
}
public void Delete(DeleteProductDto deleteProductDto)
{
// 2、实体和Dto之间赋值
Product product = new Product();
product.ProductTitle = deleteProductDto.ProductTitle;
_productRepository.Delete(product);
}
public ProductDto GetProductById(Guid id)
{
Product product = _productRepository.GetProductById(id);
// 2、AutoMapper自动映射实体
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Product, ProductDto>();
});
IMapper mapper = configuration.CreateMapper();
ProductDto productDto = mapper.Map<Product, ProductDto>(product);
return productDto;
}
public IEnumerable<ProductDto> GetProducts()
{
// 1、数据库查询数据
IEnumerable<Product> products = _productRepository.GetProducts();
// 2、AutoMapper自动映射实体
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Product, ProductDto>();
});
IMapper mapper = configuration.CreateMapper();
List<ProductDto> productDtos = mapper.Map<IEnumerable<Product>, List<ProductDto>>(products);
return productDtos;
}
public void Update(UpdateProductDto updateProductDto)
{
// 2、实体和Dto之间赋值
Product product = new Product();
product.ProductTitle = updateProductDto.ProductTitle;
_productRepository.Update(product);
}
public bool ProductExists(Guid id)
{
return _productRepository.ProductExists(id);
}
}
8.创建API控制器
8.1 条件
XT.EBusiness.HttpApi
8.2 步骤
先在XT.EBusiness.HttpApi中创建ProductsController控制器
/// <summary>
/// 商品服务控制器
/// </summary>
[Route("Products")]
[ApiController]
public class ProductsController : AbpController
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
this._productService = productService;
}
// GET: api/Products
[HttpGet]
public ActionResult<IEnumerable<ProductDto>> GetProducts()
{
return _productService.GetProducts().ToList();
}
// GET: api/Products/5
[HttpGet("{id}")]
public ActionResult<ProductDto> GetProduct(Guid id)
{
var product = _productService.GetProductById(id);
if (product == null)
{
return NotFound();
}
return product;
}
// PUT: api/Products/5
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
[HttpPut("{id}")]
public IActionResult PutProduct(UpdateProductDto updateProduct)
{
_productService.Update(updateProduct);
return NoContent();
}
// POST: api/Products
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
[HttpPost]
public ActionResult<ProductDto> PostProduct(CreateProductDto createProductDto)
{
_productService.Create(createProductDto);
return CreatedAtAction("GetProduct", createProductDto);
}
// DELETE: api/Products/5
[HttpDelete("{id}")]
public ActionResult<ProductDto> DeleteProduct(Guid id)
{
/*var product = _productService.GetProductById(id);
if (product == null)
{
return NotFound();
}
_productService.Delete(product);*/
return null;
}
private bool ProductExists(Guid id)
{
return _productService.ProductExists(id);
}
}
然后在XT.EBusiness.HttpApi模块类EBusinessHttpApiModule中引入EBusinessApplicationContractsModule
9.暴露API控制器
9.1 条件
XT.EBusiness.HttpApi.Host
9.2 步骤
先在XT.EBusiness.HttpApi.Host引入
EBusinessHttpApiModule模块
EBusinessApplicationModule模块
EBusinessEntityFrameworkCoreModule模块
然后启动YDT.EBusiness.HttpApi.Host
- 点赞
- 收藏
- 关注作者
评论(0)