165 lines
5.8 KiB
C#
165 lines
5.8 KiB
C#
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<ScratchCardRecord> _recordRepo;
|
||
|
|
private readonly ILogger<ScratchCardService> _logger;
|
||
|
|
|
||
|
|
public ScratchCardService(
|
||
|
|
IGameConfigService gameConfig,
|
||
|
|
IUserService userService,
|
||
|
|
IMongoBaseRepository<ScratchCardRecord> recordRepo,
|
||
|
|
ILogger<ScratchCardService> 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<BaseProductCount>
|
||
|
|
{
|
||
|
|
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<BaseProductCount>();
|
||
|
|
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<ScratchCardConfig> 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();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|