S2AutoScheduleJob.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using Admin.NET.Plugin.AiDOP.Production;
  2. using Furion.Schedule;
  3. using Microsoft.Extensions.Configuration;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Microsoft.Extensions.Logging;
  6. using SqlSugar;
  7. namespace Admin.NET.Plugin.AiDOP.Job;
  8. /// <summary>
  9. /// S2 定时自动全量排产。默认关闭,由配置 S2:AutoSchedule:Enabled=true 开启;
  10. /// 周期默认 60 分钟(可在作业管理中调整触发器)。
  11. /// 每个有在制工单的租户提交一次异步排程(与手工按钮共用单飞与 run_id)。
  12. /// </summary>
  13. [JobDetail("job_s2_auto_schedule", Description = "S2 定时自动全量排产", GroupName = "default", Concurrent = false)]
  14. [Period(S2AutoScheduleJob.IntervalMs, TriggerId = "trigger_s2_auto_schedule", Description = "S2 自动排产节拍(默认60分钟)")]
  15. public class S2AutoScheduleJob : IJob
  16. {
  17. public const int IntervalMs = 3600000;
  18. private readonly IServiceScopeFactory _scopeFactory;
  19. private readonly IConfiguration _configuration;
  20. private readonly ILogger _logger;
  21. public S2AutoScheduleJob(
  22. IServiceScopeFactory scopeFactory,
  23. IConfiguration configuration,
  24. ILoggerFactory loggerFactory)
  25. {
  26. _scopeFactory = scopeFactory;
  27. _configuration = configuration;
  28. _logger = loggerFactory.CreateLogger(nameof(S2AutoScheduleJob));
  29. }
  30. public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
  31. {
  32. if (!AidopJobGate.ShouldRun(nameof(S2AutoScheduleJob), _logger)) return;
  33. if (!_configuration.GetValue("S2:AutoSchedule:Enabled", false))
  34. return;
  35. using var scope = _scopeFactory.CreateScope();
  36. var db = scope.ServiceProvider.GetRequiredService<ISqlSugarClient>();
  37. var action = scope.ServiceProvider.GetRequiredService<ProductionSchedulingActionService>();
  38. var tenants = await db.Ado.SqlQueryAsync<long>(
  39. """
  40. SELECT DISTINCT tenant_id
  41. FROM WorkOrdMaster
  42. WHERE IFNULL(IsActive, 0) = 1
  43. AND IFNULL(Status, '') NOT IN ('c', 'C')
  44. AND tenant_id IS NOT NULL AND tenant_id > 0
  45. """);
  46. foreach (var tenantId in tenants)
  47. {
  48. if (stoppingToken.IsCancellationRequested)
  49. break;
  50. try
  51. {
  52. var domain = tenantId.ToString();
  53. await action.SubmitGenerateAsync(
  54. tenantId, domain, "sys-auto-schedule",
  55. enableCapacityConstraint: false,
  56. trigger: "auto");
  57. _logger.LogInformation("S2AutoScheduleJob 已提交租户 {TenantId}", tenantId);
  58. }
  59. catch (Exception ex)
  60. {
  61. // 单飞冲突或业务拒绝:记日志,继续下一租户
  62. _logger.LogWarning(ex, "S2AutoScheduleJob 跳过租户 {TenantId}", tenantId);
  63. }
  64. }
  65. }
  66. }