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; } } }