20 changed files with 919 additions and 2 deletions
@ -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>>; |
@ -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"); |
|||
} |
|||
} |
|||
} |
@ -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("电话号码格式不正确"); |
|||
} |
|||
} |
@ -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); |
@ -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>>; |
@ -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("删除用户失败"); |
|||
} |
|||
} |
|||
} |
@ -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); |
@ -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>>; |
@ -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"); |
|||
} |
|||
} |
|||
} |
@ -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("手机号格式不正确"); |
|||
}); |
|||
} |
|||
} |
@ -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); |
@ -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); |
@ -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>>; |
@ -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("获取用户列表失败"); |
|||
} |
|||
} |
|||
} |
@ -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; |
|||
} |
@ -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>>; |
@ -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("查询用户失败"); |
|||
} |
|||
} |
|||
} |
@ -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); |
@ -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…
Reference in new issue