using System; using System.Collections.Generic; using System.Linq; using AutoMapper; using Common; using Common.Utils; using CommonDomain; using CommonDomain.BaseModel; using CommonDomain.Enum; using DotNetCore.CAP; using MongoRepository; using RedisService; using UserDomain; using UserDomain.Entity; using UserDomain.Enum; using UserService.Response; using UserService.GameConfigs; using UserService.Param; namespace UserService.BattleOrder { public class BattleOrderService : IBattleOrderService { private readonly IMongoBaseRepository _userBattleOrderMongo; private readonly IMongoBaseRepository _userEntityMongo; private readonly IActivityConfigService _activityConfigService; private readonly ICapPublisher _capPublisher; private readonly IRedisService _redisService; private readonly IMapper _mapper; public BattleOrderService( IMongoBaseRepository userBattleOrderMongo, IMongoBaseRepository userEntityMongo, IActivityConfigService activityConfigService, ICapPublisher capPublisher, IRedisService redisService, IMapper mapper) { _userBattleOrderMongo = userBattleOrderMongo; _userEntityMongo = userEntityMongo; _activityConfigService = activityConfigService; _capPublisher = capPublisher; _redisService = redisService; _mapper = mapper; } public async Task GetUserBattleOrderAsync(string userId) { var config = await _activityConfigService.Get(); var configuredEndTime = config?.BattleOrderConfig?.EndTime ?? 0; var userBattleOrder = await _userBattleOrderMongo.FindOneAsync(c => c.UserId == userId); if (userBattleOrder == null) { userBattleOrder = await CreateOrResetBattleOrderAsync(userId); } else if (userBattleOrder.EndTime != configuredEndTime && (configuredEndTime == 0 || configuredEndTime > DateTimeOffset.UtcNow.ToUnixTimeSeconds())) { userBattleOrder = await CreateOrResetBattleOrderAsync(userId); } return userBattleOrder; } public async Task GetUserBattleOrderWithConfigAsync(string userId) { var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; BattleOrderGiftProductHelper.Enrich(battleOrderConfig, _redisService.GetGameConfig()); if (!IsActivityActive(battleOrderConfig)) { return new BattleOrderResponse { IsOpen = false, Message = "战令未开启或已结束" }; } var userBattleOrder = await GetUserBattleOrderAsync(userId); int maxLevel = battleOrderConfig.LevelConfig?.Count ?? 0; var canReceiveLevels = new List(); for (int i = 1; i <= userBattleOrder.Level && i <= maxLevel; i++) { bool canReceive = false; if (!userBattleOrder.NormalReceivedLevels.Contains(i)) canReceive = true; if ((userBattleOrder.PurchasedAdvances.Contains(1) || userBattleOrder.PurchasedAdvances.Contains(3)) && !userBattleOrder.LuxuryReceivedLevels.Contains(i)) canReceive = true; if ((userBattleOrder.PurchasedAdvances.Contains(2) || userBattleOrder.PurchasedAdvances.Contains(3)) && !userBattleOrder.SupremeReceivedLevels.Contains(i)) canReceive = true; if (canReceive) canReceiveLevels.Add(i); } var levelConfigs = battleOrderConfig.LevelConfig?.Select(l => new BattleOrderLevelInfo { Level = l.Level, Exp = l.Exp, NormalGiftList = l.NormalGiftList ?? new List(), LuxuryGiftList = l.LuxuryGiftList ?? new List(), SupremeGiftList = l.SupremeGiftList ?? new List() }).ToList(); var advanceGifts = battleOrderConfig.AdvanceGift?.Select(a => new BattleOrderAdvanceInfo { Type = a.Type, Name = a.Name, Count = a.Count, PayType = a.PayType, PayCount = a.PayCount }).ToList(); return new BattleOrderResponse { IsOpen = true, UserBattleOrder = new UserBattleOrderInfo { UserId = userBattleOrder.UserId, Level = userBattleOrder.Level, Exp = userBattleOrder.Exp, IsLuxury = userBattleOrder.PurchasedAdvances.Contains(1) || userBattleOrder.PurchasedAdvances.Contains(3), IsSupreme = userBattleOrder.PurchasedAdvances.Contains(2) || userBattleOrder.PurchasedAdvances.Contains(3), ReceivedLevels = userBattleOrder.NormalReceivedLevels, PurchasedAdvances = userBattleOrder.PurchasedAdvances }, Config = new BattleOrderConfigInfo { EndTime = battleOrderConfig.EndTime, RuleDesc = battleOrderConfig.RuleDesc, BuyDesc = battleOrderConfig.BuyDesc, AdvanceGiftDesc = battleOrderConfig.AdvanceGiftDesc, LevelConfig = levelConfigs, AdvanceGift = advanceGifts } }; } public async Task<(bool success, int newLevel, long remainExp)> AddExpAsync(string userId, long exp) { exp = exp * 100; if (exp <= 0) return (false, 1, 0); var userBattleOrder = await GetUserBattleOrderAsync(userId); var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; if (!IsActivityActive(battleOrderConfig)) return (false, userBattleOrder.Level, userBattleOrder.Exp); int maxLevel = battleOrderConfig.LevelConfig?.Count ?? 1; if (maxLevel <= 0) maxLevel = 1; if (userBattleOrder.Level >= maxLevel) return (true, maxLevel, userBattleOrder.Exp); long totalExp = userBattleOrder.Exp + exp; int currentLevel = userBattleOrder.Level; while (currentLevel < maxLevel) { var levelConfig = battleOrderConfig.LevelConfig?.FirstOrDefault(c => c.Level == currentLevel + 1); if (levelConfig == null) break; long nextLevelExp = levelConfig.Exp; if (totalExp >= nextLevelExp) { totalExp -= nextLevelExp; currentLevel++; } else { break; } } if (currentLevel >= maxLevel) { currentLevel = maxLevel; totalExp = 0; } userBattleOrder.Level = currentLevel; userBattleOrder.Exp = totalExp; await _userBattleOrderMongo.ReplaceOneAsync(userBattleOrder); return (true, currentLevel, totalExp); } public async Task<(bool success, string message, List rewards)> ReceiveAllRewardsAsync(string userId) { var userBattleOrder = await GetUserBattleOrderAsync(userId); var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; if (!IsActivityActive(battleOrderConfig)) return (false, "战令未开启或已结束", new List()); List allRewards = new List(); int maxLevel = battleOrderConfig.LevelConfig?.Count ?? 0; for (int level = 1; level <= userBattleOrder.Level && level <= maxLevel; level++) { var levelConfig = battleOrderConfig.LevelConfig?.FirstOrDefault(c => c.Level == level); if (levelConfig == null) continue; if (!userBattleOrder.NormalReceivedLevels.Contains(level) && levelConfig.NormalGiftList != null && levelConfig.NormalGiftList.Count > 0) { userBattleOrder.NormalReceivedLevels.Add(level); allRewards.AddRange(levelConfig.NormalGiftList); } if ((userBattleOrder.PurchasedAdvances.Contains(1) || userBattleOrder.PurchasedAdvances.Contains(3)) && !userBattleOrder.LuxuryReceivedLevels.Contains(level) && levelConfig.LuxuryGiftList != null && levelConfig.LuxuryGiftList.Count > 0) { userBattleOrder.LuxuryReceivedLevels.Add(level); allRewards.AddRange(levelConfig.LuxuryGiftList); } if ((userBattleOrder.PurchasedAdvances.Contains(2) || userBattleOrder.PurchasedAdvances.Contains(3)) && !userBattleOrder.SupremeReceivedLevels.Contains(level) && levelConfig.SupremeGiftList != null && levelConfig.SupremeGiftList.Count > 0) { userBattleOrder.SupremeReceivedLevels.Add(level); allRewards.AddRange(levelConfig.SupremeGiftList); } } await _userBattleOrderMongo.ReplaceOneAsync(userBattleOrder); return (true, $"领取成功,共{allRewards.Count}个奖励", allRewards); } public async Task<(bool success, string message, List rewards)> ReceiveLevelRewardAsync(string userId, int level) { var userBattleOrder = await GetUserBattleOrderAsync(userId); var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; if (!IsActivityActive(battleOrderConfig)) return (false, "战令未开启或已结束", new List()); if (level <= 0 || level > userBattleOrder.Level) return (false, "等级不满足", new List()); var levelConfig = battleOrderConfig.LevelConfig?.FirstOrDefault(c => c.Level == level); if (levelConfig == null) return (false, "等级配置不存在", new List()); List rewards = new List(); if (!userBattleOrder.NormalReceivedLevels.Contains(level) && levelConfig.NormalGiftList != null && levelConfig.NormalGiftList.Count > 0) { userBattleOrder.NormalReceivedLevels.Add(level); rewards.AddRange(levelConfig.NormalGiftList); } if ((userBattleOrder.PurchasedAdvances.Contains(1) || userBattleOrder.PurchasedAdvances.Contains(3)) && !userBattleOrder.LuxuryReceivedLevels.Contains(level) && levelConfig.LuxuryGiftList != null && levelConfig.LuxuryGiftList.Count > 0) { userBattleOrder.LuxuryReceivedLevels.Add(level); rewards.AddRange(levelConfig.LuxuryGiftList); } if ((userBattleOrder.PurchasedAdvances.Contains(2) || userBattleOrder.PurchasedAdvances.Contains(3)) && !userBattleOrder.SupremeReceivedLevels.Contains(level) && levelConfig.SupremeGiftList != null && levelConfig.SupremeGiftList.Count > 0) { userBattleOrder.SupremeReceivedLevels.Add(level); rewards.AddRange(levelConfig.SupremeGiftList); } if (rewards.Count == 0) return (false, "没有可领取的奖励", new List()); await _userBattleOrderMongo.ReplaceOneAsync(userBattleOrder); return (true, "领取成功", rewards); } public async Task<(bool success, string message, int newLevel, int cost)> BuyLevelsAsync(string userId, int levelCount) { if (levelCount <= 0) return (false, "购买数量不正确", 0, 0); var userBattleOrder = await GetUserBattleOrderAsync(userId); var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; if (!IsActivityActive(battleOrderConfig)) return (false, "战令未开启或已结束", userBattleOrder.Level, 0); int maxLevel = battleOrderConfig.LevelConfig?.Count ?? 1; int availableLevels = maxLevel - userBattleOrder.Level; if (availableLevels <= 0) return (false, "已达到最高等级", userBattleOrder.Level, 0); int actualBuyCount = Math.Min(levelCount, availableLevels); int totalCost = 0; for (int i = 0; i < actualBuyCount; i++) { int targetLevel = userBattleOrder.Level + i + 1; var levelConfig = battleOrderConfig.LevelConfig?.FirstOrDefault(c => c.Level == targetLevel); if (levelConfig != null) { totalCost += levelConfig.PayCount; } } if (totalCost <= 0) return (false, "价格计算错误", userBattleOrder.Level, 0); var user = await _userEntityMongo.FindByIdAsync(userId); if (user == null) return (false, "用户不存在", userBattleOrder.Level, 0); var levelConfig1 = battleOrderConfig.LevelConfig?.FirstOrDefault(c => c.Level == userBattleOrder.Level + 1); int payType = levelConfig1?.PayType ?? 1; if (payType == 1 && user.Assets.Gold < totalCost) return (false, "金币不足", userBattleOrder.Level, 0); if (payType == 2 && user.Assets.Diamond < totalCost) return (false, "钻石不足", userBattleOrder.Level, 0); var assetChangeType = payType == 1 ? UserAssetChangeTypeEnum.减少 : UserAssetChangeTypeEnum.减少; _capPublisher.Publish(TopicKeys.用户资产变更, new UserAssetParam() { ChangeType = assetChangeType, UserId = userId, Gold = payType == 1 ? -totalCost : 0, Diamond = payType == 2 ? -totalCost : 0, Remark = $"购买战令等级×{actualBuyCount}", Source = RewardSource.战令购买 }); userBattleOrder.Level += actualBuyCount; userBattleOrder.Exp = 0; await _userBattleOrderMongo.ReplaceOneAsync(userBattleOrder); return (true, $"购买成功,等级提升{actualBuyCount}级", userBattleOrder.Level, totalCost); } public async Task<(bool success, string message, List purchasedAdvances)> BuyAdvanceAsync(string userId, int type) { if (type <= 0 || type > 3) return (false, "进阶类型不正确", new List()); var userBattleOrder = await GetUserBattleOrderAsync(userId); var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; if (!IsActivityActive(battleOrderConfig)) return (false, "战令未开启或已结束", userBattleOrder.PurchasedAdvances); if (!CanPurchaseAdvance(userBattleOrder.PurchasedAdvances, type)) { return (false, "该进阶已购买或无法购买", userBattleOrder.PurchasedAdvances); } var advanceConfig = battleOrderConfig.AdvanceGift?.FirstOrDefault(c => c.Type == type); if (advanceConfig == null) return (false, "进阶配置不存在", userBattleOrder.PurchasedAdvances); var user = await _userEntityMongo.FindByIdAsync(userId); if (user == null) return (false, "用户不存在", userBattleOrder.PurchasedAdvances); int payType = advanceConfig.PayType; int payCount = advanceConfig.PayCount; if (payType == 1 && user.Assets.Gold < payCount) return (false, "金币不足", userBattleOrder.PurchasedAdvances); if (payType == 2 && user.Assets.Diamond < payCount) return (false, "钻石不足", userBattleOrder.PurchasedAdvances); if (payType == 3) return (false, "暂不支持现金支付", userBattleOrder.PurchasedAdvances); var assetChangeType = UserAssetChangeTypeEnum.减少; _capPublisher.Publish(TopicKeys.用户资产变更, new UserAssetParam() { ChangeType = assetChangeType, UserId = userId, Gold = payType == 1 ? -payCount : 0, Diamond = payType == 2 ? -payCount : 0, Remark = $"购买战令进阶:{advanceConfig.Name}", Source = RewardSource.战令购买 }); userBattleOrder.PurchasedAdvances.Add(type); await _userBattleOrderMongo.ReplaceOneAsync(userBattleOrder); return (true, $"购买成功", userBattleOrder.PurchasedAdvances); } public async Task CreateOrResetBattleOrderAsync(string userId) { var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; var existing = await _userBattleOrderMongo.FindOneAsync(c => c.UserId == userId); if (existing != null) { existing.Level = 1; existing.Exp = 0; existing.PurchasedAdvances = new List(); existing.NormalReceivedLevels = new List(); existing.LuxuryReceivedLevels = new List(); existing.SupremeReceivedLevels = new List(); existing.StartTime = DateTime.Now.ToTimeStamp(); existing.EndTime = battleOrderConfig?.EndTime ?? DateTime.Now.AddDays(30).ToTimeStamp(); await _userBattleOrderMongo.ReplaceOneAsync(existing); return existing; } var userBattleOrder = new UserBattleOrder { UserId = userId, Level = 1, Exp = 0, PurchasedAdvances = new List(), NormalReceivedLevels = new List(), LuxuryReceivedLevels = new List(), SupremeReceivedLevels = new List(), StartTime = DateTime.Now.ToTimeStamp(), EndTime = battleOrderConfig?.EndTime ?? DateTime.Now.AddDays(30).ToTimeStamp() }; await _userBattleOrderMongo.InsertOneAsync(userBattleOrder); return userBattleOrder; } public async Task GetLevelRewardStatusAsync(string userId) { var config = await _activityConfigService.Get(); var battleOrderConfig = config.BattleOrderConfig; var userBattleOrder = await GetUserBattleOrderAsync(userId); int maxLevel = battleOrderConfig.LevelConfig?.Count ?? 0; bool isLuxury = userBattleOrder.PurchasedAdvances.Contains(1) || userBattleOrder.PurchasedAdvances.Contains(3); bool isSupreme = userBattleOrder.PurchasedAdvances.Contains(2) || userBattleOrder.PurchasedAdvances.Contains(3); var list = new List(); for (int i = 1; i <= maxLevel; i++) { var lc = battleOrderConfig.LevelConfig[i - 1]; var status = new BattleOrderLevelStatus { Level = i, Exp = lc.Exp, NormalGiftList = lc.NormalGiftList ?? new List(), LuxuryGiftList = isLuxury ? (lc.LuxuryGiftList ?? new List()) : new List(), SupremeGiftList = isSupreme ? (lc.SupremeGiftList ?? new List()) : new List() }; status.NormalStatus = GetSingleStatus(i, userBattleOrder.Level, userBattleOrder.NormalReceivedLevels); status.LuxuryStatus = isLuxury ? GetSingleStatus(i, userBattleOrder.Level, userBattleOrder.LuxuryReceivedLevels) : 0; status.SupremeStatus = isSupreme ? GetSingleStatus(i, userBattleOrder.Level, userBattleOrder.SupremeReceivedLevels) : 0; list.Add(status); } return new BattleOrderLevelStatusResponse { CurrentLevel = userBattleOrder.Level, CurrentExp = userBattleOrder.Exp, IsLuxury = isLuxury, IsSupreme = isSupreme, LevelStatusList = list }; } private static int GetSingleStatus(int level, int userLevel, List receivedLevels) { if (receivedLevels.Contains(level)) return 3; if (userLevel >= level) return 2; return 1; } private static bool IsActivityActive(BattleOrderConfig config) { if (!config.IsOpen) return false; return config.EndTime <= 0 || config.EndTime > DateTimeOffset.UtcNow.ToUnixTimeSeconds(); } private bool CanPurchaseAdvance(List purchasedAdvances, int newType) { if (purchasedAdvances.Contains(3)) return false; if (purchasedAdvances.Contains(newType)) return false; if (newType == 3 && purchasedAdvances.Contains(1)) return false; if (newType == 3 && purchasedAdvances.Contains(2)) return false; return true; } } }