using MediatR; 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.Constants; using TakeoutSaaS.Shared.Abstractions.Exceptions; using TakeoutSaaS.Shared.Abstractions.Ids; using TakeoutSaaS.Shared.Abstractions.Security; using TakeoutSaaS.Shared.Abstractions.Tenancy; namespace TakeoutSaaS.Application.App.Merchants.Handlers; /// /// 创建商户合同。 /// public sealed class CreateMerchantContractCommandHandler( IMerchantRepository merchantRepository, ITenantProvider tenantProvider, IIdGenerator idGenerator, ICurrentUserAccessor currentUserAccessor) : IRequestHandler { public async Task Handle(CreateMerchantContractCommand request, CancellationToken cancellationToken) { // 1. 校验时间 if (request.EndDate <= request.StartDate) { throw new BusinessException(ErrorCodes.BadRequest, "合同结束时间必须晚于开始时间"); } // 2. 查询商户 var tenantId = tenantProvider.GetCurrentTenantId(); var merchant = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken) ?? throw new BusinessException(ErrorCodes.NotFound, "商户不存在"); // 3. 构建合同 var contract = new MerchantContract { Id = idGenerator.NextId(), MerchantId = merchant.Id, ContractNumber = request.ContractNumber.Trim(), StartDate = request.StartDate, EndDate = request.EndDate, FileUrl = request.FileUrl.Trim() }; // 4. 持久化与审计 await merchantRepository.AddContractAsync(contract, cancellationToken); await merchantRepository.AddAuditLogAsync(new MerchantAuditLog { TenantId = tenantId, MerchantId = merchant.Id, Action = MerchantAuditAction.ContractUpdated, Title = "新增合同", Description = $"合同号:{contract.ContractNumber}", OperatorId = ResolveOperatorId(), OperatorName = ResolveOperatorName() }, cancellationToken); await merchantRepository.SaveChangesAsync(cancellationToken); // 5. 返回 DTO return MerchantMapping.ToDto(contract); } private long? ResolveOperatorId() { var id = currentUserAccessor.UserId; return id == 0 ? null : id; } private string ResolveOperatorName() { var id = currentUserAccessor.UserId; return id == 0 ? "system" : $"user:{id}"; } }