Browse Source

Add UsersController and related features for user management

ws
root 3 months ago
parent
commit
219261ef93
  1. 17
      src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserCommand.cs
  2. 87
      src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserCommandHandler.cs
  3. 39
      src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserCommandValidator.cs
  4. 8
      src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserResponse.cs
  5. 10
      src/CellularManagement.Application/Features/Users/Commands/DeleteUser/DeleteUserCommand.cs
  6. 78
      src/CellularManagement.Application/Features/Users/Commands/DeleteUser/DeleteUserCommandHandler.cs
  7. 8
      src/CellularManagement.Application/Features/Users/Commands/DeleteUser/DeleteUserResponse.cs
  8. 17
      src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserCommand.cs
  9. 66
      src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserCommandHandler.cs
  10. 30
      src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserCommandValidator.cs
  11. 8
      src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserResponse.cs
  12. 15
      src/CellularManagement.Application/Features/Users/Queries/Dtos/UserDto.cs
  13. 19
      src/CellularManagement.Application/Features/Users/Queries/GetAllUsers/GetAllUsersQuery.cs
  14. 94
      src/CellularManagement.Application/Features/Users/Queries/GetAllUsers/GetAllUsersQueryHandler.cs
  15. 33
      src/CellularManagement.Application/Features/Users/Queries/GetAllUsers/GetAllUsersResponse.cs
  16. 10
      src/CellularManagement.Application/Features/Users/Queries/GetUserById/GetUserByIdQuery.cs
  17. 66
      src/CellularManagement.Application/Features/Users/Queries/GetUserById/GetUserByIdQueryHandler.cs
  18. 10
      src/CellularManagement.Application/Features/Users/Queries/GetUserById/GetUserByIdResponse.cs
  19. 4
      src/CellularManagement.Presentation/Controllers/AuthController.cs
  20. 302
      src/CellularManagement.Presentation/Controllers/UsersController.cs

17
src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserCommand.cs

@ -0,0 +1,17 @@
using MediatR;
namespace CellularManagement.Application.Features.Users.Commands.CreateUser;
/// <summary>
/// 创建用户命令
/// 用于创建新用户的命令对象
/// </summary>
/// <param name="UserName">用户名</param>
/// <param name="Email">电子邮箱</param>
/// <param name="PhoneNumber">电话号码</param>
/// <param name="Password">密码</param>
public sealed record CreateUserCommand(
string UserName,
string Email,
string PhoneNumber,
string Password) : IRequest<OperationResult<CreateUserResponse>>;

87
src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserCommandHandler.cs

@ -0,0 +1,87 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using MediatR;
using CellularManagement.Domain.Entities;
using CellularManagement.Domain.Repositories;
namespace CellularManagement.Application.Features.Users.Commands.CreateUser;
/// <summary>
/// 创建用户命令处理器
/// 处理创建新用户的业务逻辑
/// </summary>
public sealed class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, OperationResult<CreateUserResponse>>
{
private readonly UserManager<AppUser> _userManager;
private readonly ILogger<CreateUserCommandHandler> _logger;
private readonly IUnitOfWork _unitOfWork;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="userManager">用户管理器,用于管理用户身份</param>
/// <param name="logger">日志记录器</param>
/// <param name="unitOfWork">工作单元,用于事务管理</param>
public CreateUserCommandHandler(
UserManager<AppUser> userManager,
ILogger<CreateUserCommandHandler> logger,
IUnitOfWork unitOfWork)
{
_userManager = userManager;
_logger = logger;
_unitOfWork = unitOfWork;
}
/// <summary>
/// 处理创建用户命令
/// </summary>
/// <param name="request">创建用户命令</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>操作结果,包含创建的用户ID</returns>
public async Task<OperationResult<CreateUserResponse>> Handle(
CreateUserCommand request,
CancellationToken cancellationToken)
{
try
{
// 检查用户是否已存在
var existingUser = await _userManager.FindByEmailAsync(request.Email);
if (existingUser != null)
{
_logger.LogWarning("用户邮箱 {Email} 已存在", request.Email);
return OperationResult<CreateUserResponse>.CreateFailure("用户已存在");
}
// 创建新用户
var user = new AppUser
{
UserName = request.UserName,
Email = request.Email,
PhoneNumber = request.PhoneNumber
};
// 在事务中创建用户
await _unitOfWork.ExecuteTransactionAsync(async () =>
{
var result = await _userManager.CreateAsync(user, request.Password);
if (!result.Succeeded)
{
var errors = result.Errors.Select(e => e.Description).ToList();
_logger.LogWarning("创建用户失败: {Errors}", string.Join(", ", errors));
throw new InvalidOperationException(string.Join(", ", errors));
}
}, cancellationToken: cancellationToken);
_logger.LogInformation("用户 {UserId} 创建成功", user.Id);
return OperationResult<CreateUserResponse>.CreateSuccess(
new CreateUserResponse(user.Id));
}
catch (Exception ex)
{
_logger.LogError(ex, "创建用户时发生错误");
_logger.LogError(ex, "Error creating user");
return OperationResult<CreateUserResponse>.CreateFailure("Failed to create user");
}
}
}

