diff --git a/CoreCms.Net.IRepository/IBaseRepository.cs b/CoreCms.Net.IRepository/IBaseRepository.cs index 53eccce72ccb39ec9c28caedc40d136bd2d2f895..9b902ec2a8f09d14587e04485af23645634b5ae5 100644 --- a/CoreCms.Net.IRepository/IBaseRepository.cs +++ b/CoreCms.Net.IRepository/IBaseRepository.cs @@ -203,8 +203,11 @@ namespace CoreCms.Net.IRepository /// /// 条件表达式树 /// 是否使用WITH(NOLOCK) + /// 是否使用事务锁 + /// 事务锁类型 /// - Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false); + Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false,bool blUseTranLock = false, + DbLockType dbLockType = DbLockType.Wait); /// /// 根据条件查询数据 diff --git a/CoreCms.Net.Repository/BaseRepository.cs b/CoreCms.Net.Repository/BaseRepository.cs index 6d877abcffd5314ba5f44d0f7beaa4688f969e9b..e4dd0fd9f587048223e4a6e6a3029d1d0a2d60cc 100644 --- a/CoreCms.Net.Repository/BaseRepository.cs +++ b/CoreCms.Net.Repository/BaseRepository.cs @@ -331,12 +331,16 @@ namespace CoreCms.Net.Repository /// /// 条件表达式树 /// 是否使用WITH(NOLOCK) + /// 是否使用事务锁 + /// 事务锁类型 /// - public async Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false) + public async Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false,bool blUseTranLock = false, + DbLockType dbLockType = DbLockType.Wait) { return blUseNoLock ? await DbBaseClient.Queryable().With(SqlWith.NoLock).FirstAsync(predicate) - : await DbBaseClient.Queryable().FirstAsync(predicate); + : (blUseTranLock? await DbBaseClient.Queryable().TranLock(dbLockType).FirstAsync(predicate) + : await DbBaseClient.Queryable().FirstAsync(predicate)); } /// diff --git a/CoreCms.Net.Repository/Good/CoreCmsGoodsRepository.cs b/CoreCms.Net.Repository/Good/CoreCmsGoodsRepository.cs index a69c241c04fce2ba117b178cc4cce703dbf179b4..d59ef1f9fd23f02f9d36c63988a64ad87f772d34 100644 --- a/CoreCms.Net.Repository/Good/CoreCmsGoodsRepository.cs +++ b/CoreCms.Net.Repository/Good/CoreCmsGoodsRepository.cs @@ -803,7 +803,7 @@ namespace CoreCms.Net.Repository //更新记录。 bl = DbClient.Updateable() .SetColumns(it => it.freezeStock == it.freezeStock + num) - .Where(p => p.id == productModel.id && insertNum >= num).ExecuteCommandHasChange(); + .Where(p => p.id == productModel.id && insertNum >= num && p.freezeStock < p.stock).ExecuteCommandHasChange(); break; case "send": //发货 bl = DbClient.Updateable() diff --git a/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs b/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs index 1a960acbb141b1c10d7a22c8c67de201ccd78177..4584211c72be40dac7fa272819d5306742b23b12 100644 --- a/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs +++ b/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs @@ -249,24 +249,58 @@ namespace CoreCms.Net.Services //开始事务处理 await _dal.InsertAsync(order); - + //上面保存好订单表,下面保存订单的其他信息 if (orderItems != null) { jm.msg = "更改库存"; + // foreach (var item in orderItems) + // { + // var res = _goodsServices.ChangeStock(item.productId, GlobalEnumVars.OrderChangeStockType.order.ToString(), item.nums); + // if (res.status == false) + // { + // jm.msg = "更新库存数据失败"; + // return jm; + // } + // } + //更改库存 - foreach (var item in orderItems) + var avaliableOrderItems = orderItems.Where(item => { var res = _goodsServices.ChangeStock(item.productId, GlobalEnumVars.OrderChangeStockType.order.ToString(), item.nums); + if (res.status == false) { - - jm.msg = "更新库存数据失败"; - return jm; + jm.msg += $"{item.name}库存不足"; } + + return res.status; + + + }).ToList(); + + + if (avaliableOrderItems.Count == 0) + { + await _orderItemServices.InsertCommandAsync(orderItems); + + await _dal.UpdateAsync(n => new CoreCmsOrder() + { + status = (int)GlobalEnumVars.OrderStatus.Cancel, + updateTime = DateTime.Now + }, + m => m.orderId == order.orderId); + + //清除购物车信息 + await _cartServices.DeleteAsync(p => ids.Contains(p.id) && p.userId == userId && p.type == orderType); + + + jm.msg = "下单失败,库存不足"; + return jm; } - jm.msg = "订单明细更新" + orderItems.Count; - var outItems = await _orderItemServices.InsertCommandAsync(orderItems); + + jm.msg = "订单明细更新" + avaliableOrderItems.Count; + var outItems = await _orderItemServices.InsertCommandAsync(avaliableOrderItems); var outItemsBool = outItems > 0; if (outItemsBool == false) { @@ -275,6 +309,13 @@ namespace CoreCms.Net.Services jm.data = outItems; return jm; } + + + + + + + //优惠券核销 if (!string.IsNullOrEmpty(couponCode)) { @@ -304,21 +345,21 @@ namespace CoreCms.Net.Services break; case (int)GlobalEnumVars.OrderType.PinTuan: //拼团模式去校验拼团是否存在,并添加拼团记录 - var pinTuanRes = await _pinTuanRecordServices.OrderAdd(order, orderItems, teamId); + var pinTuanRes = await _pinTuanRecordServices.OrderAdd(order, avaliableOrderItems, teamId); if (pinTuanRes.status == false) { return pinTuanRes; } break; case (int)GlobalEnumVars.OrderType.Group: - var groupRes = await _promotionRecordServices.OrderAdd(order, orderItems, objectId, orderType); + var groupRes = await _promotionRecordServices.OrderAdd(order, avaliableOrderItems, objectId, orderType); if (groupRes.status == false) { return groupRes; } break; case (int)GlobalEnumVars.OrderType.Skill: - var rskillRes = await _promotionRecordServices.OrderAdd(order, orderItems, objectId, orderType); + var rskillRes = await _promotionRecordServices.OrderAdd(order, avaliableOrderItems, objectId, orderType); if (rskillRes.status == false) { return rskillRes; diff --git a/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs b/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs index 3a462c31de587b9a5a47db11882537c4c80596d0..61b650102e65d0bf88e5e3d38e7d74fc879dc6ba 100644 --- a/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs +++ b/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs @@ -465,16 +465,17 @@ namespace CoreCms.Net.Services where = where.And(p => p.isDel == false); //是否被删除 - var info = await _dal.QueryByClauseAsync(where); + var info = await _dal.QueryByClauseAsync(where,false,true); if (info != null) { jm.data = info; //判断最大领取数量 if (info.maxRecevieNums == 0) { - jm.status = true; + jm.status = false; return jm; } + var receiveCount = await _couponServices.GetCountAsync(p => p.promotionId == promotionId); if (receiveCount >= info.maxRecevieNums) { diff --git a/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs b/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs index b3dfa725d7474aaf24d2debd38b9b6625596946b..11f3dd5f64bb926fb31531444c470a7ab3f56cff 100644 --- a/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs +++ b/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs @@ -13,6 +13,7 @@ using System.Linq; using System.Threading.Tasks; using CoreCms.Net.Auth.HttpContextUser; using CoreCms.Net.Configuration; +using CoreCms.Net.IRepository.UnitOfWork; using CoreCms.Net.IServices; using CoreCms.Net.Model.Entities; using CoreCms.Net.Model.FromBody; @@ -33,18 +34,21 @@ namespace CoreCms.Net.Web.WebApi.Controllers private readonly IHttpContextUser _user; private readonly ICoreCmsCouponServices _couponServices; private readonly ICoreCmsPromotionServices _promotionServices; + private readonly IUnitOfWork _unionOfWork; /// /// 构造函数 /// /// /// /// + /// public CouponController(IHttpContextUser user - , ICoreCmsCouponServices couponServices, ICoreCmsPromotionServices promotionServices) + , ICoreCmsCouponServices couponServices, ICoreCmsPromotionServices promotionServices, IUnitOfWork unionOfWork) { _user = user; _couponServices = couponServices; _promotionServices = promotionServices; + _unionOfWork = unionOfWork; } //公共接口==================================================================================================== @@ -144,32 +148,55 @@ namespace CoreCms.Net.Web.WebApi.Controllers jm.msg = GlobalErrorCodeVars.Code15006; return jm; } - //判断优惠券是否可以领取? - var promotionModel = await _promotionServices.ReceiveCoupon(entity.id); - if (promotionModel.status == false) + + try { - return promotionModel; - } + _unionOfWork.BeginTran(); - var promotion = (CoreCmsPromotion)promotionModel.data; - if (promotion == null) - { - jm.msg = GlobalErrorCodeVars.Code15019; - return jm; - } - if (promotion.maxNums > 0) - { - //判断用户是否已领取?领取次数 - var couponResult = await _couponServices.GetMyCoupon(_user.ID, entity.id, "all", 1, 9999); - if (couponResult.status && couponResult.code >= promotion.maxNums) + //判断优惠券是否可以领取? + var promotionModel = await _promotionServices.ReceiveCoupon(entity.id); + if (promotionModel.status == false) { - jm.msg = GlobalErrorCodeVars.Code15018; + _unionOfWork.RollbackTran(); + return promotionModel; + } + + + + var promotion = (CoreCmsPromotion)promotionModel.data; + if (promotion == null) + { + _unionOfWork.RollbackTran(); + jm.msg = GlobalErrorCodeVars.Code15019; return jm; } + + if (promotion.maxNums > 0) + { + //判断用户是否已领取?领取次数 + var couponResult = await _couponServices.GetMyCoupon(_user.ID, entity.id, "all", 1, 9999); + if (couponResult.status && couponResult.code >= promotion.maxNums) + { + _unionOfWork.RollbackTran(); + jm.msg = GlobalErrorCodeVars.Code15018; + return jm; + } + } + + jm = await _couponServices.AddData(_user.ID, entity.id, promotion); + + _unionOfWork.CommitTran(); + + jm.otherData = promotionModel; + + } + catch (Exception e) + { + _unionOfWork.RollbackTran(); + jm.msg = GlobalErrorCodeVars.Code10000; } - jm = await _couponServices.AddData(_user.ID, entity.id, promotion); - jm.otherData = promotionModel; + return jm; } #endregion