SiteRealtimeService.php 1.5 KB

123456789101112131415161718192021222324252627282930
  1. <?php
  2. namespace App\Services;
  3. use Carbon\Carbon;
  4. use Illuminate\Support\Facades\DB;
  5. use Illuminate\Support\Facades\Schema;
  6. use Illuminate\Validation\ValidationException;
  7. use InvalidArgumentException;
  8. /** Written inside the same transaction as the change; consumed by the member WebSocket worker. */
  9. final class SiteRealtimeService
  10. {
  11. public static function changed(string $module, int $id, string $action, array $boundaries = [], bool $notifyNow = true): void
  12. {
  13. if (!in_array($module, ['message', 'announcement', 'maintenance'], true) || $id < 1) throw new InvalidArgumentException('Invalid site event');
  14. if (!Schema::hasTable('site_realtime_events')) {
  15. throw ValidationException::withMessages(['realtime' => '实时通知服务未初始化,请先完成系统更新']);
  16. }
  17. $now = Carbon::now('Asia/Shanghai')->format('Y-m-d H:i:s');
  18. $pending = DB::table('site_realtime_events')->where('module', $module)->where('resource_id', $id)->whereNull('dispatched_at');
  19. if ($module !== 'announcement') $pending->where('available_at', '>', $now);
  20. $pending->delete();
  21. $rows = $notifyNow ? [['module' => $module, 'resource_id' => $id, 'action' => $action, 'available_at' => $now, 'created_at' => $now]] : [];
  22. foreach ($boundaries as $edge => $at) {
  23. if ($at !== null && $at > $now) $rows[] = ['module' => $module, 'resource_id' => $id, 'action' => $edge, 'available_at' => $at, 'created_at' => $now];
  24. }
  25. if ($rows) DB::table('site_realtime_events')->insert($rows);
  26. }
  27. }