370 lines
15 KiB
C#
370 lines
15 KiB
C#
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;
|
|
using ARW.Common;
|
|
|
|
namespace ARW.Service.Api.BusinessService.GoodsManager.Goodss
|
|
{
|
|
/// <summary>
|
|
/// 商品接口实现类Api
|
|
///
|
|
/// @author lwh
|
|
/// @date 2023-07-09
|
|
/// </summary>
|
|
[AppService(ServiceType = typeof(IGoodsServiceApi), ServiceLifetime = LifeTime.Transient)]
|
|
public class GoodsServiceImplApi : BaseService<Goods>, 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接口代码
|
|
|
|
|
|
/// <summary>
|
|
/// 查询商品列表(Api)
|
|
/// </summary>
|
|
/// <param name="parm"></param>
|
|
/// <returns></returns>
|
|
public async Task<PagedInfo<GoodsVoApi>> GetGoodsListApi(GoodsQueryDtoApi parm)
|
|
{
|
|
//开始拼装查询条件
|
|
var predicate = Expressionable.Create<Goods>();
|
|
//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<Shop>((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);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 查询商品列表(Api)
|
|
/// </summary>
|
|
/// <param name="parm"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<GoodsVoApi>> GetGoodsApi(GoodsQueryDtoApi parm)
|
|
{
|
|
//开始拼装查询条件
|
|
var predicate = Expressionable.Create<Goods>();
|
|
|
|
predicate = predicate.AndIF(parm.ShopGoodsCategoryGuid != 0, s => s.ShopGoodsCategoryGuid == parm.ShopGoodsCategoryGuid);
|
|
|
|
var query = _GoodsRepository
|
|
.Queryable()
|
|
.LeftJoin<Shop>((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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查询商品详情(Api)
|
|
/// </summary>
|
|
/// <param name="parm"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> GetGoodsDetails(GoodsDtoApi parm)
|
|
{
|
|
|
|
var query = _GoodsRepository
|
|
.Queryable()
|
|
.LeftJoin<Shop>((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;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取商品的规格组列表
|
|
/// </summary>
|
|
/// <param name="json"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> GetSpecList(string json)
|
|
{
|
|
if (json != "[]")
|
|
{
|
|
json = json.Remove(0, 1);
|
|
json = json.Substring(0, json.Length - 1);
|
|
var data = JsonConvert.DeserializeObject<GoodsApiDetailsVo>(json);
|
|
|
|
var goodsSpecListVo = new List<GoodsSpecApiVo>();
|
|
|
|
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<SpecValueApiVo>()
|
|
};
|
|
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;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取商品规格值列表
|
|
/// </summary>
|
|
/// <param name="specValueIds"></param>
|
|
/// <returns></returns>
|
|
private async Task<List<SpecValueApiVo>> GetSpecValuesAsync(List<int> 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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取商品sku列表
|
|
/// </summary>
|
|
/// <param name="skuList"></param>
|
|
/// <returns></returns>
|
|
private async Task<List<GoosSkuApiVo>> GetSkuListWithSpecValuesAsync(List<GoodsSku> skuList)
|
|
{
|
|
var resList = new List<GoosSkuApiVo>();
|
|
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<int>();
|
|
|
|
foreach (var item in skuList)
|
|
{
|
|
var list = new List<SkuSpecInfo>();
|
|
|
|
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<PriceInfo>();
|
|
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
|
|
|
|
}
|
|
}
|