856 lines
34 KiB
C#
856 lines
34 KiB
C#
using Infrastructure.Attribute;
|
||
using SqlSugar;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using Infrastructure;
|
||
using ARW.Model;
|
||
using ARW.Repository;
|
||
using ARW.Repository.Business.GoodsManager.Goodss;
|
||
using ARW.Service.Business.IBusinessService.GoodsManager.Goodss;
|
||
using ARW.Model.Dto.Business.GoodsManager.Goodss;
|
||
using ARW.Model.Models.Business.GoodsManager.Goodss;
|
||
using ARW.Model.Vo.Business.GoodsManager.Goodss;
|
||
using ARW.Model.Models.Business.ShopManager.Shops;
|
||
using ARW.Service.Business.IBusinessService.GoodsManager.GoodsServicess.GoodsServicesRels;
|
||
using ARW.Model.Models.Business.GoodsManager.GoodsServicess.GoodsServicesRels;
|
||
using ARW.Service.Business.IBusinessService.GoodsManager.GoodsSpecs.Specs;
|
||
using ARW.Service.Business.IBusinessService.GoodsManager.GoodsSpecs.SpecValues;
|
||
using ARW.Service.Business.IBusinessService.GoodsManager.GoodsSpecs.GoodsSpecRels;
|
||
using ARW.Model.Models.Business.GoodsManager.GoodsSpecs.Specs;
|
||
using ARW.Model.Models.Business.GoodsManager.GoodsSpecs.SpecValues;
|
||
using ARW.Model.Models.Business.GoodsManager.GoodsSpecs.GoodsSpecRels;
|
||
using ARW.Model.Models.Business.GoodsManager.GoodsSpecs.GoodsSkus;
|
||
using ARW.Service.Business.IBusinessService.GoodsManager.GoodsSpecs.GoodsSkus;
|
||
using ARW.Repository.Business.GoodsManager.ShopGoodsCategorys;
|
||
using ARW.Model.Models.Business.GoodsManager.ShopGoodsCategorys;
|
||
using ARW.Repository.Business.GoodsManager.GoodsCategorys;
|
||
using ARW.Model.Models.Business.GoodsManager.GoodsCategorys;
|
||
using ARW.Common;
|
||
using ARW.Model.System;
|
||
using ARW.Repository.Business.ShopManager.Shops;
|
||
using ARW.Repository.Business.LogisticsManage.Deliverys;
|
||
using ARW.Repository.Business.GoodsManager.GoodsServicess;
|
||
using Senparc.CO2NET.Extensions;
|
||
using ARW.Repository.Business.Custom.Customers;
|
||
|
||
namespace ARW.Service.Business.BusinessService.GoodsManager.Goodss
|
||
{
|
||
/// <summary>
|
||
/// 商品接口实现类
|
||
///
|
||
/// @author lwh
|
||
/// @date 2023-06-19
|
||
/// </summary>
|
||
[AppService(ServiceType = typeof(IGoodsService), ServiceLifetime = LifeTime.Transient)]
|
||
public class GoodsServiceImpl : BaseService<Goods>, IGoodsService
|
||
{
|
||
private readonly GoodsRepository _GoodsRepository;
|
||
private readonly ShopGoodsCategoryRepository _ShopGoodsCategoryRepository;
|
||
private readonly GoodsCategoryRepository _GoodsCategoryRepository;
|
||
private readonly ShopRepository _ShopRepository;
|
||
private readonly DeliveryRepository _DeliveryRepository;
|
||
private readonly GoodsServicesRepository _GoodsServicesRepository;
|
||
private readonly IGoodsServicesRelService _GoodsServicesRelIService;
|
||
private readonly ISpecService _SepcIService;
|
||
private readonly ISpecValueService _SpecValueIService;
|
||
private readonly IGoodsSpecRelService _GoodsSpecRelService;
|
||
private readonly IGoodsSkuService _GoodsSkuService;
|
||
|
||
|
||
public GoodsServiceImpl(GoodsRepository GoodsRepository, IGoodsServicesRelService goodsServicesRelIService, ISpecService sepcIService, ISpecValueService specValueIService, IGoodsSpecRelService goodsSpecRelService, IGoodsSkuService goodsSkuService, ShopGoodsCategoryRepository shopGoodsCategoryRepository, GoodsCategoryRepository goodsCategoryRepository, ShopRepository shopRepository, DeliveryRepository deliveryRepository, GoodsServicesRepository goodsServicesRepository)
|
||
{
|
||
this._GoodsRepository = GoodsRepository;
|
||
_GoodsServicesRelIService = goodsServicesRelIService;
|
||
_SepcIService = sepcIService;
|
||
_SpecValueIService = specValueIService;
|
||
_GoodsSpecRelService = goodsSpecRelService;
|
||
_GoodsSkuService = goodsSkuService;
|
||
_ShopGoodsCategoryRepository = shopGoodsCategoryRepository;
|
||
_GoodsCategoryRepository = goodsCategoryRepository;
|
||
_ShopRepository = shopRepository;
|
||
_DeliveryRepository = deliveryRepository;
|
||
_GoodsServicesRepository = goodsServicesRepository;
|
||
}
|
||
|
||
#region 业务逻辑代码
|
||
|
||
|
||
/// <summary>
|
||
/// 查询商品分页列表
|
||
/// </summary>
|
||
public async Task<PagedInfo<GoodsVo>> GetGoodsList(GoodsQueryDto parm)
|
||
{
|
||
|
||
//开始拼装查询条件d
|
||
var predicate = Expressionable.Create<Goods>();
|
||
string[] goodsCategoryArr = null;
|
||
|
||
// 检索商品类目
|
||
if (parm.ShopGoodsCategoryGuid != null)
|
||
{
|
||
var data = await _ShopGoodsCategoryRepository.GetListAsync();
|
||
|
||
var SewshopGoodsCategorys = data.FindAll(delegate (ShopGoodsCategory shopGoodsCategory)
|
||
{
|
||
string[] parentShopGoodsCategoryId = shopGoodsCategory.ShopGoodsCategoryAncestralGuid.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
||
return parentShopGoodsCategoryId.Contains(parm.ShopGoodsCategoryGuid.ToString());
|
||
});
|
||
string[] shopGoodsCategoryArr = SewshopGoodsCategorys.Select(s => s.ShopGoodsCategoryGuid.ToString()).ToArray();
|
||
predicate = predicate.AndIF(parm.ShopGoodsCategoryGuid != null, s => s.ShopGoodsCategoryGuid == parm.ShopGoodsCategoryGuid || shopGoodsCategoryArr.Contains(s.ShopGoodsCategoryGuid.ToString()));
|
||
}
|
||
|
||
// 检索经营类目
|
||
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 != 0, s => s.ShopGuid == parm.ShopGuid);
|
||
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));
|
||
var query = _GoodsRepository
|
||
.Queryable()
|
||
.LeftJoin<Shop>((s, c) => s.ShopGuid == c.ShopGuid)
|
||
.Where(predicate.ToExpression())
|
||
.WhereIF(!string.IsNullOrEmpty(parm.ShopName), (s, c) => c.ShopName.Contains(parm.ShopName))
|
||
.WhereIF(parm.GoodsCategoryGuid != null, (s, c) => c.ShopBusinessCategoryGuid == parm.GoodsCategoryGuid || goodsCategoryArr.Contains(c.ShopBusinessCategoryGuid.ToString()))
|
||
.OrderBy(s => s.GoodsSort, OrderByType.Asc)
|
||
.Select((s, c) => new GoodsVo
|
||
{
|
||
GoodsId = s.GoodsId,
|
||
GoodsGuid = s.GoodsGuid,
|
||
ShopGuid = s.ShopGuid,
|
||
ShopName = c.ShopName,
|
||
ShopGoodsCategoryGuid = s.ShopGoodsCategoryGuid,
|
||
GoodsSkuIds = s.GoodsSkuIds,
|
||
DeliveryGuid = s.DeliveryGuid,
|
||
GoodsName = s.GoodsName,
|
||
GoodsCoding = s.GoodsCoding,
|
||
GoodsMainImageVideo = s.GoodsMainImageVideo,
|
||
GoodsVideoCover = s.GoodsVideoCover,
|
||
GoodsPicture = s.GoodsPicture,
|
||
GoodsSellingPoint = s.GoodsSellingPoint,
|
||
GoodsSpecType = s.GoodsSpecType,
|
||
GoodsPriceLowest = s.GoodsPriceLowest,
|
||
GoodsPriceHighest = s.GoodsPriceHighest,
|
||
GoodsDashedPriceLowest = s.GoodsDashedPriceLowest,
|
||
GoodsTotalInventory = s.GoodsTotalInventory,
|
||
GoodsSalesInitial = s.GoodsSalesInitial,
|
||
GoodsSalesActual = s.GoodsSalesActual,
|
||
GoodsDetails = s.GoodsDetails,
|
||
GoodsDeductStockType = s.GoodsDeductStockType,
|
||
GoodsIsPointsGift = s.GoodsIsPointsGift,
|
||
GoodsIsPointsDiscount = s.GoodsIsPointsDiscount,
|
||
GoodsIsAlonePointsDiscount = s.GoodsIsAlonePointsDiscount,
|
||
GoodsPointsDiscountConfig = s.GoodsPointsDiscountConfig,
|
||
GoodsIsEnableGrade = s.GoodsIsEnableGrade,
|
||
GoodsIsAloneGrade = s.GoodsIsAloneGrade,
|
||
GoodsAloneGradeEquity = s.GoodsAloneGradeEquity,
|
||
GoodsShelfStatus = s.GoodsShelfStatus,
|
||
GoodsSort = s.GoodsSort,
|
||
GoodsWeight = s.GoodsWeight,
|
||
CreateTime = s.Create_time.ToString("yyyy-MM-dd HH:mm")
|
||
});
|
||
|
||
|
||
var res = await query.ToPageAsync(parm);
|
||
|
||
var shopGoodsCategoryDict = (await _ShopGoodsCategoryRepository.GetListAsync()).ToDictionary(s => s.ShopGoodsCategoryGuid);
|
||
foreach (var item in res.Result)
|
||
{
|
||
if (!shopGoodsCategoryDict.TryGetValue(item.ShopGoodsCategoryGuid, out var category))
|
||
{
|
||
throw new Exception("商品类目不存在");
|
||
}
|
||
|
||
var categoryNameList = new List<string>();
|
||
var ancestorGuidsArr = Tools.SpitLongArrary(category.ShopGoodsCategoryAncestralGuid);
|
||
foreach (var ancestorGuid in ancestorGuidsArr)
|
||
{
|
||
if (ancestorGuid == 0) continue;
|
||
if (shopGoodsCategoryDict.TryGetValue(ancestorGuid, out var ancestor))
|
||
{
|
||
categoryNameList.Add(ancestor.ShopGoodsCategoryName);
|
||
}
|
||
}
|
||
|
||
categoryNameList.Add(category.ShopGoodsCategoryName);
|
||
|
||
item.GoodsCategoryName = string.Join("/", categoryNameList);
|
||
}
|
||
|
||
return res;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 查询全部商品列表
|
||
/// </summary>
|
||
public async Task<List<AllGoodsVo>> GetAllGoodsList(GoodsQueryDto parm)
|
||
{
|
||
|
||
//开始拼装查询条件d
|
||
var predicate = Expressionable.Create<Goods>();
|
||
|
||
predicate = predicate.AndIF(parm.ShopGuid != 0, s => s.ShopGuid == parm.ShopGuid);
|
||
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));
|
||
var query = _GoodsRepository
|
||
.Queryable()
|
||
.Where(predicate.ToExpression())
|
||
.OrderBy(s => s.GoodsSort, OrderByType.Asc)
|
||
.Select(s => new AllGoodsVo
|
||
{
|
||
GoodsId = s.GoodsId,
|
||
GoodsGuid = s.GoodsGuid,
|
||
GoodsName = s.GoodsName,
|
||
GoodsPicture = s.GoodsPicture,
|
||
GoodsPriceLowest = s.GoodsPriceLowest,
|
||
GoodsDashedPriceLowest = s.GoodsDashedPriceLowest,
|
||
GoodsShelfStatus = s.GoodsShelfStatus,
|
||
GoodsSort = s.GoodsSort,
|
||
GoodsTotalInventory = s.GoodsTotalInventory,
|
||
});
|
||
|
||
|
||
return await query.ToListAsync();
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 添加或修改商品
|
||
/// </summary>
|
||
public async Task<string> AddOrUpdateGoods(Goods model)
|
||
{
|
||
try
|
||
{
|
||
if (model.GoodsId != 0)
|
||
{
|
||
await UseTranAsync(async () =>
|
||
{
|
||
await HandleBeforeUpdate(model);
|
||
var response = await _GoodsRepository.UpdateAsync(model);
|
||
});
|
||
return "修改成功!";
|
||
}
|
||
else
|
||
{
|
||
await UseTranAsync(async () =>
|
||
{
|
||
await HandleBeforeAdd(model);
|
||
var response = await _GoodsRepository.InsertReturnSnowflakeIdAsync(model);
|
||
model.GoodsGuid = response;
|
||
await HandleAfterAdd(model);
|
||
});
|
||
|
||
return "添加成功!";
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
|
||
throw;
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 上下架商品
|
||
/// </summary>
|
||
public async Task<string> ShelfGoods(int id, int status)
|
||
{
|
||
try
|
||
{
|
||
var res = await _GoodsRepository.GetFirstAsync(s => s.GoodsId == id);
|
||
var shelfStatus = res.GoodsShelfStatus;
|
||
|
||
if (shelfStatus == status)
|
||
{
|
||
var errorRes = $"商品:【{res.GoodsName}】<span style='color:red'>已{(status == 1 ? "上" : "下")}架,请勿重复{(status == 1 ? "上" : "下")}架</span><br>";
|
||
return errorRes;
|
||
}
|
||
|
||
await UseTranAsync(async () =>
|
||
{
|
||
await _GoodsRepository.UpdateAsync(f => new Goods { GoodsShelfStatus = status, Update_time = DateTime.Now }, s => s.GoodsId == id);
|
||
});
|
||
|
||
var addStr = $"商品:【{res.GoodsName}】<span style='color:#27af49'>{(status == 1 ? "上" : "下")}架成功!</span><br>";
|
||
return addStr;
|
||
}
|
||
catch (Exception)
|
||
{
|
||
throw;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#region Excel处理
|
||
/// <summary>
|
||
/// 数据导入处理
|
||
/// </summary>
|
||
public async Task<GoodsVo> HandleImportData(GoodsVo Goods, long userId, int index)
|
||
{
|
||
// 非空判断
|
||
if (string.IsNullOrEmpty(Goods.ShopName)) throw new CustomException("店铺名称不能为空");
|
||
if (string.IsNullOrEmpty(Goods.GoodsCategoryName)) throw new CustomException("商品类目不能为空");
|
||
if (string.IsNullOrEmpty(Goods.GoodsName)) throw new CustomException("商品名称不能为空");
|
||
if (string.IsNullOrEmpty(Goods.GoodsPicture)) throw new CustomException("商品图片不能为空");
|
||
if (Goods.GoodsPriceLowest == 0) throw new CustomException("商品价格不能为空");
|
||
if (Goods.GoodsTotalInventory == 0) throw new CustomException("库存总量不能为空");
|
||
|
||
|
||
// 店铺
|
||
var shop = await _ShopRepository.GetFirstAsync(s => s.ShopName == Goods.ShopName);
|
||
if (shop == null) throw new CustomException($"店铺【{Goods.ShopName}】不存在");
|
||
if (userId != 1)
|
||
{
|
||
if (shop.ShopUserId != userId) throw new CustomException($"店铺【{Goods.ShopName}】不是您的店铺");
|
||
}
|
||
Goods.ShopGuid = shop.ShopGuid;
|
||
|
||
|
||
// 商品类目
|
||
// 拆分上级类目和当前类目(手机/xxxx系列)
|
||
var nameArr = Goods.GoodsCategoryName.Split('/');
|
||
if (nameArr.Length == 0 || nameArr.Length >= 3) throw new CustomException($"商品类目【{Goods.GoodsCategoryName}】格式不正确,参考(手机/xxxx系列 或者 手机)");
|
||
|
||
if (nameArr.Length != 1)
|
||
{
|
||
// 找出上级类目
|
||
var parentGoodsCategory = await _ShopGoodsCategoryRepository.GetFirstAsync(
|
||
s => s.ShopGoodsCategoryName == nameArr.First() &&
|
||
s.ShopGuid == Goods.ShopGuid
|
||
);
|
||
if (parentGoodsCategory == null) throw new CustomException($"上级商品类目【{nameArr.First()}】不存在");
|
||
|
||
// 找出当前类目
|
||
var currentGoodsCategory = await _ShopGoodsCategoryRepository.GetFirstAsync(
|
||
s => s.ShopGoodsCategoryName == nameArr.Last() &&
|
||
s.ShopGuid == Goods.ShopGuid &&
|
||
s.ShopGoodsCategoryParentGuid == parentGoodsCategory.ShopGoodsCategoryGuid
|
||
);
|
||
if (currentGoodsCategory == null) throw new CustomException($"当前商品类目【{nameArr.First()}】不存在");
|
||
Goods.ShopGoodsCategoryGuid = currentGoodsCategory.ShopGoodsCategoryGuid;
|
||
}
|
||
else
|
||
{
|
||
// 找出当前类目
|
||
var currentGoodsCategory = await _ShopGoodsCategoryRepository.GetFirstAsync(
|
||
s => s.ShopGoodsCategoryName == Goods.GoodsCategoryName &&
|
||
s.ShopGuid == Goods.ShopGuid
|
||
);
|
||
if (currentGoodsCategory == null) throw new CustomException($"当前商品类目【{Goods.GoodsCategoryName}】不存在");
|
||
Goods.ShopGoodsCategoryGuid = currentGoodsCategory.ShopGoodsCategoryGuid;
|
||
}
|
||
|
||
|
||
// 配送模板
|
||
var delivery = await _DeliveryRepository.GetFirstAsync(s => s.DeliveryName == "全国包邮" && s.ShopGuid == Goods.ShopGuid);
|
||
Goods.DeliveryGuid = delivery.DeliveryGuid;
|
||
|
||
|
||
// 服务与承诺
|
||
var service = await _GoodsServicesRepository.GetFirstAsync(s => s.GoodsServicesName == "七天无理由退货" && s.ShopGuid == Goods.ShopGuid);
|
||
Goods.GoodsServicesIds = service.GoodsServicesId.ToString().Select(c => c.ToString()).ToList();
|
||
|
||
|
||
// 状态
|
||
if (!string.IsNullOrEmpty(Goods.GoodsShelfStatusName))
|
||
{
|
||
if (Goods.GoodsShelfStatusName == "上架") Goods.GoodsShelfStatus = 1;
|
||
if (Goods.GoodsShelfStatusName == "下架") Goods.GoodsShelfStatus = 2;
|
||
}
|
||
else
|
||
{
|
||
Goods.GoodsShelfStatus = 1;
|
||
}
|
||
|
||
// 排序
|
||
if (Goods.GoodsSort == 0)
|
||
{
|
||
Goods.GoodsSort = 100;
|
||
}
|
||
|
||
Goods.GoodsSpecType = 1;
|
||
Goods.GoodsDeductStockType = 1;
|
||
Goods.GoodsIsPointsGift = 0;
|
||
Goods.GoodsIsPointsDiscount = 0;
|
||
Goods.GoodsIsAlonePointsDiscount = 0;
|
||
Goods.GoodsIsEnableGrade = 1;
|
||
|
||
return Goods;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// Excel导入
|
||
/// </summary>
|
||
public async Task<string> ImportExcel(GoodsVo GoodsVo, int index, bool isUpdateSupport, LoginUser user)
|
||
{
|
||
try
|
||
{
|
||
var goodsVo = await HandleImportData(GoodsVo, user.UserId, index);
|
||
var goodsData = new Goods
|
||
{
|
||
GoodsId = goodsVo.GoodsId,
|
||
GoodsGuid = goodsVo.GoodsGuid,
|
||
ShopGuid = goodsVo.ShopGuid,
|
||
ShopGoodsCategoryGuid = goodsVo.ShopGoodsCategoryGuid,
|
||
GoodsSkuIds = goodsVo.GoodsSkuIds,
|
||
DeliveryGuid = goodsVo.DeliveryGuid,
|
||
GoodsName = goodsVo.GoodsName,
|
||
GoodsCoding = goodsVo.GoodsCoding,
|
||
GoodsMainImageVideo = goodsVo.GoodsMainImageVideo,
|
||
GoodsVideoCover = goodsVo.GoodsVideoCover,
|
||
GoodsPicture = goodsVo.GoodsPicture,
|
||
GoodsSellingPoint = goodsVo.GoodsSellingPoint,
|
||
GoodsSpecType = 1,
|
||
GoodsPriceLowest = goodsVo.GoodsPriceLowest,
|
||
GoodsPriceHighest = goodsVo.GoodsPriceHighest,
|
||
GoodsDashedPriceLowest = goodsVo.GoodsDashedPriceLowest,
|
||
GoodsDashedPriceHighest = goodsVo.GoodsDashedPriceHighest,
|
||
GoodsTotalInventory = goodsVo.GoodsTotalInventory,
|
||
GoodsSalesInitial = goodsVo.GoodsSalesInitial,
|
||
GoodsSalesActual = goodsVo.GoodsSalesActual,
|
||
GoodsDetails = goodsVo.GoodsDetails,
|
||
GoodsDeductStockType = goodsVo.GoodsDeductStockType,
|
||
GoodsIsPointsGift = goodsVo.GoodsIsPointsGift,
|
||
GoodsIsPointsDiscount = goodsVo.GoodsIsPointsDiscount,
|
||
GoodsIsAlonePointsDiscount = goodsVo.GoodsIsAlonePointsDiscount,
|
||
GoodsPointsDiscountConfig = goodsVo.GoodsPointsDiscountConfig,
|
||
GoodsIsEnableGrade = goodsVo.GoodsIsEnableGrade,
|
||
GoodsIsAloneGrade = goodsVo.GoodsIsAloneGrade,
|
||
GoodsAloneGradeEquity = goodsVo.GoodsAloneGradeEquity,
|
||
GoodsShelfStatus = goodsVo.GoodsShelfStatus,
|
||
GoodsSort = goodsVo.GoodsSort,
|
||
GoodsServicesIds = string.Join(",", goodsVo.GoodsServicesIds)
|
||
};
|
||
|
||
|
||
// 空值判断
|
||
// if (Goods.GoodsId == null) throw new CustomException("商品不能为空");
|
||
|
||
if (isUpdateSupport)
|
||
{
|
||
// 判断唯一值
|
||
var model = await GetFirstAsync(s => s.GoodsId == goodsData.GoodsId);
|
||
|
||
// 如果为空就新增数据
|
||
if (model == null)
|
||
{
|
||
// 开启事务
|
||
var res = await UseTranAsync(async () =>
|
||
{
|
||
var addRes = await AddOrUpdateGoods(goodsData);
|
||
});
|
||
var addStr = $"第 {index} 行 => 商品:【{goodsData.GoodsName}】<span style='color:#27af49'>新增成功!</span><br>";
|
||
return addStr;
|
||
}
|
||
else
|
||
{
|
||
// 如果有数据就进行修改
|
||
// 开启事务
|
||
await UseTranAsync(async () =>
|
||
{
|
||
goodsData.GoodsId = model.GoodsId;
|
||
goodsData.GoodsGuid = model.GoodsGuid;
|
||
goodsData.Update_by = user.UserName;
|
||
goodsData.Update_time = DateTime.Now;
|
||
var editRes = await AddOrUpdateGoods(goodsData);
|
||
});
|
||
var editStr = $"第 {index} 行 => 商品:【{goodsData.GoodsName}】<span style='color:#e6a23c'>更新成功!</span><br>";
|
||
return editStr;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 开启事务
|
||
var res = await UseTranAsync(async () =>
|
||
{
|
||
var addRes = await AddOrUpdateGoods(goodsData);
|
||
});
|
||
//Console.WriteLine(res.IsSuccess);
|
||
var addStr = $"第 {index} 行 => 商品:【{goodsData.GoodsName}】<span style='color:#27af49'>新增成功!</span><br>";
|
||
return addStr;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
var errorRes = $"第 {index} 行 => 商品:【{GoodsVo.GoodsName}】<span style='color:red'>导入失败!{ex.Message}</span><br>";
|
||
return errorRes;
|
||
throw;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// Excel数据导出处理
|
||
/// </summary>
|
||
public async Task<List<GoodsVo>> HandleExportData(List<GoodsVo> data)
|
||
{
|
||
foreach (var item in data)
|
||
{
|
||
if (item.GoodsShelfStatus == 1) item.GoodsShelfStatusName = "上架";
|
||
if (item.GoodsShelfStatus == 2) item.GoodsShelfStatusName = "下架";
|
||
}
|
||
return data;
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
|
||
|
||
#region 商品格式处理
|
||
|
||
|
||
#region 添加处理
|
||
|
||
/// <summary>
|
||
/// 商品添加前处理处理
|
||
/// </summary>
|
||
/// <param name="model">商品Model</param>
|
||
/// <returns></returns>
|
||
public async Task<Goods> HandleBeforeAdd(Goods model)
|
||
{
|
||
// 单规格(最高价格 最高划线价格 = 最低价格 最低划线价格)
|
||
model = HandleSingleSpec(model);
|
||
|
||
// 计算价格和库存总量
|
||
model = HandlMultipleSpecCompute(model);
|
||
|
||
return model;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 商品添加后处理
|
||
/// </summary>
|
||
/// <param name="model">商品Model</param>
|
||
/// <returns></returns>
|
||
public async Task HandleAfterAdd(Goods model)
|
||
{
|
||
// 服务与承诺处理
|
||
await HandleAddGoodsService(model);
|
||
|
||
// 多规格处理
|
||
await HandleAddMultiSpec(model);
|
||
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 添加服务与承诺处理
|
||
/// </summary>
|
||
/// <param name="model">商品Model</param>
|
||
/// <returns></returns>
|
||
public async Task HandleAddGoodsService(Goods model)
|
||
{
|
||
// 服务与承诺
|
||
if (!string.IsNullOrEmpty(model.GoodsServicesIds))
|
||
{
|
||
var servicesIds = model.GoodsServicesIds.Split(',');
|
||
var servicesList = new List<GoodsServicesRel>();
|
||
foreach (var id in servicesIds)
|
||
{
|
||
var service = new GoodsServicesRel
|
||
{
|
||
ShopGuid = model.ShopGuid,
|
||
GoodsGuid = model.GoodsGuid,
|
||
ServiceId = Convert.ToInt32(id)
|
||
};
|
||
servicesList.Add(service);
|
||
}
|
||
await _GoodsServicesRelIService.InsertGoodsServicesRelAsync(servicesList);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 添加商品多规格处理
|
||
/// </summary>
|
||
/// <param name="model">商品Model</param>
|
||
/// <returns></returns>
|
||
public async Task HandleAddMultiSpec(Goods model)
|
||
{
|
||
// 多规格
|
||
if (model.GoodsSpecType == 2)
|
||
{
|
||
// 添加规格组和规格值
|
||
var index = 1;
|
||
foreach (var item in model.GoodsSpecList)
|
||
{
|
||
var spec = new Spec
|
||
{
|
||
SpecName = item.SpecName,
|
||
Level = index
|
||
};
|
||
var specId = await _SepcIService.InsertReturnIdentityAsync(spec);
|
||
foreach (var i in item.Props)
|
||
{
|
||
var specValue = new SpecValue
|
||
{
|
||
SpecId = specId,
|
||
SpecValueName = i.SpecValueName,
|
||
};
|
||
var specValueId = await _SpecValueIService.InsertReturnIdentityAsync(specValue);
|
||
|
||
// 添加商品与规格值关系
|
||
var rel = new GoodsSpecRel
|
||
{
|
||
GoodsGuid = model.GoodsGuid,
|
||
SpecId = specId,
|
||
SpecValueId = specValueId,
|
||
};
|
||
await _GoodsSpecRelService.InsertReturnIdentityAsync(rel);
|
||
}
|
||
index++;
|
||
}
|
||
|
||
|
||
// Sku处理
|
||
var specList = await _GoodsSpecRelService.GetListAsync(s => s.GoodsGuid == model.GoodsGuid);
|
||
var firstSpec = new Spec();
|
||
var secondSpec = new Spec();
|
||
var thirdSpec = new Spec();
|
||
foreach (var item in specList)
|
||
{
|
||
var spec = await _SepcIService.GetFirstAsync(s => s.SpecId == item.SpecId);
|
||
if (spec == null) continue;
|
||
|
||
if (spec.Level == 1)
|
||
{
|
||
firstSpec = spec;
|
||
}
|
||
if (spec.Level == 2)
|
||
{
|
||
secondSpec = spec;
|
||
}
|
||
if (spec.Level == 3)
|
||
{
|
||
thirdSpec = spec;
|
||
}
|
||
}
|
||
|
||
// 找出改规格组的所有规格值
|
||
foreach (var sku in model.SkuList)
|
||
{
|
||
var specValueId = await GetSpecValueId(sku, firstSpec, 1);
|
||
var specSecondValueId = await GetSpecValueId(sku, secondSpec, 2);
|
||
var specThirdValueId = await GetSpecValueId(sku, thirdSpec, 3);
|
||
|
||
var skuData = new GoodsSku
|
||
{
|
||
GoodsGuid = model.GoodsGuid,
|
||
SpecValueId = specValueId,
|
||
SpecSecondValueId = specSecondValueId,
|
||
SpecThirdValueId = specThirdValueId,
|
||
GoodsSkuImg = sku.GoodsSkuImg,
|
||
GoodsSkuSkuCode = sku.GoodsSkuSkuCode,
|
||
GoodsSkuPrice = sku.GoodsSkuPrice,
|
||
GoodsSkuLinePrice = sku.GoodsSkuLinePrice,
|
||
GoodsSkuStockNum = sku.GoodsSkuStockNum,
|
||
GoodsSkuWeight = sku.GoodsSkuWeight,
|
||
};
|
||
await _GoodsSkuService.InsertAsync(skuData);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
|
||
#region 修改处理
|
||
|
||
/// <summary>
|
||
/// 商品修改前处理
|
||
/// </summary>
|
||
/// <param name="model">商品Model</param>
|
||
/// <returns></returns>
|
||
public async Task<Goods> HandleBeforeUpdate(Goods model)
|
||
{
|
||
if (model.GoodsSpecType == 1)
|
||
{
|
||
// 单规格(最高价格 最高划线价格 = 最低价格 最低划线价格)
|
||
model = HandleSingleSpec(model);
|
||
}
|
||
|
||
if (model.GoodsSpecType == 2)
|
||
{
|
||
// 如果是下架状态就修改规格
|
||
if (model.GoodsShelfStatus == 2)
|
||
{
|
||
// 删除所有关于该商品的规格
|
||
var specList = await _GoodsSpecRelService.GetListAsync(s => s.GoodsGuid == model.GoodsGuid);
|
||
foreach (var item in specList)
|
||
{
|
||
await _SepcIService.DeleteAsync(s => s.SpecId == item.SpecId);
|
||
await _SpecValueIService.DeleteAsync(s => s.SpecId == item.SpecId);
|
||
}
|
||
|
||
await _GoodsSpecRelService.DeleteAsync(s => s.GoodsGuid == model.GoodsGuid);
|
||
await _GoodsSkuService.DeleteAsync(s => s.GoodsGuid == model.GoodsGuid);
|
||
// 再重新添加该商品的规格
|
||
await HandleAddMultiSpec(model);
|
||
}
|
||
|
||
// 计算价格和库存总量
|
||
model = HandlMultipleSpecCompute(model);
|
||
}
|
||
|
||
// 删除所有关于该商品的服务与承诺
|
||
await _GoodsServicesRelIService.DeleteAsync(s => s.GoodsGuid == model.GoodsGuid);
|
||
// 再重新添加该商品的服务与承诺
|
||
await HandleAddGoodsService(model);
|
||
|
||
return model;
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
#region 公共方法
|
||
|
||
/// <summary>
|
||
/// 商品单规格处理
|
||
/// </summary>
|
||
/// <param name="model">商品Model</param>
|
||
/// <returns></returns>
|
||
public Goods HandleSingleSpec(Goods model)
|
||
{
|
||
// 单规格
|
||
if (model.GoodsSpecType == 1)
|
||
{
|
||
// 价格
|
||
model.GoodsPriceHighest = model.GoodsPriceLowest;
|
||
|
||
// 划线价格
|
||
model.GoodsDashedPriceHighest = model.GoodsDashedPriceLowest;
|
||
}
|
||
|
||
return model;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 商品计算多规格处理
|
||
/// </summary>
|
||
/// <param name="model">商品Model</param>
|
||
/// <returns></returns>
|
||
public Goods HandlMultipleSpecCompute(Goods model)
|
||
{
|
||
// 单规格
|
||
if (model.GoodsSpecType == 2)
|
||
{
|
||
decimal lowestPrice = decimal.MaxValue;
|
||
decimal highestPrice = decimal.MinValue;
|
||
decimal lowestDashedPrice = decimal.MaxValue;
|
||
decimal highestDashedPrice = decimal.MinValue;
|
||
int totalInventory = 0;
|
||
|
||
foreach (var sku in model.SkuList)
|
||
{
|
||
if (sku.GoodsSkuPrice < lowestPrice)
|
||
{
|
||
lowestPrice = sku.GoodsSkuPrice;
|
||
}
|
||
|
||
if (sku.GoodsSkuPrice > highestPrice)
|
||
{
|
||
highestPrice = sku.GoodsSkuPrice;
|
||
}
|
||
|
||
if (sku.GoodsSkuLinePrice < lowestDashedPrice)
|
||
{
|
||
lowestDashedPrice = sku.GoodsSkuLinePrice;
|
||
}
|
||
|
||
if (sku.GoodsSkuLinePrice > highestDashedPrice)
|
||
{
|
||
highestDashedPrice = sku.GoodsSkuLinePrice;
|
||
}
|
||
|
||
totalInventory += sku.GoodsSkuStockNum;
|
||
}
|
||
|
||
model.GoodsPriceLowest = lowestPrice;
|
||
model.GoodsPriceHighest = highestPrice;
|
||
model.GoodsDashedPriceLowest = lowestDashedPrice;
|
||
model.GoodsDashedPriceHighest = highestDashedPrice;
|
||
model.GoodsTotalInventory = totalInventory;
|
||
}
|
||
|
||
return model;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 找出改规格组的所有规格值
|
||
/// </summary>
|
||
/// <param name="sku"></param>
|
||
/// <param name="spec"></param>
|
||
/// <param name="level"></param>
|
||
/// <returns></returns>
|
||
public async Task<int> GetSpecValueId(SkuDto sku, Spec spec, int level)
|
||
{
|
||
if (spec == null)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
var specValueName = level switch
|
||
{
|
||
1 => sku.SpecValue,
|
||
2 => sku.SpecSecondValue,
|
||
3 => sku.SpecThirdValue,
|
||
_ => null
|
||
};
|
||
|
||
if (specValueName != null)
|
||
{
|
||
var specValue = await _SpecValueIService.GetFirstAsync(s => s.SpecId == spec.SpecId && s.SpecValueName == specValueName);
|
||
if (specValue != null)
|
||
{
|
||
return specValue.SpecValueId;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
}
|
||
}
|