예제 #1
0
        /// <summary>
        /// 抽奖/兑奖
        /// </summary>
        /// <param name="user"></param>
        /// <param name="request"></param>
        /// <param name="requestAborted"></param>
        /// <returns></returns>
        public async Task <ResponseMessage <GiftInfo> > ConsumableScoreAsync(UserInfo user, ConsumableScoreRequest request, CancellationToken requestAborted)
        {
            var response   = new ResponseMessage <GiftInfo>();
            var periodGift = await _giftStore.GetPeriodGifts().Where(w => w.PeriodId == request.PeriodId).FirstOrDefaultAsync();

            if (periodGift == null || periodGift.Enabled == false)
            {
                response.Code    = ResponseCodeDefines.ModelStateInvalid;
                response.Message = "当前赛季奖品暂未开放";
                return(response);
            }
            //抽奖
            if (request.ConsumableType == 1)
            {
                var giftInfoList = await _giftStore.GetGiftInfos().Where(w => !w.IsDelete && w.PeriodId == request.PeriodId).ToListAsync();

                if (!giftInfoList.Any())
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "没有奖品可供抽取";
                    return(response);
                }
                var scoreInfo = await _allocateStore.GetScoreInfos().Where(w => !w.IsDelete && w.PeriodId == request.PeriodId && w.UserId == user.Id).FirstOrDefaultAsync();

                if (scoreInfo == null)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "未查询到您的积分信息";
                    return(response);
                }
                if (scoreInfo.ConsumableScore < periodGift.Score)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "您的可消费K币不足,赶紧去赚点K币吧";
                    return(response);
                }

                //总几率
                var sumOdds = giftInfoList.Sum(s => s.Odds);
                if (sumOdds > 1000)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "奖品设置异常,请联系管理员。";
                    return(response);
                }
                var giftList = giftInfoList.Where(w => w.Number != 0).ToList();//排除抽完的奖品
                if (!giftList.Any())
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "所有奖品已被抽取/兑换完,请等待新奖品上架吧。";
                    return(response);
                }

                //将奖品ID和中奖率放在数组中,并从小到大排序
                var prizeList = giftList.Select(s => new { Prize = s.Id, Change = s.Odds }).OrderBy(o => o.Change).ToList();
                //将中奖率累加,放到字典里
                var prizeDictionary = new Dictionary <string, int>();
                for (var i = 0; i < giftList.Count; i++)
                {
                    var allChange = 0;
                    for (var j = 0; j <= i; j++)
                    {
                        allChange += prizeList[j].Change;
                    }
                    prizeDictionary.Add(prizeList[i].Prize, allChange);
                }
                //产生一个1-1000的随机数
                var rd       = new Random();
                var rdChange = rd.Next(1, 1001);
                //找第一个大于随机值的奖项,如果中途有奖品抽完了,找不到到大于随机值的奖项,就直接取几率最大
                var giftResult_Id = prizeDictionary.FirstOrDefault(j => j.Value >= rdChange).Key ?? prizeDictionary.LastOrDefault().Key;
                var giftInfo      = giftInfoList.FirstOrDefault(fi => fi.Id == giftResult_Id);

                if (giftInfo.Number > 0)
                {
                    giftInfo.Number -= 1;
                }

                //事务保存
                using (var trans = await _transaction.BeginTransaction())
                {
                    try
                    {
                        //事务里面重新查一次
                        scoreInfo = await _allocateStore.GetScoreInfos().Where(w => !w.IsDelete && w.PeriodId == request.PeriodId && w.UserId == user.Id).FirstOrDefaultAsync();

                        if (scoreInfo == null)
                        {
                            response.Code    = ResponseCodeDefines.ModelStateInvalid;
                            response.Message = "未查询到您的积分信息";
                            return(response);
                        }
                        scoreInfo.ConsumableScore = scoreInfo.ConsumableScore - periodGift.Score;
                        await _allocateStore.UpdateScoreInfo(scoreInfo, requestAborted);

                        await _giftStore.UpdateGift(giftInfo, requestAborted);

                        //添加抽奖动态
                        await _dynamicHelper.AddDynamicContent(
                            DynamicType.RandomGift,
                            request.PeriodId,
                            giftInfo.Id,
                            null,
                            null,
                            user.UserName,
                            user.GroupName,
                            user.Id,
                            giftInfo.Name,
                            periodGift.Score,
                            null,
                            null
                            );

                        trans.Commit();
                    }
                    catch (Exception e)
                    {
                        trans.Rollback();
                        throw new Exception("保存事务失败", e);
                    }
                }
                response.Extension = giftInfo;
            }
            //兑奖
            else if (request.ConsumableType == 2)
            {
                var scoreInfo = await _allocateStore.GetScoreInfos().Where(w => !w.IsDelete && w.PeriodId == request.PeriodId && w.UserId == user.Id).FirstOrDefaultAsync();

                if (scoreInfo == null)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "未查询到您的积分信息";
                    return(response);
                }
                var giftInfo = await _giftStore.GetGiftInfos().Where(w => !w.IsDelete && w.PeriodId == request.PeriodId && w.Number != 0 && w.Id == request.GiftId).FirstOrDefaultAsync();

                if (giftInfo == null)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "兑换奖品不存在";
                    return(response);
                }
                if (!giftInfo.IsGet)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = $"兑换奖品{giftInfo.Name}不运行直接兑换";
                    return(response);
                }
                if (scoreInfo.ConsumableScore < giftInfo.GetScore)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "您的可消费K币不足,赶紧去赚点K币吧";
                    return(response);
                }
                if (giftInfo.Number == 0)
                {
                    response.Code    = ResponseCodeDefines.ModelStateInvalid;
                    response.Message = "奖品数量不足不能直接兑换";
                    return(response);
                }
                if (giftInfo.Number > 0)
                {
                    giftInfo.Number -= 1;
                }

                //事务保存
                using (var trans = await _transaction.BeginTransaction())
                {
                    try
                    {
                        //事务里面重新查一次
                        scoreInfo = await _allocateStore.GetScoreInfos().Where(w => !w.IsDelete && w.PeriodId == request.PeriodId && w.UserId == user.Id).FirstOrDefaultAsync();

                        if (scoreInfo == null)
                        {
                            response.Code    = ResponseCodeDefines.ModelStateInvalid;
                            response.Message = "未查询到您的积分信息";
                            trans.Rollback();
                            return(response);
                        }
                        scoreInfo.ConsumableScore = scoreInfo.ConsumableScore - giftInfo.GetScore;
                        await _allocateStore.UpdateScoreInfo(scoreInfo, requestAborted);

                        await _giftStore.UpdateGift(giftInfo, requestAborted);

                        //添加直接兑换动态
                        await _dynamicHelper.AddDynamicContent(
                            DynamicType.GetGift,
                            request.PeriodId,
                            giftInfo.Id,
                            null,
                            null,
                            user.UserName,
                            user.GroupName,
                            user.Id,
                            giftInfo.Name,
                            periodGift.Score,
                            null,
                            null
                            );

                        trans.Commit();
                    }
                    catch (Exception e)
                    {
                        trans.Rollback();
                        throw new Exception("保存事务失败", e);
                    }
                }
                response.Extension = giftInfo;
            }
            else
            {
                response.Code    = ResponseCodeDefines.ModelStateInvalid;
                response.Message = "ConsumableType参数错误";
                return(response);
            }

            // 触发个人信息变化
            await _sendClientMessageManager.SendInfos(new List <Dto.Common.SendClientType>()
            {
                Dto.Common.SendClientType.User,
                Dto.Common.SendClientType.Dynamic
            });

            return(response);
        }
