516 lines
22 KiB
C#
516 lines
22 KiB
C#
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<UserBattleOrder> _userBattleOrderMongo;
|
|
private readonly IMongoBaseRepository<UserEntity> _userEntityMongo;
|
|
private readonly IActivityConfigService _activityConfigService;
|
|
private readonly ICapPublisher _capPublisher;
|
|
private readonly IRedisService _redisService;
|
|
private readonly IMapper _mapper;
|
|
|
|
public BattleOrderService(
|
|
IMongoBaseRepository<UserBattleOrder> userBattleOrderMongo,
|
|
IMongoBaseRepository<UserEntity> userEntityMongo,
|
|
IActivityConfigService activityConfigService,
|
|
ICapPublisher capPublisher,
|
|
IRedisService redisService,
|
|
IMapper mapper)
|
|
{
|
|
_userBattleOrderMongo = userBattleOrderMongo;
|
|
_userEntityMongo = userEntityMongo;
|
|
_activityConfigService = activityConfigService;
|
|
_capPublisher = capPublisher;
|
|
_redisService = redisService;
|
|
_mapper = mapper;
|
|
}
|
|
|
|
public async Task<UserBattleOrder> 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<BattleOrderResponse> 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<int>();
|
|
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<GiftConfig>(),
|
|
LuxuryGiftList = l.LuxuryGiftList ?? new List<GiftConfig>(),
|
|
SupremeGiftList = l.SupremeGiftList ?? new List<GiftConfig>()
|
|
}).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<GiftConfig> 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<GiftConfig>());
|
|
|
|
List<GiftConfig> allRewards = new List<GiftConfig>();
|
|
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<GiftConfig> 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<GiftConfig>());
|
|
|
|
if (level <= 0 || level > userBattleOrder.Level)
|
|
return (false, "等级不满足", new List<GiftConfig>());
|
|
|
|
var levelConfig = battleOrderConfig.LevelConfig?.FirstOrDefault(c => c.Level == level);
|
|
if (levelConfig == null)
|
|
return (false, "等级配置不存在", new List<GiftConfig>());
|
|
|
|
List<GiftConfig> rewards = new List<GiftConfig>();
|
|
|
|
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<GiftConfig>());
|
|
|
|
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<int> purchasedAdvances)> BuyAdvanceAsync(string userId, int type)
|
|
{
|
|
if (type <= 0 || type > 3)
|
|
return (false, "进阶类型不正确", new List<int>());
|
|
|
|
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<UserBattleOrder> 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<int>();
|
|
existing.NormalReceivedLevels = new List<int>();
|
|
existing.LuxuryReceivedLevels = new List<int>();
|
|
existing.SupremeReceivedLevels = new List<int>();
|
|
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<int>(),
|
|
NormalReceivedLevels = new List<int>(),
|
|
LuxuryReceivedLevels = new List<int>(),
|
|
SupremeReceivedLevels = new List<int>(),
|
|
StartTime = DateTime.Now.ToTimeStamp(),
|
|
EndTime = battleOrderConfig?.EndTime ?? DateTime.Now.AddDays(30).ToTimeStamp()
|
|
};
|
|
|
|
await _userBattleOrderMongo.InsertOneAsync(userBattleOrder);
|
|
return userBattleOrder;
|
|
}
|
|
|
|
public async Task<BattleOrderLevelStatusResponse> 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<BattleOrderLevelStatus>();
|
|
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<GiftConfig>(),
|
|
LuxuryGiftList = isLuxury ? (lc.LuxuryGiftList ?? new List<GiftConfig>()) : new List<GiftConfig>(),
|
|
SupremeGiftList = isSupreme ? (lc.SupremeGiftList ?? new List<GiftConfig>()) : new List<GiftConfig>()
|
|
};
|
|
|
|
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<int> 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<int> 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;
|
|
}
|
|
}
|
|
}
|