using SqlSugar; namespace Admin.NET.Plugin.AiDOP.Infrastructure; /// /// Domain ↔ Ai-DOP tenant 解析器。 /// 直接查询 sys_tenant 系统租户表验证租户有效性,无需手动维护映射表。 /// Domain 优先取 GeneralizedCodeMaster.SystemConfig.CompanyCode,回落 8010。 /// public sealed class SourceDomainTenantResolver : ITransient { private readonly ISqlSugarClient _db; public SourceDomainTenantResolver(ISqlSugarClient db) => _db = db; /// /// 根据 sourceCode + domain 解析 tenant_id。 /// 直接查询 sys_tenant:返回第一个启用租户的 Id。 /// 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 Id AS TenantId FROM SysTenant WHERE Status = 1 ORDER BY Id LIMIT 1 """); if (rows.Count == 0) throw new InvalidOperationException("未找到启用的系统租户"); if (rows[0].TenantId <= 0) throw new InvalidOperationException("系统租户 Id 非法"); return rows[0].TenantId; } /// /// 根据 sourceCode + tenantId 解析 domain。 /// 先在 sys_tenant 验证租户存在且启用,再从 GeneralizedCodeMaster 取公司代码,回落 8010。 /// public async Task ResolveDomainAsync( string sourceCode, long tenantId, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(sourceCode) || tenantId <= 0) throw new InvalidOperationException("sourceCode/tenantId 非法"); // 验证租户在 sys_tenant 中存在且启用 var tenantExists = await _db.Ado.GetIntAsync( "SELECT COUNT(1) FROM SysTenant WHERE Id = @TenantId AND Status = 1", new List { new("@TenantId", tenantId) }); if (tenantExists <= 0) throw new InvalidOperationException($"租户不存在或未启用:tenant={tenantId}"); // 优先从 GeneralizedCodeMaster 取公司代码,回落 8010 var domainRows = await _db.Ado.SqlQueryAsync( """ SELECT Domain FROM GeneralizedCodeMaster WHERE FldName='SystemConfig' AND Val='CompanyCode' ORDER BY RecID LIMIT 1 """); var domain = domainRows.FirstOrDefault()?.Domain; return string.IsNullOrWhiteSpace(domain) ? "8010" : domain.Trim(); } private sealed class MapRow { public long TenantId { get; set; } } private sealed class DomainRow { public string? Domain { get; set; } } }