添加项目文件。
This commit is contained in:
@@ -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; } = "";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user