Files
2026-10-12 16:22:04 +08:00

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();
}
}
}