feat: 猜成语游戏 - 完整题库、管理后台、答题弹窗
- 创建 idioms 表(102条谜语式成语题库)和 idiom_game_rounds 表 - 后台成语管理页面:增删改题目 + 游戏参数(金币/经验/间隔)内联设置 + 出题按钮 - IdiomQuizController:出题/答题/当前回合查询,Redis 防并发抢答 - IdiomGameStarted / IdiomGameAnswered 广播事件 - 前端答题弹窗模块:聊天消息带【答题】按钮,点击弹出输入框 - GameConfig 注册 idiom 游戏,由 admin.game-configs 统一管理开关
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:猜成语题库后台管理控制器
|
||||
* 提供成语题目的列表展示、创建、编辑、删除、启用/禁用功能
|
||||
*
|
||||
* @author ChatRoom Laravel
|
||||
*
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Idiom;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class IdiomController extends Controller
|
||||
{
|
||||
/**
|
||||
* 显示所有成语题目列表
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
$idioms = Idiom::orderBy('sort')->orderBy('id')->get();
|
||||
|
||||
return view('admin.idioms.index', compact('idioms'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新题目
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$data = $request->validate([
|
||||
'answer' => 'required|string|max:50',
|
||||
'hint' => 'required|string|max:255',
|
||||
'sort' => 'required|integer|min:0',
|
||||
'is_active' => 'boolean',
|
||||
]);
|
||||
|
||||
$data['is_active'] = $request->boolean('is_active', true);
|
||||
Idiom::create($data);
|
||||
|
||||
return redirect()->route('admin.idioms.index')->with('success', '成语题目已添加!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新题目
|
||||
*/
|
||||
public function update(Request $request, Idiom $idiom): RedirectResponse
|
||||
{
|
||||
$data = $request->validate([
|
||||
'answer' => 'required|string|max:50',
|
||||
'hint' => 'required|string|max:255',
|
||||
'sort' => 'required|integer|min:0',
|
||||
'is_active' => 'boolean',
|
||||
]);
|
||||
|
||||
$data['is_active'] = $request->boolean('is_active');
|
||||
$idiom->update($data);
|
||||
|
||||
return redirect()->route('admin.idioms.index')->with('success', "题目「{$idiom->answer}」已更新!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换启用/禁用(AJAX)
|
||||
*/
|
||||
public function toggle(Idiom $idiom): JsonResponse
|
||||
{
|
||||
$idiom->update(['is_active' => ! $idiom->is_active]);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'is_active' => $idiom->is_active,
|
||||
'message' => $idiom->is_active ? "「{$idiom->answer}」已启用" : "「{$idiom->answer}」已禁用",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除题目
|
||||
*/
|
||||
public function destroy(Idiom $idiom): RedirectResponse
|
||||
{
|
||||
$answer = $idiom->answer;
|
||||
$idiom->delete();
|
||||
|
||||
return redirect()->route('admin.idioms.index')->with('success', "题目「{$answer}」已删除!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存猜成语游戏参数(仅更新 GameConfig params,不影响其他字段)
|
||||
*/
|
||||
public function saveSettings(Request $request): RedirectResponse
|
||||
{
|
||||
$data = $request->validate([
|
||||
'reward_gold' => 'required|integer|min:0',
|
||||
'reward_exp' => 'required|integer|min:0',
|
||||
'auto_start_interval' => 'required|integer|min:0',
|
||||
]);
|
||||
|
||||
$config = \App\Models\GameConfig::firstOrCreate(
|
||||
['game_key' => 'idiom'],
|
||||
['name' => '猜成语', 'icon' => '🧩', 'enabled' => false],
|
||||
);
|
||||
|
||||
// 合并现有 params,只覆盖提交的字段,不影响其他已有参数
|
||||
$existingParams = $config->params ?? [];
|
||||
$config->params = array_merge($existingParams, [
|
||||
'reward_gold' => (int) $data['reward_gold'],
|
||||
'reward_exp' => (int) $data['reward_exp'],
|
||||
'auto_start_interval' => (int) $data['auto_start_interval'],
|
||||
]);
|
||||
$config->save();
|
||||
$config->clearCache();
|
||||
|
||||
return redirect()->route('admin.idioms.index')->with('success', '游戏参数已保存!');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user