using MediatR; using Microsoft.Extensions.Logging; using TakeoutSaaS.Application.App.Merchants.Commands; using TakeoutSaaS.Application.App.Merchants.Dto; using TakeoutSaaS.Domain.Merchants.Entities; using TakeoutSaaS.Domain.Merchants.Enums; using TakeoutSaaS.Domain.Merchants.Repositories; using TakeoutSaaS.Shared.Abstractions.Security; namespace TakeoutSaaS.Application.App.Merchants.Handlers; /// /// 创建商户命令处理器。 /// public sealed class CreateMerchantCommandHandler( IMerchantRepository merchantRepository, ICurrentUserAccessor currentUserAccessor, ILogger logger) : IRequestHandler { /// public async Task Handle(CreateMerchantCommand request, CancellationToken cancellationToken) { // 1. 构建商户实体(RowVersion 由 PostgreSQL xmin 自动管理) var merchant = new Merchant { TenantId = request.TenantId, BrandName = request.BrandName.Trim(), BrandAlias = request.BrandAlias?.Trim(), LogoUrl = request.LogoUrl?.Trim(), Category = request.Category?.Trim(), ContactPhone = request.ContactPhone.Trim(), ContactEmail = request.ContactEmail?.Trim(), Status = request.Status, JoinedAt = DateTime.UtcNow }; // 2. 如果状态为已通过,设置审核通过时间和审核人 if (request.Status == MerchantStatus.Approved) { merchant.ApprovedAt = DateTime.UtcNow; merchant.ApprovedBy = currentUserAccessor.UserId; } // 3. 持久化商户 await merchantRepository.AddMerchantAsync(merchant, cancellationToken); await merchantRepository.SaveChangesAsync(cancellationToken); // 4. 如果状态为已通过,添加默认审核通过记录 if (request.Status == MerchantStatus.Approved) { var auditLog = new MerchantAuditLog { TenantId = merchant.TenantId, MerchantId = merchant.Id, Action = MerchantAuditAction.ReviewApproved, Title = "商户创建时直接通过审核", Description = "平台管理员创建商户时选择无需审核,系统自动通过", OperatorId = currentUserAccessor.UserId == 0 ? null : currentUserAccessor.UserId, OperatorName = currentUserAccessor.UserId == 0 ? "system" : $"user:{currentUserAccessor.UserId}" }; await merchantRepository.AddAuditLogAsync(auditLog, cancellationToken); await merchantRepository.SaveChangesAsync(cancellationToken); } // 5. 记录日志 logger.LogInformation("创建商户 {MerchantId} - {BrandName},状态:{Status}", merchant.Id, merchant.BrandName, merchant.Status); return MapToDto(merchant); } private static MerchantDto MapToDto(Merchant merchant) => new() { Id = merchant.Id, TenantId = merchant.TenantId, BrandName = merchant.BrandName, BrandAlias = merchant.BrandAlias, LogoUrl = merchant.LogoUrl, Category = merchant.Category, ContactPhone = merchant.ContactPhone, ContactEmail = merchant.ContactEmail, Status = merchant.Status, JoinedAt = merchant.JoinedAt, CreatedAt = merchant.CreatedAt }; }