| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- using Admin.NET.Core;
- namespace Admin.NET.Plugin.AiDOP.Infrastructure;
- public sealed record SmartOpsTrustedScope(long TenantId, long FactoryId, long UserId);
- /// <summary>
- /// 智慧诊断与改善闭环的可信作用域:只信登录上下文,工厂由租户关系解析。
- /// </summary>
- public sealed class SmartOpsTrustedScopeResolver : ITransient
- {
- public const long PlatformTenantId = SqlSugarConst.DefaultTenantId;
- private readonly ISqlSugarClient _db;
- private readonly UserManager _userManager;
- public SmartOpsTrustedScopeResolver(ISqlSugarClient db, UserManager userManager)
- {
- _db = db;
- _userManager = userManager;
- }
- public async Task<SmartOpsTrustedScope> ResolveAsync(long? candidateFactoryId = null)
- {
- var tenantId = AidopTenantScope.ResolveOrThrow(_userManager);
- SmartOpsTrustedScopeRules.EnsureBusinessTenant(tenantId);
- var orgId = await _db.Queryable<SysTenant>()
- .ClearFilter<ITenantIdFilter>()
- .Where(x => x.Id == tenantId)
- .Select(x => x.OrgId)
- .FirstAsync();
- var factoryId = SmartOpsTrustedScopeRules.ResolveFactory(tenantId, orgId, candidateFactoryId);
- var userId = _userManager.UserId;
- if (userId <= 0)
- throw Oops.Oh("无法确定当前用户,请重新登录");
- return new SmartOpsTrustedScope(tenantId, factoryId, userId);
- }
- }
- public static class SmartOpsTrustedScopeRules
- {
- public const long PlatformTenantId = SqlSugarConst.DefaultTenantId;
- public static void EnsureBusinessTenant(long tenantId)
- {
- if (tenantId <= 0 || tenantId == 1 || tenantId == PlatformTenantId)
- throw new InvalidOperationException("平台租户不得作为业务事实作用域");
- }
- /// <summary>
- /// 客户端工厂只是筛选建议。未授权或不存在时回落到租户 OrgId,不得使用外租户工厂。
- /// </summary>
- /// <remarks>
- /// 只判 <paramref name="orgId"/> 是否为空。
- /// 不得再用 <c>orgId == tenantId</c> 判「未配置」:Admin.NET 种子/SQL 脚本建的租户
- /// 其根组织 Id 与租户 Id 同号是官方约定(见 SysTenantSeedData「Id=OrgId=DefaultTenantId」
- /// 与 SysOrgSeedData 根组织),只有界面 AddTenant 建的租户才另发雪花号。
- /// 旧判据会把系统默认 / Ai-DOP 演示公司等种子租户全部误判为「未配置有效工厂」而拒绝服务。
- /// </remarks>
- public static long ResolveFactory(long tenantId, long orgId, long? candidateFactoryId)
- {
- // 文案面向使用者:说清「是什么状态、该找谁、去哪里配」,不暴露表名/列名。
- if (orgId <= 0)
- throw new InvalidOperationException("当前租户尚未配置所属机构,请联系管理员在「租户管理」中完成配置");
- if (candidateFactoryId is > 0
- && candidateFactoryId.Value != tenantId
- && candidateFactoryId.Value == orgId)
- return candidateFactoryId.Value;
- return orgId;
- }
- public static bool IsAuthorizedFactory(long tenantId, long orgId, long factoryId) =>
- factoryId > 0 && factoryId != tenantId && factoryId == orgId;
- }
- public static class SmartOpsImprovementPlanNo
- {
- public static string BuildPrefix(DateTime now) => $"SOP-{now:yyyyMMdd}-";
- public static string Next(string prefix, IEnumerable<string> existing)
- {
- var max = 0;
- foreach (var planNo in existing)
- {
- if (string.IsNullOrWhiteSpace(planNo) || !planNo.StartsWith(prefix, StringComparison.Ordinal))
- continue;
- if (int.TryParse(planNo.AsSpan(prefix.Length), out var n))
- max = Math.Max(max, n);
- }
- return $"{prefix}{max + 1:000}";
- }
- }
|