39
src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserCommandValidator.cs

@ -0,0 +1,39 @@
using FluentValidation;
using CellularManagement.Application.Common;
namespace CellularManagement.Application.Features.Users.Commands.CreateUser;
public sealed class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
{
public CreateUserCommandValidator()
{
// 验证用户名
RuleFor(x => x.UserName)
.NotEmpty().WithMessage("用户名不能为空")
.MinimumLength(3).WithMessage("用户名长度不能少于3个字符")
.MaximumLength(50).WithMessage("用户名长度不能超过50个字符")
.Matches("^[a-zA-Z0-9_]+$").WithMessage("用户名只能包含字母、数字和下划线");
// 验证邮箱
RuleFor(x => x.Email)
.NotEmpty().WithMessage("邮箱不能为空")
.MaximumLength(256).WithMessage("邮箱长度不能超过256个字符")
.Must(x => x.IsValidEmail()).WithMessage("邮箱格式不正确");
// 验证密码
RuleFor(x => x.Password)
.NotEmpty().WithMessage("密码不能为空")
.MinimumLength(6).WithMessage("密码长度不能少于6个字符")
.MaximumLength(50).WithMessage("密码长度不能超过50个字符")
.Matches("[A-Z]").WithMessage("密码必须包含至少一个大写字母")
.Matches("[a-z]").WithMessage("密码必须包含至少一个小写字母")
.Matches("[0-9]").WithMessage("密码必须包含至少一个数字")
.Matches("[^a-zA-Z0-9]").WithMessage("密码必须包含至少一个特殊字符");
// 验证电话号码
RuleFor(x => x.PhoneNumber)
.Matches(@"^1[3-9]\d{9}$").When(x => !string.IsNullOrEmpty(x.PhoneNumber))
.WithMessage("电话号码格式不正确");
}
}

8
src/CellularManagement.Application/Features/Users/Commands/CreateUser/CreateUserResponse.cs

@ -0,0 +1,8 @@
namespace CellularManagement.Application.Features.Users.Commands.CreateUser;
/// <summary>
/// 创建用户响应
/// 包含创建成功后的用户ID
/// </summary>
/// <param name="UserId">用户ID</param>
public sealed record CreateUserResponse(string UserId);

10
src/CellularManagement.Application/Features/Users/Commands/DeleteUser/DeleteUserCommand.cs

@ -0,0 +1,10 @@
using MediatR;
namespace CellularManagement.Application.Features.Users.Commands.DeleteUser;
/// <summary>
/// 删除用户命令
/// 用于删除指定用户的命令对象
/// </summary>
/// <param name="UserId">要删除的用户ID</param>
public sealed record DeleteUserCommand(string UserId) : IRequest<OperationResult<DeleteUserResponse>>;

78
src/CellularManagement.Application/Features/Users/Commands/DeleteUser/DeleteUserCommandHandler.cs