예제 #2
0
        public async Task <ResponseMessage <GiftInfo> > ConsumableScore(Models.UserInfo user, [FromBody] ConsumableScoreRequest request)
        {
            Logger.Trace($"用户{user?.UserName ?? ""}({user?.Id ?? ""})抽奖,请求参数为:\r\n" + JsonHelper.ToJson(request));
            var response = new ResponseMessage <GiftInfo>();

            if (!ModelState.IsValid)
            {
                response.Code    = ResponseCodeDefines.ModelStateInvalid;
                response.Message = "模型验证失败" + ModelState.GetAllErrors();
                Logger.Warn("抽奖模型验证失败:\r\n{0}", response.Message ?? "");
                return(response);
            }
            var prefixs = new string[] { "ConsumableScore" };
            var key     = "ConsumableScore";

            try
            {
                // 防止同时中奖,兑奖,数量不够。所以这里是一个一个来
                await _cache.LockSubmit(prefixs, key, "ConsumableScore", HttpContext.RequestAborted);

                response = await _giftManager.ConsumableScoreAsync(user, request, HttpContext.RequestAborted);
            }
            catch (Exception e)
            {
                response.Code    = ResponseCodeDefines.ServiceError;
                response.Message = e.Message;
                Logger.Error($"用户{user?.UserName ?? ""}({user?.Id ?? ""})抽奖,报错:{e.Message}\r\n{e.StackTrace}");
            }
            finally
            {
                // 成功失败都要移除
                await _cache.UnlockSubmit(prefixs, key);
            }
            return(response);
        }