chore: update store delivery zone handlers

This commit is contained in:
2026-01-21 11:27:13 +08:00
parent 8bde1a6440
commit 36abd83e83
6 changed files with 60 additions and 10 deletions

View File

@@ -1,4 +1,6 @@
using MediatR; using MediatR;
using Microsoft.AspNetCore.Http;
using TakeoutSaaS.Application.App.Stores;
using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Application.App.Stores.Queries; using TakeoutSaaS.Application.App.Stores.Queries;
using TakeoutSaaS.Application.App.Stores.Services; using TakeoutSaaS.Application.App.Stores.Services;
@@ -15,6 +17,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers;
public sealed class CheckStoreDeliveryZoneQueryHandler( public sealed class CheckStoreDeliveryZoneQueryHandler(
IStoreRepository storeRepository, IStoreRepository storeRepository,
ITenantProvider tenantProvider, ITenantProvider tenantProvider,
IHttpContextAccessor httpContextAccessor,
IDeliveryZoneService deliveryZoneService) IDeliveryZoneService deliveryZoneService)
: IRequestHandler<CheckStoreDeliveryZoneQuery, StoreDeliveryCheckResultDto> : IRequestHandler<CheckStoreDeliveryZoneQuery, StoreDeliveryCheckResultDto>
{ {
@@ -22,7 +25,8 @@ public sealed class CheckStoreDeliveryZoneQueryHandler(
public async Task<StoreDeliveryCheckResultDto> Handle(CheckStoreDeliveryZoneQuery request, CancellationToken cancellationToken) public async Task<StoreDeliveryCheckResultDto> Handle(CheckStoreDeliveryZoneQuery request, CancellationToken cancellationToken)
{ {
// 1. 校验门店存在 // 1. 校验门店存在
var tenantId = tenantProvider.GetCurrentTenantId(); var ignoreTenantFilter = StoreTenantAccess.ShouldIgnoreTenantFilter(httpContextAccessor);
var tenantId = ignoreTenantFilter ? 0 : tenantProvider.GetCurrentTenantId();
var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken); var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
if (store is null) if (store is null)
{ {

View File

@@ -1,5 +1,7 @@
using MediatR; using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Stores;
using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Application.App.Stores.Services; using TakeoutSaaS.Application.App.Stores.Services;
@@ -17,6 +19,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers;
public sealed class CreateStoreDeliveryZoneCommandHandler( public sealed class CreateStoreDeliveryZoneCommandHandler(
IStoreRepository storeRepository, IStoreRepository storeRepository,
ITenantProvider tenantProvider, ITenantProvider tenantProvider,
IHttpContextAccessor httpContextAccessor,
IGeoJsonValidationService geoJsonValidationService, IGeoJsonValidationService geoJsonValidationService,
ILogger<CreateStoreDeliveryZoneCommandHandler> logger) ILogger<CreateStoreDeliveryZoneCommandHandler> logger)
: IRequestHandler<CreateStoreDeliveryZoneCommand, StoreDeliveryZoneDto> : IRequestHandler<CreateStoreDeliveryZoneCommand, StoreDeliveryZoneDto>
@@ -25,12 +28,14 @@ public sealed class CreateStoreDeliveryZoneCommandHandler(
public async Task<StoreDeliveryZoneDto> Handle(CreateStoreDeliveryZoneCommand request, CancellationToken cancellationToken) public async Task<StoreDeliveryZoneDto> Handle(CreateStoreDeliveryZoneCommand request, CancellationToken cancellationToken)
{ {
// 1. 校验门店存在 // 1. 校验门店存在
var tenantId = tenantProvider.GetCurrentTenantId(); var ignoreTenantFilter = StoreTenantAccess.ShouldIgnoreTenantFilter(httpContextAccessor);
var tenantId = ignoreTenantFilter ? 0 : tenantProvider.GetCurrentTenantId();
var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken); var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
if (store is null) if (store is null)
{ {
throw new BusinessException(ErrorCodes.NotFound, "门店不存在"); throw new BusinessException(ErrorCodes.NotFound, "门店不存在");
} }
var storeTenantId = store.TenantId;
// 2. (空行后) 校验 GeoJSON // 2. (空行后) 校验 GeoJSON
var validation = geoJsonValidationService.ValidatePolygon(request.PolygonGeoJson); var validation = geoJsonValidationService.ValidatePolygon(request.PolygonGeoJson);
@@ -42,6 +47,7 @@ public sealed class CreateStoreDeliveryZoneCommandHandler(
// 3. (空行后) 构建实体 // 3. (空行后) 构建实体
var zone = new StoreDeliveryZone var zone = new StoreDeliveryZone
{ {
TenantId = storeTenantId,
StoreId = request.StoreId, StoreId = request.StoreId,
ZoneName = request.ZoneName.Trim(), ZoneName = request.ZoneName.Trim(),
PolygonGeoJson = (validation.NormalizedGeoJson ?? request.PolygonGeoJson).Trim(), PolygonGeoJson = (validation.NormalizedGeoJson ?? request.PolygonGeoJson).Trim(),

View File

@@ -1,5 +1,7 @@
using MediatR; using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Stores;
using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Domain.Stores.Repositories; using TakeoutSaaS.Domain.Stores.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy; using TakeoutSaaS.Shared.Abstractions.Tenancy;
@@ -12,18 +14,21 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers;
public sealed class DeleteStoreDeliveryZoneCommandHandler( public sealed class DeleteStoreDeliveryZoneCommandHandler(
IStoreRepository storeRepository, IStoreRepository storeRepository,
ITenantProvider tenantProvider, ITenantProvider tenantProvider,
IHttpContextAccessor httpContextAccessor,
ILogger<DeleteStoreDeliveryZoneCommandHandler> logger) ILogger<DeleteStoreDeliveryZoneCommandHandler> logger)
: IRequestHandler<DeleteStoreDeliveryZoneCommand, bool> : IRequestHandler<DeleteStoreDeliveryZoneCommand, bool>
{ {
private readonly IStoreRepository _storeRepository = storeRepository; private readonly IStoreRepository _storeRepository = storeRepository;
private readonly ITenantProvider _tenantProvider = tenantProvider; private readonly ITenantProvider _tenantProvider = tenantProvider;
private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor;
private readonly ILogger<DeleteStoreDeliveryZoneCommandHandler> _logger = logger; private readonly ILogger<DeleteStoreDeliveryZoneCommandHandler> _logger = logger;
/// <inheritdoc /> /// <inheritdoc />
public async Task<bool> Handle(DeleteStoreDeliveryZoneCommand request, CancellationToken cancellationToken) public async Task<bool> Handle(DeleteStoreDeliveryZoneCommand request, CancellationToken cancellationToken)
{ {
// 1. 读取区域 // 1. 读取区域
var tenantId = _tenantProvider.GetCurrentTenantId(); var ignoreTenantFilter = StoreTenantAccess.ShouldIgnoreTenantFilter(_httpContextAccessor);
var tenantId = ignoreTenantFilter ? 0 : _tenantProvider.GetCurrentTenantId();
var existing = await _storeRepository.FindDeliveryZoneByIdAsync(request.DeliveryZoneId, tenantId, cancellationToken); var existing = await _storeRepository.FindDeliveryZoneByIdAsync(request.DeliveryZoneId, tenantId, cancellationToken);
if (existing is null) if (existing is null)
{ {

View File

@@ -1,5 +1,7 @@
using MediatR; using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Stores;
using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Application.App.Stores.Services; using TakeoutSaaS.Application.App.Stores.Services;
@@ -17,6 +19,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers;
public sealed class UpdateStoreDeliveryZoneCommandHandler( public sealed class UpdateStoreDeliveryZoneCommandHandler(
IStoreRepository storeRepository, IStoreRepository storeRepository,
ITenantProvider tenantProvider, ITenantProvider tenantProvider,
IHttpContextAccessor httpContextAccessor,
IGeoJsonValidationService geoJsonValidationService, IGeoJsonValidationService geoJsonValidationService,
ILogger<UpdateStoreDeliveryZoneCommandHandler> logger) ILogger<UpdateStoreDeliveryZoneCommandHandler> logger)
: IRequestHandler<UpdateStoreDeliveryZoneCommand, StoreDeliveryZoneDto?> : IRequestHandler<UpdateStoreDeliveryZoneCommand, StoreDeliveryZoneDto?>
@@ -25,7 +28,8 @@ public sealed class UpdateStoreDeliveryZoneCommandHandler(
public async Task<StoreDeliveryZoneDto?> Handle(UpdateStoreDeliveryZoneCommand request, CancellationToken cancellationToken) public async Task<StoreDeliveryZoneDto?> Handle(UpdateStoreDeliveryZoneCommand request, CancellationToken cancellationToken)
{ {
// 1. 读取区域 // 1. 读取区域
var tenantId = tenantProvider.GetCurrentTenantId(); var ignoreTenantFilter = StoreTenantAccess.ShouldIgnoreTenantFilter(httpContextAccessor);
var tenantId = ignoreTenantFilter ? 0 : tenantProvider.GetCurrentTenantId();
var existing = await storeRepository.FindDeliveryZoneByIdAsync(request.DeliveryZoneId, tenantId, cancellationToken); var existing = await storeRepository.FindDeliveryZoneByIdAsync(request.DeliveryZoneId, tenantId, cancellationToken);
if (existing is null) if (existing is null)
{ {

View File

@@ -1,5 +1,7 @@
using MediatR; using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using TakeoutSaaS.Application.App.Stores;
using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Application.App.Stores.Commands;
using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Domain.Stores.Entities; using TakeoutSaaS.Domain.Stores.Entities;
@@ -17,6 +19,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers;
public sealed class UpdateStoreFeeCommandHandler( public sealed class UpdateStoreFeeCommandHandler(
IStoreRepository storeRepository, IStoreRepository storeRepository,
ITenantProvider tenantProvider, ITenantProvider tenantProvider,
IHttpContextAccessor httpContextAccessor,
ILogger<UpdateStoreFeeCommandHandler> logger) ILogger<UpdateStoreFeeCommandHandler> logger)
: IRequestHandler<UpdateStoreFeeCommand, StoreFeeDto> : IRequestHandler<UpdateStoreFeeCommand, StoreFeeDto>
{ {
@@ -24,12 +27,14 @@ public sealed class UpdateStoreFeeCommandHandler(
public async Task<StoreFeeDto> Handle(UpdateStoreFeeCommand request, CancellationToken cancellationToken) public async Task<StoreFeeDto> Handle(UpdateStoreFeeCommand request, CancellationToken cancellationToken)
{ {
// 1. 校验门店状态 // 1. 校验门店状态
var tenantId = tenantProvider.GetCurrentTenantId(); var ignoreTenantFilter = StoreTenantAccess.ShouldIgnoreTenantFilter(httpContextAccessor);
var tenantId = ignoreTenantFilter ? 0 : tenantProvider.GetCurrentTenantId();
var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken); var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
if (store is null) if (store is null)
{ {
throw new BusinessException(ErrorCodes.NotFound, "门店不存在"); throw new BusinessException(ErrorCodes.NotFound, "门店不存在");
} }
var storeTenantId = store.TenantId;
if (store.AuditStatus != StoreAuditStatus.Activated) if (store.AuditStatus != StoreAuditStatus.Activated)
{ {
throw new BusinessException(ErrorCodes.Conflict, "门店未激活,无法配置费用"); throw new BusinessException(ErrorCodes.Conflict, "门店未激活,无法配置费用");
@@ -42,7 +47,11 @@ public sealed class UpdateStoreFeeCommandHandler(
// 2. (空行后) 获取或创建费用配置 // 2. (空行后) 获取或创建费用配置
var fee = await storeRepository.GetStoreFeeAsync(request.StoreId, tenantId, cancellationToken); var fee = await storeRepository.GetStoreFeeAsync(request.StoreId, tenantId, cancellationToken);
var isNew = fee is null; var isNew = fee is null;
fee ??= new StoreFee { StoreId = request.StoreId }; fee ??= new StoreFee
{
StoreId = request.StoreId,
TenantId = storeTenantId
};
// 3. (空行后) 应用更新字段 // 3. (空行后) 应用更新字段
fee.MinimumOrderAmount = request.MinimumOrderAmount; fee.MinimumOrderAmount = request.MinimumOrderAmount;

View File

@@ -329,8 +329,19 @@ public sealed class EfStoreRepository(TakeoutAppDbContext context) : IStoreRepos
/// <inheritdoc /> /// <inheritdoc />
public Task<StoreDeliveryZone?> FindDeliveryZoneByIdAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default) public Task<StoreDeliveryZone?> FindDeliveryZoneByIdAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default)
{ {
return context.StoreDeliveryZones var query = context.StoreDeliveryZones.AsQueryable();
.Where(x => x.TenantId == tenantId && x.Id == deliveryZoneId) if (tenantId <= 0)
{
query = query.IgnoreQueryFilters()
.Where(x => x.DeletedAt == null);
}
else
{
query = query.Where(x => x.TenantId == tenantId);
}
return query
.Where(x => x.Id == deliveryZoneId)
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
} }
@@ -615,8 +626,19 @@ public sealed class EfStoreRepository(TakeoutAppDbContext context) : IStoreRepos
/// <inheritdoc /> /// <inheritdoc />
public async Task DeleteDeliveryZoneAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default) public async Task DeleteDeliveryZoneAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default)
{ {
var existing = await context.StoreDeliveryZones var query = context.StoreDeliveryZones.AsQueryable();
.Where(x => x.TenantId == tenantId && x.Id == deliveryZoneId) if (tenantId <= 0)
{
query = query.IgnoreQueryFilters()
.Where(x => x.DeletedAt == null);
}
else
{
query = query.Where(x => x.TenantId == tenantId);
}
var existing = await query
.Where(x => x.Id == deliveryZoneId)
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
if (existing != null) if (existing != null)