using Dpz.Core.Service.Mediator.Features.Account.Internal;

namespace Dpz.Core.Service.Mediator.Features.Account.Commands;

/// <summary>
/// 处理创建账号请求
/// </summary>
public class CreateAccountHandler(IRepository<User> repository, IConfiguration configuration)
    : IRequestHandler<CreateAccountRequest, ResponseResult<string>>
{
    /// <summary>
    /// 创建账号并生成 BCrypt 密码和 SecurityStamp
    /// </summary>
    public async ValueTask<ResponseResult<string>> Handle(
        CreateAccountRequest request,
        CancellationToken cancellationToken
    )
    {
        var result = new ResponseResult<string>();
        if (string.IsNullOrWhiteSpace(request.Account))
        {
            return result.WithFail("账号不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.Name))
        {
            return result.WithFail("昵称不能为空");
        }

        var actualPassword = string.IsNullOrEmpty(request.Password) ? "123456" : request.Password;
        var entity = new User
        {
            Avatar = $"{configuration["CDNBaseAddress"]}/images/member.png",
            CreateTime = DateTime.Now,
            Id = request.Account,
            LastUpdateTime = DateTime.Now,
            Name = request.Name,
            Permissions = request.Permissions ?? Permissions.Member,
            Sex = Sex.Man,
            Sign = "",
            Enable = true,
            Password = AccountSecurityHelper.CreatePasswordHash(actualPassword),
            Key = AccountSecurityHelper.GenerateSecurityStamp(),
        };

        await repository.InsertAsync(entity, cancellationToken);
        return result.WithOk(entity.Id);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个基于 CQRS(命令查询职责分离)模式MediatR 库实现的账号创建命令处理器。

主要组成部分

1. 类定义

public class CreateAccountHandler(IRepository<User> repository, IConfiguration configuration)
    : IRequestHandler<CreateAccountRequest, ResponseResult<string>>
  • 主构造函数(C# 12 新特性):注入两个依赖

    • IRepository<User>:用户仓储,负责数据持久化
    • IConfiguration:配置服务,用于读取配置项(如 CDN 地址)
  • 实现接口IRequestHandler<TRequest, TResponse>

    • 请求类型:CreateAccountRequest
    • 响应类型:ResponseResult<string>(返回用户 ID)

2. 核心处理逻辑(Handle 方法)

参数验证

if (string.IsNullOrWhiteSpace(request.Account))
    return result.WithFail("账号不能为空");
if (string.IsNullOrWhiteSpace(request.Name))
    return result.WithFail("昵称不能为空");

验证必填字段:账号和昵称

密码处理

var actualPassword = string.IsNullOrEmpty(request.Password) ? "123456" : request.Password;
  • 如果未提供密码,默认使用 "123456"

用户实体构建

var entity = new User
{
    Avatar = $"{configuration["CDNBaseAddress"]}/images/member.png",  // 从配置读取 CDN 地址
    CreateTime = DateTime.Now,
    Id = request.Account,  // 使用账号作为主键
    LastUpdateTime = DateTime.Now,
    Name = request.Name,
    Permissions = request.Permissions ?? Permissions.Member,  // 默认权限为 Member
    Sex = Sex.Man,  // 默认性别
    Sign = "",
    Enable = true,
    Password = AccountSecurityHelper.CreatePasswordHash(actualPassword),  // BCrypt 加密
    Key = AccountSecurityHelper.GenerateSecurityStamp(),  // 生成安全戳
};

关键安全措施

  • Password:使用 BCrypt 哈希算法加密(通过 AccountSecurityHelper.CreatePasswordHash
  • Key:生成 SecurityStamp(用于令牌失效机制)

数据持久化

await repository.InsertAsync(entity, cancellationToken);
return result.WithOk(entity.Id);

异步插入数据库并返回成功结果

设计特点

  1. 安全性

    • 密码使用 BCrypt 加密存储
    • 生成 SecurityStamp 支持会话管理
  2. 默认值处理

    • 默认密码:123456
    • 默认权限:Member
    • 默认头像:从配置文件读取
  3. 可扩展性

    • 使用仓储模式解耦数据访问
    • 使用 MediatR 实现命令处理
    • 配置外部化(CDN 地址等)
  4. 异步处理

    • 支持取消令牌(CancellationToken)
    • 使用 ValueTask 优化性能

潜在改进建议

  1. 添加重复检查:插入前验证账号是否已存在
  2. 密码强度验证:对自定义密码进行复杂度校验
  3. 审计日志:记录账号创建操作
  4. 事务处理:确保数据一致性
评论加载中...