@ -0,0 +1,78 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using MediatR;
using CellularManagement.Domain.Entities;
using CellularManagement.Domain.Repositories;
namespace CellularManagement.Application.Features.Users.Commands.DeleteUser;
/// <summary>
/// 删除用户命令处理器
/// 处理删除用户的业务逻辑
/// </summary>
public sealed class DeleteUserCommandHandler : IRequestHandler<DeleteUserCommand, OperationResult<DeleteUserResponse>>
{
private readonly UserManager<AppUser> _userManager;
private readonly ILogger<DeleteUserCommandHandler> _logger;
private readonly IUnitOfWork _unitOfWork;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="userManager">用户管理器,用于管理用户身份</param>
/// <param name="logger">日志记录器</param>
/// <param name="unitOfWork">工作单元,用于事务管理</param>
public DeleteUserCommandHandler(
UserManager<AppUser> userManager,
ILogger<DeleteUserCommandHandler> logger,
IUnitOfWork unitOfWork)
{
_userManager = userManager;
_logger = logger;
_unitOfWork = unitOfWork;
}
/// <summary>
/// 处理删除用户命令
/// </summary>
/// <param name="request">删除用户命令</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>操作结果,包含删除的用户ID</returns>
public async Task<OperationResult<DeleteUserResponse>> Handle(
DeleteUserCommand request,
CancellationToken cancellationToken)
{
try
{
// 查找要删除的用户
var user = await _userManager.FindByIdAsync(request.UserId);
if (user == null)
{
_logger.LogWarning("用户 {UserId} 不存在", request.UserId);
return OperationResult<DeleteUserResponse>.CreateFailure("用户不存在");
}
// 在事务中删除用户
await _unitOfWork.ExecuteTransactionAsync(async () =>
{
var result = await _userManager.DeleteAsync(user);
if (!result.Succeeded)
{
var errors = result.Errors.Select(e => e.Description).ToList();
_logger.LogWarning("删除用户失败: {Errors}", string.Join(", ", errors));
throw new InvalidOperationException(string.Join(", ", errors));
}
}, cancellationToken: cancellationToken);
_logger.LogInformation("用户 {UserId} 删除成功", user.Id);
return OperationResult<DeleteUserResponse>.CreateSuccess(
new DeleteUserResponse(user.Id));
}
catch (Exception ex)
{
_logger.LogError(ex, "删除用户时发生错误");
return OperationResult<DeleteUserResponse>.CreateFailure("删除用户失败");
}
}
}

8
src/CellularManagement.Application/Features/Users/Commands/DeleteUser/DeleteUserResponse.cs

@ -0,0 +1,8 @@
namespace CellularManagement.Application.Features.Users.Commands.DeleteUser;
/// <summary>
/// 删除用户响应
/// 包含删除成功后的用户ID
/// </summary>
/// <param name="UserId">用户ID</param>
public sealed record DeleteUserResponse(string UserId);

17
src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserCommand.cs

@ -0,0 +1,17 @@
using MediatR;
namespace CellularManagement.Application.Features.Users.Commands.UpdateUser;
/// <summary>
/// 更新用户命令
/// 用于更新指定用户信息的命令对象
/// </summary>
/// <param name="UserId">要更新的用户ID</param>
/// <param name="UserName">新的用户名</param>
/// <param name="Email">新的电子邮箱</param>
/// <param name="PhoneNumber">新的电话号码</param>
public sealed record UpdateUserCommand(
string UserId,
string UserName,
string Email,
string PhoneNumber) : IRequest<OperationResult<UpdateUserResponse>>;

66
src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserCommandHandler.cs

