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