添加项目文件。

This commit is contained in:
2026-10-12 16:22:04 +08:00
parent 7c68a0ca0a
commit aad11be43d
1000 changed files with 120807 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ChessGameSrc\ChessGameDomain\ChessGameDomain.csproj" />
<ProjectReference Include="..\..\ChessGameSrc\ChessGameService\ChessGameService.csproj" />
<ProjectReference Include="..\..\FishRoomService\FishRoomService.csproj" />
<ProjectReference Include="..\..\CustomerSrc\CustomerService.Domain\CustomerService.Domain.csproj" />
<ProjectReference Include="..\AdminService\AdminService.csproj" />
<ProjectReference Include="..\AdminApplication\AdminApplication.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Lottery\" />
</ItemGroup>
</Project>
@@ -0,0 +1,665 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AdminService.GameConfigs;
using AdminService.User;
using AdminService.User.Param;
using AdminService.User.Response;
using Common;
using Common.Utils;
using CommonDomain;
using CommonDomain.BaseModel;
using CommonDomain.Enum;
using CommonInfrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RedisService;
using UserDomain.Entity;
namespace AdminApi.AdminUser
{
[ApiController, Route("adminapi/[controller]")]
[Authorize]
public class AdminUserController : BaseController
{
private readonly IAdminUserService _userService;
private readonly IRedisService _redisService;
public AdminUserController(IAdminUserService userService, IRedisService redisService)
{
_userService = userService;
_redisService = redisService;
}
[HttpPost("GetUserList")]
public async Task<PageResponse<UserListItemDto>> GetUserList(AdminUserListParam param)
{
var result = await _userService.GetAdminUserList(param);
var onlineUserIds = _redisService.GetAllLoginUserIds().ToHashSet(StringComparer.Ordinal);
var dtos = (result.list ?? new List<UserEntity>()).Select(u =>
{
var dto = MapToUserListItemDto(u);
dto.IsOnline = onlineUserIds.Contains(u.Id);
if (dto.CurrentGameType != 3)
{
var session = _redisService.GetRedisUserCId(u.Id);
if (session == null || string.IsNullOrWhiteSpace(session.RoomId))
{
dto.CurrentGameType = 0;
dto.RoomNumber = "";
}
}
return dto;
}).ToList();
return this.ToPageResult(dtos, result.count);
}
[HttpGet("GetUserDetail")]
public async Task<BaseResponse<UserEntity>> GetUserDetail(string userId)
{
var result = await _userService.GetUser(userId);
if (result == null)
return this.ToFailResult<UserEntity>("用户不存在");
return this.ToResult(result);
}
[HttpPost("UpdateUserAssets")]
public async Task<BaseResponse<string>> UpdateUserAssets(UpdateUserAssetsParam param)
{
var result = await _userService.UpdateUserAssets(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("GetUserStatistics")]
public async Task<BaseResponse<UserStatisticsDto>> GetUserStatistics()
{
var result = await _userService.GetUserStatistics();
return this.ToResult(MapToUserStatisticsDto(result));
}
[HttpGet("GetEmailStatistics")]
public async Task<BaseResponse<EmailStatisticsDto>> GetEmailStatistics()
{
var result = await _userService.GetEmailStatistics();
return this.ToResult(MapToEmailStatisticsDto(result));
}
[HttpPost("BatchBanUser")]
public async Task<BaseResponse<string>> BatchBanUser(BatchBanUserParam param)
{
var result = await _userService.BatchBanUser(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("UnbanUser")]
public async Task<BaseResponse<string>> UnbanUser(string userId)
{
var result = await _userService.UnbanUser(userId);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("BatchSendEmail")]
public async Task<BaseResponse<string>> BatchSendEmail(BatchSendEmailParam param)
{
var result = await _userService.BatchSendEmail(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("CancelUser")]
[Authorize]
public async Task<BaseResponse<string>> CancelUser()
{
var result = await _userService.CancelUser(loginUser);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("DeleteUser")]
[Authorize]
public async Task<BaseResponse<string>> DeleteUser(string id)
{
var result = await _userService.DeleteUser(id);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("BatchDeleteUser")]
[Authorize]
public async Task<BaseResponse<string>> BatchDeleteUser([FromBody] BatchDeleteUserParam param)
{
var result = await _userService.BatchDeleteUser(param.UserIds);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("BanUser")]
[Authorize]
public async Task<BaseResponse<string>> BanUser([FromBody] BanUserParam param)
{
var result = await _userService.BanUser(param.UserId, param.Reason, param.Days);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("UpdateUser")]
[Authorize]
public async Task<BaseResponse<string>> UpdateUser(UpdateUserDataParam param)
{
var result = await _userService.UpdateUser(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("SendEmail")]
[Authorize]
public async Task<BaseResponse<string>> SendEmail(SendEmailParam param)
{
var result = await _userService.SendEmail(param, loginUser);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("GetEmailList")]
[Authorize]
public async Task<PageResponse<EmailListItemDto>> GetEmailList([FromBody] EmailListQueryParam param)
{
var (list, count) = await _userService.GetEmailList(param);
var userIds = list.Where(e => !string.IsNullOrWhiteSpace(e.UserId))
.Select(e => e.UserId).Distinct().ToList();
var userNames = await _userService.GetEmailUserNamesAsync(userIds);
var dtos = list.Select(e =>
{
userNames.TryGetValue(e.UserId ?? "", out var info);
return new EmailListItemDto
{
Id = e.Id,
UserId = e.UserId ?? "",
UserName = info.UserName,
UserNumber = info.UserNumber,
Title = e.Title ?? "",
IsRead = e.IsRead,
IsReward = e.IsReward,
RewardGold = e.RewardGold,
RewardDiamond = e.RewardDiamond,
SendTime = e.SendTime,
ReadTime = e.ReadTime,
ExpireTime = e.ExpireTime,
RewardText = BuildRewardText(e)
};
}).ToList();
return this.ToPageResult(dtos, (int)count);
}
[HttpGet("DeleteEmail")]
[Authorize]
public async Task<BaseResponse<string>> DeleteEmail(string id)
{
var result = await _userService.DeleteEmail(id);
if (result.ok)
return this.ToResult("删除成功");
else
return this.ToFailResult<string>(result.message ?? "删除失败");
}
[HttpPost("BatchDeleteEmail")]
[Authorize]
public async Task<BaseResponse<string>> BatchDeleteEmail([FromBody] List<string> ids)
{
var (success, fail) = await _userService.BatchDeleteEmail(ids);
if (fail == 0)
return this.ToResult($"成功删除 {success} 条");
return this.ToResult($"删除完成:成功 {success} 条,失败 {fail} 条");
}
[HttpPost("SetUserType")]
public async Task<BaseResponse<string>> SetUserType(string userId, int userType)
{
var result = await _userService.SetUserType(userId, userType);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("BatchSetUserType")]
public async Task<BaseResponse<string>> BatchSetUserType([FromBody] BatchSetUserTypeParam param)
{
var result = await _userService.BatchSetUserType(param.UserIds, param.UserType);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("SetBlackUser")]
public async Task<BaseResponse<string>> SetBlackUser(string userId, bool isBlack)
{
var result = await _userService.SetBlackUser(userId, isBlack);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("BatchSetBlackUser")]
public async Task<BaseResponse<string>> BatchSetBlackUser([FromBody] BatchSetBlackUserParam param)
{
var result = await _userService.BatchSetBlackUser(param.UserIds, param.IsBlack);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("UpdateUserFactor")]
public async Task<BaseResponse<string>> UpdateUserFactor([FromBody] UpdateUserFactorFlatParam param)
{
var factor = new PlayerFactor
{
ViolateValue = param.ViolateValue,
MissRate = param.MissRate,
CompensateQuota = param.CompensateQuota,
PenaltyQuota = param.PenaltyQuota,
CompensateRate = param.CompensateRate,
PenaltyRate = param.PenaltyRate,
AdditionalFactor = param.AdditionalFactor
};
var result = await _userService.UpdateUserFactor(param.UserId, factor);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("GetBlackFactorConfig")]
public async Task<BaseResponse<PlayerFactorDto>> GetBlackFactorConfig()
{
var result = await _userService.GetBlackFactorConfig();
return this.ToResult(MapToPlayerFactorDto(result));
}
[HttpPost("ResetUserFactor")]
public async Task<BaseResponse<string>> ResetUserFactor(string userId)
{
var result = await _userService.ResetUserFactor(userId);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("InitUserPassword")]
public async Task<BaseResponse<string>> InitUserPassword([FromQuery] string userId)
{
var result = await _userService.InitUserPassword(userId);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("InitSafeBoxPassword")]
public async Task<BaseResponse<string>> InitSafeBoxPassword([FromQuery] string userId)
{
var result = await _userService.InitSafeBoxPassword(userId);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("GetUserFactorList")]
public async Task<PageResponse<UserFactorListItemDto>> GetUserFactorList([FromBody] UserFactorListParam param)
{
var result = await _userService.GetUserFactorList(param);
var pageIps = (result.list ?? new List<UserEntity>())
.Where(u => !string.IsNullOrEmpty(u.RegisterIp))
.Select(u => u.RegisterIp!)
.Distinct()
.ToList();
Dictionary<string, int> ipCounts = new Dictionary<string, int>();
if (pageIps.Count > 0)
{
var allUsersWithSameIp = await _userService.GetUsersByRegisterIps(pageIps);
ipCounts = allUsersWithSameIp
.GroupBy(u => u.RegisterIp)
.ToDictionary(g => g.Key, g => g.Count());
}
var dtos = (result.list ?? new List<UserEntity>()).Select(u => new UserFactorListItemDto
{
Id = u.Id,
Number = u.BaseInfo?.Number ?? "",
UserName = u.BaseInfo?.UserName ?? "",
Mobile = u.BaseInfo?.Mobile ?? "",
UserType = u.UserType,
RegisterIp = u.RegisterIp ?? "",
LoginIp = u.Static?.LastLoginIp ?? "",
IpCount = !string.IsNullOrEmpty(u.RegisterIp) && ipCounts.ContainsKey(u.RegisterIp) ? ipCounts[u.RegisterIp] : 1,
IsBlack = u.PlayerFactor?.IsBlack ?? false,
ViolateValue = u.PlayerFactor?.ViolateValue ?? 0.2,
MissRate = u.PlayerFactor?.MissRate ?? 0,
CompensateQuota = u.PlayerFactor?.CompensateQuota ?? 0,
PenaltyQuota = u.PlayerFactor?.PenaltyQuota ?? 0,
CompensateRate = u.PlayerFactor?.CompensateRate != null ? new CompensateRateDto
{
BossRate = u.PlayerFactor.CompensateRate.BossRate,
GoldRate = u.PlayerFactor.CompensateRate.GoldRate,
SpecialRate = u.PlayerFactor.CompensateRate.SpecialRate,
Ordinary = u.PlayerFactor.CompensateRate.Ordinary
} : new CompensateRateDto(),
PenaltyRate = u.PlayerFactor?.PenaltyRate != null ? new PenaltyRateDto
{
BossRate = u.PlayerFactor.PenaltyRate.BossRate,
GoldRate = u.PlayerFactor.PenaltyRate.GoldRate,
SpecialRate = u.PlayerFactor.PenaltyRate.SpecialRate,
Ordinary = u.PlayerFactor.PenaltyRate.Ordinary
} : new PenaltyRateDto(),
CreateTime = u.CreateTime,
TotalRecharge = u.Static?.TotalRecharge ?? 0,
TotalRechargeGold = u.Static?.TotalRechargeGold ?? 0,
TotalConsumeGold = u.Static?.TotalConsumeGold ?? 0,
CurrentGold = u.Assets?.Gold ?? 0,
Profit = (u.Assets?.Gold ?? 0) - ((u.Static?.TotalRechargeGold ?? 0) + (u.PlayerFactor?.StartingBonus ?? 0)),
AdditionalFactor = u.PlayerFactor?.AdditionalFactor ?? 0,
StartingBonus = u.PlayerFactor?.StartingBonus ?? 0
});
return this.ToPageResult(dtos, result.count);
}
private static UserListItemDto MapToUserListItemDto(UserEntity entity)
{
return new UserListItemDto
{
Id = entity.Id,
Number = entity.BaseInfo?.Number ?? "",
NickName = entity.BaseInfo?.UserName ?? "",
Avatar = entity.BaseInfo?.AvatarUrl ?? "",
Mobile = entity.BaseInfo?.Mobile ?? "",
Diamond = entity.Assets?.Diamond ?? 0,
Gold = entity.Assets?.Gold ?? 0,
SafeBoxGold = entity.SafeBox?.Amount ?? 0,
VipLevel = entity.Assets?.VipLevel ?? 0,
UserType = entity.UserType,
IsBan = entity.BanInfo?.IsBan ?? false,
BanReason = entity.BanInfo?.BanReason,
BanEndTime = entity.BanInfo?.BanEndTime ?? 0,
IsBlack = entity.PlayerFactor?.IsBlack ?? false,
RegisterTime = entity.CreateTime,
RegisterIp = entity.RegisterIp ?? "",
LastLoginIp = entity.Static?.LastLoginIp ?? "",
LastLoginTime = entity.Static?.LastLoginTime ?? 0,
RoomNumber = entity.Static?.RoomNumber ?? "",
CurrentGameType = entity.Static?.CurrentGameType ?? 0,
Channel = entity.BaseInfo?.Channel ?? "",
TotalRecharge = (long)(entity.Static?.TotalRecharge ?? 0)
};
}
private static UserStatisticsDto MapToUserStatisticsDto(UserStatistics stat)
{
return new UserStatisticsDto
{
TotalUsers = stat.TotalUsers,
TodayRegisteredUsers = stat.TodayRegisteredUsers,
MonthRegisteredUsers = stat.MonthRegisteredUsers,
OnlineUsers = stat.OnlineUsers,
BannedUsers = stat.BannedUsers,
VipUsers = stat.VipUsers,
VipLevelCount = stat.VipLevelCount ?? new Dictionary<int, long>(),
TotalGold = stat.TotalGold,
TotalDiamond = stat.TotalDiamond
};
}
private static EmailStatisticsDto MapToEmailStatisticsDto(EmailStatistics stat)
{
return new EmailStatisticsDto
{
TotalEmails = stat.TotalEmails,
RewardEmails = stat.RewardEmails,
UnclaimedEmails = stat.UnclaimedEmails,
TodayEmails = stat.TodayEmails,
MonthEmails = stat.MonthEmails
};
}
private static PlayerFactorDto MapToPlayerFactorDto(PlayerFactor factor)
{
if (factor == null)
return new PlayerFactorDto();
return new PlayerFactorDto
{
IsBlack = factor.IsBlack,
IsIgnore = factor.IsIgnore,
ViolateValue = factor.ViolateValue,
CompensateRate = factor.CompensateRate?.BossRate ?? 1,
PenaltyRate = factor.PenaltyRate?.BossRate ?? 0,
CompensateQuota = factor.CompensateQuota,
PenaltyQuota = factor.PenaltyQuota,
StartingBonus = factor.StartingBonus
};
}
private static string BuildRewardText(UserEmail email)
{
var parts = new List<string>();
if (email.RewardGold > 0)
parts.Add($"金币{email.RewardGold:N0}");
if (email.RewardDiamond > 0)
parts.Add($"钻石{email.RewardDiamond}");
if (email.RewardItems != null)
{
foreach (var item in email.RewardItems)
{
if (item != null && !string.IsNullOrWhiteSpace(item.Name))
parts.Add($"{item.Name}*{item.Count}");
}
}
return parts.Count > 0 ? string.Join(" ", parts) : "无";
}
[HttpGet("GetUserProps")]
public async Task<BaseResponse<List<BaseProductCount>>> GetUserProps(string userId)
{
var result = await _userService.GetUserProps(userId);
return this.ToResult(result);
}
[HttpPost("AddUserProp")]
public async Task<BaseResponse<string>> AddUserProp(string userId, string propNumber, int count)
{
var res = await _userService.AddUserProp(userId, propNumber, count);
if (res.isok) return this.ToResult(res.msg);
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateUserPropCount")]
public async Task<BaseResponse<string>> UpdateUserPropCount(string userId, string propNumber, int count)
{
var res = await _userService.UpdateUserPropCount(userId, propNumber, count);
if (res.isok) return this.ToResult(res.msg);
return this.ToFailResult<string>(res.msg);
}
[HttpPost("DeleteUserProp")]
public async Task<BaseResponse<string>> DeleteUserProp(string userId, string propNumber)
{
var res = await _userService.DeleteUserProp(userId, propNumber);
if (res.isok) return this.ToResult(res.msg);
return this.ToFailResult<string>(res.msg);
}
[HttpGet("SyncAllUserLevel")]
public async Task<BaseResponse<string>> SyncAllUserLevel()
{
var (total, updated, msg) = await _userService.SyncAllUserLevel();
return this.ToResult(msg);
}
}
public class UserListItemDto
{
public string Id { get; set; }
public string Number { get; set; }
public string NickName { get; set; }
public string Avatar { get; set; }
public string Mobile { get; set; }
public int Diamond { get; set; }
public long Gold { get; set; }
public long SafeBoxGold { get; set; }
public int VipLevel { get; set; }
public int UserType { get; set; }
public bool IsBan { get; set; }
public string BanReason { get; set; }
public long BanEndTime { get; set; }
public bool IsBlack { get; set; }
public long RegisterTime { get; set; }
public string RegisterIp { get; set; }
public string LastLoginIp { get; set; }
public long LastLoginTime { get; set; }
public string RoomNumber { get; set; }
public int CurrentGameType { get; set; }
public bool IsOnline { get; set; }
public string Channel { get; set; }
public long TotalRecharge { get; set; }
}
public class UserStatisticsDto
{
public long TotalUsers { get; set; }
public long TodayRegisteredUsers { get; set; }
public long MonthRegisteredUsers { get; set; }
public long OnlineUsers { get; set; }
public long BannedUsers { get; set; }
public long VipUsers { get; set; }
public Dictionary<int, long> VipLevelCount { get; set; }
public long TotalGold { get; set; }
public long TotalDiamond { get; set; }
}
public class EmailStatisticsDto
{
public long TotalEmails { get; set; }
public long RewardEmails { get; set; }
public long UnclaimedEmails { get; set; }
public long TodayEmails { get; set; }
public long MonthEmails { get; set; }
}
public class PlayerFactorDto
{
public bool IsBlack { get; set; }
public bool IsIgnore { get; set; }
public double ViolateValue { get; set; }
public double CompensateRate { get; set; }
public double PenaltyRate { get; set; }
public int CompensateQuota { get; set; }
public int PenaltyQuota { get; set; }
public long StartingBonus { get; set; }
}
public class UserFactorListItemDto
{
public string Id { get; set; }
public string Number { get; set; }
public string UserName { get; set; }
public string Mobile { get; set; }
public int UserType { get; set; }
public string RegisterIp { get; set; }
public string LoginIp { get; set; }
public int IpCount { get; set; }
public bool IsBlack { get; set; }
public double ViolateValue { get; set; }
public double MissRate { get; set; }
public int CompensateQuota { get; set; }
public int PenaltyQuota { get; set; }
public CompensateRateDto CompensateRate { get; set; }
public PenaltyRateDto PenaltyRate { get; set; }
public long CreateTime { get; set; }
public double TotalRecharge { get; set; }
public long TotalRechargeGold { get; set; }
public long TotalConsumeGold { get; set; }
public long CurrentGold { get; set; }
public long Profit { get; set; }
public double AdditionalFactor { get; set; }
public long StartingBonus { get; set; }
}
public class CompensateRateDto
{
public double BossRate { get; set; } = 1;
public double GoldRate { get; set; } = 1;
public double SpecialRate { get; set; } = 1;
public double Ordinary { get; set; } = 1;
}
public class PenaltyRateDto
{
public double BossRate { get; set; } = 1;
public double GoldRate { get; set; } = 1;
public double SpecialRate { get; set; } = 1;
public double Ordinary { get; set; } = 1;
}
public class BanUserParam
{
public string UserId { get; set; } = "";
public string Reason { get; set; } = "";
public int Days { get; set; } = 0;
}
public class EmailListItemDto
{
public string Id { get; set; } = "";
public string UserId { get; set; } = "";
public string UserName { get; set; } = "";
public string UserNumber { get; set; } = "";
public string Title { get; set; } = "";
public bool IsRead { get; set; }
public bool IsReward { get; set; }
public long RewardGold { get; set; }
public int RewardDiamond { get; set; }
public long SendTime { get; set; }
public long ReadTime { get; set; }
public long ExpireTime { get; set; }
public string RewardText { get; set; } = "";
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace AdminApi
{
public static class AssemblyMarker
{
}
}
@@ -0,0 +1,114 @@
using System.Threading.Tasks;
using Common;
using CommonDomain;
using CommonInfrastructure;
using CommonInfrastructure.Response;
using CommonService;
using CommonService.BackgroundOperation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using UserDomain.Entity;
namespace AdminApi.BackgroundOperation
{
[Authorize]
[Route("adminapi/[controller]")]
[ApiController]
public class BackgroundOperationController : BaseController
{
private readonly IBackgroundOperationService _operationService;
public BackgroundOperationController(IBackgroundOperationService operationService)
{
_operationService = operationService;
}
[HttpPost("charge")]
public async Task<BaseResponse<string>> Charge([FromBody] BackgroundOperationRequest request)
{
if (request == null || string.IsNullOrWhiteSpace(request.TargetUserId))
return this.ToFailResult<string>("目标用户ID不能为空");
if (request.Amount <= 0)
return this.ToFailResult<string>("操作数量必须大于0");
var (success, message) = await _operationService.Charge(
loginUser.UserId, request.TargetUserId, request.CurrencyType, request.Amount, request.Remark);
return success
? this.ToResult("充值成功")
: this.ToFailResult<string>(message);
}
[HttpPost("deduct")]
public async Task<BaseResponse<string>> Deduct([FromBody] BackgroundOperationRequest request)
{
if (request == null || string.IsNullOrWhiteSpace(request.TargetUserId))
return this.ToFailResult<string>("目标用户ID不能为空");
if (request.Amount <= 0)
return this.ToFailResult<string>("操作数量必须大于0");
var (success, message) = await _operationService.Deduct(
loginUser.UserId, request.TargetUserId, request.CurrencyType, request.Amount, request.Remark);
return success
? this.ToResult("扣除成功")
: this.ToFailResult<string>(message);
}
[HttpGet("logs")]
public async Task<PageResponse<BackgroundOperationLog>> GetLogs(
string? adminUserId = null,
string? targetUserId = null,
int? operationType = null,
int pageIndex = 1,
int pageSize = 20)
{
var (data, total) = await _operationService.QueryLogs(
adminUserId, targetUserId, operationType, pageIndex, pageSize);
return this.ToPageResult(data, total);
}
[HttpGet("search-user")]
public async Task<BaseResponse<SearchUserResponse>> SearchUser(string keyword)
{
if (string.IsNullOrWhiteSpace(keyword))
{
return this.ToFailResult<SearchUserResponse>("搜索关键词不能为空");
}
var user = await _operationService.SearchUser(keyword);
if (user == null)
{
return this.ToFailResult<SearchUserResponse>("用户不存在");
}
var dto = new SearchUserResponse
{
UserId = user.Id,
UserName = user.BaseInfo?.UserName ?? "",
UserPhone = user.BaseInfo?.Mobile ?? "",
Gold = user.Assets?.Gold ?? 0,
Diamond = user.Assets?.Diamond ?? 0,
RegisterTime = user.CreateTime / 1000
};
return this.ToResult(dto);
}
}
public class SearchUserResponse
{
public string UserId { get; set; }
public string UserName { get; set; }
public string UserPhone { get; set; }
public long Gold { get; set; }
public int Diamond { get; set; }
public long RegisterTime { get; set; }
}
}
@@ -0,0 +1,384 @@
using System.Collections.Generic;
using System.Linq;
using AdminDomain.BeautifulNumber;
using AdminDomain.Entity;
using AdminService.BeautifulNumber;
using Common;
using CommonInfrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using UserDomain.Entity;
namespace AdminApi.BeautifulNumber
{
[ApiController, Route("adminapi/[controller]")]
[Authorize]
public class BeautifulNumberController : BaseController
{
private readonly IBeautifulNumberService _beautifulNumberService;
public BeautifulNumberController(IBeautifulNumberService beautifulNumberService)
{
_beautifulNumberService = beautifulNumberService;
}
[HttpGet("list")]
public async Task<PageResponse<BeautifulNumberDto>> GetList([FromQuery] BeautifulNumberListParam param)
{
param.page = param.page > 0 ? param.page : 1;
param.size = param.size > 0 ? param.size : 20;
var result = await _beautifulNumberService.GetList(param);
var dtos = result.list.Select(MapToDto).ToList();
return this.ToPageResult(dtos, (int)result.count);
}
[HttpGet("available")]
public async Task<PageResponse<BeautifulNumberDto>> GetAvailableList([FromQuery] BeautifulNumberListParam param)
{
param.page = param.page > 0 ? param.page : 1;
param.size = param.size > 0 ? param.size : 20;
param.status = (int)BeautifulNumberStatus.Available;
var result = await _beautifulNumberService.GetList(param);
var dtos = result.list.Select(MapToDto).ToList();
return this.ToPageResult(dtos, (int)result.count);
}
[HttpGet("check/{number}")]
public async Task<BaseResponse<BeautifulNumberDto>> CheckNumber(string number)
{
var result = await _beautifulNumberService.CheckNumber(number);
return this.ToResult(MapToDto(result));
}
private static BeautifulNumberDto MapToDto(BeautifulNumberConfig entity)
{
if (entity == null) return new BeautifulNumberDto();
return new BeautifulNumberDto
{
Id = entity.Id ?? "",
Number = entity.Number ?? "",
RuleName = entity.RuleName ?? "",
Level = entity.Level ?? "",
Price = entity.Price,
Status = (int)entity.Status,
SaleTime = entity.SaleTime,
BuyerUserId = entity.BuyerUserId ?? "",
UserId = entity.UserId ?? "",
Remark = entity.Remark ?? "",
CreateTime = entity.CreateTime
};
}
[HttpPost("delete")]
public async Task<BaseResponse<string>> Delete([FromBody] DeleteBeautifulNumberParam param)
{
var result = await _beautifulNumberService.Delete(param.Id);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("set-normal")]
public async Task<BaseResponse<string>> SetToNormal([FromBody] DeleteBeautifulNumberParam param)
{
var result = await _beautifulNumberService.SetToNormal(param.Id);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("freeze")]
public async Task<BaseResponse<string>> Freeze([FromBody] DeleteBeautifulNumberParam param)
{
var result = await _beautifulNumberService.Freeze(param.Id);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("unfreeze")]
public async Task<BaseResponse<string>> Unfreeze([FromBody] DeleteBeautifulNumberParam param)
{
var result = await _beautifulNumberService.Unfreeze(param.Id);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("update-price")]
public async Task<BaseResponse<string>> UpdatePrice([FromBody] UpdateBeautifulNumberPriceParam param)
{
var result = await _beautifulNumberService.UpdatePrice(param.Id, param.Price);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("update-number")]
public async Task<BaseResponse<string>> UpdateNumber([FromBody] UpdateBeautifulNumberParam param)
{
var result = await _beautifulNumberService.UpdateNumber(param.Id, param.Level, param.Price);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("rules")]
public async Task<BaseResponse<List<BeautifulNumberRuleDto>>> GetRules()
{
var result = await _beautifulNumberService.GetRules();
var dtos = result.Select(MapRuleToDto).ToList();
return this.ToResult(dtos);
}
private static BeautifulNumberRuleDto MapRuleToDto(BeautifulNumberRule entity)
{
if (entity == null) return new BeautifulNumberRuleDto();
return new BeautifulNumberRuleDto
{
Id = entity.Id ?? "",
RuleName = entity.RuleName ?? "",
Level = entity.Level ?? "",
Price = entity.Price,
Sort = entity.Sort,
IsEnable = entity.IsEnable
};
}
[HttpPost("update-rules")]
public async Task<BaseResponse<string>> UpdateRules([FromBody] List<UpdateBeautifulNumberRuleParam> paramList)
{
var rules = new List<BeautifulNumberRule>();
foreach (var param in paramList)
{
rules.Add(new BeautifulNumberRule
{
Id = param.Id,
RuleName = param.RuleName,
Level = param.Level,
Price = param.Price,
Sort = param.Sort,
IsEnable = param.IsEnable
});
}
var result = await _beautifulNumberService.UpdateRules(rules);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("init-rules")]
public async Task<BaseResponse<string>> InitRules()
{
var result = await _beautifulNumberService.InitRules();
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("add-rule")]
public async Task<BaseResponse<string>> AddRule([FromBody] BeautifulNumberRule rule)
{
var result = await _beautifulNumberService.AddRule(rule);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("update-rule")]
public async Task<BaseResponse<string>> UpdateRule([FromBody] BeautifulNumberRule rule)
{
var result = await _beautifulNumberService.UpdateRule(rule);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("delete-rule")]
public async Task<BaseResponse<string>> DeleteRule([FromBody] DeleteBeautifulNumberRuleParam param)
{
var result = await _beautifulNumberService.DeleteRule(param.Id);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("give-to-user")]
public async Task<BaseResponse<string>> GiveToUser([FromBody] GiveBeautifulNumberParam param)
{
var result = await _beautifulNumberService.GiveToUser(param.Number, param.UserId);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("init-numbers")]
public async Task<BaseResponse<string>> InitNumbers()
{
var result = await _beautifulNumberService.InitBeautifulNumbers();
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("add-number")]
public async Task<BaseResponse<string>> AddNumber([FromBody] AddBeautifulNumberParam param)
{
var result = await _beautifulNumberService.AddNumber(param.Number, param.Level, param.Price);
if (result.isok)
return this.ToResult<string>(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("batch-add-numbers")]
public async Task<BaseResponse<BatchAddResult>> BatchAddNumbers([FromBody] BatchAddBeautifulNumbersParam param)
{
var result = await _beautifulNumberService.BatchAddNumbers(param.Numbers, param.Level, param.Price);
return this.ToResult(new BatchAddResult { SuccessCount = result.successCount, FailCount = result.failCount, Message = result.msg });
}
}
public class BatchAddResult
{
public int SuccessCount { get; set; }
public int FailCount { get; set; }
public string Message { get; set; }
}
public class BeautifulNumberDto
{
public string Id { get; set; }
public string Number { get; set; }
public string RuleName { get; set; }
public string Level { get; set; }
public long Price { get; set; }
public int Status { get; set; }
public long SaleTime { get; set; }
public string BuyerUserId { get; set; }
public string UserId { get; set; }
public string Remark { get; set; }
public long CreateTime { get; set; }
}
public class BeautifulNumberRuleDto
{
public string Id { get; set; }
public string RuleName { get; set; }
public string Level { get; set; }
public long Price { get; set; }
public int Sort { get; set; }
public bool IsEnable { get; set; }
}
public class BatchAddBeautifulNumbersParam
{
public List<string> Numbers { get; set; }
public string Level { get; set; }
public long Price { get; set; }
}
public class GiveBeautifulNumberParam
{
public string Number { get; set; }
public string UserId { get; set; }
}
public class AddBeautifulNumberParam
{
public string Number { get; set; }
public string Level { get; set; }
public long Price { get; set; }
public int Sort { get; set; }
public string Remark { get; set; }
}
public class UpdateBeautifulNumberParam
{
public string Id { get; set; }
public string Level { get; set; }
public long Price { get; set; }
}
public class DeleteBeautifulNumberParam
{
public string Id { get; set; }
}
public class UpdateBeautifulNumberPriceParam
{
public string Id { get; set; }
public long Price { get; set; }
}
public class UpdateBeautifulNumberRuleParam
{
public string Id { get; set; }
public string RuleName { get; set; }
public string Level { get; set; }
public long Price { get; set; }
public int Sort { get; set; }
public bool IsEnable { get; set; }
}
public class AddBeautifulNumberRuleParam
{
public string RuleName { get; set; }
public string Level { get; set; }
public long Price { get; set; }
public int Sort { get; set; }
public bool IsEnable { get; set; }
}
public class UpdateSingleBeautifulNumberRuleParam
{
public string Id { get; set; }
public string RuleName { get; set; }
public string Level { get; set; }
public long Price { get; set; }
public int Sort { get; set; }
public bool IsEnable { get; set; }
}
public class DeleteBeautifulNumberRuleParam
{
public string Id { get; set; }
}
}
@@ -0,0 +1,64 @@
using AdminService.ImageUpload;
using Common;
using CommonInfrastructure;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace AdminApi.Controllers
{
[Route("adminapi/[controller]")]
[ApiController]
public class ImageUploadController : BaseController
{
private readonly IImageUploadService _imageUploadService;
public ImageUploadController(IImageUploadService imageUploadService)
{
_imageUploadService = imageUploadService;
}
[HttpPost("upload")]
public async Task<IActionResult> UploadFile(IFormFile file, [FromQuery] string? name = null)
{
if (string.IsNullOrWhiteSpace(name))
name = Request.Form["name"].FirstOrDefault();
var result = await _imageUploadService.UploadImageAsync(file, name);
return result.isOk
? Json(this.ToResult(new { path = result.path, fileName = result.fileName }))
: Json(this.ToFailResult<object>(result.errorMessage));
}
[HttpPost("upload/temp")]
public async Task<IActionResult> UploadTempFile(IFormFile file)
{
var result = await _imageUploadService.UploadImageAsync(file);
return result.isOk
? Json(this.ToResult(new { path = result.path, fileName = result.fileName }))
: Json(this.ToFailResult<object>(result.errorMessage));
}
[HttpPost("upload/config")]
public async Task<IActionResult> UploadConfigFile(IFormFile file, [FromQuery] string? number = null)
{
if (!string.Equals(Path.GetExtension(file?.FileName), ".png", StringComparison.OrdinalIgnoreCase))
return Json(this.ToFailResult<object>("配置图片必须是 PNG 格式"));
if (string.IsNullOrWhiteSpace(number))
number = Request.Form["number"].FirstOrDefault();
number = number?.Trim();
if (string.IsNullOrWhiteSpace(number)
|| number != Path.GetFileName(number)
|| number.Any(c => !char.IsLetterOrDigit(c) && c != '_' && c != '-'))
{
return Json(this.ToFailResult<object>("图片编号无效"));
}
var result = await _imageUploadService.UploadImageAsync(file, number);
return result.isOk
? Json(this.ToResult(new { path = result.path, fileName = result.fileName, number }))
: Json(this.ToFailResult<object>(result.errorMessage));
}
}
}
@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AdminService.Admin;
using Common;
using CommonInfrastructure;
using Domain.Admin.Admin;
using Domain.Admin.Admin.ENum;
using Domain.Admin.Admin.Param;
using Microsoft.AspNetCore.Mvc;
using MongoRepository;
namespace AdminApi.Controllers
{
[Route("adminapi/[controller]")]
[ApiController]
public class OperationLogController : BaseController
{
private readonly IAdminOperationLogService _operationLogService;
private readonly IMongoBaseRepository<SystemUser> _systemUserRepo;
private readonly IMongoBaseRepository<AdminOperationLog> _logRepo;
public OperationLogController(IAdminOperationLogService operationLogService, IMongoBaseRepository<SystemUser> systemUserRepo, IMongoBaseRepository<AdminOperationLog> logRepo)
{
_operationLogService = operationLogService;
_systemUserRepo = systemUserRepo;
_logRepo = logRepo;
}
[HttpPost("list")]
public async Task<PageResponse<OperationLogDto>> GetList([FromBody] OperationLogQueryParam param)
{
var (list, count) = await _operationLogService.QueryPage(param);
if (list == null)
return this.ToPageResult(new List<OperationLogDto>(), 0);
var dtos = list.Select(MapToDto);
return this.ToPageResult(dtos, (int)count);
}
[HttpGet("admins")]
public async Task<BaseResponse<List<AdminOptionDto>>> GetAdmins()
{
var users = await _systemUserRepo.FilterByAsync(x => x.State == 1);
var result = users.Select(x => new AdminOptionDto { Value = x.Id, Label = x.DisplayName }).ToList();
return this.ToResult(result);
}
[HttpGet("modules")]
public BaseResponse<List<ModuleOptionDto>> GetModules()
{
var modules = Enum.GetValues<EnumOperationModule>()
.Select(x => new ModuleOptionDto { Value = (int)x, Label = ((int)x).ToString() })
.ToList();
return this.ToResult(modules);
}
[HttpPost("Delete")]
public async Task<BaseResponse<string>> Delete(string id)
{
var result = await _logRepo.DeleteByIdAsync(id);
if (result.ok)
return this.ToResult("删除成功");
else
return this.ToFailResult<string>("删除失败");
}
[HttpPost("BatchDelete")]
public async Task<BaseResponse<string>> BatchDelete([FromBody] List<string> ids)
{
int success = 0, fail = 0;
foreach (var id in ids)
{
var result = await _logRepo.DeleteByIdAsync(id);
if (result.ok)
success++;
else
fail++;
}
if (fail == 0)
return this.ToResult($"成功删除 {success} 条");
return this.ToResult($"删除完成:成功 {success} 条,失败 {fail} 条");
}
private static OperationLogDto MapToDto(AdminOperationLog entity)
{
return new OperationLogDto
{
Id = entity.Id,
AdminId = entity.AdminId ?? "",
AdminName = entity.AdminName ?? "",
Module = entity.Module,
ActionType = entity.ActionType ?? "",
Description = entity.Description ?? "",
HttpMethod = entity.HttpMethod ?? "",
RequestPath = entity.RequestPath ?? "",
Ip = entity.Ip ?? "",
Status = entity.Status,
OperateTime = entity.OperateTime
};
}
}
public class OperationLogDto
{
public string Id { get; set; }
public string AdminId { get; set; }
public string AdminName { get; set; }
public int Module { get; set; }
public string ActionType { get; set; }
public string Description { get; set; }
public string HttpMethod { get; set; }
public string RequestPath { get; set; }
public string Ip { get; set; }
public int Status { get; set; }
public DateTime OperateTime { get; set; }
}
public class AdminOptionDto
{
public string Value { get; set; }
public string Label { get; set; }
}
public class ModuleOptionDto
{
public int Value { get; set; }
public string Label { get; set; }
}
}
@@ -0,0 +1,244 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using AdminApplication.DTOs;
using AdminDomain.Customer;
using AdminDomain.Customer.Param;
using Common;
using CommonInfrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AdminApi.Customer
{
[ApiController]
[Route("adminapi/[controller]")]
[Authorize]
public class CustomerController : BaseController
{
private readonly ICustomerService _customerService;
public CustomerController(ICustomerService customerService)
{
_customerService = customerService;
}
[HttpGet("list")]
public async Task<PageResponse<CustomerDto>> GetCustomerList([FromQuery] GetCustomerListParam param)
{
var result = await _customerService.GetCustomerList(param);
var dtos = MapToCustomerDtos(result.customers);
return this.ToPageResult(dtos, result.total);
}
[HttpGet("{id}")]
public async Task<BaseResponse<CustomerDto>> GetCustomerById(string id)
{
var result = await _customerService.GetCustomerById(id);
var dto = MapToCustomerDto(result.customer);
return this.ToResult(dto);
}
[HttpPost]
public async Task<BaseResponse<CustomerDto>> AddCustomer([FromBody] AddCustomerParam param)
{
var result = await _customerService.AddCustomer(param);
if (result.isOk)
{
var dto = MapToCustomerDto(result.customer);
return this.ToResult(dto);
}
else
{
return this.ToFailResult<CustomerDto>(result.msg);
}
}
[HttpPut]
public async Task<BaseResponse<string>> UpdateCustomer([FromBody] UpdateCustomerParam param)
{
var result = await _customerService.UpdateCustomer(param);
if (result.isOk)
{
return this.ToResult(result.msg);
}
else
{
return this.ToFailResult<string>(result.msg);
}
}
[HttpDelete("{id}")]
public async Task<BaseResponse<string>> DeleteCustomer(string id)
{
var result = await _customerService.DeleteCustomer(id);
if (result.isOk)
{
return this.ToResult(result.msg);
}
else
{
return this.ToFailResult<string>(result.msg);
}
}
[HttpGet("conversations")]
public async Task<PageResponse<ConversationDto>> GetConversationList([FromQuery] GetConversationListParam param)
{
var result = await _customerService.GetConversationList(param);
var dtos = MapToConversationDtos(result.conversations);
return this.ToPageResult(dtos, result.total);
}
[HttpGet("conversation/{id}")]
public async Task<BaseResponse<ConversationDto>> GetConversationById(string id)
{
var result = await _customerService.GetConversationById(id);
var dto = MapToConversationDto(result.conversation);
return this.ToResult(dto);
}
[HttpDelete("conversation/{id}")]
public async Task<BaseResponse<string>> DeleteConversation(string id)
{
var result = await _customerService.DeleteConversation(id);
return result.isOk
? this.ToResult(result.msg)
: this.ToFailResult<string>(result.msg);
}
[HttpGet("chatlog/{conversationId}")]
public async Task<BaseResponse<List<MessageDto>>> GetChatLog(string conversationId)
{
var result = await _customerService.GetChatLog(conversationId);
if (result.isOk)
{
var dtos = MapToMessageDtos(result.messages);
return this.ToResult(dtos);
}
else
{
return this.ToFailResult<List<MessageDto>>(result.msg);
}
}
[HttpDelete("message/{id}")]
public async Task<BaseResponse<string>> DeleteMessage(string id)
{
var result = await _customerService.DeleteMessage(id);
if (result.isOk)
{
return this.ToResult(result.msg);
}
else
{
return this.ToFailResult<string>(result.msg);
}
}
[HttpDelete("messages/{conversationId}")]
public async Task<BaseResponse<string>> DeleteAllMessages(string conversationId)
{
var result = await _customerService.DeleteAllMessages(conversationId);
if (result.isOk)
{
return this.ToResult(result.msg);
}
else
{
return this.ToFailResult<string>(result.msg);
}
}
[HttpPost("messages/delete-batch")]
public async Task<BaseResponse<string>> DeleteMessagesBatch([FromBody] DeleteMessagesBatchRequest param)
{
var result = await _customerService.DeleteMessagesBatch(param.Ids);
if (result.isOk)
{
return this.ToResult(result.msg);
}
else
{
return this.ToFailResult<string>(result.msg);
}
}
private static CustomerDto MapToCustomerDto(CustomerService.Domain.Entity.CustomerEntity? entity)
{
if (entity == null) return null!;
return new CustomerDto
{
Id = entity.Id,
UserId = entity.UserId,
UserName = entity.UserName,
Status = entity.Status,
Avatar = entity.Avatar,
CreateTime = entity.CreateTime
};
}
private static List<CustomerDto> MapToCustomerDtos(IEnumerable<CustomerService.Domain.Entity.CustomerEntity> entities)
{
var dtos = new List<CustomerDto>();
foreach (var entity in entities)
{
dtos.Add(MapToCustomerDto(entity));
}
return dtos;
}
private static ConversationDto MapToConversationDto(CustomerService.Domain.Entity.ConversationEntity? entity)
{
if (entity == null) return null!;
return new ConversationDto
{
Id = entity.Id,
UserId = entity.UserId,
UserName = entity.UserName,
UserAvatar = entity.UserAvatar,
CustomerId = entity.CustomerId,
CustomerName = entity.CustomerName,
CustomerAvatar = entity.CustomerAvatar,
Status = entity.Status,
CreateTime = entity.CreateTime,
EndTime = entity.EndTime
};
}
private static List<ConversationDto> MapToConversationDtos(IEnumerable<CustomerService.Domain.Entity.ConversationEntity> entities)
{
var dtos = new List<ConversationDto>();
foreach (var entity in entities)
{
dtos.Add(MapToConversationDto(entity));
}
return dtos;
}
private static MessageDto MapToMessageDto(CustomerService.Domain.Entity.MessageEntity entity)
{
return new MessageDto
{
Id = entity.Id,
ConversationId = entity.ConversationId,
SenderType = entity.SenderType,
SenderId = entity.SenderId,
SenderName = entity.SenderName,
SenderAvatar = entity.SenderAvatar,
ContentType = entity.ContentType,
Content = entity.Content,
CreateTime = entity.CreateTime
};
}
private static List<MessageDto> MapToMessageDtos(IEnumerable<CustomerService.Domain.Entity.MessageEntity> entities)
{
var dtos = new List<MessageDto>();
foreach (var entity in entities)
{
dtos.Add(MapToMessageDto(entity));
}
return dtos;
}
}
}
@@ -0,0 +1,110 @@
using AdminService.EmptyRoomRate;
using Common;
using CommonDomain;
using CommonDomain.Enum;
using CommonInfrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AdminApi.EmptyRoomRate
{
[ApiController, Route("adminapi/[controller]")]
[Authorize]
public class EmptyRoomRateConfigController : BaseController
{
private readonly IEmptyRoomRateConfigService _emptyRoomRateConfigService;
public EmptyRoomRateConfigController(IEmptyRoomRateConfigService emptyRoomRateConfigService)
{
_emptyRoomRateConfigService = emptyRoomRateConfigService;
}
[HttpGet("list")]
public async Task<PageResponse<EmptyRoomRateDto>> GetList(
[FromQuery] int page = 1,
[FromQuery] int size = 20,
[FromQuery] GameTypeEnum? gameType = null,
[FromQuery] int? roomLevel = null)
{
page = page > 0 ? page : 1;
size = size > 0 ? size : 20;
var result = await _emptyRoomRateConfigService.GetList(page, size, gameType, roomLevel);
var dtos = result.list.Select(MapToDto).ToList();
return this.ToPageResult(dtos, (int)result.count);
}
[HttpPost("add")]
public async Task<BaseResponse<string>> Add([FromBody] AddEmptyRoomRateParam param)
{
var result = await _emptyRoomRateConfigService.Add(param.GameType, param.RoomLevel, param.EmptyRoomRate);
if (result.isok)
return this.ToResult<string>(result.msg);
return this.ToFailResult<string>(result.msg);
}
[HttpPost("update")]
public async Task<BaseResponse<string>> Update([FromBody] UpdateEmptyRoomRateParam param)
{
var result = await _emptyRoomRateConfigService.Update(param.Id, param.EmptyRoomRate);
if (result.isok)
return this.ToResult<string>(result.msg);
return this.ToFailResult<string>(result.msg);
}
[HttpPost("delete")]
public async Task<BaseResponse<string>> Delete([FromBody] DeleteEmptyRoomRateParam param)
{
var result = await _emptyRoomRateConfigService.Delete(param.Id);
if (result.isok)
return this.ToResult<string>(result.msg);
return this.ToFailResult<string>(result.msg);
}
private static EmptyRoomRateDto MapToDto(EmptyRoomRateConfig entity)
{
if (entity == null) return new EmptyRoomRateDto();
return new EmptyRoomRateDto
{
Id = entity.Id ?? "",
GameType = (int)entity.GameType,
GameTypeName = entity.GameType.ToString(),
RoomLevel = entity.RoomLevel,
EmptyRoomRate = entity.EmptyRoomRate
};
}
}
public class EmptyRoomRateDto
{
public string Id { get; set; }
public int GameType { get; set; }
public string GameTypeName { get; set; }
public int RoomLevel { get; set; }
public int EmptyRoomRate { get; set; }
}
public class AddEmptyRoomRateParam
{
public GameTypeEnum GameType { get; set; }
public int RoomLevel { get; set; }
public int EmptyRoomRate { get; set; } = 30;
}
public class UpdateEmptyRoomRateParam
{
public string Id { get; set; }
public int EmptyRoomRate { get; set; }
}
public class DeleteEmptyRoomRateParam
{
public string Id { get; set; }
}
}
+246
View File
@@ -0,0 +1,246 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using CommonDomain;
using CommonInfrastructure;
using Microsoft.AspNetCore.Mvc;
using AdminService.Faq;
namespace AdminApi.Faq
{
[ApiController, Route("adminapi/[controller]")]
public class FaqController : BaseController
{
private readonly IFaqService _faqService;
public FaqController(IFaqService faqService)
{
_faqService = faqService;
}
[HttpGet("Categories")]
public async Task<BaseCommonResponse> GetCategories()
{
var list = await _faqService.GetAllCategories();
if (list == null)
return new ListResponse<FaqCategoryDto> { Code = CommonResponseCodeEnum.Success, Data = new List<FaqCategoryDto>() };
var dtos = list.Select(MapToCategoryDto).ToList();
return new ListResponse<FaqCategoryDto>
{
Code = CommonResponseCodeEnum.Success,
Info = "获取成功",
Data = dtos
};
}
[HttpGet("CategoryTree")]
public async Task<BaseCommonResponse> GetCategoryTree()
{
var tree = await _faqService.GetCategoryTree();
var dtos = tree.Select(MapToTreeNodeDto).ToList();
return new ListResponse<FaqCategoryTreeNodeDto>
{
Code = CommonResponseCodeEnum.Success,
Info = "获取成功",
Data = dtos
};
}
[HttpGet("CategoryDetail")]
public async Task<BaseResponse<FaqCategoryDto>> GetCategoryDetail(string id)
{
var category = await _faqService.GetCategoryById(id);
if (category == null)
return this.ToFailResult<FaqCategoryDto>("板块不存在");
return this.ToResult(MapToCategoryDto(category));
}
[HttpPost("AddCategory")]
public async Task<BaseResponse<string>> AddCategory([FromBody] FaqCategory category)
{
var result = await _faqService.AddCategory(category);
if (result.ok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("UpdateCategory")]
public async Task<BaseResponse<string>> UpdateCategory([FromBody] FaqCategory category)
{
var result = await _faqService.UpdateCategory(category);
if (result.ok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("DeleteCategory")]
public async Task<BaseResponse<string>> DeleteCategory(string id)
{
var result = await _faqService.DeleteCategory(id);
if (result.ok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("Questions")]
public async Task<BaseCommonResponse> GetQuestions(string categoryId)
{
var list = await _faqService.GetQuestionsByCategory(categoryId);
if (list == null)
return new ListResponse<FaqQuestionDto> { Code = CommonResponseCodeEnum.Success, Data = new List<FaqQuestionDto>() };
var dtos = list.Select(MapToQuestionDto).ToList();
return new ListResponse<FaqQuestionDto>
{
Code = CommonResponseCodeEnum.Success,
Info = "获取成功",
Data = dtos
};
}
[HttpPost("QuestionList")]
public async Task<BaseCommonResponse> GetQuestionList([FromBody] FaqQueryParam param)
{
var result = await _faqService.QueryQuestions(param.CategoryId, param.PageIndex, param.PageSize);
var dtos = result.list.Select(MapToQuestionDto).ToList();
return new PageDataResponse<FaqQuestionDto>
{
Code = CommonResponseCodeEnum.Success,
Info = "获取成功",
Data = dtos,
Count = (int)result.count
};
}
[HttpGet("QuestionDetail")]
public async Task<BaseResponse<FaqQuestionDto>> GetQuestionDetail(string id)
{
var question = await _faqService.GetQuestionById(id);
if (question == null)
return this.ToFailResult<FaqQuestionDto>("问题不存在");
return this.ToResult(MapToQuestionDto(question));
}
[HttpPost("AddQuestion")]
public async Task<BaseResponse<string>> AddQuestion([FromBody] FaqQuestion question)
{
var result = await _faqService.AddQuestion(question);
if (result.ok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("UpdateQuestion")]
public async Task<BaseResponse<string>> UpdateQuestion([FromBody] FaqQuestion question)
{
var result = await _faqService.UpdateQuestion(question);
if (result.ok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("DeleteQuestion")]
public async Task<BaseResponse<string>> DeleteQuestion(string id)
{
var result = await _faqService.DeleteQuestion(id);
if (result.ok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
private static FaqCategoryDto MapToCategoryDto(FaqCategory entity)
{
if (entity == null) return new FaqCategoryDto();
return new FaqCategoryDto
{
Id = entity.Id ?? "",
ParentId = entity.ParentId ?? "",
Name = entity.Name ?? "",
Icon = entity.Icon ?? "",
Sort = entity.Sort,
IsEnable = entity.IsEnable
};
}
private static FaqCategoryTreeNodeDto MapToTreeNodeDto(FaqCategoryTreeNode entity)
{
if (entity == null) return new FaqCategoryTreeNodeDto();
return new FaqCategoryTreeNodeDto
{
Id = entity.Id ?? "",
Name = entity.Name ?? "",
Icon = entity.Icon ?? "",
Sort = entity.Sort,
IsEnable = entity.IsEnable,
Children = entity.Children?.Select(MapToTreeNodeDto).ToList() ?? new List<FaqCategoryTreeNodeDto>(),
QuestionCount = entity.QuestionCount
};
}
private static FaqQuestionDto MapToQuestionDto(FaqQuestion entity)
{
if (entity == null) return new FaqQuestionDto();
return new FaqQuestionDto
{
Id = entity.Id ?? "",
CategoryId = entity.CategoryId ?? "",
Title = entity.Title ?? "",
Content = entity.Content ?? "",
Sort = entity.Sort,
IsEnable = entity.IsEnable,
CreateTime = entity.CreateTime
};
}
}
public class FaqCategoryDto
{
public string Id { get; set; }
public string ParentId { get; set; }
public string Name { get; set; }
public string Icon { get; set; }
public int Sort { get; set; }
public bool IsEnable { get; set; }
}
public class FaqCategoryTreeNodeDto
{
public string Id { get; set; }
public string Name { get; set; }
public string Icon { get; set; }
public int Sort { get; set; }
public bool IsEnable { get; set; }
public List<FaqCategoryTreeNodeDto> Children { get; set; } = new();
public int QuestionCount { get; set; }
}
public class FaqQuestionDto
{
public string Id { get; set; }
public string CategoryId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int Sort { get; set; }
public bool IsEnable { get; set; }
public DateTime CreateTime { get; set; }
}
public class FaqQueryParam
{
public string? CategoryId { get; set; }
public int PageIndex { get; set; } = 1;
public int PageSize { get; set; } = 10;
}
}
@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using CommonInfrastructure;
using Microsoft.AspNetCore.Mvc;
using MongoRepository;
using UserDomain;
using UserDomain.Entity;
using UserDomain.Param;
namespace AdminApi.Feedbacks
{
[ApiController, Route("adminapi/[controller]")]
public class FeedbackManageController : BaseController
{
private readonly IUserFeedbackService _feedbackService;
private readonly IMongoBaseRepository<UserFeedback> _feedbackRepo;
public FeedbackManageController(IUserFeedbackService feedbackService, IMongoBaseRepository<UserFeedback> feedbackRepo)
{
_feedbackService = feedbackService;
_feedbackRepo = feedbackRepo;
}
[HttpPost("List")]
public async Task<PageResponse<FeedbackDto>> GetList([FromBody] FeedbackQueryParam param)
{
var result = await _feedbackService.QueryPage(param);
var dtos = result.list.Select(MapToDto);
return this.ToPageResult(dtos, (int)result.count);
}
[HttpGet("Detail")]
public async Task<BaseResponse<FeedbackDetailDto>> GetDetail(string id)
{
var feedback = await _feedbackRepo.FindOneAsync(x => x.Id == id);
if (feedback == null)
return this.ToFailResult<FeedbackDetailDto>("反馈不存在");
return this.ToResult(MapToDetailDto(feedback));
}
[HttpPost("Reply")]
public async Task<BaseResponse<string>> Reply([FromBody] ReplyFeedbackParam param)
{
var feedback = await _feedbackRepo.FindOneAsync(x => x.Id == param.Id);
if (feedback == null)
return this.ToFailResult<string>("反馈不存在");
feedback.Reply = param.Reply;
feedback.Status = param.Status;
feedback.ReplyTime = DateTime.Now;
feedback.ReplyAdminId = loginUser.UserId;
feedback.ReplyAdminName = loginUser.UserName;
var result = await _feedbackRepo.ReplaceOneAsync(feedback);
if (result.ok)
return this.ToResult("回复成功");
else
return this.ToFailResult<string>("回复失败");
}
[HttpPost("Delete")]
public async Task<BaseResponse<string>> Delete(string id)
{
var result = await _feedbackRepo.DeleteByIdAsync(id);
if (result.ok)
return this.ToResult("删除成功");
else
return this.ToFailResult<string>("删除失败");
}
private static FeedbackDto MapToDto(UserFeedback entity)
{
return new FeedbackDto
{
Id = entity.Id,
UserId = entity.UserId ?? "",
UserNumber = entity.UserNumber ?? "",
UserName = entity.UserName ?? "",
Type = entity.Type,
Title = entity.Title ?? "",
Content = entity.Content ?? "",
Images = string.IsNullOrEmpty(entity.Images) ? new List<string>() : entity.Images.Split(',').ToList(),
QQ = entity.QQ ?? "",
Contact = entity.Contact ?? "",
Status = entity.Status,
Reply = entity.Reply ?? "",
ReplyTime = entity.ReplyTime,
SubmitTime = entity.SubmitTime
};
}
private static FeedbackDetailDto MapToDetailDto(UserFeedback entity)
{
return new FeedbackDetailDto
{
Id = entity.Id,
UserId = entity.UserId ?? "",
UserNumber = entity.UserNumber ?? "",
UserName = entity.UserName ?? "",
Type = entity.Type,
Title = entity.Title ?? "",
Content = entity.Content ?? "",
Images = string.IsNullOrEmpty(entity.Images) ? new List<string>() : entity.Images.Split(',').ToList(),
QQ = entity.QQ ?? "",
Contact = entity.Contact ?? "",
Status = entity.Status,
Reply = entity.Reply ?? "",
ReplyTime = entity.ReplyTime,
ReplyAdminId = entity.ReplyAdminId ?? "",
ReplyAdminName = entity.ReplyAdminName ?? "",
SubmitTime = entity.SubmitTime
};
}
}
public class FeedbackDto
{
public string Id { get; set; }
public string UserId { get; set; }
public string UserNumber { get; set; }
public string UserName { get; set; }
public int Type { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public List<string> Images { get; set; }
/// <summary>
/// QQ
/// </summary>
public string QQ { get; set; }
public string Contact { get; set; }
public int Status { get; set; }
public string Reply { get; set; }
public DateTime? ReplyTime { get; set; }
public DateTime SubmitTime { get; set; }
}
public class FeedbackDetailDto
{
public string Id { get; set; }
public string UserId { get; set; }
public string UserNumber { get; set; }
public string UserName { get; set; }
public int Type { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public List<string> Images { get; set; }
/// <summary>
/// QQ
/// </summary>
public string QQ { get; set; }
public string Contact { get; set; }
public int Status { get; set; }
public string Reply { get; set; }
public DateTime? ReplyTime { get; set; }
public string ReplyAdminId { get; set; }
public string ReplyAdminName { get; set; }
public DateTime SubmitTime { get; set; }
}
}
@@ -0,0 +1,224 @@
using System.Text;
using AdminService.GameConfigs;
using Common;
using CommonDomain;
using CommonDomain.BaseModel;
using CommonInfrastructure;
using Microsoft.AspNetCore.Mvc;
using NewLife;
using RedisService;
using XAct;
namespace AdminApi.GameConfigs
{
[ApiController, Route("adminapi/[controller]")]
public class ActivityConfigController : BaseController
{
private readonly IActivityConfigService _activityConfigService;
private readonly IRedisService _redisService;
public ActivityConfigController(IActivityConfigService activityConfigService, IRedisService redisService)
{
_activityConfigService = activityConfigService;
_redisService = redisService;
}
[HttpGet]
[HttpGet("Get")]
public async Task<BaseResponse<ActivityConfig>> Get()
{
var config = await _activityConfigService.Get();
if (config != null)
return this.ToResult(config);
else
return this.ToFailResult<ActivityConfig>("配置不存在");
}
[HttpPost("Update")]
public async Task<BaseResponse<string>> Update(ActivityConfig config)
{
var res = await _activityConfigService.Update(config);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("Delete")]
public async Task<BaseResponse<string>> Delete()
{
var res = await _activityConfigService.Delete();
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateBattleOrder")]
public async Task<BaseResponse<string>> UpdateBattleOrder(BattleOrderConfig config)
{
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
activityConfig.BattleOrderConfig = config;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateRelief")]
public async Task<BaseResponse<string>> UpdateRelief(ReliefConfig config)
{
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
activityConfig.ReliefConfig = config;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateSign")]
public async Task<BaseResponse<string>> UpdateSign(List<SignConfig> configs)
{
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
activityConfig.SignConfigs = configs;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateGoldShop")]
public async Task<BaseResponse<string>> UpdateGoldShop(List<GoldShopConfig> configs)
{
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
activityConfig.GoldShopConfigs = configs;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateDiamondShop")]
public async Task<BaseResponse<string>> UpdateDiamondShop(List<DiamondShopConfig> configs)
{
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
activityConfig.DiamondShopConfigs = configs;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateRegister")]
public async Task<BaseResponse<string>> UpdateRegister(RegisterConfig config)
{
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
activityConfig.RegisterConfig = config;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateFishingReturn")]
public async Task<BaseResponse<string>> UpdateFishingReturn(FishingReturnConfig config)
{
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
activityConfig.FishingReturnConfig = config;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpGet("GetFishingReturn")]
public async Task<BaseResponse<FishingReturnConfig>> GetFishingReturn()
{
var config = await _activityConfigService.Get();
if (config?.FishingReturnConfig != null)
return this.ToResult(config.FishingReturnConfig);
else
return this.ToFailResult<FishingReturnConfig>("配置不存在");
}
[HttpGet("SaveSection/{sectionName}")]
public async Task<BaseResponse<string>> SaveSection(string sectionName)
{
var prop = typeof(ActivityConfig).GetProperty(sectionName);
if (prop == null)
return this.ToFailResult<string>($"板块 {sectionName} 不存在");
var config = await _activityConfigService.Get();
if (config == null)
return this.ToFailResult<string>("配置不存在");
var sectionValue = prop.GetValue(config);
if (sectionValue == null)
return this.ToFailResult<string>($"板块 {sectionName} 数据为空");
var jsonPath = global::System.IO.Path.Combine(AppContext.BaseDirectory, "Config", "activityconfig.json");
try
{
await _activityConfigService.Update(config);
ActivityConfig fileConfig;
if (global::System.IO.File.Exists(jsonPath))
{
var json = await global::System.IO.File.ReadAllTextAsync(jsonPath, global::System.Text.Encoding.UTF8);
fileConfig = global::System.Text.Json.JsonSerializer.Deserialize<ActivityConfig>(json, new global::System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true, ReadCommentHandling = global::System.Text.Json.JsonCommentHandling.Skip }) ?? new ActivityConfig();
}
else
{
fileConfig = new ActivityConfig();
}
prop.SetValue(fileConfig, sectionValue);
var outJson = global::System.Text.Json.JsonSerializer.Serialize(fileConfig, new global::System.Text.Json.JsonSerializerOptions
{
WriteIndented = true,
Encoder = global::System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
});
await global::System.IO.File.WriteAllTextAsync(jsonPath, outJson, global::System.Text.Encoding.UTF8);
return this.ToResult($"{sectionName} 已保存到 activityconfig.json");
}
catch (Exception ex)
{
return this.ToFailResult<string>($"保存失败: {ex.Message}");
}
}
[HttpGet("ExportSection/{sectionName}")]
public async Task<IActionResult> ExportSection(string sectionName)
{
var config = await _activityConfigService.Get();
if (config == null)
return NotFound("配置不存在");
var prop = typeof(ActivityConfig).GetProperty(sectionName);
if (prop == null)
return NotFound($"板块 {sectionName} 不存在");
var data = prop.GetValue(config);
if (data == null)
return NotFound($"板块 {sectionName} 数据为空");
var json = global::System.Text.Json.JsonSerializer.Serialize(data, new global::System.Text.Json.JsonSerializerOptions
{
WriteIndented = true,
Encoder = global::System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
});
return File(global::System.Text.Encoding.UTF8.GetBytes(json), "application/json", $"{sectionName}.json");
}
}
}
@@ -0,0 +1,828 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AdminService.GameConfigs;
using ChessGameDomain;
using Common;
using CommonDomain;
using CommonDomain.Enum;
using CommonInfrastructure;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MongoRepository;
using RedisService;
using RedisService.Param;
using UserDomain.Entity;
namespace AdminApi.GameConfigs
{
[ApiController, Route("adminapi/Admin/[controller]")]
[Authorize]
public class RoomController : BaseController
{
private readonly IRedisService _redisService;
private readonly IGameConfigService _gameConfigService;
private readonly ICapPublisher _capPublisher;
private readonly IMongoBaseRepository<UserEntity> _userMongo;
private readonly ILogger<RoomController> _logger;
public RoomController(IRedisService redisService, IGameConfigService gameConfigService, ICapPublisher capPublisher, IMongoBaseRepository<UserEntity> userMongo, ILogger<RoomController> logger)
{
_redisService = redisService;
_gameConfigService = gameConfigService;
_capPublisher = capPublisher;
_userMongo = userMongo;
_logger = logger;
}
[HttpGet("GetAllRooms")]
public async Task<PageResponse<RedisGameRoom>> GetAllRooms(
int pageIndex = 1,
int pageSize = 20,
int? roomLevel = null,
string? gameType = null,
string? sortField = null,
string? sortOrder = "desc")
{
var rooms = GetAllRoomsFromRedis()?.ToList() ?? new List<RedisGameRoom>();
foreach (var room in rooms)
{
if (room?.Players != null && room.Players.Count > 1)
room.Players = room.Players.OrderBy(p => p.Position).ToList();
}
if (roomLevel.HasValue)
{
rooms = rooms.Where(r => r != null && r.RoomLevel == roomLevel.Value).ToList();
}
if (!string.IsNullOrEmpty(gameType) && int.TryParse(gameType, out var gameTypeValue))
{
rooms = rooms.Where(r => r != null && (int)r.GameType == gameTypeValue).ToList();
}
var total = rooms.Count;
if (!string.IsNullOrEmpty(sortField))
{
switch (sortField.ToLower())
{
case "currentonline":
rooms = sortOrder?.ToLower() == "asc"
? rooms.OrderBy(r => r.CurrentOnlinePlayerCount).ToList()
: rooms.OrderByDescending(r => r.CurrentOnlinePlayerCount).ToList();
break;
case "robotcount":
rooms = sortOrder?.ToLower() == "asc"
? rooms.OrderBy(r => r.RobotCount).ToList()
: rooms.OrderByDescending(r => r.RobotCount).ToList();
break;
case "roomlevel":
rooms = sortOrder?.ToLower() == "asc"
? rooms.OrderBy(r => r.RoomLevel).ToList()
: rooms.OrderByDescending(r => r.RoomLevel).ToList();
break;
default:
rooms = rooms.OrderByDescending(r => r.RoomId).ToList();
break;
}
}
var pagedRooms = rooms.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
return this.ToPageResult(pagedRooms, total);
}
[HttpGet("GetAllChessRooms")]
public async Task<PageResponse<ChessGameRoom>> GetAllChessRooms(
int pageIndex = 1,
int pageSize = 20,
int? state = null,
int? gameType = null)
{
var rooms = _redisService.GetAllChessRooms()?.ToList();
if (state.HasValue)
{
rooms = rooms.Where(r => r != null && r.state == state.Value).ToList();
}
if (gameType.HasValue)
{
rooms = rooms.Where(r => r != null && r.gameType == gameType.Value).ToList();
}
var total = rooms.Count;
rooms = rooms.OrderByDescending(r => r.CreateTime).ToList();
var pagedRooms = rooms.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
return this.ToPageResult(pagedRooms, total);
}
[HttpGet("GetChessRoomDetail")]
public async Task<BaseResponse<ChessGameRoom>> GetChessRoomDetail(string roomId)
{
var room = _redisService.GetChessRoom(roomId);
if (room == null)
return this.ToFailResult<ChessGameRoom>("房间不存在");
return this.ToResult(room);
}
[HttpGet("ClearChessRoom")]
public async Task<BaseResponse<string>> ClearChessRoom(string roomId)
{
var room = _redisService.GetChessRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
int playerCount = 0;
foreach (var user in room.users.ToList())
{
try
{
var userRedis = _redisService.GetRedisUserCId(user.userId);
if (userRedis != null)
{
userRedis.CId = "";
_redisService.SetRedisUserCId(userRedis);
}
playerCount++;
}
catch (Exception ex)
{
_logger.LogError(ex, "管理员清空象棋房间 清理userRedis失败 roomId={RoomId} userId={UserId}", roomId, user.userId);
}
}
room.users.Clear();
room.state = 0;
room.robotCount = 0;
room.gold = 0;
room.gameType = 0;
room.password = "";
room.IsGameEnded = false;
room.EndGameRequests?.Clear();
room.PendingWinUserId = null;
room.TimeoutLoserUserId = "";
room.LastActiveTime = 0;
_redisService.SetChessRoom(room);
return this.ToResult($"已清空房间 {roomId} 的所有玩家({playerCount} 人)");
}
[HttpGet("KickChessPlayer")]
public async Task<BaseResponse<string>> KickChessPlayer(string roomId, string userId)
{
if (string.IsNullOrWhiteSpace(roomId) || string.IsNullOrWhiteSpace(userId))
return this.ToFailResult<string>("房间ID和玩家ID不能为空");
var room = _redisService.GetChessRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
if (room.state == 2)
return this.ToFailResult<string>("游戏进行中不能直接踢人,请先结束对局");
if (room.users?.Any(u => u.userId == userId) != true)
return this.ToFailResult<string>("玩家不在该房间中");
await _capPublisher.PublishAsync(TopicKeys.后台踢出象棋玩家, new AdminKickChessPlayerMessage
{
RoomId = roomId,
UserId = userId,
Reason = "被管理员移出房间"
});
return this.ToResult("踢人指令已提交");
}
[HttpGet("GetChessRoomStatistics")]
public async Task<BaseResponse<ChessRoomStatistics>> GetChessRoomStatistics()
{
var rooms = _redisService.GetAllChessRooms() ?? new List<ChessGameRoom>();
var stats = new ChessRoomStatistics
{
TotalRooms = rooms.Count,
EmptyRooms = rooms.Count(r => r.state == 0 &&
(r.users == null || !r.users.Any(u => u != null && !u.IsLeave)) &&
r.robotCount == 0),
WaitingRooms = rooms.Count(r => r.state == 1),
PlayingRooms = rooms.Count(r => r.state == 2),
FinishedRooms = rooms.Count(r => r.state == 3),
TotalPlayers = rooms.SelectMany(r => r.users ?? new List<RedisChessGameUser>()).Count(),
BlackSidePlayers = rooms.SelectMany(r => r.users ?? new List<RedisChessGameUser>()).Count(u => u.type == 1),
RedSidePlayers = rooms.SelectMany(r => r.users ?? new List<RedisChessGameUser>()).Count(u => u.type == 2)
};
stats.EmptyRoomRate = stats.TotalRooms == 0
? 0
: Math.Round(stats.EmptyRooms * 100.0 / stats.TotalRooms, 2);
return this.ToResult(stats);
}
[HttpGet("DeleteChessRoom")]
public async Task<BaseResponse<string>> DeleteChessRoom(string roomId)
{
var room = _redisService.GetChessRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
_redisService.RemoveChessRoom(roomId);
return this.ToResult("已删除房间 " + roomId);
}
[HttpGet("AddChessRobot")]
public async Task<BaseResponse<string>> AddChessRobot(string roomId, int count)
{
var room = _redisService.GetChessRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
var realPlayers = room.users?.Where(u => u != null && !u.IsLeave).ToList();
if (realPlayers != null && realPlayers.Count > 0)
return this.ToFailResult<string>("房间有真人玩家,不能修改机器人数量");
room.robotCount += count;
ApplyRobotStateRule(room);
_redisService.SetChessRoom(room);
return this.ToResult("添加成功");
}
[HttpGet("SetChessRobot")]
public async Task<BaseResponse<string>> SetChessRobot(string roomId, int count)
{
var room = _redisService.GetChessRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
var realPlayers = room.users?.Where(u => u != null && !u.IsLeave).ToList();
if (realPlayers != null && realPlayers.Count > 0)
return this.ToFailResult<string>("房间有真人玩家,不能修改机器人数量");
room.robotCount = Math.Clamp(count, 0, 2);
ApplyRobotStateRule(room);
_redisService.SetChessRoom(room);
return this.ToResult("设置成功");
}
[HttpGet("GetRoomDetail")]
public async Task<BaseResponse<RedisGameRoom>> GetRoomDetail(string roomId)
{
var room = _redisService.GetGameRoom(roomId);
if (room == null)
return this.ToFailResult<RedisGameRoom>("房间不存在");
return this.ToResult(room);
}
[HttpGet("GetUserRoomRealtime")]
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
public async Task<BaseResponse<UserRoomRealtimeDto>> GetUserRoomRealtime(string userId)
{
if (string.IsNullOrWhiteSpace(userId))
return this.ToFailResult<UserRoomRealtimeDto>("用户ID不能为空");
var dto = new UserRoomRealtimeDto { Found = true };
var user = await _userMongo.FindByIdAsync(userId);
var factor = user?.PlayerFactor ?? new PlayerFactor();
dto.Gold = user?.Assets?.Gold ?? 0;
dto.TotalRechargeGold = user?.Static?.TotalRechargeGold ?? 0;
RedisGameRoom? matchedRoom = null;
RedisGamePlayer? matchedPlayer = null;
var session = _redisService.GetRedisUserCId(userId);
if (!string.IsNullOrWhiteSpace(session?.RoomId))
{
matchedRoom = _redisService.GetGameRoom(session.RoomId);
matchedPlayer = matchedRoom?.Players?
.FirstOrDefault(p => p != null && !p.IsBot && p.UserId == userId);
}
if (matchedPlayer == null)
{
var fallback = _redisService.GetGameRoomAllList()
.Where(r => r != null && r.Players != null)
.SelectMany(r => r.Players.Select(p => new { Room = r, Player = p }))
.FirstOrDefault(x => x.Player != null && !x.Player.IsBot && x.Player.UserId == userId);
matchedRoom = fallback?.Room;
matchedPlayer = fallback?.Player;
}
if (matchedRoom != null && matchedPlayer != null)
{
var room = matchedRoom;
var player = matchedPlayer;
dto.InRoom = true;
dto.RoomId = room.RoomId;
dto.RoomName = room.RoomName;
dto.GameType = (int)room.GameType;
dto.GameTypeName = room.GameType.ToString();
dto.RoomLevel = room.RoomLevel;
dto.RoomPartition = room.RoomPartition;
dto.RoomNumber = room.RoomNumber;
dto.SystemFactor = room.SystemFactor;
dto.CurrentOnlinePlayerCount = room.CurrentOnlinePlayerCount;
dto.RobotCount = room.RobotCount;
dto.Position = player.Position;
dto.UserName = player.UserName;
dto.UserNumber = player.UserNumber;
dto.Gold = player.Gold;
dto.MaxGold = player.MaxGold;
dto.BeginCoin = player.BeginCoin;
dto.CannonMultiple = player.CannonMultiple;
dto.CannonId = player.CannonId;
dto.State = player.State;
dto.IsAfk = player.IsAfk;
dto.TotalRechargeGold = player.TotalRechargeGold;
var delta = player.Gold - player.BeginCoin;
dto.WinGold = delta > 0 ? delta : 0;
dto.LoseGold = delta < 0 ? -delta : 0;
var realtimeFactor = player.PlayerFactor ?? new PlayerFactor();
if (realtimeFactor.ViolateValue > 0)
factor.ViolateValue = realtimeFactor.ViolateValue;
}
dto.IsBlack = factor.IsBlack;
dto.IsIgnore = factor.IsIgnore;
dto.ViolateValue = factor.ViolateValue;
dto.AdditionalFactor = factor.AdditionalFactor;
dto.MissRate = factor.MissRate;
dto.CompensateQuota = factor.CompensateQuota;
dto.CompensateStartGold = factor.CompensateStartGold;
dto.CompensateTargetGold = factor.CompensateTargetGold;
if (factor.CompensateQuota <= 0)
dto.CompensateRemainingQuota = 0;
else
dto.CompensateRemainingQuota = factor.CompensateTargetGold > 0
? Math.Max(0, factor.CompensateTargetGold - dto.Gold)
: Math.Max(0, factor.CompensateQuota);
dto.PenaltyQuota = factor.PenaltyQuota;
dto.StartingBonus = factor.StartingBonus;
dto.CompensateRateBoss = factor.CompensateRate?.BossRate ?? 0;
dto.CompensateRateGold = factor.CompensateRate?.GoldRate ?? 0;
dto.CompensateRateSpecial = factor.CompensateRate?.SpecialRate ?? 0;
dto.CompensateRateOrdinary = factor.CompensateRate?.Ordinary ?? 0;
dto.PenaltyRateBoss = factor.PenaltyRate?.BossRate ?? 0;
dto.PenaltyRateGold = factor.PenaltyRate?.GoldRate ?? 0;
dto.PenaltyRateSpecial = factor.PenaltyRate?.SpecialRate ?? 0;
dto.PenaltyRateOrdinary = factor.PenaltyRate?.Ordinary ?? 0;
return this.ToResult(dto);
}
[HttpGet("AddRobot")]
public async Task<BaseResponse<string>> AddRobot(string roomId, int count)
{
var room = _redisService.GetGameRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
if (count < 0)
return this.ToFailResult<string>("机器人增加数量不能小于0");
var realPlayerCount = room.Players?.Count(p => !p.IsBot) ?? room.CurrentOnlinePlayerCount;
room.CurrentOnlinePlayerCount = realPlayerCount;
room.RobotCount = Math.Clamp(room.RobotCount + count, 0, Math.Max(0, room.MaxPlayerCount - realPlayerCount));
if (room.Players != null)
{
var excessBots = room.Players.Where(p => p.IsBot).Skip(room.RobotCount).ToList();
foreach (var bot in excessBots)
{
_redisService.ClearBulletIds(roomId, bot.UserId);
room.Players.Remove(bot);
}
room.RobotCount = Math.Max(room.RobotCount, room.Players.Count(p => p.IsBot));
}
_redisService.SetGameRoom(room);
return this.ToResult($"已为房间 {roomId} 添加 {count} 个机器人");
}
[HttpGet("SetRobotCount")]
public async Task<BaseResponse<string>> SetRobotCount(string roomId, int count)
{
var room = _redisService.GetGameRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
if (count < 0)
return this.ToFailResult<string>("机器人数量不能小于0");
var realPlayerCount = room.Players?.Count(p => !p.IsBot) ?? room.CurrentOnlinePlayerCount;
room.CurrentOnlinePlayerCount = realPlayerCount;
room.RobotCount = Math.Clamp(count, 0, Math.Max(0, room.MaxPlayerCount - realPlayerCount));
if (room.Players != null)
{
var excessBots = room.Players.Where(p => p.IsBot).Skip(room.RobotCount).ToList();
foreach (var bot in excessBots)
{
_redisService.ClearBulletIds(roomId, bot.UserId);
room.Players.Remove(bot);
}
room.RobotCount = Math.Max(room.RobotCount, room.Players.Count(p => p.IsBot));
}
_redisService.SetGameRoom(room);
return this.ToResult($"已将房间 {roomId} 的机器人数量设置为 {count}");
}
[HttpGet("RegenerateAllBotIds")]
public async Task<BaseResponse<string>> RegenerateAllBotIds()
{
var rooms = GetAllRoomsFromRedis()?.ToList() ?? new List<RedisGameRoom>();
int totalBots = 0;
foreach (var room in rooms)
{
if (room?.Players == null || room.Players.Count == 0)
continue;
var bots = room.Players.Where(p => p.IsBot).ToList();
if (bots.Count == 0)
continue;
foreach (var bot in bots)
{
var oldUserId = bot.UserId;
bot.UserId = Guid.NewGuid().ToString("N");
bot.UserNumber = Common.Utils.RandomHelper.RandomNumbers(8);
totalBots++;
}
_redisService.SetGameRoom(room);
}
return this.ToResult($"已刷新 {totalBots} 个机器人编号(涉及 {rooms.Count(r => r?.Players?.Any(p => p.IsBot) == true)} 个房间)");
}
[HttpGet("ClearRoom")]
public async Task<BaseResponse<string>> ClearRoom(string roomId)
{
var room = _redisService.GetGameRoom(roomId);
if (room == null)
return this.ToFailResult<string>("房间不存在");
int success = 0, fail = 0;
foreach (var player in room.Players.Where(p => !p.IsBot).ToList())
{
try
{
await _capPublisher.PublishAsync(TopicKeys.游戏金币结算, new
{
UserId = player.UserId,
BeforeGold = player.BeginCoin,
AfterGold = player.Gold,
Remark = "管理员清空房间结算",
RoomName = room.RoomName ?? "",
RoomInfo = room.RoomId ?? ""
});
}
catch (Exception ex)
{
_logger.LogError(ex, "管理员清空房间 CAP 结算失败 roomId={RoomId} userId={UserId}", roomId, player.UserId);
}
try { _redisService.ClearBulletIds(roomId, player.UserId); }
catch (Exception ex) { _logger.LogError(ex, "管理员清空房间 清理子弹失败 roomId={RoomId} userId={UserId}", roomId, player.UserId); }
try
{
var userRedis = _redisService.GetRedisUserCId(player.UserId);
if (userRedis != null && userRedis.RoomId == roomId)
{
userRedis.RoomId = "";
userRedis.CId = "";
_redisService.SetRedisUserCId(userRedis);
}
success++;
}
catch (Exception ex)
{
_logger.LogError(ex, "管理员清空房间 清理userRedis失败 roomId={RoomId} userId={UserId}", roomId, player.UserId);
fail++;
}
}
foreach (var player in room.Players.Where(p => p.IsBot).ToList())
{
try { _redisService.ClearBulletIds(roomId, player.UserId); }
catch { }
}
var robotCount = room.RobotCount;
room.Players.Clear();
room.CurrentOnlinePlayerCount = 0;
room.RobotCount = Math.Clamp(robotCount, 0, room.MaxPlayerCount);
_redisService.SetGameRoom(room);
var msg = fail > 0
? $"已清空房间 {roomId}:成功 {success} 人,失败 {fail} 人"
: $"已清空房间 {roomId} 的所有玩家({success} 人)";
return this.ToResult(msg);
}
[HttpGet("GetRoomStatistics")]
public async Task<BaseResponse<RoomStatistics>> GetRoomStatistics()
{
var rooms = GetAllRoomsFromRedis();
if (rooms == null || rooms.Count() == 0)
{
return this.ToResult(new RoomStatistics());
}
var stats = new RoomStatistics
{
TotalRooms = rooms?.Count()?? 0,
TotalPlayers = rooms?.Where(_=>_!=null).Sum(r => r.CurrentOnlinePlayerCount) ?? 0,
TotalRobots = rooms?.Where(_ => _ != null).Sum(r => r.RobotCount) ?? 0
};
if (rooms != null && rooms.Count() > 0)
{
stats.RoomsByLevel = rooms.Where(_ => _ != null).GroupBy(r => r.RoomLevel)
.ToDictionary(g => g.Key, g => g.Count());
stats.RoomsByType = rooms.Where(_ => _ != null).GroupBy(r => r.GameType.ToString())
.ToDictionary(g => g.Key, g => g.Count());
}
return this.ToResult(stats);
}
[HttpGet("RepairChessRooms")]
public async Task<BaseResponse<string>> RepairChessRooms()
{
var rooms = _redisService.GetAllChessRooms();
if (rooms == null || rooms.Count == 0)
return this.ToFailResult<string>("没有象棋房间");
int fixedCount = 0;
foreach (var room in rooms)
{
if (room.users != null && room.users.Any(u => !u.IsLeave))
continue;
ApplyRobotStateRule(room);
_redisService.SetChessRoom(room);
fixedCount++;
}
return this.ToResult($"已修复 {fixedCount} 个象棋房间");
}
[HttpGet("InitRooms")]
public async Task<BaseResponse<string>> InitRooms()
{
_redisService.RemoveGameRoomAll();
_redisService.ClearAllChessRooms();
await _gameConfigService.InitRoom();
var config = await _gameConfigService.Get();
var chessRoomConfigs = config?.RoomConfigs.Where(c => c.GameType == GameTypeEnum.中国象棋).ToList();
if (chessRoomConfigs != null)
{
foreach (var roomConfig in chessRoomConfigs)
{
for (int y = 1; y <= roomConfig.RoomPartitionNum; y++)
{
for (int i = 0; i < roomConfig.RoomCount; i++)
{
var room = new ChessGameRoom
{
RoomId = $"{(int)GameTypeEnum.中国象棋}{y}{i.ToString("00")}",
CreateTime = DateTime.Now,
createUserId = "",
gameType = 0,
gold = roomConfig.RoomGoldLimit,
Id = Guid.NewGuid().ToString(),
users = new List<RedisChessGameUser>(),
EndGameRequests = new Dictionary<string, long>(),
LastActiveTime = 0,
TimeoutSeconds = 60,
robotCount = 0
};
ApplyRobotStateRule(room);
_redisService.SetChessRoom(room);
}
}
}
}
return this.ToResult("房间初始化成功");
}
[HttpGet("ReInitChessRooms")]
public async Task<BaseResponse<string>> ReInitChessRooms()
{
var config = await _gameConfigService.Get();
var chessConfig = config?.ChessConfig;
if (chessConfig == null)
return this.ToFailResult<string>("象棋配置不存在");
_redisService.ClearAllChessRooms();
var chessRoomConfigs = config.RoomConfigs.Where(c => c.GameType == GameTypeEnum.中国象棋).ToList();
if (chessRoomConfigs.Count == 0)
return this.ToFailResult<string>("未找到象棋房间配置");
int count = 0;
foreach (var roomConfig in chessRoomConfigs)
{
for (int y = 1; y <= roomConfig.RoomPartitionNum; y++)
{
for (int i = 0; i < roomConfig.RoomCount; i++)
{
var room = new ChessGameRoom
{
RoomId = $"{(int)GameTypeEnum.中国象棋}{y}{i.ToString("00")}",
CreateTime = DateTime.Now,
createUserId = "",
gameType = 0,
gold = roomConfig.RoomGoldLimit,
Id = Guid.NewGuid().ToString(),
users = new List<RedisChessGameUser>(),
EndGameRequests = new Dictionary<string, long>(),
LastActiveTime = 0,
TimeoutSeconds = 60,
robotCount = 0
};
ApplyRobotStateRule(room);
_redisService.SetChessRoom(room);
count++;
}
}
}
return this.ToResult($"象棋房间已重新初始化,共 {count} 个房间");
}
private IEnumerable<RedisGameRoom> GetAllRoomsFromRedis()
{
return _redisService.GetGameRoomAllList();
}
private static void ApplyRobotStateRule(ChessGameRoom room)
{
var userCount = room.users?.Count ?? 0;
var totalCount = userCount + room.robotCount;
if (totalCount == 0)
{
room.state = 0;
room.password = "";
}
else if (totalCount == 1)
{
room.state = 1;
if (string.IsNullOrEmpty(room.password))
room.password = Random.Shared.Next(100000, 999999).ToString();
}
else
{
room.state = 2;
if (string.IsNullOrEmpty(room.password))
room.password = Random.Shared.Next(100000, 999999).ToString();
}
}
}
public class RoomStatistics
{
public int TotalRooms { get; set; } = 0;
public int TotalPlayers { get; set; } = 0;
public int TotalRobots { get; set; } = 0;
public Dictionary<int, int> RoomsByLevel { get; set; } = new();
public Dictionary<string, int> RoomsByType { get; set; } = new();
}
public class ChessRoomStatistics
{
public int TotalRooms { get; set; } = 0;
public int EmptyRooms { get; set; } = 0;
public double EmptyRoomRate { get; set; } = 0;
public int WaitingRooms { get; set; } = 0;
public int PlayingRooms { get; set; } = 0;
public int FinishedRooms { get; set; } = 0;
public int TotalPlayers { get; set; } = 0;
public int BlackSidePlayers { get; set; } = 0;
public int RedSidePlayers { get; set; } = 0;
}
public class UserRoomRealtimeDto
{
public bool Found { get; set; } = false;
public bool InRoom { get; set; } = false;
public long WinGold { get; set; } = 0;
public long LoseGold { get; set; } = 0;
public string RoomId { get; set; } = string.Empty;
public string RoomName { get; set; } = string.Empty;
public int GameType { get; set; }
public string GameTypeName { get; set; } = string.Empty;
public int RoomLevel { get; set; }
public int RoomPartition { get; set; }
public int RoomNumber { get; set; }
public double SystemFactor { get; set; } = 1.0;
public int CurrentOnlinePlayerCount { get; set; }
public int RobotCount { get; set; }
public int Position { get; set; }
public string UserName { get; set; } = string.Empty;
public string UserNumber { get; set; } = string.Empty;
public long Gold { get; set; }
public long BeginCoin { get; set; }
public long MaxGold { get; set; }
public int CannonMultiple { get; set; }
public string CannonId { get; set; } = string.Empty;
public int State { get; set; }
public bool IsAfk { get; set; }
public long TotalRechargeGold { get; set; }
public bool IsBlack { get; set; }
public bool IsIgnore { get; set; }
public double ViolateValue { get; set; }
public double AdditionalFactor { get; set; }
public double MissRate { get; set; }
public int CompensateQuota { get; set; }
public long CompensateStartGold { get; set; }
public long CompensateTargetGold { get; set; }
public long CompensateRemainingQuota { get; set; }
public int PenaltyQuota { get; set; }
public long StartingBonus { get; set; }
public double CompensateRateBoss { get; set; }
public double CompensateRateGold { get; set; }
public double CompensateRateSpecial { get; set; }
public double CompensateRateOrdinary { get; set; }
public double PenaltyRateBoss { get; set; }
public double PenaltyRateGold { get; set; }
public double PenaltyRateSpecial { get; set; }
public double PenaltyRateOrdinary { get; set; }
}
}
@@ -0,0 +1,63 @@
using Common;
using CommonDomain;
using CommonInfrastructure;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using MongoRepository;
namespace AdminApi.GameConfigs
{
[ApiController, Route("adminapi/[controller]")]
public class BotConfigController : BaseController
{
private readonly IMongoBaseRepository<BotProfileEntity> _botRepo;
public BotConfigController(IMongoBaseRepository<BotProfileEntity> botRepo)
{
_botRepo = botRepo;
}
[HttpGet("GetAll")]
public async Task<BaseResponse<List<BotProfileEntity>>> GetAll()
{
var list = await _botRepo.FilterByAsync(_ => true);
return this.ToResult(list.ToList());
}
[HttpPost("Add")]
public async Task<BaseResponse<string>> Add(BotProfileEntity entity)
{
if (string.IsNullOrWhiteSpace(entity.Name))
return this.ToFailResult<string>("名称不能为空");
await _botRepo.InsertOneAsync(entity);
return this.ToResult("添加成功");
}
[HttpPost("Update")]
public async Task<BaseResponse<string>> Update(BotProfileEntity entity)
{
if (string.IsNullOrWhiteSpace(entity.Id))
return this.ToFailResult<string>("缺少Id");
if (string.IsNullOrWhiteSpace(entity.Name))
return this.ToFailResult<string>("名称不能为空");
var update = Builders<BotProfileEntity>.Update
.Set(x => x.Name, entity.Name)
.Set(x => x.Avatar, entity.Avatar ?? string.Empty);
await _botRepo.UpdateByIdAsync(entity.Id, update);
return this.ToResult("更新成功");
}
[HttpPost("Delete")]
public async Task<BaseResponse<string>> Delete([FromQuery] string id)
{
if (string.IsNullOrWhiteSpace(id))
return this.ToFailResult<string>("缺少Id");
await _botRepo.DeleteByIdAsync(id);
return this.ToResult("删除成功");
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,98 @@
using System;
using Common;
using CommonDomain;
using CommonInfrastructure;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using RedisService;
namespace AdminApi.GameConfigs
{
[ApiController, Route("adminapi/Admin/[controller]")]
[AllowAnonymous]
public class TempSpawnFishController : BaseController
{
private readonly ICapPublisher _capPublisher;
private readonly IRedisService _redisService;
private readonly ILogger<TempSpawnFishController> _logger;
public TempSpawnFishController(ICapPublisher capPublisher, IRedisService redisService, ILogger<TempSpawnFishController> logger)
{
_capPublisher = capPublisher;
_redisService = redisService;
_logger = logger;
}
[HttpGet("SpawnFish")]
public async Task<BaseResponse<string>> SpawnFish(
string roomId,
string fishNumber,
int count = 1,
int? seconds = null,
int? routeId = null)
{
if (string.IsNullOrWhiteSpace(roomId) || string.IsNullOrWhiteSpace(fishNumber))
{
return new BaseResponse<string>
{
Code = CommonResponseCodeEnum.ParamError,
Info = "roomId / fishNumber 不能为空"
};
}
var room = _redisService.GetGameRoom(roomId);
if (room == null)
{
return new BaseResponse<string>
{
Code = CommonResponseCodeEnum.ParamError,
Info = $"房间 {roomId} 不存在或不在线"
};
}
count = Math.Clamp(count <= 0 ? 1 : count, 1, 2000);
var effectiveSeconds = (seconds.HasValue && seconds.Value > 0) ? seconds.Value : 30;
var operationId = Guid.NewGuid().ToString("N");
var publishedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
var msg = new TempSpawnFishMessage
{
RoomId = roomId,
FishNumber = fishNumber,
Count = count,
RouteId = routeId,
Seconds = effectiveSeconds,
OperationId = operationId,
PublishedAtUnixMs = publishedAt
};
try
{
await _capPublisher.PublishAsync(TopicKeys.临时强制出鱼, msg);
return new BaseResponse<string>
{
Code = CommonResponseCodeEnum.Success,
Info = "已推送临时出鱼指令(异步),operationId=" + operationId,
Data = operationId
};
}
catch (Exception ex)
{
_logger.LogError(ex,
"[TempSpawn] CAP发布失败 operationId={OperationId} roomId={RoomId} fishNumber={FishNumber} count={Count}",
operationId, roomId, fishNumber, count);
return new BaseResponse<string>
{
Code = CommonResponseCodeEnum.Error,
Info = "发布失败:" + ex.Message
};
}
}
}
}
@@ -0,0 +1,137 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using CommonInfrastructure;
using Microsoft.AspNetCore.Mvc;
using MongoRepository;
using UserDomain;
using UserDomain.Entity;
using UserDomain.Param;
namespace AdminApi.LoginLogs
{
[ApiController, Route("adminapi/[controller]")]
public class UserLoginLogController : BaseController
{
private readonly IMongoBaseRepository<UserLoginLog> _logRepo;
public UserLoginLogController(IMongoBaseRepository<UserLoginLog> logRepo)
{
_logRepo = logRepo;
}
[HttpPost("List")]
public async Task<PageResponse<UserLoginLogDto>> GetList([FromBody] UserLoginLogQueryParam param)
{
var result = await _logRepo.QueryPageAsync(
filterExpression: x =>
(string.IsNullOrEmpty(param.UserId) || x.UserId == param.UserId) &&
(string.IsNullOrEmpty(param.UserNumber) || x.UserNumber == param.UserNumber) &&
(string.IsNullOrEmpty(param.UserName) || (x.UserName != null && x.UserName.Contains(param.UserName))) &&
(!param.LoginType.HasValue || x.LoginType == param.LoginType) &&
(!param.Status.HasValue || x.Status == param.Status) &&
(!param.Platform.HasValue || x.Platform == param.Platform) &&
(!param.StartTime.HasValue || x.LoginTime >= param.StartTime) &&
(!param.EndTime.HasValue || x.LoginTime <= param.EndTime),
orderExpression: x => x.LoginTime,
desc: true,
pageSize: param.PageSize,
pageIndex: param.PageIndex
);
var dtos = result.list.Select(MapToDto);
return this.ToPageResult(dtos, (int)result.count);
}
[HttpGet("Detail")]
public async Task<BaseResponse<UserLoginLogDto>> GetDetail(string id)
{
var log = await _logRepo.FindOneAsync(x => x.Id == id);
if (log == null)
return this.ToFailResult<UserLoginLogDto>("日志不存在");
return this.ToResult(MapToDto(log));
}
[HttpPost("Delete")]
public async Task<BaseResponse<string>> Delete(string id)
{
var result = await _logRepo.DeleteByIdAsync(id);
if (result.ok)
return this.ToResult("删除成功");
else
return this.ToFailResult<string>("删除失败");
}
[HttpPost("BatchDelete")]
public async Task<BaseResponse<string>> BatchDelete([FromBody] List<string> ids)
{
int success = 0, fail = 0;
foreach (var id in ids)
{
var result = await _logRepo.DeleteByIdAsync(id);
if (result.ok)
success++;
else
fail++;
}
if (fail == 0)
return this.ToResult($"成功删除 {success} 条");
return this.ToResult($"删除完成:成功 {success} 条,失败 {fail} 条");
}
private static UserLoginLogDto MapToDto(UserLoginLog entity)
{
return new UserLoginLogDto
{
Id = entity.Id,
UserId = entity.UserId ?? "",
UserNumber = entity.UserNumber ?? "",
UserName = entity.UserName ?? "",
LoginType = entity.LoginType,
Status = entity.Status,
Ip = entity.Ip ?? "",
IpLocation = entity.IpLocation ?? "",
DeviceType = entity.DeviceType ?? "",
DeviceId = entity.DeviceId ?? "",
Platform = entity.Platform,
ClientVersion = entity.ClientVersion ?? "",
FailReason = entity.FailReason ?? "",
LoginTime = entity.LoginTime
};
}
}
public class UserLoginLogDto
{
public string Id { get; set; }
public string UserId { get; set; }
public string UserNumber { get; set; }
public string UserName { get; set; }
public int LoginType { get; set; }
public int Status { get; set; }
public string Ip { get; set; }
public string IpLocation { get; set; }
public string DeviceType { get; set; }
public string DeviceId { get; set; }
public int Platform { get; set; }
public string ClientVersion { get; set; }
public string FailReason { get; set; }
public DateTime LoginTime { get; set; }
}
}
@@ -0,0 +1,236 @@
using AdminService.GameConfigs;
using Common;
using CommonDomain;
using CommonDomain.BaseModel;
using CommonInfrastructure;
using Microsoft.AspNetCore.Mvc;
namespace AdminApi.Lottery
{
[ApiController, Route("adminapi/[controller]")]
public class LotteryController : BaseController
{
private readonly IActivityConfigService _activityConfigService;
private readonly IGameConfigService _gameConfigService;
public LotteryController(IActivityConfigService activityConfigService, IGameConfigService gameConfigService)
{
_activityConfigService = activityConfigService;
_gameConfigService = gameConfigService;
}
[HttpGet("list")]
public async Task<BaseResponse<List<LotteryActivityVm>>> List()
{
var config = await _activityConfigService.Get();
if (config == null)
return this.ToResult(new List<LotteryActivityVm>());
var lotto = config.LotteryActivityConfig;
if (lotto == null || string.IsNullOrWhiteSpace(lotto.ActivityName))
return this.ToResult(new List<LotteryActivityVm>());
LotteryPrizeProductHelper.Enrich(lotto, await _gameConfigService.Get());
var vm = new LotteryActivityVm
{
ActivityId = config.Id,
ActivityName = lotto.ActivityName,
IsOpen = lotto.IsOpen,
StartTime = lotto.StartTime,
EndTime = lotto.EndTime,
CostsByPool = lotto.CostsByPool,
UserMaxDraw = lotto.UserMaxDraw,
Pools = lotto.Pools
};
return this.ToResult(new List<LotteryActivityVm> { vm });
}
[HttpGet("detail")]
public async Task<BaseResponse<LotteryActivityVm>> Detail([FromQuery] string activityId)
{
var config = await _activityConfigService.Get();
if (config == null)
return this.ToFailResult<LotteryActivityVm>("活动配置不存在");
LotteryPrizeProductHelper.Enrich(config.LotteryActivityConfig, await _gameConfigService.Get());
var vm = new LotteryActivityVm
{
ActivityId = config.Id,
ActivityName = config.LotteryActivityConfig.ActivityName,
IsOpen = config.LotteryActivityConfig.IsOpen,
StartTime = config.LotteryActivityConfig.StartTime,
EndTime = config.LotteryActivityConfig.EndTime,
CostsByPool = config.LotteryActivityConfig.CostsByPool,
UserMaxDraw = config.LotteryActivityConfig.UserMaxDraw,
Pools = config.LotteryActivityConfig.Pools
};
return this.ToResult(vm);
}
[HttpPost("save")]
public async Task<BaseResponse<string>> Save([FromBody] LotteryActivityVm param)
{
if (string.IsNullOrWhiteSpace(param.ActivityName))
return this.ToFailResult<string>("活动名称不能为空");
var pools = param.Pools ?? new List<LotteryPoolLevel>();
if (pools.SelectMany(pool => pool.PrizeList ?? new List<LotteryPrize>())
.Any(prize => !string.IsNullOrWhiteSpace(prize.OtherId)))
{
var gameConfig = await _gameConfigService.Get();
if (gameConfig == null)
return this.ToFailResult<string>("道具配置不存在,无法补全奖项信息");
EnrichPrizeProducts(pools, gameConfig);
}
var activityConfig = await _activityConfigService.Get() ?? new ActivityConfig();
var previousLottery = activityConfig.LotteryActivityConfig;
var cycleChanged = previousLottery == null
|| previousLottery.StartTime != param.StartTime
|| previousLottery.EndTime != param.EndTime;
if (cycleChanged)
{
foreach (var prize in pools.SelectMany(pool => pool.PrizeList ?? new List<LotteryPrize>()))
prize.DrawnCount = 0;
}
var normalizedCostsByPool = new Dictionary<int, List<long>>();
var poolNames = new Dictionary<int, string> { [1] = "炮台", [2] = "战神", [3] = "翅膀" };
for (var poolType = 1; poolType <= 3; poolType++)
{
List<long>? poolCosts = null;
param.CostsByPool?.TryGetValue(poolType, out poolCosts);
var validPoolCosts = poolCosts?.Where(cost => cost > 0).ToList();
if (validPoolCosts == null || validPoolCosts.Count == 0)
return this.ToFailResult<string>($"请配置{poolNames[poolType]}奖池消耗金币");
normalizedCostsByPool[poolType] = validPoolCosts;
}
activityConfig.LotteryActivityConfig = new LotteryActivityConfig
{
ActivityName = param.ActivityName,
IsOpen = param.IsOpen,
StartTime = param.StartTime,
EndTime = param.EndTime,
CostsByPool = normalizedCostsByPool,
UserMaxDraw = param.UserMaxDraw,
Pools = pools
};
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult("保存成功");
else
return this.ToFailResult<string>(res.msg);
}
private static void EnrichPrizeProducts(List<LotteryPoolLevel> pools, GameConfig gameConfig)
{
LotteryPrizeProductHelper.Enrich(new LotteryActivityConfig { Pools = pools }, gameConfig);
}
[HttpPost("toggle")]
public async Task<BaseResponse<string>> Toggle([FromBody] LotteryToggleParam param)
{
var activityConfig = await _activityConfigService.Get();
if (activityConfig == null)
return this.ToFailResult<string>("活动配置不存在");
activityConfig.LotteryActivityConfig.IsOpen = param.IsOpen;
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult(param.IsOpen ? "活动已开启" : "活动已关闭");
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("initialize")]
public async Task<BaseResponse<string>> Initialize()
{
var path = Path.Combine(AppContext.BaseDirectory, "Config", "lottery-init.json");
if (!global::System.IO.File.Exists(path))
return this.ToFailResult<string>("奖池初始化模板不存在");
LotteryActivityConfig? template;
try
{
var json = await global::System.IO.File.ReadAllTextAsync(path);
template = global::System.Text.Json.JsonSerializer.Deserialize<LotteryActivityConfig>(json,
new global::System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
catch (global::System.Text.Json.JsonException)
{
return this.ToFailResult<string>("奖池初始化模板格式错误");
}
var pools = template?.Pools;
var prizes = pools?.SelectMany(pool => pool.PrizeList ?? new List<LotteryPrize>()).ToList();
if (template == null || string.IsNullOrWhiteSpace(template.ActivityName)
|| template.CostsByPool == null
|| new[] { 1, 2, 3 }.Any(type => !template.CostsByPool.TryGetValue(type, out var costs) || costs == null || costs.Count == 0)
|| pools == null || pools.Count == 0 || prizes == null || prizes.Count == 0
|| new[] { 1, 2, 3 }.Any(type => !pools.Any(pool => pool.PoolType == type && pool.PrizeList?.Count > 0))
|| prizes.Any(prize => string.IsNullOrWhiteSpace(prize.PrizeId))
|| prizes.Select(prize => prize.PrizeId).Distinct().Count() != prizes.Count)
return this.ToFailResult<string>("奖池初始化模板不完整,未修改现有配置");
template.IsOpen = false;
foreach (var prize in prizes) prize.DrawnCount = 0;
var config = await _activityConfigService.Get() ?? new ActivityConfig();
config.LotteryActivityConfig = template;
var result = await _activityConfigService.Update(config);
return result.isok
? this.ToResult("奖池配置已初始化,活动保持关闭")
: this.ToFailResult<string>(result.msg);
}
[HttpDelete("delete")]
public async Task<BaseResponse<string>> Delete()
{
var activityConfig = await _activityConfigService.Get();
if (activityConfig == null)
return this.ToFailResult<string>("活动配置不存在");
activityConfig.LotteryActivityConfig = new LotteryActivityConfig();
var res = await _activityConfigService.Update(activityConfig);
if (res.isok)
return this.ToResult("删除成功");
else
return this.ToFailResult<string>(res.msg);
}
}
public class LotteryActivityVm
{
public string ActivityId { get; set; } = string.Empty;
public string ActivityName { get; set; } = string.Empty;
public bool IsOpen { get; set; } = false;
public long StartTime { get; set; } = 0;
public long EndTime { get; set; } = 0;
public Dictionary<int, List<long>> CostsByPool { get; set; } = new Dictionary<int, List<long>>();
public int UserMaxDraw { get; set; } = 100;
public List<LotteryPoolLevel> Pools { get; set; } = new List<LotteryPoolLevel>();
}
public class LotteryToggleParam
{
public string ActivityId { get; set; } = string.Empty;
public bool IsOpen { get; set; }
}
}
@@ -0,0 +1,88 @@
using Domain.Admin.Notices;
using AdminService.Notices;
using AdminService.Notices.Param;
using Common;
using CommonInfrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AdminApi.Notices;
[ApiController, Route("adminapi/[controller]")]
[Authorize]
public class NoticeController : BaseController
{
private readonly INoticeService _noticeService;
public NoticeController(INoticeService noticeService)
{
_noticeService = noticeService;
}
[HttpPost("add")]
public async Task<BaseResponse<string>> AddNotice([FromBody] AddNoticeParam param)
{
var result = await _noticeService.Add(param);
return result.isok
? this.ToResult(result.msg)
: this.ToFailResult<string>(result.msg);
}
[HttpPost("update")]
public async Task<BaseResponse<string>> UpdateNotice([FromBody] UpdateNoticeParam param)
{
var result = await _noticeService.Update(param);
return result.isok
? this.ToResult(result.msg)
: this.ToFailResult<string>(result.msg);
}
[HttpGet("delete")]
public async Task<BaseResponse<string>> DeleteNotice([FromQuery] string id)
{
var result = await _noticeService.Delete(id);
return result.isok
? this.ToResult(result.msg)
: this.ToFailResult<string>(result.msg);
}
[HttpPost("list")]
public async Task<PageResponse<NoticeListItemDto>> GetNoticeList([FromBody] GetNoticeListParam param)
{
var (list, count) = await _noticeService.GetList(param);
if (list == null)
return this.ToPageResult(new List<NoticeListItemDto>(), 0);
var dtos = list.Select(n => new NoticeListItemDto
{
Id = n.Id,
Title = n.Title,
Recommend = n.Recommend,
TopImage = n.TopImage,
CreateTime = n.CreateTime
});
return this.ToPageResult(dtos, (int)count);
}
[HttpGet("get")]
[AllowAnonymous]
public async Task<BaseResponse<NoticeDto>> GetNotice([FromQuery] string id)
{
var notice = await _noticeService.Get(id);
if (notice == null)
{
return this.ToFailResult<NoticeDto>("公告不存在");
}
var dto = new NoticeDto
{
Id = notice.Id,
Title = notice.Title,
Content = notice.Content,
Recommend = notice.Recommend,
TopImage = notice.TopImage,
ContentImages = notice.ContentImages,
CreateTime = notice.CreateTime
};
return this.ToResult(dto);
}
}
+2
View File
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
@@ -0,0 +1,330 @@
using System.Linq;
using AdminService.System;
using AdminService.System.Param;
using AdminService.System.Response;
using Common;
using CommonInfrastructure ;
using Domain.Admin.Admin;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace AdminApi.System
{
[ApiController, Route("adminapi/[controller]")]
[Authorize]
public class SystemController : BaseController
{
private readonly ISystemService _systemService;
public SystemController(ISystemService systemService)
{
_systemService = systemService;
}
[HttpPost("user/add")]
public async Task<BaseResponse<string>> AddUser(AddUserParam param)
{
var result = await _systemService.AddUser(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("user/update")]
public async Task<BaseResponse<string>> UpdateUser(UpdateUserParam param)
{
var result = await _systemService.UpdateUser(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("user/update/icon")]
public async Task<BaseResponse<string>> UpdateUserIcon(string id, string icon)
{
var result = await _systemService.UpdateUserIcon(id,icon);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("user/update/state")]
public async Task<BaseResponse<string>> UpdateUserState(string id, int state)
{
var result = await _systemService.UpdateUserState(id, state);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("user/delete")]
public async Task<BaseResponse<string>> DeleteUser(string id)
{
var result = await _systemService.DeleteUser(id);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("user/login")]
[AllowAnonymous]
public async Task<BaseResponse<AdminUserToken>> UserLogin(string userName, string password)
{
var result = await _systemService.UserLogin(userName, password);
if (result.isok)
return this.ToResult(result.model);
else
return this.ToFailResult<AdminUserToken>(result.msg);
}
[HttpPost("user/list")]
public async Task<PageResponse<SystemUserDto>> GetUserList(GetUserListParam param)
{
var result = await _systemService.GetUserList(param);
var dtos = result.list.Select(MapToSystemUserDto).ToList();
return this.ToPageResult(dtos, (int)result.count);
}
[HttpGet("user/getuser")]
public async Task<BaseResponse<SystemUserDto>> GetUser()
{
if (string.IsNullOrEmpty(loginUser.UserId))
return this.ToFailResult<SystemUserDto>("用户未登录");
var result = await _systemService.GetUser(loginUser.UserId);
if (result == null)
return this.ToFailResult<SystemUserDto>("用户不存在");
return this.ToResult(MapToSystemUserDto(result));
}
private static SystemUserDto MapToSystemUserDto(SystemUser entity)
{
if (entity == null) return new SystemUserDto();
return new SystemUserDto
{
Id = entity.Id ?? "",
UserName = entity.UserName ?? "",
DisplayName = entity.DisplayName ?? "",
Icon = entity.Icon ?? "",
RegisterTime = entity.RegisterTime,
State = entity.State,
RoleId = entity.SystemRole?.Id ?? "",
RoleName = entity.SystemRole?.Name ?? ""
};
}
[HttpGet("user/nav")]
public async Task<ListResponse<SystemNavigationResponse>> GetUserNav()
{
if (string.IsNullOrEmpty(loginUser.UserId))
return this.ToListFailResult<SystemNavigationResponse>("用户未登录");
var result = await _systemService.GetUserNav(this.loginUser);
if (result == null)
return this.ToListFailResult<SystemNavigationResponse>("获取菜单失败");
return this.ToListResult(result);
}
[HttpPost("role/add")]
public async Task<BaseResponse<string>> AddRole(AddRoleParam param)
{
var result = await _systemService.AddRole(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("role/update")]
public async Task<BaseResponse<string>> UpdateRole(UpdateRoleParam param)
{
var result = await _systemService.UpdateRole(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("role/updatenav")]
public async Task<BaseResponse<string>> UpdateRoleNav(UpdateRoleNavParam param)
{
var result = await _systemService.UpdateRoleNav(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("role/delete")]
public async Task<BaseResponse<string>> DeleteRole(string id)
{
var result = await _systemService.DeleteRole(id);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("role/list")]
public async Task<ListResponse<SystemUserRoleDto>> GetRoleList(int page, int limit)
{
var result = await _systemService.GetRoleList();
var dtos = result.Select(MapToSystemUserRoleDto).ToList();
return this.ToListResult(dtos);
}
private static SystemUserRoleDto MapToSystemUserRoleDto(SystemUserRole entity)
{
if (entity == null) return new SystemUserRoleDto();
return new SystemUserRoleDto
{
Id = entity.Id ?? "",
RoleName = entity.RoleName ?? "",
Description = entity.Description ?? "",
NavIds = entity.NavIds ?? new List<string>()
};
}
[HttpGet("role/get")]
public async Task<BaseResponse<SystemUserRoleDto>> GetUserRole(string id)
{
var result = await _systemService.GetUserRole(id);
return this.ToResult(MapToSystemUserRoleDto(result));
}
[HttpPost("nav/add")]
public async Task<BaseResponse<string>> AddNav(AddNavParam param)
{
var result = await _systemService.AddNav(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("nav/update")]
public async Task<BaseResponse<string>> UpdateNav(UpdateNavParam param)
{
var result = await _systemService.UpdateNav(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("nav/delete")]
public async Task<BaseResponse<string>> DeleteNav(string id)
{
var result = await _systemService.DeleteNav(id);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("nav/list")]
public async Task<ListResponse<SystemNavigationResponse>> GetNavList(string? id="")
{
var result = await _systemService.GetNavList(id);
return this.ToListResult(result);
}
public class SystemUserDto
{
public string Id { get; set; }
public string UserName { get; set; }
public string DisplayName { get; set; }
public string Icon { get; set; }
public DateTime RegisterTime { get; set; }
public int State { get; set; }
public string RoleId { get; set; }
public string RoleName { get; set; }
}
public class SystemUserRoleDto
{
public string Id { get; set; }
public string RoleName { get; set; }
public string Description { get; set; }
public List<string> NavIds { get; set; } = new List<string>();
}
[HttpPost("dic/add")]
public async Task<BaseResponse<string>> AddDic(AddDicParam param)
{
var result = await _systemService.AddDic(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpPost("dic/update")]
public async Task<BaseResponse<string>> UpdateDic(UpdateDicParam param)
{
var result = await _systemService.UpdateDic(param);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("dic/delete")]
public async Task<BaseResponse<string>> DeleteDic(string id)
{
var result = await _systemService.DeleteDic(id);
if (result.isok)
return this.ToResult(result.msg);
else
return this.ToFailResult<string>(result.msg);
}
[HttpGet("dic/list")]
public async Task<ListResponse<SystemDicResponse>> GetDicList(string id="")
{
var result = await _systemService.GetDicList(id);
return this.ToListResult(result);
}
[HttpGet("dic/list/code")]
public async Task<ListResponse<SystemDicResponse>> GetDicListByCode(string code)
{
var result = await _systemService.GetDicListByCode(code);
return this.ToListResult(result);
}
[HttpGet("dic/get/code")]
public async Task<BaseResponse<SystemDic>> GetDictByCode(string code)
{
var result = await _systemService.GetDictByCode(code);
return this.ToResult(result);
}
}
}
+78
View File
@@ -0,0 +1,78 @@
using AdminService.Tasks;
using AdminService.Tasks.Param;
using Common;
using CommonDomain;
using CommonInfrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AdminApi.Task
{
[ApiController, Route("adminapi/[controller]")]
[Authorize]
public class TaskController : BaseController
{
private readonly ITaskService _taskService;
public TaskController(ITaskService taskService)
{
_taskService = taskService;
}
[HttpGet("Init")]
public async Task<string> Init()
{
return await _taskService.InitDefaultTasks();
}
[HttpGet("DayTaskReward")]
public async Task<string> DayTaskReward()
{
return await _taskService.DayTaskReward();
}
[HttpPost("AddTask")]
public async Task<BaseResponse<string>> AddTask([FromBody] GameTask param)
{
var res = await _taskService.AddTask(param);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpGet("DeleteTask")]
public async Task<BaseResponse<string>> DeleteTask(string id)
{
var res = await _taskService.DeleteTask(id);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpGet("UpdateTaskState")]
public async Task<BaseResponse<string>> UpdateTaskState(string id, int state)
{
var res = await _taskService.UpdateTaskState(id, state);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("UpdateTask")]
public async Task<BaseResponse<string>> UpdateTask([FromBody] GameTask param)
{
var res = await _taskService.UpdateTask(param);
if (res.isok)
return this.ToResult(res.msg);
else
return this.ToFailResult<string>(res.msg);
}
[HttpPost("GetTaskList")]
public async Task<PageResponse<GameTask>> GetTaskList(GetTaskListParam param)
{
var res = await _taskService.GetTaskList(param);
return this.ToPageResult(res.list, res.count);
}
}
}
@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AdminService.User.Param;
using Common;
using Common.Utils;
using CommonDomain.BaseModel;
using CommonInfrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using MongoRepository;
using UserDomain.Entity;
using UserDomain.Enum;
namespace AdminApi.UserAssetChanges
{
[ApiController, Route("adminapi/[controller]")]
[Authorize]
public class UserAssetChangeController : BaseController
{
private readonly IMongoBaseRepository<UserReward> _rewardMongo;
private readonly IMongoBaseRepository<UserEntity> _userMongo;
public UserAssetChangeController(IMongoBaseRepository<UserReward> rewardMongo, IMongoBaseRepository<UserEntity> userMongo)
{
_rewardMongo = rewardMongo;
_userMongo = userMongo;
}
[HttpPost("list")]
public async Task<PageResponse<UserAssetChangeDto>> GetList([FromBody] UserAssetChangeQueryParam param)
{
var filter = Builders<UserReward>.Filter.Empty;
filter &= Builders<UserReward>.Filter.Nin(x => x.Source, new List<RewardSource>() { RewardSource.开炮, RewardSource.击杀鱼});
if (!string.IsNullOrWhiteSpace(param.UserId))
{
filter &= Builders<UserReward>.Filter.Eq(x => x.UserId, param.UserId);
}
if (param.CurrencyTypes != null && param.CurrencyTypes.Count > 0)
{
filter &= Builders<UserReward>.Filter.In(x => x.CurrencyType, param.CurrencyTypes);
}
if (param.ChangeTypes != null && param.ChangeTypes.Count > 0)
{
filter &= Builders<UserReward>.Filter.In(x => x.Type, param.ChangeTypes);
}
if (param.Sources != null && param.Sources.Count > 0)
{
var sourceEnums = param.Sources.Select(s => Enum.TryParse<RewardSource>(s, out var src) ? src : (RewardSource?)null)
.Where(x => x.HasValue)
.Select(x => x.Value)
.ToList();
if (sourceEnums.Count > 0)
{
filter &= Builders<UserReward>.Filter.In(x => x.Source, sourceEnums);
}
}
if (param.CurrencyType.HasValue)
{
filter &= Builders<UserReward>.Filter.Eq(x => x.CurrencyType, param.CurrencyType.Value);
}
if (param.TimeStart.HasValue)
{
filter &= Builders<UserReward>.Filter.Gte(x => x.CreateTime, param.TimeStart.Value);
}
if (param.TimeEnd.HasValue)
{
filter &= Builders<UserReward>.Filter.Lte(x => x.CreateTime, param.TimeEnd.Value);
}
var sort = Builders<UserReward>.Sort.Descending(x => x.CreateTime);
var result = await _rewardMongo.QueryPageAsync(
filter,
sort,
true,
param.PageSize.Value,
param.PageIndex.Value
);
var list = result.list ?? new List<UserReward>();
var userIds = list.Select(x => x.UserId).Distinct().ToList();
var users = await _userMongo.FilterByAsync(x => userIds.Contains(x.Id));
var userDict = users.ToDictionary(u => u.Id, u => u.BaseInfo?.UserName ?? "");
if (list == null)
return this.ToPageResult(new List<UserAssetChangeDto>(), 0);
var dtos = list.Select(x => new UserAssetChangeDto
{
Id = x.Id,
UserId = x.UserId,
UserName = userDict.TryGetValue(x.UserId, out var name) ? name : "",
Type = x.Type,
ChangeTypeText = x.Type == 1 ? "增加" : "减少",
Source = x.Source.ToString(),
CurrencyType = x.CurrencyType,
CurrencyTypeText = x.CurrencyType == 1 ? "金币" : x.CurrencyType == 2 ? "保险箱金币" : "钻石",
BeforeCount = x.BeforeCount,
ChangeCount = x.ChangeCount,
AfterCount = x.AfterCount,
Remark = x.Remark,
CreateTime = x.CreateTime.ToDateTime()
});
return this.ToPageResult(dtos, (int)result.count);
}
[HttpGet("sources")]
public BaseResponse<List<SourceOptionDto>> GetSources()
{
var sources = Enum.GetValues<RewardSource>()
.Select(x => new SourceOptionDto { Value = x.ToString(), Label = x.ToString() })
.ToList();
return this.ToResult(sources);
}
}
public class UserAssetChangeDto
{
public string Id { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public int Type { get; set; }
public string ChangeTypeText { get; set; }
public string Source { get; set; }
public int CurrencyType { get; set; }
public string CurrencyTypeText { get; set; }
public long BeforeCount { get; set; }
public long ChangeCount { get; set; }
public long AfterCount { get; set; }
public string Remark { get; set; }
public DateTime CreateTime { get; set; }
}
public class SourceOptionDto
{
public string Value { get; set; }
public string Label { get; set; }
}
}