using SqlSugar;
namespace Admin.NET.Plugin.AiDOP.Infrastructure;
///
/// 165 Domain ↔ Ai-DOP tenant 显式映射。映射缺失或多行一律抛错,禁止回落 8010/0/主租户。
///
public sealed class SourceDomainTenantResolver : ITransient
{
private readonly ISqlSugarClient _db;
public SourceDomainTenantResolver(ISqlSugarClient db) => _db = db;
public async Task ResolveTenantIdAsync(
string sourceCode,
string domain,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(sourceCode) || string.IsNullOrWhiteSpace(domain))
throw new InvalidOperationException("sourceCode/domain 不能为空");
var rows = await _db.Ado.SqlQueryAsync(
"""
SELECT tenant_id AS TenantId
FROM ado_source_domain_tenant_map
WHERE source_code=@SourceCode AND domain=@Domain AND status=1
""",
new List
{
new("@SourceCode", sourceCode.Trim()),
new("@Domain", domain.Trim())
});
if (rows.Count == 0)
throw new InvalidOperationException(
$"未找到启用的 Domain 映射:source={sourceCode}, domain={domain}");
if (rows.Count > 1)
throw new InvalidOperationException(
$"Domain 映射不唯一:source={sourceCode}, domain={domain}, count={rows.Count}");
if (rows[0].TenantId <= 0)
throw new InvalidOperationException(
$"Domain 映射 tenant_id 非法:source={sourceCode}, domain={domain}");
return rows[0].TenantId;
}
public async Task ResolveDomainAsync(
string sourceCode,
long tenantId,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(sourceCode) || tenantId <= 0)
throw new InvalidOperationException("sourceCode/tenantId 非法");
var rows = await _db.Ado.SqlQueryAsync(
"""
SELECT domain AS Domain
FROM ado_source_domain_tenant_map
WHERE source_code=@SourceCode AND tenant_id=@TenantId AND status=1
""",
new List
{
new("@SourceCode", sourceCode.Trim()),
new("@TenantId", tenantId)
});
if (rows.Count == 0)
throw new InvalidOperationException(
$"未找到启用的租户 Domain 映射:source={sourceCode}, tenant={tenantId}");
if (rows.Count > 1)
throw new InvalidOperationException(
$"租户 Domain 映射不唯一:source={sourceCode}, tenant={tenantId}, count={rows.Count}");
if (string.IsNullOrWhiteSpace(rows[0].Domain))
throw new InvalidOperationException("Domain 映射值为空");
return rows[0].Domain!.Trim();
}
private sealed class MapRow
{
public long TenantId { get; set; }
}
private sealed class DomainRow
{
public string? Domain { get; set; }
}
}