Files
chatroom/resources/views/admin/game-configs/index.blade.php
T

489 lines
31 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('admin.layouts.app')
@section('title', '游戏管理')
@section('content')
@php
$riddleTypeOptions = \App\Models\Riddle::typeOptions();
@endphp
<div class="space-y-6">
{{-- 页头 --}}
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 flex justify-between items-center">
<div>
<h2 class="text-lg font-bold text-gray-800">🎮 游戏管理</h2>
<p class="text-xs text-gray-500 mt-1">统一管理聊天室所有娱乐游戏的开关状态与核心参数,所有游戏默认关闭。</p>
</div>
<button type="button" data-game-stats-url="{{ route('admin.game-history.stats') }}"
class="px-4 py-2 bg-indigo-50 text-indigo-700 rounded-lg text-sm font-bold hover:bg-indigo-100 transition">
📊 加载实时统计
</button>
</div>
{{-- 实时统计摘要区(AJAX 异步加载,默认隐藏) --}}
<div id="game-stats-panel" class="hidden">
<div class="grid grid-cols-2 md:grid-cols-5 gap-4" id="game-stats-grid">
{{-- JS 动态填充 --}}
</div>
</div>
{{-- 游戏卡片列表 --}}
<div class="grid grid-cols-1 gap-6">
@foreach ($games as $game)
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"
id="game-card-{{ $game->game_key }}">
{{-- 卡片头部:游戏名 + 开关 --}}
<div
class="flex items-center justify-between p-5 border-b border-gray-100
{{ $game->enabled ? 'bg-emerald-50' : 'bg-gray-50' }}">
<div class="flex items-center gap-3">
<span class="text-3xl">{{ $game->icon }}</span>
<div>
<div class="font-bold text-gray-800 flex items-center gap-2">
{{ $game->name }}
<span id="badge-{{ $game->game_key }}"
class="text-xs px-2 py-0.5 rounded-full font-bold
{{ $game->enabled ? 'bg-emerald-100 text-emerald-700' : 'bg-gray-200 text-gray-500' }}">
{{ $game->enabled ? '运行中' : '已关闭' }}
</span>
</div>
<div class="text-xs text-gray-500 mt-0.5">{{ $game->description }}</div>
</div>
</div>
{{-- 操作按钮组 --}}
<div class="flex items-center gap-2">
{{-- 历史记录链接 --}}
@php
$historyRoute = match ($game->game_key) {
'baccarat' => 'admin.game-history.baccarat',
'slot_machine' => 'admin.game-history.slot',
'mystery_box' => 'admin.game-history.mystery-box',
'horse_racing' => 'admin.game-history.horse',
'fortune_telling' => 'admin.game-history.fortune',
'lottery' => 'admin.game-history.lottery',
'gomoku' => 'admin.game-history.gomoku',
default => null,
};
@endphp
@if ($historyRoute)
<a href="{{ route($historyRoute) }}"
class="px-4 py-2 bg-indigo-50 text-indigo-700 rounded-lg font-bold text-sm hover:bg-indigo-100 transition shadow-sm">
📋 历史记录
</a>
@endif
{{-- 大开关按钮 --}}
<button type="button" data-game-toggle-url="{{ route('admin.game-configs.toggle', $game) }}"
data-game-key="{{ $game->game_key }}"
id="toggle-btn-{{ $game->game_key }}"
class="px-5 py-2 rounded-lg font-bold text-sm transition shadow-sm
{{ $game->enabled ? 'bg-red-500 hover:bg-red-600 text-white' : 'bg-emerald-500 hover:bg-emerald-600 text-white' }}">
{{ $game->enabled ? '⏸ 关闭游戏' : '▶ 开启游戏' }}
</button>
</div>
</div>
{{-- 参数配置区域 --}}
<div class="p-5">
<form action="{{ route('admin.game-configs.params', $game) }}" method="POST"
data-game-room-form
@if ($game->game_key === 'idiom') data-idiom-config-form @endif>
@csrf
@php
$params = $game->params ?? [];
$labels = gameParamLabels($game->game_key);
$hiddenLegacyKeys = $game->game_key === 'mystery_box'
? ['min_reward', 'max_reward', 'rare_min_reward', 'rare_max_reward']
: [];
$hiddenConfigKeys = ['room_scope_mode', 'room_ids'];
$paramKeys = array_values(array_unique(array_merge(array_keys($labels), array_keys($params))));
$paramKeys = array_values(array_filter($paramKeys, fn ($key) => ! in_array($key, array_merge($hiddenLegacyKeys, $hiddenConfigKeys), true)));
@endphp
@if ($game->game_key === 'idiom')
@include('admin.game-configs.partials.riddle-config-card', [
'params' => $params,
'availableRooms' => $availableRooms,
'riddleTypeOptions' => $riddleTypeOptions,
])
@else
@php
$roomScopeConfig = gameRoomScopeConfig($params);
@endphp
<div class="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4">
@foreach ($paramKeys as $paramKey)
@php
$paramValue = $params[$paramKey] ?? ($labels[$paramKey]['default'] ?? '');
if ($game->game_key === 'mystery_box') {
$legacyFallbackMap = [
'normal_reward_min' => 'min_reward',
'normal_reward_max' => 'max_reward',
'rare_reward_min' => 'rare_min_reward',
'rare_reward_max' => 'rare_max_reward',
];
if (($paramValue === '' || $paramValue === null) && isset($legacyFallbackMap[$paramKey])) {
$paramValue = $params[$legacyFallbackMap[$paramKey]] ?? $paramValue;
}
}
@endphp
@php $meta = $labels[$paramKey] ?? ['label' => $paramKey, 'type' => 'number', 'unit' => ''] @endphp
<div>
<label class="mb-1 block text-xs font-bold text-gray-600">
{{ $meta['label'] }}
@if ($meta['unit'])
<span class="font-normal text-gray-400">{{ $meta['unit'] }}</span>
@endif
</label>
@if ($meta['type'] === 'boolean')
<select name="params[{{ $paramKey }}]"
class="w-full rounded-lg border border-gray-300 p-2 text-sm focus:border-indigo-400">
<option value="1" {{ $paramValue ? 'selected' : '' }}></option>
<option value="0" {{ !$paramValue ? 'selected' : '' }}></option>
</select>
@elseif ($meta['type'] === 'array')
<input type="text" name="params[{{ $paramKey }}]"
value="{{ implode(',', (array) $paramValue) }}"
class="w-full rounded-lg border border-gray-300 p-2 text-sm focus:border-indigo-400"
placeholder="多个值用逗号分隔">
@else
<input type="{{ $meta['type'] }}" name="params[{{ $paramKey }}]"
value="{{ $paramValue }}" step="{{ $meta['step'] ?? 1 }}"
min="{{ $meta['min'] ?? 0 }}"
class="w-full rounded-lg border border-gray-300 p-2 text-sm focus:border-indigo-400">
@endif
</div>
@endforeach
</div>
<div class="mt-4 border-t border-gray-100 pt-4">
@include('admin.game-configs.partials.common-room-scope', [
'availableRooms' => $availableRooms,
'roomScopeConfig' => $roomScopeConfig,
'roomScopeTitle' => '参与房间',
])
</div>
@endif
<div class="mt-4 flex items-center gap-3">
<button type="submit"
class="px-6 py-2 bg-indigo-600 text-white rounded-lg font-bold hover:bg-indigo-700 transition text-sm shadow-sm">
💾 保存参数
</button>
<span class="text-xs text-gray-400">修改后立即生效(缓存60秒刷新)</span>
</div>
</form>
{{-- 神秘箱子:手动投放区域 --}}
@if ($game->game_key === 'mystery_box')
<div class="mt-4 pt-4 border-t border-gray-100">
<div class="text-xs font-bold text-gray-600 mb-2">🎯 手动投放箱子</div>
<div class="flex items-center gap-3 flex-wrap">
<button type="button" data-game-drop-box-type="normal"
data-game-drop-box-url="{{ route('admin.mystery-box.drop') }}"
data-game-hover-opacity=".85"
style="padding:8px 16px; background:linear-gradient(135deg,#059669,#10b981); color:#fff; border:none; border-radius:8px; font-size:13px; font-weight:700; cursor:pointer; transition:opacity .15s;">
📦 投放普通箱
</button>
<button type="button" data-game-drop-box-type="rare"
data-game-drop-box-url="{{ route('admin.mystery-box.drop') }}"
data-game-hover-opacity=".85"
style="padding:8px 16px; background:linear-gradient(135deg,#7c3aed,#a78bfa); color:#fff; border:none; border-radius:8px; font-size:13px; font-weight:700; cursor:pointer; transition:opacity .15s;">
💎 投放稀有箱
</button>
<button type="button" data-game-drop-box-type="trap"
data-game-drop-box-url="{{ route('admin.mystery-box.drop') }}"
data-game-hover-opacity=".85"
style="padding:8px 16px; background:linear-gradient(135deg,#7f1d1d,#ef4444); color:#fff; border:none; border-radius:8px; font-size:13px; font-weight:700; cursor:pointer; transition:opacity .15s;">
☠️ 投放黑化箱
</button>
<span class="text-xs text-gray-400">投放到当前配置的首选房间,立即广播暗号。</span>
</div>
</div>
@endif
{{-- 双色球彩票:手动操作区域 --}}
@if ($game->game_key === 'lottery')
<div class="mt-4 pt-4 border-t border-gray-100">
<div class="text-xs font-bold text-gray-600 mb-3">🎟️ 手动操作</div>
{{-- 当前期次状态展示 --}}
<div id="lottery-issue-status"
class="mb-3 text-xs text-gray-500 bg-red-50 border border-red-100 rounded-lg p-3">
<span class="text-red-400"> 点击下方「加载期次状态」查看当前状态</span>
</div>
<div class="flex items-center gap-3 flex-wrap">
<button type="button" data-game-lottery-current-url="{{ url('/lottery/current') }}"
data-game-hover-opacity=".85"
style="padding:8px 16px; background:linear-gradient(135deg,#475569,#64748b); color:#fff; border:none; border-radius:8px; font-size:13px; font-weight:700; cursor:pointer; transition:opacity .15s;">
🔄 加载期次状态
</button>
<button type="button" data-game-lottery-open-url="{{ route('admin.lottery.open-issue') }}"
data-game-hover-opacity=".85"
style="padding:8px 16px; background:linear-gradient(135deg,#059669,#10b981); color:#fff; border:none; border-radius:8px; font-size:13px; font-weight:700; cursor:pointer; transition:opacity .15s;">
手动开新期
</button>
<button type="button" data-game-lottery-force-url="{{ route('admin.lottery.force-draw') }}"
data-game-hover-opacity=".85"
style="padding:8px 16px; background:linear-gradient(135deg,#dc2626,#ef4444); color:#fff; border:none; border-radius:8px; font-size:13px; font-weight:700; cursor:pointer; transition:opacity .15s;">
🎊 立即强制开奖
</button>
<span class="text-xs text-gray-400">开新期仅在无进行中期次时生效;强制开奖将提前结束当期</span>
</div>
</div>
@endif
</div>
</div>
@endforeach
@if ($games->isEmpty())
<div class="bg-white rounded-xl border border-gray-100 p-12 text-center text-gray-400">
暂无游戏配置,请先运行 <code class="bg-gray-100 px-2 py-1 rounded">php artisan db:seed
--class=GameConfigSeeder</code>
</div>
@endif
</div>
</div>
@endsection
@php
/**
* 返回各游戏参数的中文标签说明。
*
* @param string $gameKey
* @return array<string, array{label: string, type: string, unit: string}>
*/
function gameParamLabels(string $gameKey): array
{
return match ($gameKey) {
'baccarat' => [
'interval_minutes' => ['label' => '开局间隔', 'type' => 'number', 'unit' => '分钟', 'min' => 1],
'bet_window_seconds' => ['label' => '押注窗口', 'type' => 'number', 'unit' => '秒', 'min' => 10],
'min_bet' => ['label' => '最低押注', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'max_bet' => ['label' => '最高押注', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'payout_big' => ['label' => '大赔率(1:N', 'type' => 'number', 'unit' => '', 'min' => 1],
'payout_small' => ['label' => '小赔率(1:N', 'type' => 'number', 'unit' => '', 'min' => 1],
'payout_triple' => ['label' => '豹子赔率(1:N', 'type' => 'number', 'unit' => '', 'min' => 1],
'kill_points' => ['label' => '庄家收割点数', 'type' => 'array', 'unit' => '逗号分隔'],
],
'slot_machine' => [
'cost_per_spin' => ['label' => '每次旋转消耗', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'house_edge_percent' => [
'label' => '庄家边际',
'type' => 'number',
'unit' => '%',
'min' => 0,
'step' => 0.1,
],
'daily_limit' => ['label' => '每日转动上限', 'type' => 'number', 'unit' => '次(0=不限)', 'min' => 0],
'jackpot_payout' => ['label' => '三个7赔率(1:N', 'type' => 'number', 'unit' => '', 'min' => 1],
'triple_payout' => ['label' => '三💎赔率(1:N', 'type' => 'number', 'unit' => '', 'min' => 1],
'same_payout' => ['label' => '其他三同(1:N', 'type' => 'number', 'unit' => '', 'min' => 1],
'pair_payout' => ['label' => '两同赔率(1:N', 'type' => 'number', 'unit' => '', 'min' => 1],
'curse_enabled' => ['label' => '开启诅咒(三💀)', 'type' => 'boolean', 'unit' => ''],
],
'mystery_box' => [
'auto_drop_enabled' => ['label' => '自动定时投放', 'type' => 'boolean', 'unit' => ''],
'auto_interval_hours' => ['label' => '自动投放间隔', 'type' => 'number', 'unit' => '小时', 'min' => 1],
'claim_window_seconds' => ['label' => '领取窗口', 'type' => 'number', 'unit' => '秒', 'min' => 10],
// 新键名
'normal_reward_min' => ['label' => '普通箱最低奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'normal_reward_max' => ['label' => '普通箱最高奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'rare_reward_min' => ['label' => '稀有箱最低奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'rare_reward_max' => ['label' => '稀有箱最高奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'trap_penalty_min' => ['label' => '黑化箱最低惩罚', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'trap_penalty_max' => ['label' => '黑化箱最高惩罚', 'type' => 'number', 'unit' => '金币', 'min' => 1],
// 旧键名兼容(数据库中已存在的旧配置)
'min_reward' => ['label' => '普通箱最低奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'max_reward' => ['label' => '普通箱最高奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'rare_min_reward' => ['label' => '稀有箱最低奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'rare_max_reward' => ['label' => '稀有箱最高奖励', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'trap_chance_percent' => [
'label' => '黑化箱概率',
'type' => 'number',
'unit' => '%',
'min' => 0,
'max' => 100,
],
],
'horse_racing' => [
'interval_minutes' => ['label' => '比赛间隔', 'type' => 'number', 'unit' => '分钟', 'min' => 5],
'bet_window_seconds' => ['label' => '押注窗口', 'type' => 'number', 'unit' => '秒', 'min' => 10],
'race_duration' => ['label' => '跑马动画时长', 'type' => 'number', 'unit' => '秒', 'min' => 10],
'horse_count' => ['label' => '参赛马匹数', 'type' => 'number', 'unit' => '匹', 'min' => 2, 'max' => 8],
'min_bet' => ['label' => '最低押注', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'max_bet' => ['label' => '最高押注', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'seed_pool' => ['label' => '系统初始化资金池', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'house_take_percent' => [
'label' => '庄家抽水',
'type' => 'number',
'unit' => '%',
'min' => 0,
'max' => 20,
],
],
'fortune_telling' => [
'free_count_per_day' => ['label' => '每日免费次数', 'type' => 'number', 'unit' => '次', 'min' => 0],
'extra_cost' => ['label' => '额外次数消耗', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'buff_duration_hours' => ['label' => '加成持续时间', 'type' => 'number', 'unit' => '小时', 'min' => 1],
'jackpot_chance' => [
'label' => '上上签概率',
'type' => 'number',
'unit' => '%',
'min' => 0,
'max' => 100,
],
'good_chance' => ['label' => '上签概率', 'type' => 'number', 'unit' => '%', 'min' => 0, 'max' => 100],
'bad_chance' => ['label' => '下签概率', 'type' => 'number', 'unit' => '%', 'min' => 0, 'max' => 100],
'curse_chance' => [
'label' => '大凶签概率',
'type' => 'number',
'unit' => '%',
'min' => 0,
'max' => 100,
],
],
'fishing' => [
'fishing_cost' => ['label' => '每次抛竿消耗', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'fishing_wait_min' => ['label' => '浮漂等待最短', 'type' => 'number', 'unit' => '秒', 'min' => 1],
'fishing_wait_max' => ['label' => '浮漂等待最长', 'type' => 'number', 'unit' => '秒', 'min' => 1],
'fishing_cooldown' => ['label' => '收竿后冷却时间', 'type' => 'number', 'unit' => '秒', 'min' => 10],
],
'lottery' => [
// ── 开奖时间 ──
'draw_hour' => [
'label' => '开奖时(24h制)',
'type' => 'number',
'unit' => '时',
'min' => 0,
'max' => 23,
],
'draw_minute' => ['label' => '开奖分', 'type' => 'number', 'unit' => '分', 'min' => 0, 'max' => 59],
'stop_sell_minutes' => ['label' => '停售提前', 'type' => 'number', 'unit' => '分钟', 'min' => 1],
// ── 购票限制 ──
'ticket_price' => ['label' => '每注金额', 'type' => 'number', 'unit' => '金币', 'min' => 1],
'max_tickets_per_user' => ['label' => '单人每期上限', 'type' => 'number', 'unit' => '注', 'min' => 1],
'max_tickets_per_buy' => ['label' => '单次购买上限', 'type' => 'number', 'unit' => '注', 'min' => 1],
// ── 奖池分配 ──
'pool_ratio' => [
'label' => '购票进奖池比例',
'type' => 'number',
'unit' => '%',
'min' => 1,
'max' => 100,
],
'prize_1st_ratio' => [
'label' => '一等奖占奖池',
'type' => 'number',
'unit' => '%',
'min' => 1,
'max' => 100,
],
'prize_2nd_ratio' => [
'label' => '二等奖占奖池',
'type' => 'number',
'unit' => '%',
'min' => 1,
'max' => 100,
],
'prize_3rd_ratio' => [
'label' => '三等奖占奖池',
'type' => 'number',
'unit' => '%',
'min' => 1,
'max' => 100,
],
'carry_ratio' => ['label' => '强制滚存', 'type' => 'number', 'unit' => '%', 'min' => 0, 'max' => 50],
// ── 固定小奖 ──
'prize_4th_fixed' => ['label' => '四等奖固定金额/注', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'prize_5th_fixed' => ['label' => '五等奖固定金额/注', 'type' => 'number', 'unit' => '金币', 'min' => 0],
// ── 超级期 ──
'super_issue_threshold' => [
'label' => '超级期触发连续无一等奖',
'type' => 'number',
'unit' => '期',
'min' => 1,
],
'super_issue_inject' => [
'label' => '超级期系统注入上限',
'type' => 'number',
'unit' => '金币',
'min' => 0,
],
],
'gomoku' => [
// ── PvP 对战 ──
'pvp_reward' => ['label' => 'PvP 胜利奖励', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'pvp_invite_timeout' => ['label' => 'PvP 邀请超时', 'type' => 'number', 'unit' => '秒', 'min' => 10],
'pvp_move_timeout' => ['label' => '每步落子超时', 'type' => 'number', 'unit' => '秒', 'min' => 10],
'pvp_ready_timeout' => ['label' => '对局准备超时', 'type' => 'number', 'unit' => '秒', 'min' => 10],
// ── 人机对战:简单 (Level 1) ──
'pve_fee_level_1' => ['label' => 'AI简单 入场费', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'pve_reward_level_1' => ['label' => 'AI简单 胜利奖励', 'type' => 'number', 'unit' => '金币', 'min' => 0],
// ── 人机对战:普通 (Level 2) ──
'pve_fee_level_2' => ['label' => 'AI普通 入场费', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'pve_reward_level_2' => ['label' => 'AI普通 胜利奖励', 'type' => 'number', 'unit' => '金币', 'min' => 0],
// ── 人机对战:困难 (Level 3) ──
'pve_fee_level_3' => ['label' => 'AI困难 入场费', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'pve_reward_level_3' => ['label' => 'AI困难 胜利奖励', 'type' => 'number', 'unit' => '金币', 'min' => 0],
// ── 人机对战:专家 (Level 4) ──
'pve_fee_level_4' => ['label' => 'AI专家 入场费', 'type' => 'number', 'unit' => '金币', 'min' => 0],
'pve_reward_level_4' => ['label' => 'AI专家 胜利奖励', 'type' => 'number', 'unit' => '金币', 'min' => 0],
],
'idiom' => [
'reward_gold' => ['label' => '答对奖励金币', 'type' => 'number', 'unit' => '枚', 'min' => 0],
'reward_exp' => ['label' => '答对奖励经验', 'type' => 'number', 'unit' => '点', 'min' => 0],
'auto_start_interval' => ['label' => '自动出题间隔', 'type' => 'number', 'unit' => '分钟(0=仅手动)', 'min' => 0],
],
default => [],
};
}
/**
* 解析猜谜活动公共配置,并兼容旧版题型拆分配置。
*
* @return array{reward_gold:int,reward_exp:int,expire_minutes:int,auto_start_interval:int,room_mode:string,room_ids:array<int, int>}
*/
function gameRiddleSharedConfig(array $params): array
{
$fallbackTypeConfig = collect((array) ($params['type_configs'] ?? []))
->first(fn ($typeConfig) => is_array($typeConfig) && $typeConfig !== [], []);
$roomMode = (string) ($params['room_scope_mode'] ?? ($fallbackTypeConfig['room_mode'] ?? 'single'));
if (! in_array($roomMode, ['all', 'single', 'multiple'], true)) {
$roomMode = 'single';
}
return [
'reward_gold' => max(0, (int) ($params['reward_gold'] ?? ($fallbackTypeConfig['reward_gold'] ?? 50))),
'reward_exp' => max(0, (int) ($params['reward_exp'] ?? ($fallbackTypeConfig['reward_exp'] ?? 30))),
'expire_minutes' => max(0, (int) ($params['expire_minutes'] ?? ($fallbackTypeConfig['expire_minutes'] ?? 5))),
'auto_start_interval' => max(0, (int) ($params['auto_start_interval'] ?? ($fallbackTypeConfig['auto_start_interval'] ?? 0))),
'room_mode' => $roomMode,
'room_ids' => collect((array) ($params['room_ids'] ?? ($fallbackTypeConfig['room_ids'] ?? [])))
->map(fn ($roomId) => (int) $roomId)
->filter(fn ($roomId) => $roomId > 0)
->unique()
->values()
->all(),
];
}
/**
* 解析通用游戏的房间范围配置。
*
* @return array{room_scope_mode:string,room_ids:array<int, int>}
*/
function gameRoomScopeConfig(array $params): array
{
$roomScopeService = app(\App\Services\GameRoomScopeService::class);
return $roomScopeService->getScopeConfigForParams($params);
}
@endphp