public static async Task <OrderCountResponse> SetUserCreateFlashOrderCountCacheAsync( OrderCountCacheRequest request) { var keyModels = SetKeys(request); var flashSale = await DalFlashSale.FetchFlashSaleProductModel(new OrderItems() { PID = request.Pid, ActivityId = new Guid(request.ActivityId) }); var response = new OrderCountResponse(); using (var client = CacheHelper.CreateCounterClient(ClientName)) { //Queryable<int> personSorts = new Queryable[4, 5, 6]; //个人限购 if (flashSale.MaxQuantity.HasValue) { foreach (var key in keyModels.OrderBy(r => r.Sort).Where(r => r.Sort == 4 || r.Sort == 5 || r.Sort == 6)) { response = await SetCountValue(response, key.Key, request.PerSonalNum, client); if (response.RedisField) { break; } } } //会场限购 if (flashSale.PlaceQuantity.HasValue && flashSale.PlaceQuantity.Value > 0) { var saleProducts = (await DalFlashSale.SelectFlashSaleFromDBAsync(new Guid(request.ActivityId))).Products.ToList(); var salePids = saleProducts.Where(r => r.IsJoinPlace).Select(r => r.PID).ToList(); if (salePids.Contains(request.Pid)) { foreach (var key in keyModels.OrderBy(r => r.Sort).Where(r => r.Sort == 1 || r.Sort == 2 || r.Sort == 3)) { response = await SetCountValue(response, key.Key, request.PlaceNum, client); if (response.RedisField) { break; } } } } } if (response.RedisField) { return(response); } return(await GetUserCreateFlashOrderCountCacheAsync(request)); }
private static async Task <CheckFlashSaleResponseModel> CheckFlashSaleByPidAsync(OrderItems item, Guid userId, string deviceId, string userTel) { var hasMaxLimit = false; var hasPlaceLimit = false; string allPlaceLimitId = null; try { if (!item.ActivityId.HasValue) { return new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.NoExist, } } ; var flashSale = await DalFlashSale.FetchFlashSaleProductModel(item); if (flashSale == null) { return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.NoExist, }); } var model = await FlashSaleCounter.RedisHashRecord(item.PID, item); if (model.Code == CheckFlashSaleStatus.CreateOrderFailed) { return new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, } } ; var record = model.Record; var remainQuantity = flashSale.TotalQuantity - record; if (remainQuantity < 0) { return new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.NoEnough, } } ; var request = new GenerateKeyRequest { DeviceId = deviceId, UserId = userId.ToString(), UserTel = userTel, ActivityId = item.ActivityId.ToString(), Pid = item.PID }; var countKey = new GenerateFlashSaleKey(request); if (flashSale.MaxQuantity.HasValue) { var personLimit1 = await FlashSaleCounter.RedisCounterRecord(countKey.PersonalkeyUserId, LimitType.PersonalLimit, CounterKeyType.UserIdKey, item, userId, deviceId, userTel, null, -1); if (personLimit1.Code < 0) { return new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, } } ; var personLimit2 = await FlashSaleCounter.RedisCounterRecord(countKey.PersonalkeyDeviceId, LimitType.PersonalLimit, CounterKeyType.DeviceIdKey, item, userId, deviceId, userTel, null, personLimit1.DeviceCount); if (personLimit2.Code < 0) { var orderItem = new CheckFlashSaleResponseModel { Num = item.Num }; await FlashSaleCounter.DecrementCountCount(orderItem, countKey.PersonalkeyUserId); return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } var personLimit3 = await FlashSaleCounter.RedisCounterRecord(countKey.PersonalkeyUseTel, LimitType.PersonalLimit, CounterKeyType.UserTelKey, item, userId, deviceId, userTel, null, personLimit1.TelCount); if (personLimit3.Code < 0) { var orderItem = new CheckFlashSaleResponseModel { Num = item.Num }; await FlashSaleCounter.DecrementCountCount(orderItem, countKey.PersonalkeyUserId); await FlashSaleCounter.DecrementCountCount(orderItem, countKey.PersonalkeyDeviceId); return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } if (personLimit1.Code < 0 || personLimit2.Code < 0 || personLimit3.Code < 0) { return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } var maxLimit = Math.Max(Math.Max(personLimit1.Record, personLimit2.Record), personLimit3.Record); hasMaxLimit = true; if (maxLimit > flashSale.MaxQuantity) { return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.MaxQuantityLimit, HasQuantityLimit = true }); } } if (flashSale.PlaceQuantity.HasValue && flashSale.PlaceQuantity.Value > 0) { var saleProducts = (await DalFlashSale.SelectFlashSaleProductsAsync(item.ActivityId.Value)).ToList(); var salePids = saleProducts.Where(r => r.IsJoinPlace).Select(r => r.PID).ToList(); if (salePids.Contains(item.PID)) { var placeLimit1 = await FlashSaleCounter.RedisCounterRecord(countKey.PlacekeyUserId, LimitType.PlaceLimit, CounterKeyType.UserIdKey, item, userId, deviceId, userTel, salePids, -1); if (placeLimit1.Code < 0) { return new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, } } ; var placeLimit2 = await FlashSaleCounter.RedisCounterRecord(countKey.PlacekeyDeviceId, LimitType.PlaceLimit, CounterKeyType.DeviceIdKey, item, userId, deviceId, userTel, salePids, placeLimit1.DeviceCount); if (placeLimit2.Code < 0) { var orderItem = new CheckFlashSaleResponseModel { Num = item.Num }; await FlashSaleCounter.DecrementCountCount(orderItem, countKey.PlacekeyUserId); return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } var placeLimit3 = await FlashSaleCounter.RedisCounterRecord(countKey.PlacekeyUseTel, LimitType.PlaceLimit, CounterKeyType.UserTelKey, item, userId, deviceId, userTel, salePids, placeLimit1.TelCount); if (placeLimit3.Code < 0) { var orderItem = new CheckFlashSaleResponseModel { Num = item.Num }; await FlashSaleCounter.DecrementCountCount(orderItem, countKey.PlacekeyUserId); await FlashSaleCounter.DecrementCountCount(orderItem, countKey.PlacekeyDeviceId); return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } if (placeLimit1.Code < 0 || placeLimit2.Code < 0 || placeLimit3.Code < 0) { return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } hasPlaceLimit = true; var placeLimit = Math.Max(Math.Max(placeLimit1.Record, placeLimit2.Record), placeLimit3.Record); if (placeLimit > flashSale.PlaceQuantity.Value) { return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.PlaceQuantityLimit, HasQuantityLimit = hasMaxLimit, HasPlaceLimit = true }); } } } #region 针对618增加一个全局会场限购 if (flashSale.ActiveType == 3 && FlashSaleManager.CheckAllPlaceLimitStatrtDate()) { var allPLimitId = GlobalConstant.AllPlaceLimitId; item.AllPlaceLimitId = allPLimitId; var request1 = new GenerateKeyRequest { DeviceId = deviceId, UserId = userId.ToString(), UserTel = userTel, ActivityId = item.AllPlaceLimitId, Pid = item.PID, IsAllPlaceLimit = true }; var countKeyAllLimit = new GenerateFlashSaleKey(request1); var config = await FlashSaleManager.SelectFlashSaleDataByActivityIDAsync(new Guid(allPLimitId)); if (config.PlaceQuantity.HasValue) { var saleProducts = config.Products.ToList(); var salePids = saleProducts.Where(r => r.IsJoinPlace).Select(r => r.PID).ToList(); if (salePids.Contains(item.PID)) { var placeLimit1 = await FlashSaleCounter.RedisCounterRecord( countKeyAllLimit.PlacekeyUserId, LimitType.AllPlaceLimit, CounterKeyType.UserIdKey, item, userId, deviceId, userTel, salePids, -1); if (placeLimit1.Code < 0) { return new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, } } ; var placeLimit2 = await FlashSaleCounter.RedisCounterRecord(countKeyAllLimit.PlacekeyDeviceId, LimitType.AllPlaceLimit, CounterKeyType.DeviceIdKey, item, userId, deviceId, userTel, salePids, placeLimit1.DeviceCount); if (placeLimit2.Code < 0) { var orderItem = new CheckFlashSaleResponseModel { Num = item.Num }; await FlashSaleCounter.DecrementCountCount(orderItem, countKeyAllLimit.PlacekeyUserId); return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } var placeLimit3 = await FlashSaleCounter.RedisCounterRecord(countKeyAllLimit.PlacekeyUseTel, LimitType.AllPlaceLimit, CounterKeyType.UserTelKey, item, userId, deviceId, userTel, salePids, placeLimit1.TelCount); if (placeLimit3.Code < 0) { var orderItem = new CheckFlashSaleResponseModel { Num = item.Num }; await FlashSaleCounter.DecrementCountCount(orderItem, countKeyAllLimit.PlacekeyUserId); await FlashSaleCounter.DecrementCountCount(orderItem, countKeyAllLimit.PlacekeyDeviceId); return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } if (placeLimit1.Code < 0 || placeLimit2.Code < 0 || placeLimit3.Code < 0) { return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, }); } var allplaceLimit = Math.Max(Math.Max(placeLimit1.Record, placeLimit2.Record), placeLimit3.Record); allPlaceLimitId = allPLimitId; if (allplaceLimit > config.PlaceQuantity.Value) { return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.PlaceQuantityLimit, AllPlaceLimitId = allPlaceLimitId }); } } #region 错误代码 //var hashRecord618 = await FlashSaleCounter.RedisAllPlaceLimitHashRecord(item.PID, item); //if (hashRecord618 != null) //{ // if (hashRecord618.Code == CheckFlashSaleStatus.CreateOrderFailed) // return new CheckFlashSaleResponseModel() // { // Code = CheckFlashSaleStatus.CreateOrderFailed, // }; // var saledAll = model.Record; // var config = // await FlashSaleManager.SelectFlashSaleDataByActivityIDAsync( // new Guid(allPLimitId)); // var configQty = config.Products.Where(r => r.PID == item.PID).Select(r => r.TotalQuantity).FirstOrDefault(); // allPlaceLimitId = allPLimitId; // if (configQty - saledAll < 0) // return new CheckFlashSaleResponseModel() // { // Code = CheckFlashSaleStatus.NoEnough, // AllPlaceLimitId = allPlaceLimitId // }; //} #endregion } } #endregion return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.Succeed, HasPlaceLimit = hasPlaceLimit, HasQuantityLimit = hasMaxLimit, AllPlaceLimitId = allPlaceLimitId }); #endregion } catch (Exception ex) { Logger.Info(ex); return(new CheckFlashSaleResponseModel() { Code = CheckFlashSaleStatus.CreateOrderFailed, HasPlaceLimit = hasPlaceLimit, HasQuantityLimit = hasMaxLimit }); } }
/// <summary> /// 记录购买记录进计数器 /// </summary> /// <param name="key"></param> /// <param name="item"></param> /// <returns></returns> public static async Task <SimpleResponseModel> RedisHashRecord(string key, OrderItems item) { using (var client = CacheHelper.CreateHashClient(item.ActivityId.ToString(), TimeSpan.FromDays(30))) { var recordCache = await client.GetAsync <int>(key); double retryresult = 0; IResult <double> increment; var incrementNum = 0; if (!recordCache.Success) { if (recordCache.Message == "Key不存在") //暂时写死错误信息,后面如果底层针对这种情况有固定errorcode返回修改下 { if (item.ActivityId.ToString() == "c6cc9628-21aa-4f85-a19c-fd12529159e8") //买三送一活动打log { Logger.Info($"hash缓存加之前=》Key{key}value{recordCache.Value}活动id:{item.ActivityId.ToString()}"); } var result = await DalFlashSale.FetchFlashSaleProductModel(item); var quantity = result.SaleOutQuantity; increment = await client.IncrementAsync(key, quantity + item.Num); incrementNum = quantity + item.Num; } else { Logger.Error($"redis计数记录失败=>CheckFlashSaleAsync{key}"); return(new SimpleResponseModel { Code = CheckFlashSaleStatus.CreateOrderFailed, Mesage = "计数器执行失败" }); } } else { increment = await client.IncrementAsync(key, item.Num); incrementNum = item.Num; } if (!increment.Success) //失败情况后续考虑 { retryresult = await RedisCountRetry(() => client.IncrementAsync(key, incrementNum)); if (retryresult < 0) { Logger.Error($"redis计数记录失败=>CheckFlashSaleAsync{key}"); return(new SimpleResponseModel { Code = CheckFlashSaleStatus.CreateOrderFailed, Mesage = "计数器执行失败" }); } } if (item.ActivityId.ToString() == "c6cc9628-21aa-4f85-a19c-fd12529159e8") //买三送一活动打log { Logger.Info($"hash缓存加之后=》Key:{key}value:{increment.Value}活动id:{item.ActivityId.ToString()}"); } return(new SimpleResponseModel { Code = CheckFlashSaleStatus.Succeed, Record = (int)(increment.Success ? increment.Value : retryresult), Mesage = "成功" }); } }