- 新增 GameHistoryController,提供各游戏历史记录查询接口 - 百家乐:局次列表 + 单局下注明细(含结果分布统计) - 老虎机:转动记录含图案分布,支持结果类型/玩家名筛选 - 赛马:场次列表 + 单场下注明细(含马匹信息展示) - 神秘箱子:投放/领取历史,支持箱子类型/领取状态筛选 - 神秘占卜:签文等级分布统计 + 历史记录,支持等级/玩家名筛选 - 新增 /admin/game-history/ 路由组(stats + 各游戏历史 + 单局详情共9条路由) - 游戏管理页(/admin/game-configs)优化: - 每个游戏卡片新增「📋 历史记录」直达按钮 - 新增「📊 加载实时统计」按钮,AJAX 异步拉取并展示各游戏汇总卡片 - 更新 GAMES_TODO.md,标记通用待办已完成
508 lines
28 KiB
PHP
508 lines
28 KiB
PHP
@extends('admin.layouts.app')
|
||
|
||
@section('title', '游戏管理')
|
||
|
||
@section('content')
|
||
<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 onclick="loadGameStats()"
|
||
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>
|
||
|
||
@if (session('success'))
|
||
<div class="bg-green-50 border border-green-200 text-green-700 px-4 py-3 rounded-lg text-sm">
|
||
✅ {{ session('success') }}
|
||
</div>
|
||
@endif
|
||
|
||
{{-- 游戏卡片列表 --}}
|
||
<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',
|
||
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 onclick="toggleGame('{{ $game->game_key }}', {{ $game->id }})"
|
||
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">
|
||
@csrf
|
||
|
||
@php
|
||
$params = $game->params ?? [];
|
||
$labels = gameParamLabels($game->game_key);
|
||
@endphp
|
||
|
||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
||
@foreach ($params as $paramKey => $paramValue)
|
||
@php $meta = $labels[$paramKey] ?? ['label' => $paramKey, 'type' => 'number', 'unit' => ''] @endphp
|
||
<div>
|
||
<label class="block text-xs font-bold text-gray-600 mb-1">
|
||
{{ $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 border border-gray-300 rounded-lg 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 border border-gray-300 rounded-lg 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 border border-gray-300 rounded-lg p-2 text-sm focus:border-indigo-400">
|
||
@endif
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
|
||
<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 onclick="dropBox('normal', {{ $game->id }})"
|
||
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;"
|
||
onmouseover="this.style.opacity='.85'" onmouseout="this.style.opacity='1'">
|
||
📦 投放普通箱
|
||
</button>
|
||
<button onclick="dropBox('rare', {{ $game->id }})"
|
||
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;"
|
||
onmouseover="this.style.opacity='.85'" onmouseout="this.style.opacity='1'">
|
||
💎 投放稀有箱
|
||
</button>
|
||
<button onclick="dropBox('trap', {{ $game->id }})"
|
||
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;"
|
||
onmouseover="this.style.opacity='.85'" onmouseout="this.style.opacity='1'">
|
||
☠️ 投放黑化箱
|
||
</button>
|
||
<span class="text-xs text-gray-400">直接向 #1 房间投放,立即广播暗号</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>
|
||
|
||
<script>
|
||
/**
|
||
* 切换游戏开启/关闭状态
|
||
*/
|
||
function toggleGame(gameKey, gameId) {
|
||
fetch(`/admin/game-configs/${gameId}/toggle`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||
'Accept': 'application/json',
|
||
},
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (!data.ok) return;
|
||
|
||
const enabled = data.enabled;
|
||
const card = document.getElementById(`game-card-${gameKey}`);
|
||
const badge = document.getElementById(`badge-${gameKey}`);
|
||
const btn = document.getElementById(`toggle-btn-${gameKey}`);
|
||
const header = card?.querySelector('.flex.items-center.justify-between');
|
||
|
||
// 更新徽章
|
||
badge.textContent = enabled ? '运行中' : '已关闭';
|
||
badge.className = `text-xs px-2 py-0.5 rounded-full font-bold ${enabled
|
||
? 'bg-emerald-100 text-emerald-700'
|
||
: 'bg-gray-200 text-gray-500'}`;
|
||
|
||
// 更新按钮
|
||
btn.textContent = enabled ? '⏸ 关闭游戏' : '▶ 开启游戏';
|
||
btn.className = `px-5 py-2 rounded-lg font-bold text-sm transition shadow-sm ${enabled
|
||
? 'bg-red-500 hover:bg-red-600 text-white'
|
||
: 'bg-emerald-500 hover:bg-emerald-600 text-white'}`;
|
||
|
||
// 更新头部背景
|
||
if (header) {
|
||
header.classList.toggle('bg-emerald-50', enabled);
|
||
header.classList.toggle('bg-gray-50', !enabled);
|
||
}
|
||
|
||
// 全局弹窗提示
|
||
window.adminDialog.alert(data.message, enabled ? '游戏已开启' : '游戏已关闭', enabled ? '✅' : '⏸');
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 管理员手动投放神秘箱子
|
||
*
|
||
* @param {string} boxType 箱子类型:normal | rare | trap
|
||
*/
|
||
function dropBox(boxType) {
|
||
const typeNames = {
|
||
normal: '普通箱',
|
||
rare: '稀有箱',
|
||
trap: '黑化箱'
|
||
};
|
||
const typeIcons = {
|
||
normal: '📦',
|
||
rare: '💎',
|
||
trap: '☠️'
|
||
};
|
||
const name = typeNames[boxType] || boxType;
|
||
const icon = typeIcons[boxType] || '📦';
|
||
|
||
window.adminDialog.confirm(
|
||
`确定要向 <b>#1 房间</b> 投放一个「${name}」吗?<br><span style="color:#64748b; font-size:12px;">箱子投放后将立即在公屏广播暗号,用户限时领取。</span>`,
|
||
`投放${name}`,
|
||
() => {
|
||
fetch('/admin/mystery-box/drop', {
|
||
method: 'POST',
|
||
headers: {
|
||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||
'Content-Type': 'application/json',
|
||
'Accept': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
box_type: boxType
|
||
}),
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
window.adminDialog.alert(
|
||
data.message || (data.ok ? '投放成功!' : '投放失败'),
|
||
data.ok ? '投放成功' : '投放失败',
|
||
data.ok ? icon : '❌'
|
||
);
|
||
})
|
||
.catch(() => window.adminDialog.alert('网络错误,请重试', '网络错误', '🌐'));
|
||
},
|
||
icon
|
||
);
|
||
}
|
||
</script>
|
||
|
||
<script>
|
||
/**
|
||
* 加载各游戏实时统计摘要并渲染到顶部面板
|
||
*/
|
||
function loadGameStats() {
|
||
const panel = document.getElementById('game-stats-panel');
|
||
const grid = document.getElementById('game-stats-grid');
|
||
|
||
grid.innerHTML = '<div class="col-span-5 text-center text-gray-400 text-sm py-4">⏳ 加载中...</div>';
|
||
panel.classList.remove('hidden');
|
||
|
||
fetch('{{ route('admin.game-history.stats') }}', {
|
||
headers: {
|
||
'Accept': 'application/json'
|
||
}
|
||
})
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
const cards = [{
|
||
icon: '🎲',
|
||
title: '百家乐',
|
||
items: [{
|
||
label: '总局数',
|
||
value: data.baccarat.total_rounds.toLocaleString()
|
||
},
|
||
{
|
||
label: '总下注',
|
||
value: data.baccarat.total_bets.toLocaleString() + ' 笔'
|
||
},
|
||
{
|
||
label: '今日局数',
|
||
value: data.baccarat.today_rounds.toLocaleString()
|
||
},
|
||
],
|
||
color: 'border-red-200 bg-red-50',
|
||
},
|
||
{
|
||
icon: '🎰',
|
||
title: '老虎机',
|
||
items: [{
|
||
label: '总转动',
|
||
value: data.slot.total_spins.toLocaleString() + ' 次'
|
||
},
|
||
{
|
||
label: '三7大奖',
|
||
value: data.slot.jackpot_count.toLocaleString() + ' 次'
|
||
},
|
||
{
|
||
label: '今日转动',
|
||
value: data.slot.today_spins.toLocaleString()
|
||
},
|
||
],
|
||
color: 'border-amber-200 bg-amber-50',
|
||
},
|
||
{
|
||
icon: '🐎',
|
||
title: '赛马竞猜',
|
||
items: [{
|
||
label: '总场次',
|
||
value: data.horse.total_races.toLocaleString()
|
||
},
|
||
{
|
||
label: '总注池',
|
||
value: data.horse.total_pool.toLocaleString() + ' 金'
|
||
},
|
||
{
|
||
label: '今日场次',
|
||
value: data.horse.today_races.toLocaleString()
|
||
},
|
||
],
|
||
color: 'border-emerald-200 bg-emerald-50',
|
||
},
|
||
{
|
||
icon: '📦',
|
||
title: '神秘箱子',
|
||
items: [{
|
||
label: '总投放',
|
||
value: data.mystery_box.total_dropped.toLocaleString()
|
||
},
|
||
{
|
||
label: '已领取',
|
||
value: data.mystery_box.total_claimed.toLocaleString()
|
||
},
|
||
{
|
||
label: '今日投放',
|
||
value: data.mystery_box.today_dropped.toLocaleString()
|
||
},
|
||
],
|
||
color: 'border-purple-200 bg-purple-50',
|
||
},
|
||
{
|
||
icon: '🔮',
|
||
title: '神秘占卜',
|
||
items: [{
|
||
label: '总占卜',
|
||
value: data.fortune.total_times.toLocaleString() + ' 次'
|
||
},
|
||
{
|
||
label: '上上签',
|
||
value: data.fortune.jackpot_count.toLocaleString()
|
||
},
|
||
{
|
||
label: '今日次数',
|
||
value: data.fortune.today_times.toLocaleString()
|
||
},
|
||
],
|
||
color: 'border-indigo-200 bg-indigo-50',
|
||
},
|
||
];
|
||
|
||
grid.innerHTML = cards.map(card => `
|
||
<div class="bg-white rounded-xl shadow-sm border ${card.color} p-4">
|
||
<div class="flex items-center gap-2 mb-3">
|
||
<span class="text-xl">${card.icon}</span>
|
||
<span class="font-bold text-gray-700 text-sm">${card.title}</span>
|
||
</div>
|
||
<div class="space-y-1.5">
|
||
${card.items.map(item => `
|
||
<div class="flex justify-between text-xs">
|
||
<span class="text-gray-500">${item.label}</span>
|
||
<span class="font-bold text-gray-700">${item.value}</span>
|
||
</div>
|
||
`).join('')}
|
||
</div>
|
||
</div>
|
||
`).join('');
|
||
})
|
||
.catch(() => {
|
||
grid.innerHTML = '<div class="col-span-5 text-center text-red-400 text-sm py-4">❌ 加载失败,请重试</div>';
|
||
});
|
||
}
|
||
</script>
|
||
@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],
|
||
'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],
|
||
],
|
||
default => [],
|
||
};
|
||
}
|
||
@endphp
|