AidopTenantInitService.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using Admin.NET.Plugin.AiDOP.Entity;
  2. using Admin.NET.Plugin.AiDOP.Service.S8.OrderFlow;
  3. using Yitter.IdGenerator;
  4. namespace Admin.NET.Plugin.AiDOP.Infrastructure;
  5. /// <summary>
  6. /// Ai-DOP 每租户必备基线:S8 七个业务角色 + KPI calc config(从 AIDOP 模板租户复制)。
  7. /// 形态为「每租户复制」,便于各租户独立调整 KPI 公式与角色配置。
  8. /// </summary>
  9. public sealed class AidopTenantInitService : ITransient
  10. {
  11. /// <summary>AIDOP 运行租户:KPI calc config 模板来源。</summary>
  12. public const long KpiTemplateTenantId = 797403760988229L;
  13. private static readonly (string Code, string Name, int OrderNo)[] S8BusinessRoles =
  14. {
  15. ("ROLE_ORDER_PLANNER", "订单计划员", 800),
  16. ("ROLE_PRODUCTION_PLANNER", "生产计划员", 801),
  17. ("ROLE_PURCHASER", "采购员", 802),
  18. ("ROLE_WH_INBOUND", "仓库收货员", 803),
  19. ("ROLE_WH_OUTBOUND", "仓库发货员", 804),
  20. ("ROLE_QC", "质检员", 805),
  21. ("ROLE_EQUIP_MAINT", "设备维修员", 806),
  22. };
  23. private readonly ISqlSugarClient _db;
  24. public AidopTenantInitService(ISqlSugarClient db) => _db = db;
  25. /// <summary>幂等种入目标租户的 S8 业务角色与 KPI calc config;允许重复调用。</summary>
  26. public async Task InitTenantBaselineAsync(long tenantId)
  27. {
  28. if (tenantId <= 0) return;
  29. await SeedS8BusinessRolesAsync(tenantId);
  30. await SeedKpiCalcConfigFromTemplateAsync(tenantId);
  31. }
  32. private async Task SeedS8BusinessRolesAsync(long tenantId)
  33. {
  34. var ct = DateTime.Now;
  35. foreach (var (code, name, orderNo) in S8BusinessRoles)
  36. {
  37. var exists = await _db.Queryable<SysRole>()
  38. .ClearFilter<ITenantIdFilter>()
  39. .AnyAsync(r => r.TenantId == tenantId && r.Code == code);
  40. if (exists) continue;
  41. await _db.Insertable(new SysRole
  42. {
  43. Id = YitIdHelper.NextId(),
  44. TenantId = tenantId,
  45. Name = name,
  46. Code = code,
  47. OrderNo = orderNo,
  48. DataScope = DataScopeEnum.Self,
  49. Status = StatusEnum.Enable,
  50. Remark = "S8 业务角色(异常协同承接)",
  51. CreateTime = ct,
  52. }).ExecuteCommandAsync();
  53. }
  54. }
  55. private async Task SeedKpiCalcConfigFromTemplateAsync(long tenantId)
  56. {
  57. if (tenantId == KpiTemplateTenantId) return;
  58. var templates = await _db.Queryable<AdoSmartOpsKpiCalcConfig>()
  59. .ClearFilter<ITenantIdFilter>()
  60. .Where(c => c.TenantId == KpiTemplateTenantId)
  61. .ToListAsync();
  62. if (templates.Count == 0) return;
  63. var now = DateTime.Now;
  64. foreach (var tpl in templates)
  65. {
  66. var exists = await _db.Queryable<AdoSmartOpsKpiCalcConfig>()
  67. .ClearFilter<ITenantIdFilter>()
  68. .AnyAsync(c => c.TenantId == tenantId && c.MetricCode == tpl.MetricCode && c.VersionNo == tpl.VersionNo);
  69. if (exists) continue;
  70. await _db.Insertable(new AdoSmartOpsKpiCalcConfig
  71. {
  72. TenantId = tenantId,
  73. MetricCode = tpl.MetricCode,
  74. ModuleCode = tpl.ModuleCode,
  75. VersionNo = tpl.VersionNo,
  76. CalcEngineType = tpl.CalcEngineType,
  77. DataSourceCode = tpl.DataSourceCode,
  78. SqlScript = tpl.SqlScript,
  79. SqlParametersJson = tpl.SqlParametersJson,
  80. TimeoutSeconds = tpl.TimeoutSeconds,
  81. PublishStatus = tpl.PublishStatus,
  82. IsCurrent = tpl.IsCurrent,
  83. Remark = tpl.Remark,
  84. CreatedBy = "AidopTenantInit",
  85. CreatedAt = now,
  86. }).ExecuteCommandAsync();
  87. }
  88. }
  89. }