using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CommonDomain; using CommonDomain.BaseModel; using Microsoft.Extensions.Logging; using MongoRepository; using UserDomain.Entity; using UserDomain.Enum; using UserService.GameConfigs; using UserService.Param; using UserService.User; namespace UserService.ScratchCard { public class ScratchCardService : IScratchCardService { private const string ScratchCardNumber = "40005"; private readonly IGameConfigService _gameConfig; private readonly IUserService _userService; private readonly IMongoBaseRepository _recordRepo; private readonly ILogger _logger; public ScratchCardService( IGameConfigService gameConfig, IUserService userService, IMongoBaseRepository recordRepo, ILogger logger) { _gameConfig = gameConfig; _userService = userService; _recordRepo = recordRepo; _logger = logger; } public async Task<(bool success, string message, ScratchCardResult? result)> Draw(string userId) { var gameConfig = await _gameConfig.Get(); if (gameConfig == null) return (false, "游戏配置不存在", null); var configs = gameConfig.ScratchCardConfig; if (configs == null || configs.Count == 0) return (false, "刮刮卡活动暂未开放", null); var user = await _userService.GetUser(userId); if (user == null) return (false, "用户不存在", null); var prop = user.Props.FirstOrDefault(p => p.Number == ScratchCardNumber); if (prop == null || prop.Count <= 0) return (false, "刮刮卡数量不足", null); var deductResult = await _userService.UpdateAssets(new UserAssetParam { UserId = userId, ChangeType = UserAssetChangeTypeEnum.减少, RewardItems = new List { new BaseProductCount { Number = ScratchCardNumber, Count = 1 } }, Source = RewardSource.刮刮卡, Remark = "使用刮刮卡", IsAddRecord = false }); if (!deductResult.isok) return (false, deductResult.msg, null); var prize = DrawPrize(configs); if (prize == null) return (false, "奖项配置异常", null); var rewardItems = new List(); if (prize.Type == 3 && prize.BaseProduct != null) { rewardItems.Add(new BaseProductCount { Number = prize.BaseProduct.Number, Name = prize.BaseProduct.Name, Type = prize.BaseProduct.Type, Count = prize.Count }); } (bool isok, string msg) awardResult; try { awardResult = await _userService.UpdateAssets(new UserAssetParam { UserId = userId, ChangeType = UserAssetChangeTypeEnum.增加, Gold = prize.Type == 1 ? prize.Count : 0, Diamond = prize.Type == 2 ? prize.Count : 0, RewardItems = rewardItems, Source = RewardSource.刮刮卡, Remark = "刮刮卡奖励" }); } catch (Exception ex) { _logger.LogError(ex, "刮刮卡发奖失败 userId={UserId} prizeType={PrizeType} count={Count}", userId, prize.Type, prize.Count); return (false, "刮奖失败,请稍后重试", null); } if (!awardResult.isok) return (false, awardResult.msg, null); var record = new ScratchCardRecord { UserId = userId, PrizeType = prize.Type, PrizeName = prize.Type == 1 ? $"{prize.Count}金币" : prize.Type == 2 ? $"{prize.Count}钻石" : prize.BaseProduct?.Name ?? "", Count = prize.Count, BaseProduct = prize.BaseProduct }; try { await _recordRepo.InsertOneAsync(record); } catch (Exception ex) { _logger.LogError(ex, "刮刮卡中奖记录写入失败 userId={UserId} prizeType={PrizeType} count={Count}", userId, prize.Type, prize.Count); } var result = new ScratchCardResult { PrizeType = prize.Type, PrizeName = prize.Type == 1 ? $"{prize.Count}金币" : prize.Type == 2 ? $"{prize.Count}钻石" : prize.BaseProduct?.Name ?? "", Count = prize.Count, BaseProduct = prize.BaseProduct }; return (true, "恭喜获得奖励!", result); } private static ScratchCardConfig? DrawPrize(List configs) { var totalWeight = configs.Sum(c => (long)c.Weight); if (totalWeight <= 0) return null; var random = new Random(); var randomValue = random.NextInt64(0, totalWeight); long currentSum = 0; foreach (var config in configs) { currentSum += config.Weight; if (randomValue < currentSum) return config; } return configs.LastOrDefault(); } } }