feat: 彩票业务迁移并补全后台权限与代理结算体系
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Services\Draw;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Events\OddsUpdateBroadcast;
|
||||
use App\Events\PlayCatalogUpdatedBroadcast;
|
||||
use App\Events\PlayToggleBroadcast;
|
||||
@@ -11,6 +12,7 @@ use App\Events\JackpotBurstBroadcast;
|
||||
use App\Events\DrawCountdownBroadcast;
|
||||
use App\Events\DrawStatusChangeBroadcast;
|
||||
use App\Events\DrawResultPublishedBroadcast;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
/**
|
||||
* 对齐界面文档 §2.1:大厅公共频道广播(`lottery-hall`)。
|
||||
@@ -19,20 +21,33 @@ use App\Events\DrawResultPublishedBroadcast;
|
||||
*/
|
||||
final class LotteryHallRealtimeBroadcaster
|
||||
{
|
||||
private const COUNTDOWN_FP_CACHE_KEY = 'lottery:hall:countdown:last-fingerprint';
|
||||
|
||||
public function __construct(
|
||||
private readonly DrawHallSnapshotBuilder $snapshot,
|
||||
) {}
|
||||
|
||||
/** 每秒调度:`draw.countdown` 推送大厅快照(与 GET draw/current 一致),避免仅本地倒计时无法切期。 */
|
||||
/** 每秒调度:边界变化立刻推送,完整快照按低频校准,避免仅本地倒计时无法切期。 */
|
||||
public function countdownPulse(): void
|
||||
{
|
||||
if (! $this->driverSupportsRealtime()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nowUtc = Carbon::now()->utc();
|
||||
$ms = (int) floor(microtime(true) * 1000);
|
||||
$fingerprint = $this->snapshot->hallTargetFingerprint($nowUtc);
|
||||
$lastFingerprint = Cache::get(self::COUNTDOWN_FP_CACHE_KEY);
|
||||
$stateChanged = $this->fingerprintChanged($lastFingerprint, $fingerprint);
|
||||
$shouldSync = $this->shouldBroadcastSyncPulse($nowUtc);
|
||||
|
||||
broadcast(new DrawCountdownBroadcast($this->snapshot->build(), $ms));
|
||||
Cache::put(self::COUNTDOWN_FP_CACHE_KEY, $fingerprint, now()->addMinutes(10));
|
||||
|
||||
if (! $stateChanged && ! $shouldSync) {
|
||||
return;
|
||||
}
|
||||
|
||||
broadcast(new DrawCountdownBroadcast($this->snapshot->build($nowUtc), $ms));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,4 +212,24 @@ final class LotteryHallRealtimeBroadcaster
|
||||
|
||||
return ! in_array($driver, ['null', 'log'], true);
|
||||
}
|
||||
|
||||
private function shouldBroadcastSyncPulse(Carbon $nowUtc): bool
|
||||
{
|
||||
$interval = match ((int) config('lottery.realtime_hall_countdown_sync_interval_seconds', 5)) {
|
||||
1, 2, 5, 10 => (int) config('lottery.realtime_hall_countdown_sync_interval_seconds', 5),
|
||||
default => 5,
|
||||
};
|
||||
|
||||
return $interval === 1 || ((int) $nowUtc->format('s')) % $interval === 0;
|
||||
}
|
||||
|
||||
private function fingerprintChanged(mixed $before, ?array $after): bool
|
||||
{
|
||||
if (! is_array($before)) {
|
||||
return $after !== null;
|
||||
}
|
||||
|
||||
return ($before['draw_no'] ?? null) !== ($after['draw_no'] ?? null)
|
||||
|| ($before['status'] ?? null) !== ($after['status'] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user