using Infrastructure.Attribute; using SqlSugar; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ARW.Model; using ARW.Repository; using ARW.Repository.Business.GoodsManager.Goodss; using ARW.Service.Api.IBusinessService.GoodsManager.Goodss; using ARW.Model.Dto.Api.GoodsManager.Goodss; using ARW.Model.Models.Business.GoodsManager.Goodss; using ARW.Model.Vo.Api.GoodsManager.Goodss; using ARW.Model.Models.Business.ShopManager.Shops; using ARW.Repository.Business.GoodsManager.GoodsSpecs.GoodsSpecRels; using ARW.Repository.Business.GoodsManager.GoodsSpecs.Specs; using ARW.Repository.Business.GoodsManager.GoodsSpecs.SpecValues; using Newtonsoft.Json; using Senparc.CO2NET.Extensions; using ARW.Model.Models.Business.GoodsManager.GoodsSpecs.GoodsSkus; using ARW.Repository.Business.GoodsManager.GoodsSpecs.GoodsSkus; using ARW.Model.Models.Business.GoodsManager.GoodsCategorys; using ARW.Repository.Business.GoodsManager.GoodsCategorys; using System; namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss { /// /// 商品接口实现类Api /// /// @author lwh /// @date 2023-07-09 /// [AppService(ServiceType = typeof(IGoodsServiceApi), ServiceLifetime = LifeTime.Transient)] public class GoodsServiceImplApi : BaseService, IGoodsServiceApi { private readonly GoodsRepository _GoodsRepository; private readonly GoodsSpecRelRepository _GoodsSpecRelRepository; private readonly SpecRepository _SpecRepository; private readonly SpecValueRepository _SpecValueRepository; private readonly GoodsSkuRepository _GoodsSkuRepository; private readonly GoodsCategoryRepository _GoodsCategoryRepository; public GoodsServiceImplApi(GoodsRepository GoodsRepository, GoodsSpecRelRepository goodsSpecRelRepository, SpecRepository specRepository, SpecValueRepository specValueRepository, GoodsSkuRepository goodsSkuRepository, GoodsCategoryRepository goodsCategoryRepository) { this._GoodsRepository = GoodsRepository; _GoodsSpecRelRepository = goodsSpecRelRepository; _SpecRepository = specRepository; _SpecValueRepository = specValueRepository; _GoodsSkuRepository = goodsSkuRepository; _GoodsCategoryRepository = goodsCategoryRepository; } #region Api接口代码 /// /// 查询商品列表(Api) /// /// /// public async Task> GetGoodsListApi(GoodsQueryDtoApi parm) { //开始拼装查询条件 var predicate = Expressionable.Create(); //string[] goodsCategoryArr = null; // 检索经营类目 //if (parm.GoodsCategoryGuid != null) //{ // var data = await _GoodsCategoryRepository.GetListAsync(); // var SewGoodsCategorys = data.FindAll(delegate (GoodsCategory goodsCategory) // { // string[] parentGoodsCategoryId = goodsCategory.GoodsCategoryAncestralGuid.Split(",", StringSplitOptions.RemoveEmptyEntries); // return parentGoodsCategoryId.Contains(parm.GoodsCategoryGuid.ToString()); // }); // goodsCategoryArr = SewGoodsCategorys.Select(s => s.GoodsCategoryGuid.ToString()).ToArray(); //} predicate = predicate.AndIF(parm.ShopGuid != null, s => s.ShopGuid == parm.ShopGuid); predicate = predicate.AndIF(parm.ShopGoodsCategoryGuid != 0, s => s.ShopGoodsCategoryGuid == parm.ShopGoodsCategoryGuid); predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.GoodsName), s => s.GoodsName.Contains(parm.GoodsName)); predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.GoodsCoding), s => s.GoodsCoding.Contains(parm.GoodsCoding)); predicate = predicate.AndIF(parm.MinPrice != 0, s => s.GoodsPriceLowest >= parm.MinPrice); predicate = predicate.AndIF(parm.MaxPrice != 0, s => s.GoodsPriceLowest <= parm.MaxPrice); var sortType = OrderByType.Asc; if(parm.GoodsSortType == 1) sortType = OrderByType.Desc; var query = _GoodsRepository .Queryable() .LeftJoin((s, c) => s.ShopGuid == c.ShopGuid) .Where(predicate.ToExpression()) .WhereIF(parm.GoodsCategoryGuid != null, (s,c) => c.ShopBusinessCategoryGuid == parm.GoodsCategoryGuid) //.WhereIF(parm.GoodsCategoryGuid != null, (s, c) => c.ShopBusinessCategoryGuid == parm.GoodsCategoryGuid || goodsCategoryArr.Contains(c.ShopBusinessCategoryGuid.ToString())) .Where(s => s.GoodsShelfStatus == 1) .OrderByIF(parm.GoodsSort == 0 , s => s.GoodsSort, OrderByType.Asc) .OrderByIF(parm.GoodsSort == 1 , s => s.GoodsPriceLowest, sortType) .OrderByIF(parm.GoodsSort == 2 , s => s.GoodsSalesInitial + s.GoodsSalesActual, sortType) //.OrderBy(s => s.GoodsSort, OrderByType.Desc) .Select((s, c) => new GoodsVoApi { SpuId = s.GoodsGuid, ShopGuid = s.ShopGuid, ShopName = c.ShopName, CategoryIds = s.ShopGoodsCategoryGuid, Title = s.GoodsName, GoodsCoding = s.GoodsCoding, Video = s.GoodsMainImageVideo, PrimaryImage = s.GoodsVideoCover, Images = s.GoodsPicture, Price = s.GoodsPriceLowest, OriginPrice = s.GoodsDashedPriceLowest, SpuStockQuantity = s.GoodsTotalInventory, SoldNum = s.GoodsSalesInitial + s.GoodsSalesActual, IsPutOnSale = s.GoodsShelfStatus, }); return await query.ToPageAsync(parm); } /// /// 查询商品列表(Api) /// /// /// public async Task> GetGoodsApi(GoodsQueryDtoApi parm) { //开始拼装查询条件 var predicate = Expressionable.Create(); predicate = predicate.AndIF(parm.ShopGoodsCategoryGuid != 0, s => s.ShopGoodsCategoryGuid == parm.ShopGoodsCategoryGuid); var query = _GoodsRepository .Queryable() .LeftJoin((s, c) => s.ShopGuid == c.ShopGuid) .Where(predicate.ToExpression()) .Where(s => s.GoodsShelfStatus == 1) .OrderBy(s => s.GoodsSort, OrderByType.Asc) .Select((s, c) => new GoodsVoApi { SpuId = s.GoodsGuid, ShopGuid = s.ShopGuid, ShopName = c.ShopName, CategoryIds = s.ShopGoodsCategoryGuid, Title = s.GoodsName, GoodsCoding = s.GoodsCoding, Video = s.GoodsMainImageVideo, PrimaryImage = s.GoodsVideoCover, Images = s.GoodsPicture, Price = s.GoodsPriceLowest, OriginPrice = s.GoodsDashedPriceLowest, SpuStockQuantity = s.GoodsTotalInventory, SoldNum = s.GoodsSalesInitial + s.GoodsSalesActual, IsPutOnSale = s.GoodsShelfStatus, }); var list = await query.ToListAsync(); foreach (var item in list) { item.Thumb = item.Images.Split(',').First(); } return list; } /// /// 查询商品详情(Api) /// /// /// public async Task GetGoodsDetails(GoodsDtoApi parm) { var query = _GoodsRepository .Queryable() .LeftJoin((s, c) => s.ShopGuid == c.ShopGuid) .Where(s => s.GoodsGuid == parm.SpuId) .Select((s,c) => new GoodsApiDetailsVo { SpuId = s.GoodsGuid, ShopGuid = s.ShopGuid, ShopLogo = c.ShopLogo, ShopName = c.ShopName, ShopSalesOrderCount = c.ShopSalesOrderCount, ShopIntro = c.ShopIntro, CategoryIds = s.ShopGoodsCategoryGuid, Title = s.GoodsName, GoodsCoding = s.GoodsCoding, Video = s.GoodsMainImageVideo, PrimaryImage = s.GoodsVideoCover, Images = s.GoodsPicture, MinSalePrice = s.GoodsPriceLowest, MaxSalePrice = s.GoodsPriceHighest, MaxLinePrice = s.GoodsDashedPriceHighest, SpuStockQuantity = s.GoodsTotalInventory, SoldNum = s.GoodsSalesInitial + s.GoodsSalesActual, Desc = s.GoodsDetails, IsPutOnSale = s.GoodsShelfStatus, }).Take(1); var json = await query.ToJsonAsync(); var data = await GetSpecList(json); return data; } /// /// 获取商品的规格组列表 /// /// /// public async Task GetSpecList(string json) { if (json != "[]") { json = json.Remove(0, 1); json = json.Substring(0, json.Length - 1); var data = JsonConvert.DeserializeObject(json); var goodsSpecListVo = new List(); var specIds = (await _GoodsSpecRelRepository.GetListAsync(s => s.GoodsGuid == data.SpuId)) .Select(item => item.SpecId) .Distinct() .ToList(); var specs = await _SpecRepository.GetListAsync(s => specIds.Contains(s.SpecId)); var specValueIds = (await _GoodsSpecRelRepository.GetListAsync(s => s.GoodsGuid == data.SpuId)) .Where(item => item.SpecValueId != 0) .Select(item => item.SpecValueId) .Distinct() .ToList(); var specValues = await GetSpecValuesAsync(specValueIds); foreach (var spec in specs) { var goodsSpecVo = new GoodsSpecApiVo { SpecId = spec.SpecId, Title = spec.SpecName, SpecValueList = new List() }; goodsSpecVo.SpecValueList.AddRange(specValues.Where(sv => sv.SpecId == spec.SpecId)); goodsSpecListVo.Add(goodsSpecVo); } // 获取Sku列表 var skuList = await _GoodsSkuRepository.GetListAsync(s => s.GoodsGuid == data.SpuId); data.SkuList = await GetSkuListWithSpecValuesAsync(skuList); data.SpecList = goodsSpecListVo; json = data.ToJson(); } return json; } /// /// 获取商品规格值列表 /// /// /// private async Task> GetSpecValuesAsync(List specValueIds) { var specValues = await _SpecValueRepository.GetListAsync(sv => specValueIds.Contains(sv.SpecValueId)); return specValues.Select(sv => new SpecValueApiVo { SpecValueId = sv.SpecValueId, SpecId = sv.SpecId, SpecValue = sv.SpecValueName, }).ToList(); } /// /// 获取商品sku列表 /// /// /// private async Task> GetSkuListWithSpecValuesAsync(List skuList) { var resList = new List(); var specValueIds = skuList.SelectMany(sku => new[] { sku.SpecValueId, sku.SpecSecondValueId, sku.SpecThirdValueId }) .Distinct() .Where(id => id != 0) .ToList(); // sku所属商品规格 var specValues = await GetSpecValuesAsync(specValueIds); var addedSpecValueIds = new HashSet(); foreach (var item in skuList) { var list = new List(); await AddSkuSpecInfo(item.SpecValueId); await AddSkuSpecInfo(item.SpecSecondValueId); await AddSkuSpecInfo(item.SpecThirdValueId); async Task AddSkuSpecInfo(int specValueId) { if (specValueId != 0) { //addedSpecValueIds.Add(specValueId); var sku = specValues.FirstOrDefault(sv => sv.SpecValueId == specValueId); var spec = await _SpecRepository.GetFirstAsync(s => s.SpecId == sku.SpecId); var skuSpecInfo = new SkuSpecInfo { SpecId = sku.SpecId, SpecTitle = spec.SpecName, SpecValueId = sku.SpecValueId, SpecValue = sku.SpecValue }; list.Add(skuSpecInfo); } } // sku价格 var skuPriceInfoList = new List(); var skuPriceInfo1 = new PriceInfo { PriceType = 1, Price = item.GoodsSkuPrice, PriceTypeName = "销售价格" }; skuPriceInfoList.Add(skuPriceInfo1); if (item.GoodsSkuLinePrice != 0) { var skuPriceInfo2 = new PriceInfo { PriceType = 2, Price = item.GoodsSkuLinePrice, PriceTypeName = "划线价格" }; skuPriceInfoList.Add(skuPriceInfo2); } var skuVo = new GoosSkuApiVo { SkuId = item.GoodsSkuId, SkuImage = item.GoodsSkuImg, SpecInfo = list, PriceInfo = skuPriceInfoList, Quantity = item.GoodsSkuStockNum, Weight = item.GoodsSkuWeight }; resList.Add(skuVo); } return resList; } #endregion } }