@ -0,0 +1,66 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using MediatR;
using CellularManagement.Domain.Entities;
using CellularManagement.Domain.Repositories;
namespace CellularManagement.Application.Features.Users.Commands.UpdateUser;
public sealed class UpdateUserCommandHandler : IRequestHandler<UpdateUserCommand, OperationResult<UpdateUserResponse>>
{
private readonly UserManager<AppUser> _userManager;
private readonly ILogger<UpdateUserCommandHandler> _logger;
private readonly IUnitOfWork _unitOfWork;
public UpdateUserCommandHandler(
UserManager<AppUser> userManager,
ILogger<UpdateUserCommandHandler> logger,
IUnitOfWork unitOfWork)
{
_userManager = userManager;
_logger = logger;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult<UpdateUserResponse>> Handle(
UpdateUserCommand request,
CancellationToken cancellationToken)
{
try
{
var user = await _userManager.FindByIdAsync(request.UserId);
if (user == null)
{
_logger.LogWarning("User {UserId} not found", request.UserId);
return OperationResult<UpdateUserResponse>.CreateFailure("User not found");
}
// Update user properties if provided
if (request.UserName != null) user.UserName = request.UserName;
if (request.Email != null) user.Email = request.Email;
if (request.PhoneNumber != null) user.PhoneNumber = request.PhoneNumber;
// Update user in transaction
await _unitOfWork.ExecuteTransactionAsync(async () =>
{
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
{
var errors = result.Errors.Select(e => e.Description).ToList();
_logger.LogWarning("Failed to update user: {Errors}", string.Join(", ", errors));
throw new InvalidOperationException(string.Join(", ", errors));
}
}, cancellationToken: cancellationToken);
_logger.LogInformation("User {UserId} updated successfully", user.Id);
return OperationResult<UpdateUserResponse>.CreateSuccess(
new UpdateUserResponse(user.Id));
}
catch (Exception ex)
{
_logger.LogError(ex, "Error updating user");
return OperationResult<UpdateUserResponse>.CreateFailure("Failed to update user");
}
}
}

30
src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserCommandValidator.cs

@ -0,0 +1,30 @@
using FluentValidation;
namespace CellularManagement.Application.Features.Users.Commands.UpdateUser;
public sealed class UpdateUserCommandValidator : AbstractValidator<UpdateUserCommand>
{
public UpdateUserCommandValidator()
{
RuleFor(x => x.UserId)
.NotEmpty().WithMessage("用户ID不能为空");
When(x => x.UserName != null, () =>
{
RuleFor(x => x.UserName)
.Length(3, 50).WithMessage("用户名长度必须在3-50个字符之间");
});
When(x => x.Email != null, () =>
{
RuleFor(x => x.Email)
.EmailAddress().WithMessage("邮箱格式不正确");
});
When(x => x.PhoneNumber != null, () =>
{
RuleFor(x => x.PhoneNumber)
.Matches(@"^1[3-9]\d{9}$").WithMessage("手机号格式不正确");
});
}
}

8
src/CellularManagement.Application/Features/Users/Commands/UpdateUser/UpdateUserResponse.cs

@ -0,0 +1,8 @@
namespace CellularManagement.Application.Features.Users.Commands.UpdateUser;
/// <summary>
/// 更新用户响应
/// 包含更新成功后的用户ID
/// </summary>
/// <param name="UserId">用户ID</param>
public sealed record UpdateUserResponse(string UserId);

15
src/CellularManagement.Application/Features/Users/Queries/Dtos/UserDto.cs

@ -0,0 +1,15 @@
namespace CellularManagement.Application.Features.Users.Queries.Dtos;
/// <summary>
/// 用户数据传输对象
/// 用于在API层和领域层之间传输用户数据
/// </summary>
/// <param name="UserId">用户ID</param>
/// <param name="UserName">用户名</param>
/// <param name="Email">电子邮箱</param>
/// <param name="PhoneNumber">电话号码</param>
public sealed record UserDto(
string UserId,
string UserName,
string Email,
string PhoneNumber);

19
src/CellularManagement.Application/Features/Users/Queries/GetAllUsers/GetAllUsersQuery.cs

@ -0,0 +1,19 @@
using MediatR;
namespace CellularManagement.Application.Features.Users.Queries.GetAllUsers;
/// <summary>
/// 获取所有用户查询
/// 支持按用户名、邮箱、手机号进行条件查询
/// </summary>
/// <param name="PageNumber">页码,从1开始</param>
/// <param name="PageSize">每页记录数</param>
/// <param name="UserName">用户名(可选,支持模糊查询)</param>
/// <param name="Email">邮箱(可选,支持模糊查询)</param>
/// <param name="PhoneNumber">手机号(可选,支持模糊查询)</param>
public sealed record GetAllUsersQuery(
int PageNumber = 1,
int PageSize = 10,
string? UserName = null,
string? Email = null,
string? PhoneNumber = null) : IRequest<OperationResult<GetAllUsersResponse>>;

94
src/CellularManagement.Application/Features/Users/Queries/GetAllUsers/GetAllUsersQueryHandler.cs

@ -0,0 +1,94 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using MediatR;
using CellularManagement.Domain.Entities;
using CellularManagement.Application.Features.Users.Queries.Dtos;
using Microsoft.EntityFrameworkCore;
namespace CellularManagement.Application.Features.Users.Queries.GetAllUsers;
/// <summary>
/// 获取所有用户查询处理器
/// 处理获取系统中所有用户信息的业务逻辑
/// </summary>
public sealed class GetAllUsersQueryHandler : IRequestHandler<GetAllUsersQuery, OperationResult<GetAllUsersResponse>>
{
private readonly UserManager<AppUser> _userManager;
private readonly ILogger<GetAllUsersQueryHandler> _logger;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="userManager">用户管理器,用于管理用户身份</param>
/// <param name="logger">日志记录器</param>
public GetAllUsersQueryHandler(
UserManager<AppUser> userManager,
ILogger<GetAllUsersQueryHandler> logger)
{
_userManager = userManager;
_logger = logger;
}
/// <summary>
/// 处理获取所有用户命令
/// </summary>
/// <param name="request">查询命令</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>操作结果,包含所有用户信息列表</returns>
public async Task<OperationResult<GetAllUsersResponse>> Handle(
GetAllUsersQuery request,
CancellationToken cancellationToken)
{
try
{
// 构建基础查询
var query = _userManager.Users.AsQueryable();
// 应用条件过滤
if (!string.IsNullOrWhiteSpace(request.UserName))
{
query = query.Where(u => u.UserName.Contains(request.UserName));
}
if (!string.IsNullOrWhiteSpace(request.Email))
{
query = query.Where(u => u.Email.Contains(request.Email));
}
if (!string.IsNullOrWhiteSpace(request.PhoneNumber))
{
query = query.Where(u => u.PhoneNumber.Contains(request.PhoneNumber));
}
// 获取总记录数
var totalCount = await query.CountAsync(cancellationToken);
// 应用分页
var users = await query
.Skip((request.PageNumber - 1) * request.PageSize)
.Take(request.PageSize)
.ToListAsync(cancellationToken);
// 转换为DTO对象
var userDtos = users.Select(user => new UserDto(
user.Id,
user.UserName,
user.Email,
user.PhoneNumber)).ToList();
// 构建响应对象
var response = new GetAllUsersResponse(
userDtos,
totalCount,
request.PageNumber,
request.PageSize);
return OperationResult<GetAllUsersResponse>.CreateSuccess(response);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取所有用户时发生错误");
return OperationResult<GetAllUsersResponse>.CreateFailure("获取用户列表失败");
}
}
}

33
src/CellularManagement.Application/Features/Users/Queries/GetAllUsers/GetAllUsersResponse.cs

@ -0,0 +1,33 @@
using CellularManagement.Application.Features.Users.Queries.Dtos;
namespace CellularManagement.Application.Features.Users.Queries.GetAllUsers;
/// <summary>
/// 获取所有用户响应
/// 包含用户列表和分页信息
/// </summary>
/// <param name="Users">用户列表</param>
/// <param name="TotalCount">总记录数</param>
/// <param name="PageNumber">当前页码</param>
/// <param name="PageSize">每页记录数</param>
public sealed record GetAllUsersResponse(
List<UserDto> Users,
int TotalCount,
int PageNumber,
int PageSize)
{
/// <summary>
/// 总页数
/// </summary>
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
/// <summary>
/// 是否有上一页
/// </summary>
public bool HasPreviousPage => PageNumber > 1;
/// <summary>
/// 是否有下一页
/// </summary>
public bool HasNextPage => PageNumber < TotalPages;
}

10
src/CellularManagement.Application/Features/Users/Queries/GetUserById/GetUserByIdQuery.cs

@ -0,0 +1,10 @@
using MediatR;
namespace CellularManagement.Application.Features.Users.Queries.GetUserById;
/// <summary>
/// 获取用户详情查询
/// 用于获取指定用户详细信息的查询对象
/// </summary>
/// <param name="UserId">要查询的用户ID</param>
public sealed record GetUserByIdQuery(string UserId) : IRequest<OperationResult<GetUserByIdResponse>>;

66
src/CellularManagement.Application/Features/Users/Queries/GetUserById/GetUserByIdQueryHandler.cs

@ -0,0 +1,66 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using MediatR;
using CellularManagement.Domain.Entities;
using CellularManagement.Application.Features.Users.Queries.Dtos;
namespace CellularManagement.Application.Features.Users.Queries.GetUserById;
/// <summary>
/// 根据ID查询用户处理器
/// 处理根据ID查询用户信息的业务逻辑
/// </summary>
public sealed class GetUserByIdQueryHandler : IRequestHandler<GetUserByIdQuery, OperationResult<GetUserByIdResponse>>
{
private readonly UserManager<AppUser> _userManager;
private readonly ILogger<GetUserByIdQueryHandler> _logger;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="userManager">用户管理器,用于管理用户身份</param>
/// <param name="logger">日志记录器</param>
public GetUserByIdQueryHandler(
UserManager<AppUser> userManager,
ILogger<GetUserByIdQueryHandler> logger)
{
_userManager = userManager;
_logger = logger;
}
/// <summary>
/// 处理根据ID查询用户命令
/// </summary>
/// <param name="request">查询用户命令</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>操作结果,包含查询到的用户信息</returns>
public async Task<OperationResult<GetUserByIdResponse>> Handle(
GetUserByIdQuery request,
CancellationToken cancellationToken)
{
try
{
// 根据ID查询用户
var user = await _userManager.FindByIdAsync(request.UserId);
if (user == null)
{
_logger.LogWarning("用户 {UserId} 不存在", request.UserId);
return OperationResult<GetUserByIdResponse>.CreateFailure("用户不存在");
}
var dto = new UserDto(user.Id,
user.UserName,
user.Email,
user.PhoneNumber);
// 构建响应对象
var response = new GetUserByIdResponse(dto);
return OperationResult<GetUserByIdResponse>.CreateSuccess(response);
}
catch (Exception ex)
{
_logger.LogError(ex, "查询用户时发生错误");
return OperationResult<GetUserByIdResponse>.CreateFailure("查询用户失败");
}
}
}

10
src/CellularManagement.Application/Features/Users/Queries/GetUserById/GetUserByIdResponse.cs

@ -0,0 +1,10 @@
using CellularManagement.Application.Features.Users.Queries.Dtos;
namespace CellularManagement.Application.Features.Users.Queries.GetUserById;
/// <summary>
/// 用户查询响应
/// 包含查询到的用户详细信息
/// </summary>
/// <param name="User">用户信息</param>
public sealed record GetUserByIdResponse(UserDto User);

4
src/CellularManagement.Presentation/Controllers/AuthController.cs

@ -63,7 +63,7 @@ public class AuthController : ApiController
/// <response code="200">登录成功,返回用户信息和令牌</response>
/// <response code="400">登录失败,返回错误信息</response>
/// <response code="429">登录尝试次数过多</response>
[HttpPost("login")]
[HttpPost()]
[ProducesResponseType(typeof(OperationResult<AuthenticateUserResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(OperationResult<AuthenticateUserResponse>), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(OperationResult<AuthenticateUserResponse>), StatusCodes.Status429TooManyRequests)]
@ -137,7 +137,7 @@ public class AuthController : ApiController
/// </returns>
/// <response code="200">注册成功,返回用户ID</response>
/// <response code="400">注册失败,返回错误信息</response>
[HttpPost("register")]
[HttpPost()]
[ProducesResponseType(typeof(OperationResult<RegisterUserResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(OperationResult<RegisterUserResponse>), StatusCodes.Status400BadRequest)]
public async Task<ActionResult<OperationResult<RegisterUserResponse>>> Register([FromBody] RegisterUserCommand command)

302
src/CellularManagement.Presentation/Controllers/UsersController.cs

@ -0,0 +1,302 @@
using Microsoft.AspNetCore.Mvc;
using MediatR;
using CellularManagement.Application.Features.Users.Commands.CreateUser;
using CellularManagement.Application.Features.Users.Commands.UpdateUser;
using CellularManagement.Application.Features.Users.Commands.DeleteUser;
using CellularManagement.Application.Features.Users.Queries.GetUserById;
using CellularManagement.Application.Features.Users.Queries.GetAllUsers;
using CellularManagement.Presentation.Abstractions;
using CellularManagement.Application.Common;
using Microsoft.Extensions.Logging;
using CellularManagement.Application.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authorization;
namespace CellularManagement.Presentation.Controllers;
/// <summary>
/// 用户管理控制器
/// 提供用户管理相关的 API 接口,包括用户信息的查询、更新和删除等功能
/// </summary>
public class UsersController : ApiController
{
private readonly ILogger<UsersController> _logger;
/// <summary>
/// 初始化用户管理控制器
/// </summary>
/// <param name="mediator">MediatR 中介者,用于处理命令和查询</param>
/// <param name="logger">日志记录器</param>
public UsersController(
IMediator mediator,
ILogger<UsersController> logger) : base(mediator)
{
_logger = logger;
}
/// <summary>
/// 创建新用户
/// </summary>
/// <remarks>
/// 示例请求:
///
/// POST /api/users
/// {
/// "userName": "用户名",
/// "email": "邮箱",
/// "phoneNumber": "手机号",
/// "password": "密码"
/// }
///
/// </remarks>
/// <param name="command">创建用户命令,包含用户信息</param>
/// <returns>
/// 创建结果,包含:
/// - 成功:返回创建的用户ID
/// - 失败:返回错误信息
/// </returns>
/// <response code="201">创建成功,返回用户ID</response>
/// <response code="400">创建失败,返回错误信息</response>
[HttpPost]
[ProducesResponseType(typeof(OperationResult<CreateUserResponse>), StatusCodes.Status201Created)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status400BadRequest)]
public async Task<ActionResult<OperationResult<CreateUserResponse>>> CreateUser([FromBody] CreateUserCommand command)
{
try
{
var result = await mediator.Send(command);
if (result.IsSuccess)
{
_logger.LogInformation("创建用户成功,用户ID: {UserId}", result.Data?.UserId);
return CreatedAtAction(nameof(GetUserById), new { id = result.Data?.UserId }, result);
}
else
{
_logger.LogWarning("创建用户失败: {Error}",
result.ErrorMessages?.FirstOrDefault());
return BadRequest(result);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "创建用户时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError,
OperationResult<object>.CreateFailure("系统错误,请稍后重试"));
}
}
/// <summary>
/// 获取用户列表
/// </summary>
/// <remarks>
/// 示例请求:
///
/// GET /api/users
/// {
/// "pageNumber": 1,
/// "pageSize": 10,
/// "userName": "张三",
/// "email": "example@domain.com",
/// "phoneNumber": "138"
/// }
///
/// </remarks>
/// <param name="query">查询参数,包含分页和过滤条件</param>
/// <returns>
/// 查询结果,包含:
/// - 成功:返回用户列表和分页信息
/// - 失败:返回错误信息
/// </returns>
/// <response code="200">查询成功,返回用户列表</response>
/// <response code="400">查询失败,返回错误信息</response>
[HttpGet]
[AllowAnonymous]
[ProducesResponseType(typeof(OperationResult<GetAllUsersResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status400BadRequest)]
public async Task<ActionResult<OperationResult<GetAllUsersResponse>>> GetUsers([FromQuery] GetAllUsersQuery query)
{
try
{
var result = await mediator.Send(query);
if (result.IsSuccess)
{
_logger.LogInformation("获取用户列表成功,共 {TotalCount} 条记录,当前第 {PageNumber} 页",
result.Data?.TotalCount,
result.Data?.PageNumber);
}
else
{
_logger.LogWarning("获取用户列表失败: {Error}",
result.ErrorMessages?.FirstOrDefault());
}
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取用户列表时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError,
OperationResult<object>.CreateFailure("系统错误,请稍后重试"));
}
}
/// <summary>
/// 获取指定用户信息
/// </summary>
/// <remarks>
/// 示例请求:
///
/// GET /api/users/{id}
///
/// </remarks>
/// <param name="id">用户ID</param>
/// <returns>
/// 查询结果,包含:
/// - 成功:返回用户详细信息
/// - 失败:返回错误信息
/// </returns>
/// <response code="200">查询成功,返回用户信息</response>
/// <response code="400">查询失败,返回错误信息</response>
/// <response code="404">用户不存在</response>
[HttpGet("{id}")]
[ProducesResponseType(typeof(OperationResult<GetUserByIdResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status404NotFound)]
public async Task<ActionResult<OperationResult<GetUserByIdResponse>>> GetUserById([FromRoute] string id)
{
try
{
var query = new GetUserByIdQuery(id);
var result = await mediator.Send(query);
if (result.IsSuccess)
{
_logger.LogInformation("获取用户 {UserId} 信息成功", id);
}
else
{
_logger.LogWarning("获取用户 {UserId} 信息失败: {Error}",
id,
result.ErrorMessages?.FirstOrDefault());
}
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取用户 {UserId} 信息时发生异常", id);
return StatusCode(StatusCodes.Status500InternalServerError,
OperationResult<object>.CreateFailure("系统错误,请稍后重试"));
}
}
/// <summary>
/// 更新用户信息
/// </summary>
/// <remarks>
/// 示例请求:
///
/// PUT /api/users/{id}
/// {
/// "userName": "新用户名",
/// "email": "新邮箱",
/// "phoneNumber": "新手机号"
/// }
///
/// </remarks>
/// <param name="id">用户ID</param>
/// <param name="command">更新命令,包含要更新的用户信息</param>
/// <returns>
/// 更新结果,包含:
/// - 成功:返回更新后的用户信息
/// - 失败:返回错误信息
/// </returns>
/// <response code="200">更新成功,返回用户信息</response>
/// <response code="400">更新失败,返回错误信息</response>
/// <response code="404">用户不存在</response>
[HttpPut("{id}")]
[ProducesResponseType(typeof(OperationResult<UpdateUserResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status404NotFound)]
public async Task<ActionResult<OperationResult<UpdateUserResponse>>> UpdateUser(
[FromRoute] string id,
[FromBody] UpdateUserCommand command)
{
try
{
command = command with { UserId = id };
var result = await mediator.Send(command);
if (result.IsSuccess)
{
_logger.LogInformation("更新用户 {UserId} 信息成功", id);
}
else
{
_logger.LogWarning("更新用户 {UserId} 信息失败: {Error}",
id,
result.ErrorMessages?.FirstOrDefault());
}
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "更新用户 {UserId} 信息时发生异常", id);
return StatusCode(StatusCodes.Status500InternalServerError,
OperationResult<object>.CreateFailure("系统错误,请稍后重试"));
}
}
/// <summary>
/// 删除用户
/// </summary>
/// <remarks>
/// 示例请求:
///
/// DELETE /api/users/{id}
///
/// </remarks>
/// <param name="id">用户ID</param>
/// <returns>
/// 删除结果,包含:
/// - 成功:返回成功信息
/// - 失败:返回错误信息
/// </returns>
/// <response code="200">删除成功</response>
/// <response code="400">删除失败,返回错误信息</response>
/// <response code="404">用户不存在</response>
[HttpDelete("{id}")]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(OperationResult<object>), StatusCodes.Status404NotFound)]
public async Task<ActionResult<OperationResult<object>>> DeleteUser([FromRoute] string id)
{
try
{
var command = new DeleteUserCommand(id);
var result = await mediator.Send(command);
if (result.IsSuccess)
{
_logger.LogInformation("删除用户 {UserId} 成功", id);
}
else
{
_logger.LogWarning("删除用户 {UserId} 失败: {Error}",
id,
result.ErrorMessages?.FirstOrDefault());
}
return Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "删除用户 {UserId} 时发生异常", id);
return StatusCode(StatusCodes.Status500InternalServerError,
OperationResult<object>.CreateFailure("系统错误,请稍后重试"));
}
}
}
Loading…
Cancel
Save