263 lines
9.6 KiB
C#
263 lines
9.6 KiB
C#
using RIZO.Mall.Model;
|
|
using RIZO.Mall.Model.Dto;
|
|
using RIZO.Mall.Service.IService;
|
|
|
|
namespace RIZO.Mall.Service
|
|
{
|
|
/// <summary>
|
|
/// 商品管理Service业务层处理
|
|
/// </summary>
|
|
[AppService(ServiceType = typeof(IProductService))]
|
|
public class ProductService : BaseService<Product>, IProductService
|
|
{
|
|
private readonly ISkusService skusService;
|
|
private readonly IProductSpecService specService;
|
|
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="skusService"></param>
|
|
/// <param name="shoppingProductSpecService"></param>
|
|
public ProductService(ISkusService skusService, IProductSpecService shoppingProductSpecService)
|
|
{
|
|
this.skusService = skusService;
|
|
this.specService = shoppingProductSpecService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查询商品管理列表
|
|
/// </summary>
|
|
/// <param name="parm"></param>
|
|
/// <returns></returns>
|
|
public PagedInfo<ProductDto> GetList(ShoppingProductQueryDto parm)
|
|
{
|
|
var predicate = QueryExp(parm);
|
|
|
|
var response = Queryable()
|
|
.Where(predicate.ToExpression())
|
|
.Includes(x => x.Skus.Where(f => f.IsDelete == 0).ToList())
|
|
.Includes(x => x.Category)
|
|
.Includes(x => x.Brand)
|
|
.ToPage<Product, ProductDto>(parm);
|
|
foreach (var item in response.Result)
|
|
{
|
|
item.Stock = item.Skus.Sum(s => s.Stock);
|
|
item.TotalSalesVolume = item.Skus.Sum(s => s.SalesVolume);
|
|
}
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取详情
|
|
/// </summary>
|
|
/// <param name="ProductId"></param>
|
|
/// <returns></returns>
|
|
public ProductDto GetInfo(long ProductId)
|
|
{
|
|
var response = Queryable()
|
|
.Where(x => x.ProductId == ProductId)
|
|
.First();
|
|
var info = response.Adapt<ProductDto>();
|
|
|
|
var spec = specService.GetList(f => f.ProductId == info.ProductId);
|
|
var skus = skusService.GetSkus(info.ProductId);
|
|
|
|
info.Spec = spec.Adapt<List<ProductSpecDto>>();
|
|
info.Skus = skus.ToList().OrderBy(f => f.SortId).Adapt<List<SkusDto>>();
|
|
|
|
return info;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加商品管理
|
|
/// </summary>
|
|
/// <param name="dto"></param>
|
|
/// <returns></returns>
|
|
public Product AddShoppingProduct(ProductDto dto)
|
|
{
|
|
var model = dto.Adapt<Product>();
|
|
var result = UseTran(() =>
|
|
{
|
|
CalcProduct(dto, model);
|
|
|
|
model = InsertReturnEntity(model) ?? throw new Exception("添加商品失败");
|
|
|
|
if (dto.Skus != null)
|
|
{
|
|
dto.Skus.ForEach(it =>
|
|
{
|
|
it.ProductId = model.ProductId;
|
|
it.SpecCombination = string.Join(";", it.Specs.Select(x => $"{x.Name}:{x.Value}"));
|
|
});
|
|
|
|
skusService.Insert(dto.Skus.Adapt<List<Skus>>());
|
|
}
|
|
//插入商品规格
|
|
dto.Spec.ForEach(x => x.ProductId = model.ProductId);
|
|
specService.InsertRange(dto.Spec.Adapt<List<ProductSpec>>());
|
|
});
|
|
if (result.IsSuccess)
|
|
{
|
|
return model;
|
|
}
|
|
throw new CustomException("添加失败");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 修改商品管理
|
|
/// </summary>
|
|
/// <param name="dto"></param>
|
|
/// <returns></returns>
|
|
public Product UpdateShoppingProduct(ProductDto dto)
|
|
{
|
|
var model = dto.Adapt<Product>();
|
|
var result = UseTran(() =>
|
|
{
|
|
model.Skus.ForEach(f => f.ProductId = model.ProductId);
|
|
CalcProduct(dto, model);
|
|
|
|
Update(model, true, "修改商品");
|
|
|
|
var skus = skusService.GetSkus(model.ProductId);
|
|
var allSkuIds = skus.Select(f => f.SkuId).ToList();
|
|
|
|
// 删除旧的规格
|
|
//specService.DeleteSpecByProductId(model.ProductId);
|
|
// 插入新的规格
|
|
dto.Spec.ForEach(f => f.ProductId = model.ProductId);
|
|
//specService.InsertRange(dto.Spec.Adapt<List<ProductSpec>>());
|
|
specService.UpdateProductSpec(model.ProductId, dto.Spec.Adapt<List<ProductSpec>>());
|
|
|
|
var insertSkus = model.Skus.Where(f => !skus.Any(s => s.SkuId == f.SkuId)).ToList();
|
|
var updateSkus = model.Skus.Where(f => skus.Any(s => s.SkuId == f.SkuId)).ToList();
|
|
var deleteSkus = skus.Where(f => !model.Skus.Any(s => s.SkuId == f.SkuId)).ToList();
|
|
|
|
// 软删除sku
|
|
if (deleteSkus.Count > 0)
|
|
{
|
|
skusService.Deleteable()
|
|
.Where(f => f.IsDelete == 0)
|
|
.In(deleteSkus.Select(f => f.SkuId))
|
|
.IsLogic()
|
|
.ExecuteCommand();
|
|
logger.Info($"删除的skuid={deleteSkus.Select(f => f.SkuId)}");
|
|
}
|
|
|
|
//更新现有的sku
|
|
foreach (var item in insertSkus)
|
|
{
|
|
item.SpecCombination = UpdateCombination(item);
|
|
}
|
|
|
|
// 插入新的sku
|
|
skusService.Insert(insertSkus);
|
|
//更新现有的sku
|
|
foreach (var item in updateSkus)
|
|
{
|
|
item.ProductId = model.ProductId;
|
|
item.SpecCombination = UpdateCombination(item);
|
|
skusService.Update(item, true, "修改商品sku");
|
|
}
|
|
});
|
|
if (!result.IsSuccess)
|
|
{
|
|
throw new CustomException(ResultCode.CUSTOM_ERROR, "修改失败", result.ErrorMessage);
|
|
}
|
|
return model;
|
|
}
|
|
|
|
private string UpdateCombination(Skus item)
|
|
{
|
|
return string.Join(";", item.Specs.Select(x => $"{x.Name}:{x.Value}"));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 修改商品管理
|
|
/// </summary>
|
|
/// <param name="dto"></param>
|
|
/// <returns></returns>
|
|
public long UpdateInfo(ProductDto dto)
|
|
{
|
|
var model = dto.Adapt<Product>();
|
|
|
|
var result = Update(model, t => new
|
|
{
|
|
t.SortId,
|
|
t.ProductName,
|
|
t.MainImage,
|
|
t.ImageUrls,
|
|
t.SaleStatus,
|
|
t.CategoryId,
|
|
t.BrandId,
|
|
t.Introduce,
|
|
t.Unit,
|
|
t.OriginalPrice,
|
|
t.VideoUrl,
|
|
t.DetailsHtml
|
|
}, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
private void CalcProduct(ProductDto dto, Product model)
|
|
{
|
|
var summary = string.Join(", ", dto.Spec.Select(s =>
|
|
$"{s.Name}: {string.Join("/", s.SpecValues)}"
|
|
));
|
|
|
|
//最低价
|
|
model.Price = dto.Skus.Min(s => s.Price);
|
|
model.MaxPrice = dto.Skus.Max(s => s.Price);
|
|
model.SpecSummary = summary;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 导出商品管理
|
|
/// </summary>
|
|
/// <param name="parm"></param>
|
|
/// <returns></returns>
|
|
public PagedInfo<ProductDto> ExportList(ShoppingProductQueryDto parm)
|
|
{
|
|
var predicate = QueryExp(parm);
|
|
|
|
var response = Queryable()
|
|
.Where(predicate.ToExpression())
|
|
.Includes(x => x.Skus.Where(f => f.IsDelete == 0).ToList())
|
|
.Includes(x => x.Category)
|
|
.Includes(x => x.Brand)
|
|
.Select((it) => new ProductDto
|
|
{
|
|
Stock = it.Skus.Sum(s => s.Stock),
|
|
TotalSalesVolume = it.Skus.Sum(s => s.SalesVolume),
|
|
BrandName = it.Brand.Name,
|
|
CategoryName = it.Category.Name,
|
|
}, true)
|
|
.ToPage(parm);
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查询导出表达式
|
|
/// </summary>
|
|
/// <param name="parm"></param>
|
|
/// <returns></returns>
|
|
private static Expressionable<Product> QueryExp(ShoppingProductQueryDto parm)
|
|
{
|
|
var predicate = Expressionable.Create<Product>();
|
|
|
|
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.ProductName), it => it.ProductName.Contains(parm.ProductName));
|
|
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.ProductCode), it => it.ProductCode == parm.ProductCode);
|
|
predicate = predicate.AndIF(parm.CategoryId != null, it => it.CategoryId == parm.CategoryId);
|
|
predicate = predicate.AndIF(parm.BrandId != null, it => it.BrandId == parm.BrandId);
|
|
predicate = predicate.AndIF(parm.ProductId != null, it => it.ProductId == parm.ProductId);
|
|
predicate = predicate.AndIF(parm.SaleStatus != null, it => it.SaleStatus == parm.SaleStatus);
|
|
//predicate = predicate.AndIF(parm.BeginAddTime == null, it => it.AddTime >= DateTime.Now.ToShortDateString().ParseToDateTime());
|
|
predicate = predicate.AndIF(parm.BeginAddTime != null, it => it.AddTime >= parm.BeginAddTime);
|
|
predicate = predicate.AndIF(parm.EndAddTime != null, it => it.AddTime <= parm.EndAddTime);
|
|
predicate = predicate.And(it => it.IsDelete == 0);
|
|
return predicate;
|
|
}
|
|
}
|
|
} |