S2AutoScheduleJob.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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 (!_configuration.GetValue("S2:AutoSchedule:Enabled", false))
  33. return;
  34. using var scope = _scopeFactory.CreateScope();
  35. var db = scope.ServiceProvider.GetRequiredService<ISqlSugarClient>();
  36. var action = scope.ServiceProvider.GetRequiredService<ProductionSchedulingActionService>();
  37. var tenants = await db.Ado.SqlQueryAsync<long>(
  38. """
  39. SELECT DISTINCT tenant_id
  40. FROM WorkOrdMaster
  41. WHERE IFNULL(IsActive, 0) = 1
  42. AND IFNULL(Status, '') NOT IN ('c', 'C')
  43. AND tenant_id IS NOT NULL AND tenant_id > 0
  44. """);
  45. foreach (var tenantId in tenants)
  46. {
  47. if (stoppingToken.IsCancellationRequested)
  48. break;
  49. try
  50. {
  51. var domain = tenantId.ToString();
  52. await action.SubmitGenerateAsync(
  53. tenantId, domain, "sys-auto-schedule",
  54. enableCapacityConstraint: false,
  55. trigger: "auto");
  56. _logger.LogInformation("S2AutoScheduleJob 已提交租户 {TenantId}", tenantId);
  57. }
  58. catch (Exception ex)
  59. {
  60. // 单飞冲突或业务拒绝:记日志,继续下一租户
  61. _logger.LogWarning(ex, "S2AutoScheduleJob 跳过租户 {TenantId}", tenantId);
  62. }
  63. }
  64. }
  65. }