diff --git a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CheckStoreDeliveryZoneQueryHandler.cs b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CheckStoreDeliveryZoneQueryHandler.cs index be01143..4c7c8c1 100644 --- a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CheckStoreDeliveryZoneQueryHandler.cs +++ b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CheckStoreDeliveryZoneQueryHandler.cs @@ -1,4 +1,6 @@ using MediatR; +using Microsoft.AspNetCore.Http; +using TakeoutSaaS.Application.App.Stores; using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Application.App.Stores.Queries; using TakeoutSaaS.Application.App.Stores.Services; @@ -15,6 +17,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers; public sealed class CheckStoreDeliveryZoneQueryHandler( IStoreRepository storeRepository, ITenantProvider tenantProvider, + IHttpContextAccessor httpContextAccessor, IDeliveryZoneService deliveryZoneService) : IRequestHandler { @@ -22,7 +25,8 @@ public sealed class CheckStoreDeliveryZoneQueryHandler( public async Task Handle(CheckStoreDeliveryZoneQuery request, CancellationToken cancellationToken) { // 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); if (store is null) { diff --git a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CreateStoreDeliveryZoneCommandHandler.cs b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CreateStoreDeliveryZoneCommandHandler.cs index 185350e..548c7d0 100644 --- a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CreateStoreDeliveryZoneCommandHandler.cs +++ b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/CreateStoreDeliveryZoneCommandHandler.cs @@ -1,5 +1,7 @@ using MediatR; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; +using TakeoutSaaS.Application.App.Stores; using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Application.App.Stores.Services; @@ -17,6 +19,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers; public sealed class CreateStoreDeliveryZoneCommandHandler( IStoreRepository storeRepository, ITenantProvider tenantProvider, + IHttpContextAccessor httpContextAccessor, IGeoJsonValidationService geoJsonValidationService, ILogger logger) : IRequestHandler @@ -25,12 +28,14 @@ public sealed class CreateStoreDeliveryZoneCommandHandler( public async Task Handle(CreateStoreDeliveryZoneCommand request, CancellationToken cancellationToken) { // 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); if (store is null) { throw new BusinessException(ErrorCodes.NotFound, "门店不存在"); } + var storeTenantId = store.TenantId; // 2. (空行后) 校验 GeoJSON var validation = geoJsonValidationService.ValidatePolygon(request.PolygonGeoJson); @@ -42,6 +47,7 @@ public sealed class CreateStoreDeliveryZoneCommandHandler( // 3. (空行后) 构建实体 var zone = new StoreDeliveryZone { + TenantId = storeTenantId, StoreId = request.StoreId, ZoneName = request.ZoneName.Trim(), PolygonGeoJson = (validation.NormalizedGeoJson ?? request.PolygonGeoJson).Trim(), diff --git a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/DeleteStoreDeliveryZoneCommandHandler.cs b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/DeleteStoreDeliveryZoneCommandHandler.cs index c7e7abb..e6e3935 100644 --- a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/DeleteStoreDeliveryZoneCommandHandler.cs +++ b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/DeleteStoreDeliveryZoneCommandHandler.cs @@ -1,5 +1,7 @@ using MediatR; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; +using TakeoutSaaS.Application.App.Stores; using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Domain.Stores.Repositories; using TakeoutSaaS.Shared.Abstractions.Tenancy; @@ -12,18 +14,21 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers; public sealed class DeleteStoreDeliveryZoneCommandHandler( IStoreRepository storeRepository, ITenantProvider tenantProvider, + IHttpContextAccessor httpContextAccessor, ILogger logger) : IRequestHandler { private readonly IStoreRepository _storeRepository = storeRepository; private readonly ITenantProvider _tenantProvider = tenantProvider; + private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor; private readonly ILogger _logger = logger; /// public async Task Handle(DeleteStoreDeliveryZoneCommand request, CancellationToken cancellationToken) { // 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); if (existing is null) { diff --git a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreDeliveryZoneCommandHandler.cs b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreDeliveryZoneCommandHandler.cs index 66ef04b..031e9e7 100644 --- a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreDeliveryZoneCommandHandler.cs +++ b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreDeliveryZoneCommandHandler.cs @@ -1,5 +1,7 @@ using MediatR; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; +using TakeoutSaaS.Application.App.Stores; using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Application.App.Stores.Services; @@ -17,6 +19,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers; public sealed class UpdateStoreDeliveryZoneCommandHandler( IStoreRepository storeRepository, ITenantProvider tenantProvider, + IHttpContextAccessor httpContextAccessor, IGeoJsonValidationService geoJsonValidationService, ILogger logger) : IRequestHandler @@ -25,7 +28,8 @@ public sealed class UpdateStoreDeliveryZoneCommandHandler( public async Task Handle(UpdateStoreDeliveryZoneCommand request, CancellationToken cancellationToken) { // 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); if (existing is null) { diff --git a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreFeeCommandHandler.cs b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreFeeCommandHandler.cs index a437c9c..24efa85 100644 --- a/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreFeeCommandHandler.cs +++ b/src/Application/TakeoutSaaS.Application/App/Stores/Handlers/UpdateStoreFeeCommandHandler.cs @@ -1,5 +1,7 @@ using MediatR; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; +using TakeoutSaaS.Application.App.Stores; using TakeoutSaaS.Application.App.Stores.Commands; using TakeoutSaaS.Application.App.Stores.Dto; using TakeoutSaaS.Domain.Stores.Entities; @@ -17,6 +19,7 @@ namespace TakeoutSaaS.Application.App.Stores.Handlers; public sealed class UpdateStoreFeeCommandHandler( IStoreRepository storeRepository, ITenantProvider tenantProvider, + IHttpContextAccessor httpContextAccessor, ILogger logger) : IRequestHandler { @@ -24,12 +27,14 @@ public sealed class UpdateStoreFeeCommandHandler( public async Task Handle(UpdateStoreFeeCommand request, CancellationToken cancellationToken) { // 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); if (store is null) { throw new BusinessException(ErrorCodes.NotFound, "门店不存在"); } + var storeTenantId = store.TenantId; if (store.AuditStatus != StoreAuditStatus.Activated) { throw new BusinessException(ErrorCodes.Conflict, "门店未激活,无法配置费用"); @@ -42,7 +47,11 @@ public sealed class UpdateStoreFeeCommandHandler( // 2. (空行后) 获取或创建费用配置 var fee = await storeRepository.GetStoreFeeAsync(request.StoreId, tenantId, cancellationToken); var isNew = fee is null; - fee ??= new StoreFee { StoreId = request.StoreId }; + fee ??= new StoreFee + { + StoreId = request.StoreId, + TenantId = storeTenantId + }; // 3. (空行后) 应用更新字段 fee.MinimumOrderAmount = request.MinimumOrderAmount; diff --git a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfStoreRepository.cs b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfStoreRepository.cs index 5612f4c..b8edc9c 100644 --- a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfStoreRepository.cs +++ b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfStoreRepository.cs @@ -329,8 +329,19 @@ public sealed class EfStoreRepository(TakeoutAppDbContext context) : IStoreRepos /// public Task FindDeliveryZoneByIdAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default) { - return context.StoreDeliveryZones - .Where(x => x.TenantId == tenantId && x.Id == deliveryZoneId) + var query = context.StoreDeliveryZones.AsQueryable(); + 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); } @@ -615,8 +626,19 @@ public sealed class EfStoreRepository(TakeoutAppDbContext context) : IStoreRepos /// public async Task DeleteDeliveryZoneAsync(long deliveryZoneId, long tenantId, CancellationToken cancellationToken = default) { - var existing = await context.StoreDeliveryZones - .Where(x => x.TenantId == tenantId && x.Id == deliveryZoneId) + var query = context.StoreDeliveryZones.AsQueryable(); + 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); if (existing != null)