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

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

/// <summary>
/// 处理修改账号头像请求
/// </summary>
public class UpdateAccountAvatarHandler(
    IRepository<User> userRepository,
    IRepository<UserHistory> userHistoryRepository,
    IMediator mediator,
    IFusionCache fusionCache
) : IRequestHandler<UpdateAccountAvatarRequest, ResponseResult<VmUserInfo?>>
{
    /// <summary>
    /// 修改头像并返回最新用户信息
    /// </summary>
    public async ValueTask<ResponseResult<VmUserInfo?>> Handle(
        UpdateAccountAvatarRequest request,
        CancellationToken cancellationToken
    )
    {
        var user = await AccountRepositoryHelper.GetUserAsync(
            userRepository,
            request.Account,
            cancellationToken
        );
        if (user == null)
        {
            return ResponseResult<VmUserInfo?>.Fail($"账号【{request.Account}】不存在");
        }

        await AccountRepositoryHelper.SaveUserHistoryAsync(
            userHistoryRepository,
            user.Id,
            [AccountRepositoryHelper.Change(nameof(user.Avatar), user.Avatar, request.Avatar)],
            cancellationToken
        );

        var update = Builders<User>
            .Update.Set(x => x.Avatar, request.Avatar)
            .Set(x => x.LastUpdateTime, DateTime.Now);
        await userRepository.UpdateAsync(x => x.Id == user.Id, update, cancellationToken);
        var userInfo = await mediator.Send(
            new GetUserInfoRequest { Account = request.Account },
            cancellationToken
        );
        await fusionCache.SetAsync(
            UserSessionKeys.ChangedAtKey(request.Account),
            DateTime.Now,
            TimeSpan.FromDays(30),
            token: cancellationToken
        );
        return ResponseResult<VmUserInfo?>.Ok(userInfo);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个基于 MediatR 模式的命令处理器(Handler),用于处理用户修改头像的业务逻辑。

主要组成部分

1. 类定义

public class UpdateAccountAvatarHandler(...)
    : IRequestHandler<UpdateAccountAvatarRequest, ResponseResult<VmUserInfo?>>
  • 使用 C# 12 主构造函数语法注入依赖项
  • 实现 IRequestHandler 接口,处理 UpdateAccountAvatarRequest 请求并返回 ResponseResult<VmUserInfo?>

2. 依赖注入的服务

  • IRepository<User>: 用户数据仓储
  • IRepository<UserHistory>: 用户历史记录仓储
  • IMediator: MediatR 中介者,用于发送查询请求
  • IFusionCache: 融合缓存服务

3. 核心业务流程 (Handle 方法)

步骤 1: 验证用户是否存在

var user = await AccountRepositoryHelper.GetUserAsync(...);
if (user == null) {
    return ResponseResult<VmUserInfo?>.Fail($"账号【{request.Account}】不存在");
}
  • 根据账号查询用户
  • 若不存在则返回失败响应

步骤 2: 保存历史变更记录

await AccountRepositoryHelper.SaveUserHistoryAsync(
    userHistoryRepository,
    user.Id,
    [AccountRepositoryHelper.Change(nameof(user.Avatar), user.Avatar, request.Avatar)],
    cancellationToken
);
  • 记录头像字段的旧值和新值到历史表
  • 用于审计和回溯

步骤 3: 更新数据库

var update = Builders<User>
    .Update.Set(x => x.Avatar, request.Avatar)
    .Set(x => x.LastUpdateTime, DateTime.Now);
await userRepository.UpdateAsync(x => x.Id == user.Id, update, cancellationToken);
  • 使用 MongoDB 的 Update Builder 更新头像和最后更新时间

步骤 4: 获取最新用户信息

var userInfo = await mediator.Send(
    new GetUserInfoRequest { Account = request.Account },
    cancellationToken
);
  • 通过 MediatR 发送查询请求,获取更新后的用户完整信息

步骤 5: 更新缓存标记

await fusionCache.SetAsync(
    UserSessionKeys.ChangedAtKey(request.Account),
    DateTime.Now,
    TimeSpan.FromDays(30),
    token: cancellationToken
);
  • 在缓存中记录用户信息变更时间
  • 有效期 30 天,用于标识用户数据是否需要刷新

步骤 6: 返回结果

return ResponseResult<VmUserInfo?>.Ok(userInfo);
  • 返回包含最新用户信息的成功响应

设计特点

关注点分离: 使用 Helper 类封装通用逻辑
审计追踪: 自动记录变更历史
缓存策略: 标记数据变更时间以支持缓存失效
中介者模式: 通过 MediatR 解耦查询逻辑
异步编程: 全程使用 async/await 提升性能

评论加载中...