/*********************************************************************** * Project: baifenBinfa * ProjectName: 百分兵法管理系统 * Web: http://chuanyin.com * Author: * Email: * CreateTime: 202403/02 * Description: 暂无 ***********************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CoreCms.Net.Auth.HttpContextUser; using CoreCms.Net.Configuration; using CoreCms.Net.IRepository; using CoreCms.Net.IRepository.UnitOfWork; using CoreCms.Net.IServices; using CoreCms.Net.IServices.baifenbingfa; using CoreCms.Net.Loging; using CoreCms.Net.Model.Entities; using CoreCms.Net.Model.Entities.Expression; using CoreCms.Net.Model.ViewModels.DTO; using CoreCms.Net.Model.ViewModels.UI; using CoreCms.Net.Utility.Extensions; using CoreCms.Net.Utility.Helper; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SqlSugar; namespace CoreCms.Net.Services { /// /// 购物车表 接口实现 /// public class CoreCmsCartServices : BaseServices, ICoreCmsCartServices { private readonly ICoreCmsCartRepository _dal; private readonly ICoreCmsGoodsCollectionServices _goodsCollectionServices; private readonly ICoreCmsPinTuanRuleServices _pinTuanRuleServices; private readonly ICoreCmsShipServices _shipServices; private readonly ICoreCmsPromotionServices _promotionServices; private readonly ICoreCmsPromotionConditionServices _promotionConditionServices; private readonly ICoreCmsPromotionResultServices _promotionResultServices; private readonly ICoreCmsCouponServices _couponServices; private readonly ICoreCmsUserServices _userServices; private readonly ICoreCmsSettingServices _settingServices; private readonly IServiceProvider _serviceProvider; private readonly ICoreCmsProductsServices _productsServices; private readonly ICoreCmsPinTuanGoodsServices _pinTuanGoodsServices; private readonly ICoreCmsPinTuanRecordServices _pinTuanRecordServices; private readonly ICoreCmsGoodsServices _goodsServices; private readonly ICoreCmsGoodsCategoryServices _goodsCategoryServices; private readonly ICoreCmsSolitaireServices _solitaireServices; private readonly ICoreCmsUserShipServices _userShipServices; private readonly ICoreCmsStoreServices _storeServices; private readonly IBfbfComAPIService _bfbfComAPIService; private readonly IHttpContextUser _user; public CoreCmsCartServices( ICoreCmsCartRepository dal , IServiceProvider serviceProvider , ICoreCmsGoodsCollectionServices goodsCollectionServices , ICoreCmsPinTuanRuleServices pinTuanRuleServices , ICoreCmsShipServices shipServices , ICoreCmsPromotionServices promotionServices , ICoreCmsCouponServices couponServices , ICoreCmsUserServices userServices , ICoreCmsSettingServices settingServices , ICoreCmsProductsServices productsServices , ICoreCmsPinTuanGoodsServices pinTuanGoodsServices , IBfbfComAPIService bfbfComAPIService ,ICoreCmsPromotionConditionServices promotionConditionServices , ICoreCmsGoodsServices goodsServices , ICoreCmsGoodsCategoryServices goodsCategoryServices , ICoreCmsPromotionResultServices promotionResultServices , ICoreCmsPinTuanRecordServices pinTuanRecordServices , ICoreCmsSolitaireServices solitaireServices , ICoreCmsUserShipServices userShipServices , ICoreCmsStoreServices storeServices ,IHttpContextUser user) { this._dal = dal; base.BaseDal = dal; _serviceProvider = serviceProvider; _goodsCollectionServices = goodsCollectionServices; _pinTuanRuleServices = pinTuanRuleServices; _shipServices = shipServices; _promotionServices = promotionServices; _couponServices = couponServices; _userServices = userServices; _settingServices = settingServices; _productsServices = productsServices; _pinTuanGoodsServices = pinTuanGoodsServices; _promotionConditionServices = promotionConditionServices; _goodsServices = goodsServices; _goodsCategoryServices = goodsCategoryServices; _promotionResultServices = promotionResultServices; _pinTuanRecordServices = pinTuanRecordServices; _solitaireServices = solitaireServices; _userShipServices = userShipServices; _storeServices = storeServices; _bfbfComAPIService = bfbfComAPIService; _user = user; } #region 设置购物车商品数量==================================================== /// /// 设置购物车商品数量 /// /// /// /// /// /// /// /// public async Task SetCartNum(int id, int nums, int userId, int numType, int type = 1) { var jm = new WebApiCallBack(); if (nums <= 0) { jm.msg = "商品数量必须为正整数"; return jm; } if (userId == 0) { jm.msg = "用户信息获取失败"; return jm; } if (id == 0) { jm.msg = "请提交要设置的信息"; return jm; } var cartModel = await _dal.QueryByClauseAsync(p => p.userId == userId && p.productId == id); if (cartModel == null) { jm.msg = "获取购物车数据失败"; return jm; } var outData = await Add(userId, cartModel.productId, nums, numType, type,isCustomizable:cartModel.isCustomizable); jm.status = outData.status; jm.msg = jm.status ? GlobalConstVars.SetDataSuccess : GlobalConstVars.SetDataFailure; jm.otherData = outData; return jm; } #endregion #region 重写删除指定ID集合的数据(批量删除) /// /// 重写删除指定ID集合的数据(批量删除) /// /// /// /// public async Task DeleteByIdsAsync(int id, int userId) { var jm = new WebApiCallBack(); if (userId == 0) { jm.msg = "用户信息获取失败"; return jm; } if (id <= 0) { jm.msg = "请提交要删除的货品"; return jm; } jm.status = await _dal.DeleteAsync(p => p.id == id && p.userId == userId); jm.msg = jm.status ? "删除成功" : "删除失败"; return jm; } #endregion #region 添加单个货品到购物车 /// /// 添加单个货品到购物车 /// /// 用户id /// 货品序号 /// 数量 /// 数量类型/1是直接增加/2是赋值 /// 1普通购物还是2团购秒杀3团购模式4秒杀模式6砍价模式7赠品 /// 关联对象类型 /// 关联对象类型 /// public async Task Add(int userId, int productId, int nums, int numType, int cartTypes = 1, int objectId = 0,bool isCustomizable = false) { var jm = new WebApiCallBack(); using var container = _serviceProvider.CreateScope(); var orderServices = container.ServiceProvider.GetService(); var productsServices = container.ServiceProvider.GetService(); var goodsServices = container.ServiceProvider.GetService(); //获取数据 if (nums <= 0) { jm.msg = "请选择货品数量"; return jm; } if (productId <= 0) { jm.msg = "请选择货品"; return jm; } //获取货品信息 var products = await productsServices.GetProductInfo(productId, false, userId); //第二个参数是不算促销信息,否则促销信息就算重复了 if (products == null) { jm.msg = "获取货品信息失败"; return jm; } if(isCustomizable==true&&products.isCustomizable!=true) { jm.msg = "该货物不支持定制"; return jm; } //判断是否下架 var isMarketable = await productsServices.GetShelfStatus(productId); if (isMarketable == false) { jm.msg = "货品已下架"; return jm; } //剩余库存可购判定 var canBuyNum = products.stock; //获取是否存在记录 var catInfo = await _dal.QueryByClauseAsync(p => p.userId == userId && p.productId == productId && p.objectId == objectId); //根据购物车存储类型匹配数据 switch (cartTypes) { case (int)GlobalEnumVars.OrderType.Common: break; case (int)GlobalEnumVars.OrderType.PinTuan: numType = (int)GlobalEnumVars.OrderType.PinTuan; //拼团模式去判断是否开启拼团,是否存在 var callBack = await AddCartHavePinTuan(products.id, userId, nums, objectId); if (callBack.status == false) { return callBack; } //此人的购物车中的所有购物车拼团商品都删掉,因为立即购买也是要加入购物车的,所以需要清空之前历史的加入过购物车的商品 await _dal.DeleteAsync(p => p.type == (int)GlobalEnumVars.OrderType.PinTuan && p.userId == userId); catInfo = null; break; case (int)GlobalEnumVars.OrderType.Group or (int)GlobalEnumVars.OrderType.Seckill: //标准模式不需要做什么判断 //判断商品是否做团购秒杀 if (goodsServices.IsInGroup((int)products.goodsId, out var promotionsModel, objectId) == true) { jm.msg = "进入判断商品是否做团购秒杀"; var typeIds = new int[] { (int)GlobalEnumVars.OrderType.Group, (int)GlobalEnumVars.OrderType.Seckill }; //此人的购物车中的所有购物车拼团商品都删掉,因为立即购买也是要加入购物车的,所以需要清空之前历史的加入过购物车的商品 await _dal.DeleteAsync(p => typeIds.Contains(p.type) && p.productId == products.id && p.userId == userId); catInfo = null; var checkOrder = orderServices.FindLimitOrderByGoodId(products.goodsId, userId, promotionsModel.startTime, promotionsModel.endTime, cartTypes); if (promotionsModel.maxGoodsNums > 0) { if (checkOrder.TotalOrders + nums > promotionsModel.maxGoodsNums) { jm.data = 15610; jm.msg = GlobalErrorCodeVars.Code15610; return jm; } } if (promotionsModel.maxNums > 0) { if (checkOrder.TotalUserOrders + nums > promotionsModel.maxNums) { jm.data = 15611; ; jm.msg = GlobalErrorCodeVars.Code15611; return jm; } } } break; case (int)GlobalEnumVars.OrderType.Bargain: break; case (int)GlobalEnumVars.OrderType.Solitaire: break; default: jm.data = 10000; return jm; } if (catInfo == null) { if (nums > canBuyNum) { jm.msg = "库存不足"; return jm; } catInfo = new CoreCmsCart { userId = userId, productId = productId, nums = nums, type = cartTypes, objectId = objectId, //支持定制 isCustomizable= isCustomizable, }; var outId = await _dal.InsertAsync(catInfo); jm.status = outId > 0; jm.data = outId; } else { if (numType == 1) { catInfo.nums = nums + catInfo.nums; if (catInfo.nums > canBuyNum) { jm.msg = "库存不足"; return jm; } } else { catInfo.nums = nums; } jm.status = await _dal.UpdateAsync(catInfo); jm.data = catInfo.id; } jm.msg = jm.status ? "添加成功" : "添加失败"; return jm; } #endregion #region 在加入购物车的时候,判断是否有参加拼团的商品 /// /// 在加入购物车的时候,判断是否有参加拼团的商品 /// /// /// 用户序列 /// 加入购物车数量 /// 规则序列 /// 货品是否定制 public async Task AddCartHavePinTuan(int productId, int userId = 0, int nums = 1, int ruleId = 0) { var jm = new WebApiCallBack(); var products = await _productsServices.QueryByIdAsync(productId); if (products == null) { jm.data = 10000; jm.msg = GlobalErrorCodeVars.Code10000; return jm; } var pinTuanGoods = await _pinTuanGoodsServices.QueryByClauseAsync(p => p.goodsId == products.goodsId && p.ruleId == ruleId); if (pinTuanGoods == null) { jm.data = 10000; jm.msg = GlobalErrorCodeVars.Code10000; return jm; } var pinTuanRule = await _pinTuanRuleServices.QueryByClauseAsync(p => p.id == pinTuanGoods.ruleId && p.isStatusOpen == true); if (pinTuanRule == null) { jm.data = 10000; jm.msg = GlobalErrorCodeVars.Code10000; return jm; } if (pinTuanRule.startTime > DateTime.Now) { jm.data = 15601; jm.msg = GlobalErrorCodeVars.Code15601; return jm; } if (pinTuanRule.endTime < DateTime.Now) { jm.data = 15602; jm.msg = GlobalErrorCodeVars.Code15602; return jm; } //查询是否存在已经开团,并且自己是队长的拼团 var havaGroup = await _pinTuanRecordServices.ExistsAsync(p => p.userId == userId && p.goodsId == products.goodsId && p.status == (int)GlobalEnumVars.PinTuanRecordStatus.InProgress); if (havaGroup) { jm.data = 15613; //jm.msg = GlobalErrorCodeVars.Code15613; jm.msg = "您存在已开启的拼团"; return jm; } using var container = _serviceProvider.CreateScope(); var orderRepository = container.ServiceProvider.GetService(); var checkOrder = orderRepository.FindLimitOrder(products.id, userId, pinTuanRule.startTime, pinTuanRule.endTime, (int)GlobalEnumVars.OrderType.PinTuan); if (pinTuanRule.maxGoodsNums > 0) { if (checkOrder.TotalOrders + nums > pinTuanRule.maxGoodsNums) { jm.data = 15610; jm.msg = GlobalErrorCodeVars.Code15610; return jm; } } if (pinTuanRule.maxNums > 0) { if (checkOrder.TotalUserOrders > pinTuanRule.maxNums) { jm.data = 15611; jm.msg = GlobalErrorCodeVars.Code15611; return jm; } } jm.status = true; return jm; } #endregion #region 获取购物车原始列表(未核算) /// /// 获取购物车原始列表(未核算) /// /// 用户序号 /// 已选择货号 /// 购物车类型/同订单类型 /// 关联非订单类型数据序列 /// goodsId /// public async Task GetCartDtoData(int userId, int[] ids = null, int type = 1, int objectId = 0, int goodsId = 0) { var jm = new WebApiCallBack() { methodDescription = "获取购物车原始列表(未核算)" }; //强制过滤一遍,防止出现可以造假数据 await _dal.DeleteAsync(p => p.userId == userId && p.nums <= 0); using var container = _serviceProvider.CreateScope(); var productsService = container.ServiceProvider.GetService(); var goodsServices = container.ServiceProvider.GetService(); List carts; if (ids != null && ids.Any()) { carts = await _dal.QueryListByClauseAsync(p => p.userId == userId && p.type == type && ids.Contains(p.id), p => p.id, OrderByType.Asc); } else { carts = await _dal.QueryListByClauseAsync(p => p.userId == userId && p.type == type, p => p.id, OrderByType.Asc); } if (goodsId>0) { var products = await _productsServices.GetProducts(goodsId); int[] ss = products.Select(x => x.id).ToArray(); carts = carts.Where(p => ss.Contains(p.productId)).ToList(); } var cartDto = new CartDto { userId = userId, type = type }; foreach (var item in carts) { var cartProducts = new CartProducts(); //如果没有此商品,就在购物车里删掉 var productInfo = await productsService.GetProductInfo(item.productId, false, userId); if (productInfo == null) { await _dal.DeleteAsync(item); continue; } //商品下架,就从购物车里面删除 var ps = await productsService.GetShelfStatus(item.productId); if (ps == false) { await _dal.DeleteAsync(item); continue; } //商品金额设置为0,就从购物车里面删除 if (productInfo.price <= 0) { await _dal.DeleteAsync(item); continue; } //获取重量 var goodsWeight = await goodsServices.GetWeight(item.productId); //开始赋值 cartProducts.id = item.id; cartProducts.userId = userId; cartProducts.productId = item.productId; cartProducts.nums = item.nums; cartProducts.type = item.type; cartProducts.weight = goodsWeight; cartProducts.products = productInfo; cartProducts.isCustomizable = item.isCustomizable; //如果传过来了购物车数据,就算指定的购物车的数据,否则,就算全部购物车的数据 if (ids != null && ids.Any() && ids.Contains(item.id)) { cartProducts.isSelect = true; } else { cartProducts.isSelect = false; } //判断商品是否已收藏 cartProducts.isCollection = await _goodsCollectionServices.Check(userId, cartProducts.products.goodsId); cartDto.list.Add(cartProducts); } //如果不同的购物车类型,可能会做一些不同的操作。 switch (type) { case (int)GlobalEnumVars.OrderType.Common: //标准模式不需要修改订单数据和商品数据 { if(await _bfbfComAPIService.IsDictionary(_user.ID)) { foreach (var item in cartDto.list) { item.products.price=item.products.distributionPrice; } } } break; case (int)GlobalEnumVars.OrderType.PinTuan: //拼团模式走拼团价,去修改商品价格 var result = _pinTuanRuleServices.PinTuanInfo(cartDto.list, objectId); if (result.status) { cartDto.list = result.data as List; } else { return result; } break; case (int)GlobalEnumVars.OrderType.Group: //团购模式不需要修改订单数据和商品数据 break; case (int)GlobalEnumVars.OrderType.Seckill: //秒杀模式不需要修改订单数据和商品数据 break; case (int)GlobalEnumVars.OrderType.Bargain: //砍价模式 break; case (int)GlobalEnumVars.OrderType.Solitaire: //接龙模式,去获取接龙商品价格。 var solitaireInfo = await _solitaireServices.SolitaireInfo(objectId, cartDto.list); if (solitaireInfo.status) { cartDto.list = solitaireInfo.data as List; } else { return solitaireInfo; } break; default: jm.msg = GlobalErrorCodeVars.Code10000; return jm; } jm.status = true; jm.data = cartDto; jm.msg = GlobalConstVars.GetDataSuccess; return jm; } #endregion #region 获取处理后的购物车信息 /// /// 获取处理后的购物车信息 /// /// 用户序列 /// 选中的购物车商品 /// 订单类型 /// 收货地址id /// 消费的积分 /// 优惠券码 /// 关联上面的是否免运费/1=快递配送(要去算运费)生成订单记录快递方式 2=门店自提(不需要计算运费)生成订单记录门店自提信息 /// 用户收货地址 /// 关联非普通订单营销类型序列 /// public async Task GetCartInfos(int userId, int[] ids, int orderType, int areaId, int point, string couponCode, int deliveryType = (int)GlobalEnumVars.OrderReceiptType.Logistics, int userShipId = 0, int objectId = 0, int goodsId = 0) { var jm = new WebApiCallBack() { methodDescription = "获取处理后的购物车信息" }; var cartDto = new CartDto(); //必须初始化 var cartDtoData = await GetCartDtoData(userId, ids, orderType, objectId, goodsId); if (!cartDtoData.status) { jm.msg = "1"; return cartDtoData; } cartDto = cartDtoData.data as CartDto; jm.msg = "2"; //算订单总金额 foreach (var item in cartDto.list) { jm.msg = "3"; //库存不足不计算金额不可以选择 if (item.nums > item.products.stock) { item.isSelect = false; } //单条商品总价 item.products.amount = Math.Round(item.nums * (decimal)item.products.price, 2); //定制商品添加定制价格 if (item.isCustomizable) //是定制商品 { item.products.amount += _bfbfComAPIService.CommandCustomizable(item.nums); item.CustomizableMoney = _bfbfComAPIService.CommandCustomizable(item.nums); } if (item.isSelect) { //算订单总商品价格 cartDto.goodsAmount = Math.Round(cartDto.goodsAmount + item.products.amount, 2); //算订单总价格 cartDto.amount = Math.Round(cartDto.amount + item.products.amount, 2); //计算总重量 cartDto.weight = Math.Round(cartDto.weight + Math.Round(item.weight * item.nums, 2), 2); } } //门店订单,强制无运费 if (deliveryType == (int)GlobalEnumVars.OrderReceiptType.SelfDelivery) { cartDto.costFreight = 0; } else if (deliveryType == (int)GlobalEnumVars.OrderReceiptType.Logistics) { // 运费判断 var blFreight = await CartFreight(cartDto, areaId); if (blFreight == false) { jm.data = cartDto; jm.msg = "运费判断"; return jm; } } else if (deliveryType == (int)GlobalEnumVars.OrderReceiptType.IntraCityService) { await CartFreightByIntraCityService(cartDto, userShipId); } //接下来算订单促销金额,有些模式不需要计算促销信息,这里就增加判断 if (orderType == (int)GlobalEnumVars.OrderType.Common) { jm.data = await _promotionServices.ToPromotion(cartDto); jm.msg = "订单促销金额计算"; } else if ((orderType == (int)GlobalEnumVars.OrderType.Group || orderType == (int)GlobalEnumVars.OrderType.Seckill) && objectId > 0) { //团购秒杀默认时间过期后,不可以下单 var dt = DateTime.Now; var promotionInfo = await _promotionServices.QueryByClauseAsync(p => p.startTime < dt && p.endTime > dt && p.id == objectId); var checkRes = await _promotionServices.SetPromotion(promotionInfo, cartDto); if (checkRes == false) { jm.msg = GlobalErrorCodeVars.Code15600; return jm; } } else if (orderType == (int)GlobalEnumVars.OrderType.PinTuan) { jm.data = await _promotionServices.ToPromotion(cartDto); jm.msg = "拼团也计算促销信息"; } //使用优惠券,判断优惠券是否可用 var bl = await CartCoupon(cartDto, couponCode); if (bl == false) { jm.status = false; jm.data = cartDto.error.data; jm.msg = cartDto.error.msg; return jm; } //使用积分 var pointDto = await CartPoint(cartDto, userId, point); if (pointDto.status == false) { jm.status = false; jm.msg = pointDto.msg; return jm; } //判断最终价格 if (cartDto.amount < 0) { cartDto.amount = 0; } jm.status = true; jm.data = cartDto; jm.msg = "4"; return jm; } #endregion #region 算运费 /// /// 算运费 /// /// 购物车信息 /// 收货地址id /// public async Task CartFreight(CartDto cartDto, int areaId) { if (areaId > 0) { cartDto.costFreight = await _shipServices.GetShipCost(areaId, cartDto.weight, cartDto.goodsAmount); cartDto.amount = Math.Round(cartDto.amount + cartDto.costFreight, 2); } return true; } #endregion #region 根据经纬度算运费 /// /// 根据经纬度算运费 /// /// 购物车信息 /// 用户地址信息 /// public async Task CartFreightByIntraCityService(CartDto cartDto, int userShipId) { if (userShipId > 0) { var userShip = await _userShipServices.QueryByClauseAsync(p => p.id == userShipId); if (userShip == null) { return true; } var store = await _storeServices.QueryByClauseAsync(p => p.isDefault == true); if (store == null) { return true; } if (string.IsNullOrEmpty(userShip.longitude) || string.IsNullOrEmpty(userShip.latitude) || string.IsNullOrEmpty(store.longitude) || string.IsNullOrEmpty(store.latitude)) { return true; } //第一种调用方法 var result = MapHelper.GetDistance(Convert.ToDouble(userShip.latitude.Trim()), Convert.ToDouble(userShip.longitude.Trim()), Convert.ToDouble(store.latitude.Trim()), Convert.ToDouble(store.longitude.Trim())); var allConfigs = await _settingServices.GetConfigDictionaries(); var intraCityServiceBy2Km = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.IntraCityServiceBy2KM).ObjectToDecimal(0); var intraCityServiceBy5Km = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.IntraCityServiceBy5KM).ObjectToDecimal(0); var intraCityServiceBy10Km = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.IntraCityServiceBy10KM).ObjectToDecimal(0); var intraCityServiceBy15Km = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.IntraCityServiceBy15KM).ObjectToDecimal(0); var intraCityServiceBy20Km = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.IntraCityServiceBy20KM).ObjectToDecimal(0); var intraCityServiceByExceed20Km = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.IntraCityServiceByExceed20KM).ObjectToDecimal(0); if (result is >= 0 and <= 2) cartDto.costFreight = intraCityServiceBy2Km; else if (result is > 2 and <= 5) cartDto.costFreight = intraCityServiceBy5Km; else if (result is > 5 and <= 10) cartDto.costFreight = intraCityServiceBy10Km; else if (result is > 10 and <= 15) cartDto.costFreight = intraCityServiceBy15Km; else if (result is > 15 and <= 20) cartDto.costFreight = intraCityServiceBy20Km; else if (result > 20) cartDto.costFreight = Math.Round(intraCityServiceByExceed20Km * (decimal)result).ObjectToDecimal(); else if (result < 0) cartDto.costFreight = intraCityServiceBy2Km; else cartDto.costFreight = cartDto.costFreight; var intraCityServiceFreeCredit = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.IntraCityServiceFreeCredit).ObjectToDecimal(0); if (intraCityServiceFreeCredit > 0 && cartDto.amount > intraCityServiceFreeCredit) { cartDto.costFreight = 0; } cartDto.amount = Math.Round(cartDto.amount + cartDto.costFreight, 2); } return true; } #endregion #region 购物车中使用优惠券 /// /// 购物车中使用优惠券 /// /// /// /// public async Task CartCoupon(CartDto cartDto, string couponCode) { if (!string.IsNullOrEmpty(couponCode)) { var arr = couponCode.Split(","); //判断优惠券是否可用 var couponInfo = await _couponServices.CodeToInfo(arr, true); if (couponInfo.status == false) { cartDto.error = couponInfo; return false; } //判断优惠券是否符合规格 var res = await _promotionServices.ToCoupon(cartDto, couponInfo.data as List); if (res.status == false) { cartDto.error = res; return false; } } return true; } #endregion #region 购物车中使用积分 /// /// 购物车中使用积分 /// /// /// /// /// public async Task CartPoint(CartDto cartDto, int userId, int point) { var jm = new WebApiCallBack() { status = true }; if (point > 0) { var user = await _userServices.QueryByClauseAsync(p => p.id == userId); if (user.point < point) { jm.status = false; jm.msg = "积分不足,无法使用积分"; return jm; } //判断积分值多少钱 //计算可用积分 var allConfigs = await _settingServices.GetConfigDictionaries(); //判断是全局模式还是单品模式 var pointExchangeModel = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.PointExchangeModel).ObjectToInt(); if (pointExchangeModel == 1) { //计算可用积分//订单积分使用比例 var ordersPointProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.OrdersPointProportion).ObjectToDecimal(10); var proportion = Math.Round(ordersPointProportion / 100, 4); //最多可以抵扣的金额 var maxPointDeductedMoney = Math.Round(cartDto.amount * proportion, 4); //订单积分折现比例(多少积分可以折现1块钱) var pointDiscountedProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.PointDiscountedProportion).ObjectToDecimal(100); //积分兑换比例 var pointDeductedMoney = Math.Round(Convert.ToDecimal(point) / pointDiscountedProportion, 4); ; //积分可以抵扣的钱 if (maxPointDeductedMoney < pointDeductedMoney) { jm.status = false; jm.msg = "积分超过订单可使用的积分数量"; return jm; } cartDto.point = point; cartDto.pointExchangeMoney = pointDeductedMoney; cartDto.amount -= pointDeductedMoney; } else { //可抵扣金额 decimal money = 0; foreach (var item in cartDto.list) { money += item.nums * item.products.pointsDeduction; } //计算抵扣这么多金额需要多少积分。 //订单积分折现比例(多少积分可以折现1块钱) var pointDiscountedProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.PointDiscountedProportion).ObjectToInt(100); //计算需要多少积分 var needsPoint = money * pointDiscountedProportion; cartDto.point = point; cartDto.pointExchangeMoney = money; cartDto.amount -= money; } } jm.data = cartDto; return jm; } #endregion #region 获取购物车用户数据总数 /// /// 获取购物车用户数据总数 /// /// public async Task GetCountAsync(int userId) { return await _dal.GetCountAsync(userId); } #endregion #region 获取购物车商品总价格 /// /// 获取购物车商品总价格 /// /// public async Task GetMoneyAsync(int userId) { return await _dal.GetMoneyAsync(userId); } #endregion #region 根据提交的数据判断哪些购物券可以使用 /// /// 根据提交的数据判断哪些购物券可以使用 /// /// /// /// public async Task GetCartAvailableCoupon(int userId, int[] ids = null) { var jm = new WebApiCallBack(); var dt = DateTime.Now; var resultData = new List(); //取用户数据,如果用户没登录,都没意义。 var user = await _userServices.QueryByClauseAsync(p => p.id == userId); if (user == null) { return jm; } //先取购物车数据,如果购物车都没存购货品数据,优惠券就没意义 //获取货品数据 var carts = await _dal.QueryListByClauseAsync(p => p.userId == userId && p.type == (int)GlobalEnumVars.OrderType.Common); if (!carts.Any()) { return jm; } var productIds = carts.Select(p => p.productId).ToList(); var products = await _productsServices.QueryListByClauseAsync(p => productIds.Contains(p.id)); if (!products.Any()) { return jm; } var cartProducts = new List(); var goodIds = new List(); foreach (var item in carts) { var cp = new CartProducts { products = products.Find(p => p.id == item.productId) }; if (cp.products == null) { continue; } //开始赋值 cp.id = item.id; cp.userId = userId; cp.productId = item.productId; cp.nums = item.nums; cp.type = item.type; //如果传过来了购物车数据,就算指定的购物车的数据,否则,就算全部购物车的数据 if (ids != null && ids.Any()) { if (ids.Contains(item.id)) { goodIds.Add(cp.products.goodsId); cartProducts.Add(cp); } continue; } goodIds.Add(cp.products.goodsId); cartProducts.Add(cp); } //如果获取赛选后没了,就返回无 if (!cartProducts.Any()) return jm; //获取商品数据 var goods = await _goodsServices.QueryListByClauseAsync(p => goodIds.Contains(p.id)); //如果商品都被已下架或者删除,也没了。 if (!goods.Any()) return jm; cartProducts.ForEach(p => { p.good = goods.Find(g => g.id == p.products.goodsId); }); //获取我的可用优惠券 var wherec = PredicateBuilder.True(); wherec = wherec.And(p => p.userId == userId); wherec = wherec.And(p => p.isUsed == false); wherec = wherec.And(p => p.endTime > dt); var userCoupon = await _couponServices.QueryPageMapperAsync(wherec, p => p.createTime, OrderByType.Desc, false); if (!userCoupon.Any()) { return jm; } //获取所有商品分类 var goodsCategories = await _goodsCategoryServices.GetCaChe(); foreach (var coupon in userCoupon) { if (coupon.promotion == null) { continue; } //先判断优惠券是否可以使用 //判断规则是否开启 if (coupon.promotion.isEnable == false) continue; //判断优惠券规则是否到达开始时间 if (coupon.startTime > dt) continue; //判断优惠券规则是否已经到结束时间了,也就是是否过期了 if (coupon.endTime < dt) continue; //再来判断是否符合规格 //判断是哪个规则,并且确认是否符合|只要有一个规则不满足,就失效。 var type = 0; foreach (var pc in coupon.conditions) { type = 0; JObject parameters = (JObject)JsonConvert.DeserializeObject(pc.parameters); if (parameters == null) break; var objNums = 0; switch (pc.code) { case "GOODS_ALL": //只要购物车有商品就支持,因为是购物车付款调用接口,所以不存在无商品情况 type = 2; break; case "GOODS_IDS": //指定某些商品满足条件 if (!parameters.ContainsKey("goodsId") || !parameters.ContainsKey("nums")) break; objNums = parameters["nums"].ObjectToInt(0); var goodsIds = CommonHelper.StringToIntArray(parameters["goodsId"].ObjectToString()); //只要有一个商品支持,此优惠券就可以使用。 if (goodsIds.Any()) { foreach (var p in cartProducts) { if (!goodsIds.Contains(p.products.goodsId)) { continue; } if (p.nums >= objNums) { type = 2; break; } } } break; case "GOODS_CATS": //指定商品是否满足分类 if (!parameters.ContainsKey("catId") || !parameters.ContainsKey("nums")) break; var objCatId = parameters["catId"].ObjectToInt(0); objNums = parameters["nums"].ObjectToInt(0); foreach (var product in cartProducts) { type = _goodsCategoryServices.IsHave(goodsCategories, objCatId, product.good.goodsCategoryId) ? product.nums >= objNums ? 2 : 1 : 0; if (type == 2) { break; } } break; case "GOODS_BRANDS": //指定商品品牌满足条件 if (!parameters.ContainsKey("brandId") || !parameters.ContainsKey("nums")) break; var objBrandId = parameters["brandId"].ObjectToInt(0); objNums = parameters["nums"].ObjectToInt(0); foreach (var product in cartProducts) { type = product.good.brandId == objBrandId ? product.nums >= objNums ? 2 : 1 : 0; if (type == 2) { break; } } break; case "ORDER_FULL": //订单满XX金额满足条件 if (!parameters.ContainsKey("money")) break; var objMoney = parameters["money"].ObjectToDecimal(); //算订单总商品价格 decimal goodsAmount = 0; foreach (var product in cartProducts) { var money = product.products.price * product.nums; goodsAmount = Math.Round(goodsAmount + money, 2); } if (goodsAmount >= objMoney) { type = 2; } break; case "USER_GRADE": //用户符合指定等级 if (!parameters.ContainsKey("grades")) break; var arr = CommonHelper.StringToIntArray(parameters["grades"].ObjectToString()); if (arr.Contains(user.grade)) { type = 2; } break; default: break; } //不满足条件,直接跳过 if (type != 2) { break; } } if (type == 2) { resultData.Add(coupon); } } //结果集拼装 var resutlList = new List(); if (resultData != null && resultData.Any()) { foreach (var item in resultData) { var expression1 = string.Empty; var expression2 = string.Empty; foreach (var condition in item.conditions) { expression1 += PromotionHelper.GetConditionMsg(condition.code, condition.parameters); } foreach (var result in item.results) { expression2 += PromotionHelper.GetResultMsg(result.code, result.parameters); } var dto = new GetMyCouponResultDto { couponCode = item.couponCode, promotionId = item.promotionId, isUsed = item.isUsed, userId = item.userId, usedId = item.usedId, createTime = item.createTime, updateTime = item.updateTime, couponName = item.promotion.name, expression1 = expression1, expression2 = expression2, isExpire = item.endTime > dt, startTime = item.startTime, endTime = item.endTime, stime = item.startTime.ToString("yyyy-MM-dd"), etime = item.endTime.ToString("yyyy-MM-dd") }; resutlList.Add(dto); } } jm.status = true; jm.data = new { list = resutlList, changeData = resultData, cartProducts, user }; //jm.otherData = userCoupon; return jm; } #endregion } }