Files
BuYuHouDuan/CommonService/BackgroundOperationService.cs
T
2026-10-12 16:22:04 +08:00

260 lines
9.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Common;
using CommonDomain;
using CommonDomain.BaseModel;
using Domain.Admin.Admin;
using DotNetCore.CAP;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using MongoRepository;
using RedisService;
using UserDomain.Entity;
using UserService.User;
using UserService.Param;
using UserDomain.Enum;
namespace CommonService
{
public class BackgroundOperationService : IBackgroundOperationService
{
private readonly IMongoBaseRepository<BackgroundOperationLog> _logRepo;
private readonly IUserService _userService;
private readonly ICapPublisher _capPublisher;
private readonly IMongoBaseRepository<SystemUser> _adminRepo;
private readonly IRedisService _redisService;
private readonly ILogger<BackgroundOperationService> _logger;
public BackgroundOperationService(
IMongoBaseRepository<BackgroundOperationLog> logRepo,
IUserService userService,
ICapPublisher capPublisher,
IMongoBaseRepository<SystemUser> adminRepo,
IRedisService redisService,
ILogger<BackgroundOperationService> logger)
{
_logRepo = logRepo;
_userService = userService;
_capPublisher = capPublisher;
_adminRepo = adminRepo;
_redisService = redisService;
_logger = logger;
}
public async Task<(bool success, string message)> Charge(
string adminUserId, string targetUserId, int currencyType, long amount, string remark)
{
var targetUser = await _userService.GetUser(targetUserId);
if (targetUser == null)
return (false, "目标用户不存在");
var isBuiltInAdmin = adminUserId == "administrator";
var adminUser = isBuiltInAdmin
? new SystemUser { Id = "administrator", UserName = "administrator" }
: await _adminRepo.FindByIdAsync(adminUserId);
if (adminUser == null)
return (false, "管理员用户不存在");
if (currencyType == 1)
{
targetUser.Assets.Gold += amount;
}
else if (currencyType == 2)
{
targetUser.Assets.Diamond += (int)amount;
var rechargeMoney = amount / 100.0;
targetUser.Static.TotalRecharge += rechargeMoney;
try
{
var gameConfig = _redisService.GetGameConfig();
var newVipLevels = targetUser.VipLevelVerify(gameConfig);
if (newVipLevels != null && newVipLevels.Count > 0)
{
var levelNames = string.Join(",", newVipLevels);
_capPublisher.Publish("VipLevelUp", new
{
UserId = targetUserId,
NewLevels = newVipLevels,
Remark = $"后台充值钻石触发VIP升级: {levelNames}"
});
}
}
catch (Exception ex)
{
_logger.LogError(ex, "后台充值更新VIP失败 userId={UserId}", targetUserId);
}
}
else
{
return (false, "不支持的货币类型");
}
await _userService.UpdateUser(targetUser);
var logId = "";
if (!isBuiltInAdmin)
{
var log = new BackgroundOperationLog
{
AdminUserId = adminUserId,
AdminUserName = adminUser.UserName ?? adminUserId,
TargetUserId = targetUserId,
TargetUserName = targetUser.BaseInfo.UserName,
OperationType = 1,
CurrencyType = currencyType,
Amount = amount,
Remark = remark,
OperationTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
};
await _logRepo.InsertOneAsync(log);
logId = log.Id;
}
_capPublisher.Publish("UserAssetChange", new UserAssetParam
{
UserId = targetUserId,
ChangeType = UserAssetChangeTypeEnum.增加,
Gold = currencyType == 1 ? amount : 0,
Diamond = currencyType == 2 ? (int)amount : 0,
Source = RewardSource.后台操作,
Remark = $"后台充值:{remark}",
OtherId = logId,
RoomName = "后台操作",
RoomInfo = "后台充值"
});
_capPublisher.Publish("BackgroundOperation.NotifyUser", new BackgroundOperationNotifyMessage
{
UserId = targetUserId,
CurrencyType = currencyType,
ChangeType = 1,
Amount = amount,
NewGold = targetUser.Assets.Gold,
NewDiamond = targetUser.Assets.Diamond,
Source = "后台充值",
Remark = remark
});
return (true, "充值成功");
}
public async Task<(bool success, string message)> Deduct(
string adminUserId, string targetUserId, int currencyType, long amount, string remark)
{
var targetUser = await _userService.GetUser(targetUserId);
if (targetUser == null)
return (false, "目标用户不存在");
if (currencyType == 1)
{
if (targetUser.Assets.Gold < amount)
return (false, "用户金币余额不足");
}
else if (currencyType == 2)
{
if (targetUser.Assets.Diamond < amount)
return (false, "用户钻石余额不足");
}
else
{
return (false, "不支持的货币类型");
}
var isBuiltInAdmin2 = adminUserId == "administrator";
var adminUser = isBuiltInAdmin2
? new SystemUser { Id = "administrator", UserName = "administrator" }
: await _adminRepo.FindByIdAsync(adminUserId);
var adminUserName = adminUser?.UserName ?? adminUserId;
if (currencyType == 1)
{
targetUser.Assets.Gold -= amount;
}
else if (currencyType == 2)
{
targetUser.Assets.Diamond -= (int)amount;
}
await _userService.UpdateUser(targetUser);
var logId2 = "";
if (!isBuiltInAdmin2)
{
var log = new BackgroundOperationLog
{
AdminUserId = adminUserId,
AdminUserName = adminUserName,
TargetUserId = targetUserId,
TargetUserName = targetUser.BaseInfo.UserName,
OperationType = 2,
CurrencyType = currencyType,
Amount = amount,
Remark = remark,
OperationTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
};
await _logRepo.InsertOneAsync(log);
logId2 = log.Id;
}
_capPublisher.Publish("UserAssetChange", new UserAssetParam
{
UserId = targetUserId,
ChangeType = UserAssetChangeTypeEnum.减少,
Gold = currencyType == 1 ? amount : 0,
Diamond = currencyType == 2 ? (int)amount : 0,
Source = RewardSource.后台操作,
Remark = $"后台扣除:{remark}",
OtherId = logId2,
RoomName = "后台操作",
RoomInfo = "后台扣除"
});
_capPublisher.Publish("BackgroundOperation.NotifyUser", new BackgroundOperationNotifyMessage
{
UserId = targetUserId,
CurrencyType = currencyType,
ChangeType = 2,
Amount = amount,
NewGold = targetUser.Assets.Gold,
NewDiamond = targetUser.Assets.Diamond,
Source = "后台扣除",
Remark = remark
});
return (true, "扣除成功");
}
public async Task<(List<BackgroundOperationLog> data, int total)> QueryLogs(
string? adminUserId = null,
string? targetUserId = null,
int? operationType = null,
int pageIndex = 1,
int pageSize = 20)
{
var where = LinqExtensions.True<BackgroundOperationLog>();
if (!string.IsNullOrEmpty(adminUserId))
where = where.And(l => l.AdminUserId == adminUserId);
if (!string.IsNullOrEmpty(targetUserId))
where = where.And(l => l.TargetUserId == targetUserId);
if (operationType.HasValue)
where = where.And(l => l.OperationType == operationType.Value);
var total = await _logRepo.CountAsync(where);
var (count, list) = await _logRepo.QueryPageAsync(where, l => l.OperationTime, false, pageSize, pageIndex);
return (list, (int)total);
}
public async Task<UserEntity> SearchUser(string keyword)
{
var user = await _userService.SearchUser(keyword);
return user;
}
}
}