Add paginated user retrieval functionality in AdminController and related services. Implemented UsersFilter for filtering user queries and added LastConnectionDate property to User model. Updated database schema and frontend API to support new user management features.

This commit is contained in:
2025-11-17 20:04:17 +07:00
parent 06ef33b7ab
commit 02e46e8d0d
20 changed files with 2559 additions and 6 deletions

View File

@@ -263,5 +263,94 @@ public class AdminController : BaseController
RelatedBacktestsDeleted = backtestsDeleted
});
}
/// <summary>
/// Retrieves paginated users for admin users.
/// This endpoint returns all users with all their properties.
/// </summary>
/// <param name="page">Page number (defaults to 1)</param>
/// <param name="pageSize">Number of items per page (defaults to 50, max 100)</param>
/// <param name="sortBy">Field to sort by (defaults to "Id")</param>
/// <param name="sortOrder">Sort order - "asc" or "desc" (defaults to "desc")</param>
/// <param name="userNameContains">Filter by user name contains</param>
/// <param name="ownerAddressContains">Filter by owner address contains</param>
/// <param name="agentNameContains">Filter by agent name contains</param>
/// <param name="telegramChannelContains">Filter by telegram channel contains</param>
/// <returns>A paginated list of users.</returns>
[HttpGet]
[Route("Users/Paginated")]
public async Task<ActionResult<PaginatedUsersResponse>> GetUsersPaginated(
[FromQuery] int page = 1,
[FromQuery] int pageSize = 50,
[FromQuery] UserSortableColumn sortBy = UserSortableColumn.Id,
[FromQuery] string sortOrder = "desc",
[FromQuery] string? userNameContains = null,
[FromQuery] string? ownerAddressContains = null,
[FromQuery] string? agentNameContains = null,
[FromQuery] string? telegramChannelContains = null)
{
if (!await IsUserAdmin())
{
_logger.LogWarning("Non-admin user attempted to access admin users endpoint");
return StatusCode(403, new { error = "Only admin users can access this endpoint" });
}
if (page < 1)
{
return BadRequest("Page must be greater than 0");
}
if (pageSize < 1 || pageSize > 100)
{
return BadRequest("Page size must be between 1 and 100");
}
if (sortOrder != "asc" && sortOrder != "desc")
{
return BadRequest("Sort order must be 'asc' or 'desc'");
}
// Build filter
var filter = new UsersFilter
{
UserNameContains = string.IsNullOrWhiteSpace(userNameContains) ? null : userNameContains.Trim(),
OwnerAddressContains = string.IsNullOrWhiteSpace(ownerAddressContains) ? null : ownerAddressContains.Trim(),
AgentNameContains = string.IsNullOrWhiteSpace(agentNameContains) ? null : agentNameContains.Trim(),
TelegramChannelContains = string.IsNullOrWhiteSpace(telegramChannelContains) ? null : telegramChannelContains.Trim()
};
var (users, totalCount) =
await _userService.GetUsersPaginatedAsync(
page,
pageSize,
sortBy,
sortOrder,
filter);
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
var response = new PaginatedUsersResponse
{
Users = users.Select(u => new UserListItemResponse
{
Id = u.Id,
Name = u.Name,
AgentName = u.AgentName,
AvatarUrl = u.AvatarUrl,
TelegramChannel = u.TelegramChannel,
OwnerWalletAddress = u.OwnerWalletAddress,
IsAdmin = u.IsAdmin,
LastConnectionDate = u.LastConnectionDate
}),
TotalCount = totalCount,
CurrentPage = page,
PageSize = pageSize,
TotalPages = totalPages,
HasNextPage = page < totalPages,
HasPreviousPage = page > 1
};
return Ok(response);
}
}