refactor: AdminApi 剔除租户侧能力

This commit is contained in:
2026-01-29 23:24:44 +00:00
parent 71e5a9dc29
commit 4f8424adb6
139 changed files with 622 additions and 4691 deletions

View File

@@ -8,7 +8,6 @@ using TakeoutSaaS.Domain.Dictionary.ValueObjects;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
namespace TakeoutSaaS.Application.Dictionary.Services;
@@ -18,9 +17,7 @@ namespace TakeoutSaaS.Application.Dictionary.Services;
public sealed class DictionaryQueryService(
IDictionaryGroupRepository groupRepository,
IDictionaryItemRepository itemRepository,
DictionaryMergeService mergeService,
IDictionaryHybridCache cache,
ITenantProvider tenantProvider)
IDictionaryHybridCache cache)
{
private static readonly TimeSpan CacheTtl = TimeSpan.FromMinutes(30);
@@ -31,8 +28,21 @@ public sealed class DictionaryQueryService(
DictionaryGroupQuery query,
CancellationToken cancellationToken = default)
{
var tenantId = tenantProvider.GetCurrentTenantId();
// 1. 解析查询租户与作用域
var tenantId = query.TenantId ?? 0;
if (query.Scope == DictionaryScope.Business && tenantId <= 0)
{
throw new BusinessException(ErrorCodes.ValidationFailed, "Scope=Business 时必须指定 TenantId");
}
// 2. (空行后) 确定作用域与目标租户
var scope = query.Scope ?? (tenantId == 0 ? DictionaryScope.System : DictionaryScope.Business);
if (scope == DictionaryScope.System)
{
tenantId = 0;
}
// 3. (空行后) 构建缓存键并加载分页数据
var sortDescending = string.Equals(query.SortOrder, "desc", StringComparison.OrdinalIgnoreCase);
var targetTenant = scope == DictionaryScope.System ? 0 : tenantId;
@@ -118,7 +128,6 @@ public sealed class DictionaryQueryService(
return null;
}
EnsureGroupReadable(group);
return DictionaryMapper.ToGroupDto(group);
}
@@ -139,7 +148,6 @@ public sealed class DictionaryQueryService(
throw new BusinessException(ErrorCodes.NotFound, "字典分组不存在");
}
EnsureGroupReadable(group);
var items = await itemRepository.GetByGroupIdAsync(group.TenantId, groupId, token);
return items
.Where(item => item.IsEnabled)
@@ -162,7 +170,8 @@ public sealed class DictionaryQueryService(
throw new BusinessException(ErrorCodes.ValidationFailed, "字典编码格式不正确");
}
var tenantId = tenantProvider.GetCurrentTenantId();
// 1. 管理端默认读取系统字典TenantId=0
var tenantId = 0;
var normalized = new DictionaryCode(code);
var cacheKey = DictionaryCacheKeys.BuildDictionaryKey(tenantId, normalized);
@@ -177,17 +186,12 @@ public sealed class DictionaryQueryService(
return Array.Empty<DictionaryItemDto>();
}
if (tenantId == 0)
{
var systemItems = await itemRepository.GetByGroupIdAsync(0, systemGroup.Id, token);
return systemItems
.Where(item => item.IsEnabled)
.OrderBy(item => item.SortOrder)
.Select(DictionaryMapper.ToItemDto)
.ToList();
}
return await mergeService.MergeItemsAsync(tenantId, systemGroup.Id, token);
var systemItems = await itemRepository.GetByGroupIdAsync(0, systemGroup.Id, token);
return systemItems
.Where(item => item.IsEnabled)
.OrderBy(item => item.SortOrder)
.Select(DictionaryMapper.ToItemDto)
.ToList();
},
cancellationToken);
@@ -227,15 +231,6 @@ public sealed class DictionaryQueryService(
return result;
}
private void EnsureGroupReadable(DictionaryGroup group)
{
var tenantId = tenantProvider.GetCurrentTenantId();
if (tenantId != 0 && group.Scope == DictionaryScope.Business && group.TenantId != tenantId)
{
throw new BusinessException(ErrorCodes.Forbidden, "无权访问其他租户字典");
}
}
private sealed class DictionaryGroupPage
{
public IReadOnlyList<DictionaryGroupDto> Items { get; init; } = Array.Empty<DictionaryGroupDto>();