chore: add documentation comments and stylecop rules
This commit is contained in:
@@ -22,20 +22,17 @@ public sealed class AddMerchantDocumentCommandHandler(
|
||||
ICurrentUserAccessor currentUserAccessor)
|
||||
: IRequestHandler<AddMerchantDocumentCommand, MerchantDocumentDto>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly IIdGenerator _idGenerator = idGenerator;
|
||||
private readonly ICurrentUserAccessor _currentUserAccessor = currentUserAccessor;
|
||||
|
||||
public async Task<MerchantDocumentDto> Handle(AddMerchantDocumentCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
// 1. 获取租户并查询商户
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
?? throw new BusinessException(ErrorCodes.NotFound, "商户不存在");
|
||||
|
||||
// 2. 构建证照记录
|
||||
var document = new MerchantDocument
|
||||
{
|
||||
Id = _idGenerator.NextId(),
|
||||
Id = idGenerator.NextId(),
|
||||
MerchantId = merchant.Id,
|
||||
DocumentType = request.DocumentType,
|
||||
Status = MerchantDocumentStatus.Pending,
|
||||
@@ -45,8 +42,9 @@ public sealed class AddMerchantDocumentCommandHandler(
|
||||
ExpiresAt = request.ExpiresAt
|
||||
};
|
||||
|
||||
await _merchantRepository.AddDocumentAsync(document, cancellationToken);
|
||||
await _merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
// 3. 持久化与审计
|
||||
await merchantRepository.AddDocumentAsync(document, cancellationToken);
|
||||
await merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
{
|
||||
TenantId = tenantId,
|
||||
MerchantId = merchant.Id,
|
||||
@@ -57,20 +55,21 @@ public sealed class AddMerchantDocumentCommandHandler(
|
||||
OperatorName = ResolveOperatorName()
|
||||
}, cancellationToken);
|
||||
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 4. 返回 DTO
|
||||
return MerchantMapping.ToDto(document);
|
||||
}
|
||||
|
||||
private long? ResolveOperatorId()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? null : id;
|
||||
}
|
||||
|
||||
private string ResolveOperatorName()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? "system" : $"user:{id}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,22 +18,23 @@ public sealed class CreateMerchantCategoryCommandHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<CreateMerchantCategoryCommand, MerchantCategoryDto>
|
||||
{
|
||||
private readonly IMerchantCategoryRepository _categoryRepository = categoryRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<MerchantCategoryDto> Handle(CreateMerchantCategoryCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
// 1. 获取租户上下文
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var normalizedName = request.Name.Trim();
|
||||
|
||||
if (await _categoryRepository.ExistsAsync(normalizedName, tenantId, cancellationToken))
|
||||
// 2. 检查重名
|
||||
if (await categoryRepository.ExistsAsync(normalizedName, tenantId, cancellationToken))
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.Conflict, $"类目“{normalizedName}”已存在");
|
||||
}
|
||||
|
||||
var categories = await _categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
// 3. 计算排序
|
||||
var categories = await categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
var targetOrder = request.DisplayOrder ?? (categories.Count == 0 ? 1 : categories.Max(x => x.DisplayOrder) + 1);
|
||||
|
||||
// 4. 构建实体
|
||||
var entity = new MerchantCategory
|
||||
{
|
||||
Name = normalizedName,
|
||||
@@ -41,8 +42,9 @@ public sealed class CreateMerchantCategoryCommandHandler(
|
||||
IsActive = request.IsActive
|
||||
};
|
||||
|
||||
await _categoryRepository.AddAsync(entity, cancellationToken);
|
||||
await _categoryRepository.SaveChangesAsync(cancellationToken);
|
||||
// 5. 持久化并返回
|
||||
await categoryRepository.AddAsync(entity, cancellationToken);
|
||||
await categoryRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return MerchantMapping.ToDto(entity);
|
||||
}
|
||||
|
||||
@@ -13,12 +13,10 @@ namespace TakeoutSaaS.Application.App.Merchants.Handlers;
|
||||
public sealed class CreateMerchantCommandHandler(IMerchantRepository merchantRepository, ILogger<CreateMerchantCommandHandler> logger)
|
||||
: IRequestHandler<CreateMerchantCommand, MerchantDto>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ILogger<CreateMerchantCommandHandler> _logger = logger;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<MerchantDto> Handle(CreateMerchantCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 构建商户实体
|
||||
var merchant = new Merchant
|
||||
{
|
||||
BrandName = request.BrandName.Trim(),
|
||||
@@ -31,10 +29,12 @@ public sealed class CreateMerchantCommandHandler(IMerchantRepository merchantRep
|
||||
JoinedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
await _merchantRepository.AddMerchantAsync(merchant, cancellationToken);
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
// 2. 持久化
|
||||
await merchantRepository.AddMerchantAsync(merchant, cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
_logger.LogInformation("创建商户 {MerchantId} - {BrandName}", merchant.Id, merchant.BrandName);
|
||||
// 3. 记录日志
|
||||
logger.LogInformation("创建商户 {MerchantId} - {BrandName}", merchant.Id, merchant.BrandName);
|
||||
return MapToDto(merchant);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,25 +22,23 @@ public sealed class CreateMerchantContractCommandHandler(
|
||||
ICurrentUserAccessor currentUserAccessor)
|
||||
: IRequestHandler<CreateMerchantContractCommand, MerchantContractDto>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly IIdGenerator _idGenerator = idGenerator;
|
||||
private readonly ICurrentUserAccessor _currentUserAccessor = currentUserAccessor;
|
||||
|
||||
public async Task<MerchantContractDto> Handle(CreateMerchantContractCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 校验时间
|
||||
if (request.EndDate <= request.StartDate)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.BadRequest, "合同结束时间必须晚于开始时间");
|
||||
}
|
||||
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
// 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(),
|
||||
Id = idGenerator.NextId(),
|
||||
MerchantId = merchant.Id,
|
||||
ContractNumber = request.ContractNumber.Trim(),
|
||||
StartDate = request.StartDate,
|
||||
@@ -48,8 +46,9 @@ public sealed class CreateMerchantContractCommandHandler(
|
||||
FileUrl = request.FileUrl.Trim()
|
||||
};
|
||||
|
||||
await _merchantRepository.AddContractAsync(contract, cancellationToken);
|
||||
await _merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
// 4. 持久化与审计
|
||||
await merchantRepository.AddContractAsync(contract, cancellationToken);
|
||||
await merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
{
|
||||
TenantId = tenantId,
|
||||
MerchantId = merchant.Id,
|
||||
@@ -60,19 +59,21 @@ public sealed class CreateMerchantContractCommandHandler(
|
||||
OperatorName = ResolveOperatorName()
|
||||
}, cancellationToken);
|
||||
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 5. 返回 DTO
|
||||
return MerchantMapping.ToDto(contract);
|
||||
}
|
||||
|
||||
private long? ResolveOperatorId()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? null : id;
|
||||
}
|
||||
|
||||
private string ResolveOperatorName()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? "system" : $"user:{id}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,21 +13,20 @@ public sealed class DeleteMerchantCategoryCommandHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<DeleteMerchantCategoryCommand, bool>
|
||||
{
|
||||
private readonly IMerchantCategoryRepository _categoryRepository = categoryRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<bool> Handle(DeleteMerchantCategoryCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var existing = await _categoryRepository.FindByIdAsync(request.CategoryId, tenantId, cancellationToken);
|
||||
// 1. 获取租户上下文
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var existing = await categoryRepository.FindByIdAsync(request.CategoryId, tenantId, cancellationToken);
|
||||
|
||||
if (existing == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await _categoryRepository.RemoveAsync(existing, cancellationToken);
|
||||
await _categoryRepository.SaveChangesAsync(cancellationToken);
|
||||
// 2. 删除并保存
|
||||
await categoryRepository.RemoveAsync(existing, cancellationToken);
|
||||
await categoryRepository.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,25 +15,21 @@ public sealed class DeleteMerchantCommandHandler(
|
||||
ILogger<DeleteMerchantCommandHandler> logger)
|
||||
: IRequestHandler<DeleteMerchantCommand, bool>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly ILogger<DeleteMerchantCommandHandler> _logger = logger;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> Handle(DeleteMerchantCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 校验存在性
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var existing = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var existing = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
if (existing == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 删除
|
||||
await _merchantRepository.DeleteMerchantAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
_logger.LogInformation("删除商户 {MerchantId}", request.MerchantId);
|
||||
await merchantRepository.DeleteMerchantAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
logger.LogInformation("删除商户 {MerchantId}", request.MerchantId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,20 +16,21 @@ public sealed class GetMerchantAuditLogsQueryHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetMerchantAuditLogsQuery, PagedResult<MerchantAuditLogDto>>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<PagedResult<MerchantAuditLogDto>> Handle(GetMerchantAuditLogsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var logs = await _merchantRepository.GetAuditLogsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
// 1. 获取租户上下文并查询日志
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var logs = await merchantRepository.GetAuditLogsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
var total = logs.Count;
|
||||
|
||||
// 2. 分页映射
|
||||
var paged = logs
|
||||
.Skip((request.Page - 1) * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.Select(MerchantMapping.ToDto)
|
||||
.ToList();
|
||||
|
||||
// 3. 返回结果
|
||||
return new PagedResult<MerchantAuditLogDto>(paged, request.Page, request.PageSize, total);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,19 +12,18 @@ namespace TakeoutSaaS.Application.App.Merchants.Handlers;
|
||||
public sealed class GetMerchantByIdQueryHandler(IMerchantRepository merchantRepository, ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetMerchantByIdQuery, MerchantDto?>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<MerchantDto?> Handle(GetMerchantByIdQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
// 1. 获取租户上下文
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
if (merchant == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. 返回 DTO
|
||||
return new MerchantDto
|
||||
{
|
||||
Id = merchant.Id,
|
||||
|
||||
@@ -15,14 +15,13 @@ public sealed class GetMerchantCategoriesQueryHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetMerchantCategoriesQuery, IReadOnlyList<string>>
|
||||
{
|
||||
private readonly IMerchantCategoryRepository _categoryRepository = categoryRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<IReadOnlyList<string>> Handle(GetMerchantCategoriesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var categories = await _categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
// 1. 获取租户上下文并读取类目
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var categories = await categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
|
||||
// 2. 过滤启用类目并去重
|
||||
return categories
|
||||
.Where(x => x.IsActive)
|
||||
.Select(x => x.Name.Trim())
|
||||
|
||||
@@ -17,16 +17,15 @@ public sealed class GetMerchantContractsQueryHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetMerchantContractsQuery, IReadOnlyList<MerchantContractDto>>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<IReadOnlyList<MerchantContractDto>> Handle(GetMerchantContractsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
_ = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
// 1. 获取租户上下文并校验商户存在
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
_ = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
?? throw new BusinessException(ErrorCodes.NotFound, "商户不存在");
|
||||
|
||||
var contracts = await _merchantRepository.GetContractsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
// 2. 查询合同列表
|
||||
var contracts = await merchantRepository.GetContractsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
return MerchantMapping.ToContractDtos(contracts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,18 +16,18 @@ public sealed class GetMerchantDetailQueryHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetMerchantDetailQuery, MerchantDetailDto>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<MerchantDetailDto> Handle(GetMerchantDetailQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
// 1. 获取租户上下文并查询商户
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
?? throw new BusinessException(ErrorCodes.NotFound, "商户不存在");
|
||||
|
||||
var documents = await _merchantRepository.GetDocumentsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
var contracts = await _merchantRepository.GetContractsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
// 2. 查询证照与合同
|
||||
var documents = await merchantRepository.GetDocumentsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
var contracts = await merchantRepository.GetContractsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
|
||||
// 3. 返回明细 DTO
|
||||
return new MerchantDetailDto
|
||||
{
|
||||
Merchant = MerchantMapping.ToDto(merchant),
|
||||
|
||||
@@ -17,16 +17,15 @@ public sealed class GetMerchantDocumentsQueryHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<GetMerchantDocumentsQuery, IReadOnlyList<MerchantDocumentDto>>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<IReadOnlyList<MerchantDocumentDto>> Handle(GetMerchantDocumentsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
_ = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
// 1. 获取租户上下文并校验商户存在
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
_ = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
?? throw new BusinessException(ErrorCodes.NotFound, "商户不存在");
|
||||
|
||||
var documents = await _merchantRepository.GetDocumentsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
// 2. 查询证照列表
|
||||
var documents = await merchantRepository.GetDocumentsAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
return MerchantMapping.ToDocumentDtos(documents);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ public sealed class ListMerchantCategoriesQueryHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<ListMerchantCategoriesQuery, IReadOnlyList<MerchantCategoryDto>>
|
||||
{
|
||||
private readonly IMerchantCategoryRepository _categoryRepository = categoryRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<IReadOnlyList<MerchantCategoryDto>> Handle(ListMerchantCategoriesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var categories = await _categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
// 1. 获取租户上下文
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var categories = await categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
|
||||
// 2. 映射 DTO
|
||||
return MerchantMapping.ToCategoryDtos(categories);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,14 @@ public sealed class ReorderMerchantCategoriesCommandHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<ReorderMerchantCategoriesCommand, bool>
|
||||
{
|
||||
private readonly IMerchantCategoryRepository _categoryRepository = categoryRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
public async Task<bool> Handle(ReorderMerchantCategoriesCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var categories = await _categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
// 1. 获取租户并查询类目
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var categories = await categoryRepository.ListAsync(tenantId, cancellationToken);
|
||||
var map = categories.ToDictionary(x => x.Id);
|
||||
|
||||
// 2. 更新排序
|
||||
foreach (var item in request.Items)
|
||||
{
|
||||
if (!map.TryGetValue(item.CategoryId, out var category))
|
||||
@@ -35,8 +34,9 @@ public sealed class ReorderMerchantCategoriesCommandHandler(
|
||||
category.DisplayOrder = item.DisplayOrder;
|
||||
}
|
||||
|
||||
await _categoryRepository.UpdateRangeAsync(map.Values, cancellationToken);
|
||||
await _categoryRepository.SaveChangesAsync(cancellationToken);
|
||||
// 3. 持久化
|
||||
await categoryRepository.UpdateRangeAsync(map.Values, cancellationToken);
|
||||
await categoryRepository.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,21 +20,20 @@ public sealed class ReviewMerchantCommandHandler(
|
||||
ICurrentUserAccessor currentUserAccessor)
|
||||
: IRequestHandler<ReviewMerchantCommand, MerchantDto>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly ICurrentUserAccessor _currentUserAccessor = currentUserAccessor;
|
||||
|
||||
public async Task<MerchantDto> Handle(ReviewMerchantCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
// 1. 读取商户
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var merchant = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken)
|
||||
?? throw new BusinessException(ErrorCodes.NotFound, "商户不存在");
|
||||
|
||||
// 2. 已审核通过则直接返回
|
||||
if (request.Approve && merchant.Status == MerchantStatus.Approved)
|
||||
{
|
||||
return MerchantMapping.ToDto(merchant);
|
||||
}
|
||||
|
||||
// 3. 更新审核状态
|
||||
var previousStatus = merchant.Status;
|
||||
merchant.Status = request.Approve ? MerchantStatus.Approved : MerchantStatus.Rejected;
|
||||
merchant.ReviewRemarks = request.Remarks;
|
||||
@@ -44,8 +43,9 @@ public sealed class ReviewMerchantCommandHandler(
|
||||
merchant.JoinedAt = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
await _merchantRepository.UpdateMerchantAsync(merchant, cancellationToken);
|
||||
await _merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
// 4. 持久化与审计
|
||||
await merchantRepository.UpdateMerchantAsync(merchant, cancellationToken);
|
||||
await merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
{
|
||||
TenantId = tenantId,
|
||||
MerchantId = merchant.Id,
|
||||
@@ -55,20 +55,21 @@ public sealed class ReviewMerchantCommandHandler(
|
||||
OperatorId = ResolveOperatorId(),
|
||||
OperatorName = ResolveOperatorName()
|
||||
}, cancellationToken);
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 5. 返回 DTO
|
||||
return MerchantMapping.ToDto(merchant);
|
||||
}
|
||||
|
||||
private long? ResolveOperatorId()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? null : id;
|
||||
}
|
||||
|
||||
private string ResolveOperatorName()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? "system" : $"user:{id}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,27 +20,27 @@ public sealed class ReviewMerchantDocumentCommandHandler(
|
||||
ICurrentUserAccessor currentUserAccessor)
|
||||
: IRequestHandler<ReviewMerchantDocumentCommand, MerchantDocumentDto>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly ICurrentUserAccessor _currentUserAccessor = currentUserAccessor;
|
||||
|
||||
public async Task<MerchantDocumentDto> Handle(ReviewMerchantDocumentCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var document = await _merchantRepository.FindDocumentByIdAsync(request.MerchantId, tenantId, request.DocumentId, cancellationToken)
|
||||
// 1. 读取证照
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var document = await merchantRepository.FindDocumentByIdAsync(request.MerchantId, tenantId, request.DocumentId, cancellationToken)
|
||||
?? throw new BusinessException(ErrorCodes.NotFound, "证照不存在");
|
||||
|
||||
// 2. 若状态无变化且备注相同,直接返回
|
||||
var targetStatus = request.Approve ? MerchantDocumentStatus.Approved : MerchantDocumentStatus.Rejected;
|
||||
if (document.Status == targetStatus && document.Remarks == request.Remarks)
|
||||
{
|
||||
return MerchantMapping.ToDto(document);
|
||||
}
|
||||
|
||||
// 3. 更新状态
|
||||
document.Status = targetStatus;
|
||||
document.Remarks = request.Remarks;
|
||||
|
||||
await _merchantRepository.UpdateDocumentAsync(document, cancellationToken);
|
||||
await _merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
// 4. 持久化与审计
|
||||
await merchantRepository.UpdateDocumentAsync(document, cancellationToken);
|
||||
await merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
{
|
||||
TenantId = tenantId,
|
||||
MerchantId = document.MerchantId,
|
||||
@@ -50,20 +50,21 @@ public sealed class ReviewMerchantDocumentCommandHandler(
|
||||
OperatorId = ResolveOperatorId(),
|
||||
OperatorName = ResolveOperatorName()
|
||||
}, cancellationToken);
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 5. 返回 DTO
|
||||
return MerchantMapping.ToDto(document);
|
||||
}
|
||||
|
||||
private long? ResolveOperatorId()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? null : id;
|
||||
}
|
||||
|
||||
private string ResolveOperatorName()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? "system" : $"user:{id}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,21 +15,21 @@ public sealed class SearchMerchantsQueryHandler(
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<SearchMerchantsQuery, PagedResult<MerchantDto>>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<PagedResult<MerchantDto>> Handle(SearchMerchantsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var merchants = await _merchantRepository.SearchAsync(tenantId, request.Status, cancellationToken);
|
||||
// 1. 获取租户并查询商户
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var merchants = await merchantRepository.SearchAsync(tenantId, request.Status, cancellationToken);
|
||||
|
||||
// 2. 排序与分页
|
||||
var sorted = ApplySorting(merchants, request.SortBy, request.SortDescending);
|
||||
var paged = sorted
|
||||
.Skip((request.Page - 1) * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToList();
|
||||
|
||||
// 3. 映射 DTO
|
||||
var items = paged.Select(merchant => new MerchantDto
|
||||
{
|
||||
Id = merchant.Id,
|
||||
@@ -45,6 +45,7 @@ public sealed class SearchMerchantsQueryHandler(
|
||||
CreatedAt = merchant.CreatedAt
|
||||
}).ToList();
|
||||
|
||||
// 4. 返回分页结果
|
||||
return new PagedResult<MerchantDto>(items, request.Page, request.PageSize, merchants.Count);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,16 +16,12 @@ public sealed class UpdateMerchantCommandHandler(
|
||||
ILogger<UpdateMerchantCommandHandler> logger)
|
||||
: IRequestHandler<UpdateMerchantCommand, MerchantDto?>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly ILogger<UpdateMerchantCommandHandler> _logger = logger;
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<MerchantDto?> Handle(UpdateMerchantCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. 读取现有商户
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var existing = await _merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var existing = await merchantRepository.FindByIdAsync(request.MerchantId, tenantId, cancellationToken);
|
||||
if (existing == null)
|
||||
{
|
||||
return null;
|
||||
@@ -41,9 +37,9 @@ public sealed class UpdateMerchantCommandHandler(
|
||||
existing.Status = request.Status;
|
||||
|
||||
// 3. 持久化
|
||||
await _merchantRepository.UpdateMerchantAsync(existing, cancellationToken);
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
_logger.LogInformation("更新商户 {MerchantId} - {BrandName}", existing.Id, existing.BrandName);
|
||||
await merchantRepository.UpdateMerchantAsync(existing, cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
logger.LogInformation("更新商户 {MerchantId} - {BrandName}", existing.Id, existing.BrandName);
|
||||
|
||||
// 4. 返回 DTO
|
||||
return MapToDto(existing);
|
||||
|
||||
@@ -20,16 +20,14 @@ public sealed class UpdateMerchantContractStatusCommandHandler(
|
||||
ICurrentUserAccessor currentUserAccessor)
|
||||
: IRequestHandler<UpdateMerchantContractStatusCommand, MerchantContractDto>
|
||||
{
|
||||
private readonly IMerchantRepository _merchantRepository = merchantRepository;
|
||||
private readonly ITenantProvider _tenantProvider = tenantProvider;
|
||||
private readonly ICurrentUserAccessor _currentUserAccessor = currentUserAccessor;
|
||||
|
||||
public async Task<MerchantContractDto> Handle(UpdateMerchantContractStatusCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = _tenantProvider.GetCurrentTenantId();
|
||||
var contract = await _merchantRepository.FindContractByIdAsync(request.MerchantId, tenantId, request.ContractId, cancellationToken)
|
||||
// 1. 查询合同
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var contract = await merchantRepository.FindContractByIdAsync(request.MerchantId, tenantId, request.ContractId, cancellationToken)
|
||||
?? throw new BusinessException(ErrorCodes.NotFound, "合同不存在");
|
||||
|
||||
// 2. 更新状态
|
||||
if (request.Status == ContractStatus.Active)
|
||||
{
|
||||
contract.Status = ContractStatus.Active;
|
||||
@@ -46,8 +44,9 @@ public sealed class UpdateMerchantContractStatusCommandHandler(
|
||||
contract.Status = request.Status;
|
||||
}
|
||||
|
||||
await _merchantRepository.UpdateContractAsync(contract, cancellationToken);
|
||||
await _merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
// 3. 持久化与审计
|
||||
await merchantRepository.UpdateContractAsync(contract, cancellationToken);
|
||||
await merchantRepository.AddAuditLogAsync(new MerchantAuditLog
|
||||
{
|
||||
TenantId = tenantId,
|
||||
MerchantId = contract.MerchantId,
|
||||
@@ -58,19 +57,21 @@ public sealed class UpdateMerchantContractStatusCommandHandler(
|
||||
OperatorName = ResolveOperatorName()
|
||||
}, cancellationToken);
|
||||
|
||||
await _merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
await merchantRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 4. 返回 DTO
|
||||
return MerchantMapping.ToDto(contract);
|
||||
}
|
||||
|
||||
private long? ResolveOperatorId()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? null : id;
|
||||
}
|
||||
|
||||
private string ResolveOperatorName()
|
||||
{
|
||||
var id = _currentUserAccessor.UserId;
|
||||
var id = currentUserAccessor.UserId;
|
||||
return id == 0 ? "system" : $"user:{id}";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user