SiteRealtimeService.php 1.4 KB

1234567891011121314151617181920212223242526272829
  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 = []): 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. DB::table('site_realtime_events')->where('module', $module)->where('resource_id', $id)
  19. ->whereNull('dispatched_at')->where('available_at', '>', $now)->delete();
  20. $rows = [['module' => $module, 'resource_id' => $id, 'action' => $action, 'available_at' => $now, 'created_at' => $now]];
  21. foreach ($boundaries as $edge => $at) {
  22. if ($at !== null && $at > $now) $rows[] = ['module' => $module, 'resource_id' => $id, 'action' => $edge, 'available_at' => $at, 'created_at' => $now];
  23. }
  24. DB::table('site_realtime_events')->insert($rows);
  25. }
  26. }