ProductService.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. using ZR.Mall.Model;
  2. using ZR.Mall.Model.Dto;
  3. using ZR.Mall.Service.IService;
  4. namespace ZR.Mall.Service
  5. {
  6. /// <summary>
  7. /// 商品管理Service业务层处理
  8. /// </summary>
  9. [AppService(ServiceType = typeof(IProductService))]
  10. public class ProductService : BaseService<Product>, IProductService
  11. {
  12. private readonly ISkusService skusService;
  13. private readonly IProductSpecService specService;
  14. private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
  15. /// <summary>
  16. ///
  17. /// </summary>
  18. /// <param name="skusService"></param>
  19. /// <param name="shoppingProductSpecService"></param>
  20. public ProductService(ISkusService skusService, IProductSpecService shoppingProductSpecService)
  21. {
  22. this.skusService = skusService;
  23. this.specService = shoppingProductSpecService;
  24. }
  25. /// <summary>
  26. /// 查询商品管理列表
  27. /// </summary>
  28. /// <param name="parm"></param>
  29. /// <returns></returns>
  30. public PagedInfo<ProductDto> GetList(ShoppingProductQueryDto parm)
  31. {
  32. var predicate = QueryExp(parm);
  33. var response = Queryable()
  34. .Where(predicate.ToExpression())
  35. .Includes(x => x.Skus.Where(f => f.IsDelete == 0).ToList())
  36. .Includes(x => x.Category)
  37. .Includes(x => x.Brand)
  38. .ToPage<Product, ProductDto>(parm);
  39. foreach (var item in response.Result)
  40. {
  41. item.Stock = item.Skus.Sum(s => s.Stock);
  42. item.TotalSalesVolume = item.Skus.Sum(s => s.SalesVolume);
  43. }
  44. return response;
  45. }
  46. /// <summary>
  47. /// 获取详情
  48. /// </summary>
  49. /// <param name="ProductId"></param>
  50. /// <returns></returns>
  51. public ProductDto GetInfo(long ProductId)
  52. {
  53. var response = Queryable()
  54. .Where(x => x.ProductId == ProductId)
  55. .First();
  56. var info = response.Adapt<ProductDto>();
  57. var spec = specService.GetList(f => f.ProductId == info.ProductId);
  58. var skus = skusService.GetSkus(info.ProductId);
  59. info.Spec = spec.Adapt<List<ProductSpecDto>>();
  60. info.Skus = skus.ToList().OrderBy(f => f.SortId).Adapt<List<SkusDto>>();
  61. return info;
  62. }
  63. /// <summary>
  64. /// 添加商品管理
  65. /// </summary>
  66. /// <param name="dto"></param>
  67. /// <returns></returns>
  68. public Product AddShoppingProduct(ProductDto dto)
  69. {
  70. var model = dto.Adapt<Product>();
  71. var result = UseTran(() =>
  72. {
  73. CalcProduct(dto, model);
  74. model = InsertReturnEntity(model) ?? throw new Exception("添加商品失败");
  75. if (dto.Skus != null)
  76. {
  77. dto.Skus.ForEach(it =>
  78. {
  79. it.ProductId = model.ProductId;
  80. it.SpecCombination = string.Join(";", it.Specs.Select(x => $"{x.Name}:{x.Value}"));
  81. });
  82. skusService.Insert(dto.Skus.Adapt<List<Skus>>());
  83. }
  84. //插入商品规格
  85. dto.Spec.ForEach(x => x.ProductId = model.ProductId);
  86. specService.InsertRange(dto.Spec.Adapt<List<ProductSpec>>());
  87. });
  88. if (result.IsSuccess)
  89. {
  90. return model;
  91. }
  92. throw new CustomException("添加失败");
  93. }
  94. /// <summary>
  95. /// 修改商品管理
  96. /// </summary>
  97. /// <param name="dto"></param>
  98. /// <returns></returns>
  99. public Product UpdateShoppingProduct(ProductDto dto)
  100. {
  101. var model = dto.Adapt<Product>();
  102. var result = UseTran(() =>
  103. {
  104. model.Skus.ForEach(f => f.ProductId = model.ProductId);
  105. CalcProduct(dto, model);
  106. Update(model, true, "修改商品");
  107. var skus = skusService.GetSkus(model.ProductId);
  108. var allSkuIds = skus.Select(f => f.SkuId).ToList();
  109. // 删除旧的规格
  110. //specService.DeleteSpecByProductId(model.ProductId);
  111. // 插入新的规格
  112. dto.Spec.ForEach(f => f.ProductId = model.ProductId);
  113. //specService.InsertRange(dto.Spec.Adapt<List<ProductSpec>>());
  114. specService.UpdateProductSpec(model.ProductId, dto.Spec.Adapt<List<ProductSpec>>());
  115. var insertSkus = model.Skus.Where(f => !skus.Any(s => s.SkuId == f.SkuId)).ToList();
  116. var updateSkus = model.Skus.Where(f => skus.Any(s => s.SkuId == f.SkuId)).ToList();
  117. var deleteSkus = skus.Where(f => !model.Skus.Any(s => s.SkuId == f.SkuId)).ToList();
  118. // 软删除sku
  119. if (deleteSkus.Count > 0)
  120. {
  121. skusService.Deleteable()
  122. .Where(f => f.IsDelete == 0)
  123. .In(deleteSkus.Select(f => f.SkuId))
  124. .IsLogic()
  125. .ExecuteCommand();
  126. logger.Info($"删除的skuid={deleteSkus.Select(f => f.SkuId)}");
  127. }
  128. //更新现有的sku
  129. foreach (var item in insertSkus)
  130. {
  131. item.SpecCombination = UpdateCombination(item);
  132. }
  133. // 插入新的sku
  134. skusService.Insert(insertSkus);
  135. //更新现有的sku
  136. foreach (var item in updateSkus)
  137. {
  138. item.ProductId = model.ProductId;
  139. item.SpecCombination = UpdateCombination(item);
  140. skusService.Update(item, true, "修改商品sku");
  141. }
  142. });
  143. if (!result.IsSuccess)
  144. {
  145. throw new CustomException(ResultCode.CUSTOM_ERROR, "修改失败", result.ErrorMessage);
  146. }
  147. return model;
  148. }
  149. private string UpdateCombination(Skus item)
  150. {
  151. return string.Join(";", item.Specs.Select(x => $"{x.Name}:{x.Value}"));
  152. }
  153. /// <summary>
  154. /// 修改商品管理
  155. /// </summary>
  156. /// <param name="dto"></param>
  157. /// <returns></returns>
  158. public long UpdateInfo(ProductDto dto)
  159. {
  160. var model = dto.Adapt<Product>();
  161. var result = Update(model, t => new
  162. {
  163. t.SortId,
  164. t.ProductName,
  165. t.MainImage,
  166. t.ImageUrls,
  167. t.SaleStatus,
  168. t.CategoryId,
  169. t.BrandId,
  170. t.Introduce,
  171. t.Unit,
  172. t.OriginalPrice,
  173. t.VideoUrl,
  174. t.DetailsHtml
  175. }, true);
  176. return result;
  177. }
  178. private void CalcProduct(ProductDto dto, Product model)
  179. {
  180. var summary = string.Join(", ", dto.Spec.Select(s =>
  181. $"{s.Name}: {string.Join("/", s.SpecValues)}"
  182. ));
  183. //最低价
  184. model.Price = dto.Skus.Min(s => s.Price);
  185. model.MaxPrice = dto.Skus.Max(s => s.Price);
  186. model.SpecSummary = summary;
  187. }
  188. /// <summary>
  189. /// 导出商品管理
  190. /// </summary>
  191. /// <param name="parm"></param>
  192. /// <returns></returns>
  193. public PagedInfo<ProductDto> ExportList(ShoppingProductQueryDto parm)
  194. {
  195. var predicate = QueryExp(parm);
  196. var response = Queryable()
  197. .Where(predicate.ToExpression())
  198. .Includes(x => x.Skus.Where(f => f.IsDelete == 0).ToList())
  199. .Includes(x => x.Category)
  200. .Includes(x => x.Brand)
  201. .Select((it) => new ProductDto
  202. {
  203. Stock = it.Skus.Sum(s => s.Stock),
  204. TotalSalesVolume = it.Skus.Sum(s => s.SalesVolume),
  205. BrandName = it.Brand.Name,
  206. CategoryName = it.Category.Name,
  207. }, true)
  208. .ToPage(parm);
  209. return response;
  210. }
  211. /// <summary>
  212. /// 查询导出表达式
  213. /// </summary>
  214. /// <param name="parm"></param>
  215. /// <returns></returns>
  216. private static Expressionable<Product> QueryExp(ShoppingProductQueryDto parm)
  217. {
  218. var predicate = Expressionable.Create<Product>();
  219. predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.ProductName), it => it.ProductName.Contains(parm.ProductName));
  220. predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.ProductCode), it => it.ProductCode == parm.ProductCode);
  221. predicate = predicate.AndIF(parm.CategoryId != null, it => it.CategoryId == parm.CategoryId);
  222. predicate = predicate.AndIF(parm.BrandId != null, it => it.BrandId == parm.BrandId);
  223. predicate = predicate.AndIF(parm.ProductId != null, it => it.ProductId == parm.ProductId);
  224. predicate = predicate.AndIF(parm.SaleStatus != null, it => it.SaleStatus == parm.SaleStatus);
  225. //predicate = predicate.AndIF(parm.BeginAddTime == null, it => it.AddTime >= DateTime.Now.ToShortDateString().ParseToDateTime());
  226. predicate = predicate.AndIF(parm.BeginAddTime != null, it => it.AddTime >= parm.BeginAddTime);
  227. predicate = predicate.AndIF(parm.EndAddTime != null, it => it.AddTime <= parm.EndAddTime);
  228. return predicate;
  229. }
  230. }
  231. }