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:
1726
src/Managing.Infrastructure.Database/Migrations/20251117115213_AddLastConnectionDateToUsers.Designer.cs
generated
Normal file
1726
src/Managing.Infrastructure.Database/Migrations/20251117115213_AddLastConnectionDateToUsers.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Managing.Infrastructure.Databases.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddLastConnectionDateToUsers : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTimeOffset>(
|
||||
name: "LastConnectionDate",
|
||||
table: "Users",
|
||||
type: "timestamp with time zone",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LastConnectionDate",
|
||||
table: "Users");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1413,6 +1413,9 @@ namespace Managing.Infrastructure.Databases.Migrations
|
||||
b.Property<bool>("IsAdmin")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LastConnectionDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
|
||||
@@ -14,6 +14,7 @@ public class UserEntity
|
||||
public string? AvatarUrl { get; set; }
|
||||
public string? TelegramChannel { get; set; }
|
||||
public string? OwnerWalletAddress { get; set; }
|
||||
public DateTimeOffset? LastConnectionDate { get; set; }
|
||||
public bool IsAdmin { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using Managing.Application.Abstractions.Repositories;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.Abstractions.Shared;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Users;
|
||||
using Managing.Infrastructure.Databases.PostgreSql.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Infrastructure.Databases.PostgreSql;
|
||||
|
||||
@@ -318,4 +320,77 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
|
||||
}
|
||||
}, nameof(SaveOrUpdateUserAsync), ("userName", user.Name), ("userId", user.Id));
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<User> Users, int TotalCount)> GetUsersPaginatedAsync(int page, int pageSize, UserSortableColumn sortBy, string sortOrder, UsersFilter filter)
|
||||
{
|
||||
return await ExecuteWithLoggingAsync(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
|
||||
|
||||
var query = _context.Users.AsNoTracking();
|
||||
|
||||
// Apply filters
|
||||
if (!string.IsNullOrWhiteSpace(filter.UserNameContains))
|
||||
{
|
||||
query = query.Where(u => EF.Functions.ILike(u.Name, $"%{filter.UserNameContains.Trim()}%"));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.OwnerAddressContains))
|
||||
{
|
||||
query = query.Where(u => EF.Functions.ILike(u.OwnerWalletAddress, $"%{filter.OwnerAddressContains.Trim()}%"));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.AgentNameContains))
|
||||
{
|
||||
query = query.Where(u => EF.Functions.ILike(u.AgentName, $"%{filter.AgentNameContains.Trim()}%"));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.TelegramChannelContains))
|
||||
{
|
||||
query = query.Where(u => EF.Functions.ILike(u.TelegramChannel, $"%{filter.TelegramChannelContains.Trim()}%"));
|
||||
}
|
||||
|
||||
// Get total count for pagination
|
||||
var totalCount = await query.CountAsync().ConfigureAwait(false);
|
||||
|
||||
// Apply sorting
|
||||
query = sortBy switch
|
||||
{
|
||||
UserSortableColumn.Id => sortOrder.ToLower() == "desc" ? query.OrderByDescending(u => u.Id) : query.OrderBy(u => u.Id),
|
||||
UserSortableColumn.Name => sortOrder.ToLower() == "desc" ? query.OrderByDescending(u => u.Name) : query.OrderBy(u => u.Name),
|
||||
UserSortableColumn.OwnerWalletAddress => sortOrder.ToLower() == "desc" ? query.OrderByDescending(u => u.OwnerWalletAddress) : query.OrderBy(u => u.OwnerWalletAddress),
|
||||
UserSortableColumn.AgentName => sortOrder.ToLower() == "desc" ? query.OrderByDescending(u => u.AgentName) : query.OrderBy(u => u.AgentName),
|
||||
_ => query.OrderBy(u => u.Id) // Default sorting
|
||||
};
|
||||
|
||||
// Apply pagination
|
||||
var users = await query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(u => new UserEntity
|
||||
{
|
||||
Id = u.Id,
|
||||
Name = u.Name,
|
||||
AgentName = u.AgentName,
|
||||
AvatarUrl = u.AvatarUrl,
|
||||
TelegramChannel = u.TelegramChannel,
|
||||
OwnerWalletAddress = u.OwnerWalletAddress,
|
||||
IsAdmin = u.IsAdmin,
|
||||
LastConnectionDate = u.LastConnectionDate
|
||||
})
|
||||
.ToListAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var domainUsers = users.Select(PostgreSqlMappers.Map).ToList();
|
||||
|
||||
return (domainUsers, totalCount);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await PostgreSqlConnectionHelper.SafeCloseConnectionAsync(_context);
|
||||
}
|
||||
}, nameof(GetUsersPaginatedAsync), ("page", page), ("pageSize", pageSize), ("sortBy", sortBy), ("sortOrder", sortOrder));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user