| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- <?php
- namespace App\Services\AdminRealtime;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- /**
- * 后台实时推送事件登记。
- *
- * 只登记「哪张表的哪条记录发生了什么」,事务提交后写入 admin_realtime_events;
- * 列表行由推送网关拉取时按对应列表接口的口径解析(见 AdminRealtimeRows)。
- * 登记失败只记 realtime 日志,绝不抛出,不影响下单、充值等主业务。
- */
- final class AdminRealtime
- {
- /** 监听的表 => 仅这些列变化时不推送(例如通知标记、更新时间) */
- public const RESOURCES = [
- 'sport_order' => ['update_time'],
- 'lhc_order' => ['updated_at'],
- 'sport_game_order' => ['updated_at'],
- 'jisu_game_order' => ['updated_at'],
- 'third_game_orders' => ['updated_at'],
- 'bets' => ['updated_at'],
- 'recharges' => ['updated_at', 'is_send'],
- 'payment_orders' => ['updated_at', 'is_send'],
- 'withdraws' => ['updated_at', 'is_send'],
- 'manual_audits' => ['updated_at'],
- 'users' => [],
- ];
- /** 用户列表只推新增;在线状态由 OnlineStatusScanner 产生 */
- public const USER_ONLINE = 'user_online';
- public static function captureModel(Model $model, string $action): void
- {
- $table = $model->getTable();
- if (!array_key_exists($table, self::RESOURCES)) return;
- if ($table === 'users' && $action !== 'created') return;
- if ($action === 'updated' && !array_diff(array_keys($model->getChanges()), self::RESOURCES[$table])) return;
- self::record($table, $model->getKey(), $action);
- }
- /**
- * @param string $resource 表名(不含前缀)或 user_online
- * @param int|string|array $ids 记录主键
- * @param string $action created / updated / deleted / online / offline
- */
- public static function record(string $resource, $ids, string $action = 'updated'): void
- {
- if (!config('admin_realtime.enabled')) return;
- $ids = array_values(array_unique(array_filter(array_map('strval', (array) $ids), static fn(string $id): bool => $id !== '')));
- if (!$ids) return;
- $write = static function () use ($resource, $ids, $action): void {
- try {
- $now = now('Asia/Shanghai')->format('Y-m-d H:i:s');
- foreach (array_chunk($ids, 500) as $chunk) {
- DB::table('admin_realtime_events')->insert(array_map(static fn(string $id): array => [
- 'resource' => $resource, 'resource_id' => $id, 'action' => $action, 'source' => 'bot-28', 'created_at' => $now,
- ], $chunk));
- }
- } catch (\Throwable $e) {
- Log::channel('realtime')->error('admin_realtime_record_failed', [
- 'resource' => $resource, 'action' => $action, 'count' => count($ids), 'error' => $e->getMessage(),
- ]);
- }
- };
- // 事务内调用时等提交后再写,回滚则丢弃;不在事务内立即写
- try {
- DB::afterCommit($write);
- } catch (\Throwable $e) {
- $write();
- }
- }
- }
|