refactor(idiom): 将游戏配置和题库移到 IdiomSeeder,迁移只建表

This commit is contained in:
pllx
2026-04-29 00:10:01 +08:00
parent f13cfe4bc1
commit 9bc085cb7d
3 changed files with 162 additions and 30 deletions
+17 -8
View File
@@ -170,17 +170,26 @@ class GameConfigSeeder extends Seeder
],
],
// ─── 猜成语 ───────────────────────────────────────────────
// ─── 五子棋 ───────────────────────────────────────────────
[
'game_key' => 'idiom',
'name' => '猜成语',
'icon' => '🧩',
'description' => '管理员手动出题或系统定时自动出题,用户抢答成语,第一个答对的获得金币和经验奖励。',
'game_key' => 'gomoku',
'name' => '五子棋',
'icon' => '♟️',
'description' => 'PvP 对战/人机对战,房间内随时发起邀请,超时或认输均自动结算。',
'enabled' => false,
'params' => [
'reward_gold' => 50, // 答对奖励金币
'reward_exp' => 30, // 答对奖励经验
'auto_start_interval' => 0, // 自动出题间隔(分钟,0=手动
'pvp_reward' => 200, // PvP 胜利奖励金币
'pvp_invite_timeout' => 30, // PvP 邀请超时(秒)
'pvp_move_timeout' => 45, // 每步落子超时(秒
'pvp_ready_timeout' => 20, // 对局准备超时(秒)
'pve_fee_level_1' => 50, // AI简单 入场费
'pve_reward_level_1' => 100, // AI简单 胜利奖励
'pve_fee_level_2' => 100, // AI普通 入场费
'pve_reward_level_2' => 200, // AI普通 胜利奖励
'pve_fee_level_3' => 200, // AI困难 入场费
'pve_reward_level_3' => 400, // AI困难 胜利奖励
'pve_fee_level_4' => 500, // AI专家 入场费
'pve_reward_level_4' => 1000, // AI专家 胜利奖励
],
],
];
+141 -12
View File
@@ -1,30 +1,159 @@
<?php
/**
* 猜成语题库导入脚本
* storage/data/idioms.php 导入初始数据
* 文件功能:猜成语题库填充器
*
* 初始化游戏配置和成语题库数据。
* 使用 updateOrCreate 确保重复执行不影响已有数据。
*
* @author ChatRoom Laravel
* @version 1.0.0
*/
namespace Database\Seeders;
use App\Models\GameConfig;
use App\Models\Idiom;
use Illuminate\Database\Seeder;
class IdiomSeeder extends Seeder
{
/**
* 填充猜成语游戏配置和题库。
*/
public function run(): void
{
$idioms = require storage_path('data/idioms.php');
// ── 游戏配置(已存在则跳过) ──
GameConfig::updateOrCreate(
['game_key' => 'idiom'],
[
'name' => '猜成语',
'icon' => '🧩',
'description' => '管理员手动出题或系统定时自动出题,用户抢答成语,第一个答对的获得金币和经验奖励。',
'enabled' => false,
'params' => [
'reward_gold' => 50,
'reward_exp' => 30,
'auto_start_interval' => 0,
],
],
);
foreach ($idioms as $i => $item) {
Idiom::create([
'answer' => $item['answer'],
'hint' => $item['hint'],
'is_active' => true,
'sort' => $i,
]);
// ── 题库数据 ──
$idioms = [
['answer' => '画蛇添足', 'hint' => '🧩 四人比赛画蛇,最慢的那个反而多此一举。猜一成语'],
['answer' => '守株待兔', 'hint' => '🧩 农夫不干活,天天蹲树桩旁等天上掉馅饼。猜一成语'],
['answer' => '掩耳盗铃', 'hint' => '🧩 小偷以为捂住自己耳朵,别人就听不见铃铛响了。猜一成语'],
['answer' => '亡羊补牢', 'hint' => '🧩 羊圈破了个洞,羊跑了几只才想起修。猜一成语'],
['answer' => '刻舟求剑', 'hint' => '🧩 船上做了个记号就能在江里找回剑?猜一成语'],
['answer' => '叶公好龙', 'hint' => '🧩 家里到处画龙雕龙,真龙来了却吓得屁滚尿流。猜一成语'],
['answer' => '狐假虎威', 'hint' => '🧩 狐狸走在老虎前面,小动物们到底怕谁?猜一成语'],
['answer' => '井底之蛙', 'hint' => '🧩 住在井里,却以为天空只有井口那么大。猜一成语'],
['answer' => '对牛弹琴', 'hint' => '🧩 弹了一首好曲子,听众却在低头吃草。猜一成语'],
['answer' => '杯弓蛇影', 'hint' => '🧩 酒杯里有个弯弯曲曲的东西在动,吓得大病一场。猜一成语'],
['answer' => '鹤立鸡群', 'hint' => '🧩 一只长腿白鸟混进了院子里的小黄鸡中。猜一成语'],
['answer' => '画龙点睛', 'hint' => '🧩 最后两笔点上后,墙上的龙竟然飞走了。猜一成语'],
['answer' => '鸡飞蛋打', 'hint' => '🧩 偷鸡不成,竹篮打水一场空。猜一成语'],
['answer' => '马到成功', 'hint' => '🧩 战旗一挥,马蹄刚踏出去就赢了。猜一成语'],
['answer' => '虎头蛇尾', 'hint' => '🧩 开头气势如虹,结尾却草草收场。猜一成语'],
['answer' => '龙飞凤舞', 'hint' => '🧩 王羲之喝醉了,笔下的字好像要飞起来。猜一成语'],
['answer' => '鸡犬不宁', 'hint' => '🧩 闹得天翻地覆,连院子里的小动物都不得安生。猜一成语'],
['answer' => '狼吞虎咽', 'hint' => '🧩 饿了三天的壮汉看到一碗面。猜一成语'],
['answer' => '鱼目混珠', 'hint' => '🧩 地摊上有人拿玻璃球当夜明珠卖。猜一成语'],
['answer' => '鼠目寸光', 'hint' => '🧩 只看得到眼前一寸的路,走远就迷路。猜一成语'],
['answer' => '九牛一毛', 'hint' => '🧩 亿万富翁丢了一分钱,连弯腰捡都懒得捡。猜一成语'],
['answer' => '如鱼得水', 'hint' => '🧩 刘备说:有了诸葛亮,就像什么回到了什么里?猜一成语'],
['answer' => '鸟语花香', 'hint' => '🧩 春天来了,你能听到什么、闻到什么?猜一成语'],
['answer' => '风花雪月', 'hint' => '🧩 才子佳人写的诗,看起来很美,其实没什么实际内容。猜一成语'],
['answer' => '山清水秀', 'hint' => '🧩 桂林漓江边上,你能看到什么颜色?猜一成语'],
['answer' => '水落石出', 'hint' => '🧩 水位下降后,河床下的东西藏不住了。猜一成语'],
['answer' => '火中取栗', 'hint' => '🧩 猫爪子被烫伤了,猴子却在旁边偷笑吃栗子。猜一成语'],
['answer' => '石破天惊', 'hint' => '🧩 一块石头裂开,伴随着一声巨响,所有人都惊呆了。猜一成语'],
['answer' => '翻天覆地', 'hint' => '🧩 孙悟空大闹天宫后,凌霄宝殿变成了什么样?猜一成语'],
['answer' => '开天辟地', 'hint' => '🧩 盘古拿着斧头,对着混沌用力一劈。猜一成语'],
['answer' => '惊天动地', 'hint' => '🧩 汶川大地震那天,连天上的云都在颤抖。猜一成语'],
['answer' => '花好月圆', 'hint' => '🧩 婚礼请柬上最常见的四个字祝福。猜一成语'],
['answer' => '冰清玉洁', 'hint' => '🧩 她的品格像冬天的什么和深山里的什么?猜一成语'],
['answer' => '海阔天空', 'hint' => '🧩 走出小县城,来到大都市,才发现世界有多大。猜一成语'],
['answer' => '雪中送炭', 'hint' => '🧩 大冬天你最需要什么?有人偏偏就送来了什么。猜一成语'],
['answer' => '锦上添花', 'hint' => '🧩 已经够漂亮了,还要再点缀一下。猜一成语'],
['answer' => '落井下石', 'hint' => '🧩 有人掉坑里了,你不救也就算了,还往下面扔砖头。猜一成语'],
['answer' => '纸上谈兵', 'hint' => '🧩 赵括说起兵法头头是道,上了战场却一败涂地。猜一成语'],
['answer' => '胸有成竹', 'hint' => '🧩 画家文同还没下笔,心里已经有了完整的竹子。猜一成语'],
['answer' => '一帆风顺', 'hint' => '🧩 出海前最想听到的一句祝福。猜一成语'],
['answer' => '水到渠成', 'hint' => '🧩 不用刻意挖渠,水自然会找到它的路。猜一成语'],
['answer' => '百发百中', 'hint' => '🧩 养由基站在百步之外射柳叶,箭无虚发。猜一成语'],
['answer' => '一鸣惊人', 'hint' => '🧩 齐威王三年不上朝不理政,一出手就震惊了各国。猜一成语'],
['answer' => '对答如流', 'hint' => '🧩 老师提问,他不用思考就说出答案,像江水一样不停。猜一成语'],
['answer' => '顺手牵羊', 'hint' => '🧩 路过别人家门口,看到一只羊没人看管……猜一成语'],
['answer' => '勇往直前', 'hint' => '🧩 前面是刀山火海,他眼睛都不眨一下继续走。猜一成语'],
['answer' => '百折不挠', 'hint' => '🧩 被摔倒一百次,第一百零一次依然站起来。猜一成语'],
['answer' => '持之以恒', 'hint' => '🧩 水滴不断地滴在石头上,千年后石头被滴穿了。猜一成语'],
['answer' => '知己知彼', 'hint' => '🧩 孙子兵法说:了解自己又了解对方,百战不殆。猜一成语'],
['answer' => '四面楚歌', 'hint' => '🧩 项羽被包围在垓下,四面八方都传来熟悉的歌声。猜一成语'],
['answer' => '草木皆兵', 'hint' => '🧩 淝水之战中,苻坚看到山上的草和树,都以为是敌军。猜一成语'],
['answer' => '一箭双雕', 'hint' => '🧩 长孙晟一箭射出去,两只大鸟应声落地。猜一成语'],
['answer' => '背水一战', 'hint' => '🧩 韩信把军队放在河边列阵,断了所有人的退路。猜一成语'],
['answer' => '声东击西', 'hint' => '🧩 明明要打左边,却装作全力进攻右边。猜一成语'],
['answer' => '调虎离山', 'hint' => '🧩 想占老虎的老窝,得先把老虎引出去。猜一成语'],
['answer' => '空城计', 'hint' => '🧩 诸葛亮大开城门,在城楼上弹琴,敌军反而不敢进城。猜一成语'],
['answer' => '缓兵之计', 'hint' => '🧩 打不过怎么办?先假装谈判争取时间。猜一成语'],
['answer' => '卧薪尝胆', 'hint' => '🧩 越王勾践每天睡在柴堆上,还要舔一口苦胆。猜一成语'],
['answer' => '三顾茅庐', 'hint' => '🧩 刘备为了请一个人出山,大冬天跑了三趟。猜一成语'],
['answer' => '望梅止渴', 'hint' => '🧩 曹操说前面有片梅林,士兵们嘴里都开始流口水了。猜一成语'],
['answer' => '七步成诗', 'hint' => '🧩 曹植被亲哥哥逼着在很短的时间里写诗保命。猜一成语'],
['answer' => '才高八斗', 'hint' => '🧩 谢灵运说:天下才华共一石,曹植独占八斗。猜一成语'],
['answer' => '入木三分', 'hint' => '🧩 王羲之在木板上写字,墨迹渗入木头三分深。猜一成语'],
['answer' => '一字千金', 'hint' => '🧩 吕不韦悬赏:谁能给《吕氏春秋》改动一个字,赏千金。猜一成语'],
['answer' => '一诺千金', 'hint' => '🧩 季布的一句话,比黄金千两还贵重。猜一成语'],
['answer' => '半途而废', 'hint' => '🧩 走到半山腰觉得累了,就转身下山了。猜一成语'],
['answer' => '实事求是', 'hint' => '🧩 不夸大不缩小,是什么就是什么。猜一成语'],
['answer' => '量力而行', 'hint' => '🧩 蚂蚁想搬走大象?先掂量掂量自己有几斤几两。猜一成语'],
['answer' => '自相矛盾', 'hint' => '🧩 楚国人夸自己的矛能刺穿任何盾,又夸自己的盾什么都刺不穿。猜一成语'],
['answer' => '买椟还珠', 'hint' => '🧩 花大价钱买了精美盒子,却把里面的珍珠还给了老板。猜一成语'],
['answer' => '杞人忧天', 'hint' => '🧩 有个怪人天天担心天会塌下来,地会陷下去。猜一成语'],
['answer' => '画饼充饥', 'hint' => '🧩 饿了看着墙上画的大饼,假装自己吃饱了。猜一成语'],
['answer' => '空中楼阁', 'hint' => '🧩 没有地基,没有支柱,一座房子浮在云端。猜一成语'],
['answer' => '异想天开', 'hint' => '🧩 有人想在天上种田,海里摘星星。猜一成语'],
['answer' => '千方百计', 'hint' => '🧩 为了达到目的,把所有能想到的办法都用上了。猜一成语'],
['answer' => '不计其数', 'hint' => '🧩 海边的沙子有多少?天上的星星有多少?猜一成语'],
['answer' => '成千上万', 'hint' => '🧩 体育场里坐满了人,放眼望去黑压压一片。猜一成语'],
['answer' => '独一无二', 'hint' => '🧩 世界上没有第二个一模一样的你。猜一成语'],
['answer' => '举世闻名', 'hint' => '🧩 地球上有几个人,就有几个人知道他。猜一成语'],
['answer' => '名不虚传', 'hint' => '🧩 听说很好吃,亲自尝了一口,果然名不虚传。不对,我说的就是~猜一成语'],
['answer' => '名副其实', 'hint' => '🧩 大家都叫他「神算子」,他算卦确实从没错过。猜一成语'],
['answer' => '引人入胜', 'hint' => '🧩 这本书太好看了,一翻开就停不下来,像被吸进去了一样。猜一成语'],
['answer' => '身临其境', 'hint' => '🧩 VR眼镜里的世界太真实了,好像自己真的在里面。猜一成语'],
['answer' => '迫不及待', 'hint' => '🧩 快递到了,鞋都没穿就跑下楼去拿。猜一成语'],
['answer' => '争先恐后', 'hint' => '🧩 超市大减价,大门一开所有人都在往前冲。猜一成语'],
['answer' => '如履薄冰', 'hint' => '🧩 每一步都小心翼翼,生怕脚下突然裂开。猜一成语'],
['answer' => '小心翼翼', 'hint' => '🧩 手里捧着一个装满水的气球,大气都不敢喘。猜一成语'],
['answer' => '心花怒放', 'hint' => '🧩 听到被录取的消息,心里像有千万朵花同时绽放。猜一成语'],
['answer' => '欢天喜地', 'hint' => '🧩 过年了,小孩拿到压岁钱在大街上又蹦又跳。猜一成语'],
['answer' => '眉开眼笑', 'hint' => '🧩 嘴角上扬,眼角弯弯,整张脸都在表达开心。猜一成语'],
['answer' => '手舞足蹈', 'hint' => '🧩 听到最喜欢的歌,身体不由自主地跟着节奏动起来。猜一成语'],
['answer' => '兴高采烈', 'hint' => '🧩 中彩票后,他整个人像打了鸡血一样。猜一成语'],
['answer' => '得意忘形', 'hint' => '🧩 考了第一名就开始翘尾巴,连走路姿势都不一样了。猜一成语'],
['answer' => '怒气冲天', 'hint' => '🧩 他气得头顶冒烟,火焰快要烧到天花板了。猜一成语'],
['answer' => '火冒三丈', 'hint' => '🧩 听到这个消息,他脑袋上的火苗蹿得比房子还高。猜一成语'],
['answer' => '心急如焚', 'hint' => '🧩 等结果的那几分钟,心脏像放在火上烤。猜一成语'],
['answer' => '愁眉苦脸', 'hint' => '🧩 眉头拧成麻花,嘴角向下弯,整张脸写满了不开心。猜一成语'],
['answer' => '泪如雨下', 'hint' => '🧩 他哭得比外面的倾盆大雨还要猛。猜一成语'],
['answer' => '目瞪口呆', 'hint' => '🧩 看到 UFO 从头顶飞过,他张大了嘴巴一句话也说不出来。猜一成语'],
['answer' => '惊弓之鸟', 'hint' => '🧩 被弓箭射过一次的鸟,听到弓弦声就吓得乱飞。猜一成语'],
['answer' => '千钧一发', 'hint' => '🧩 一万斤的重物吊在一根头发丝上,随时会断。猜一成语'],
['answer' => '愚公移山', 'hint' => '🧩 九十岁老头发誓要搬走门口的两座大山,子子孙孙无穷匮也。猜一成语'],
];
foreach ($idioms as $idiom) {
Idiom::updateOrCreate(
['answer' => $idiom['answer']],
[
'hint' => $idiom['hint'],
'is_active' => true,
'sort' => 0,
],
);
}
$this->command->info('已导入 '.count($idioms).' 条成语题目。');
}
}
+4 -10
View File
@@ -49,7 +49,7 @@ function handleIdiomGameAnswered(e) {
const div = document.createElement("div");
div.className = "msg-line";
div.innerHTML = `<span style="color:#16a34a;font-weight:bold;">🎉 恭喜 <b data-idiom-winner="${winner_username}" style="cursor:pointer;border-bottom:1px dashed #16a34a;" title="点击查看资料">${winner_username}</b> 率先答对成语「${answer}」,获得 ${reward_gold} 金币、${reward_exp} 经验!</span><span class="msg-time">(${timeStr})</span>`;
div.innerHTML = `<span style="color:#16a34a;font-weight:bold;">🎉 恭喜 <span class="msg-user" data-chat-message-user data-u="${winner_username}" style="color:#16a34a;cursor:pointer;border-bottom:1px dashed #16a34a;">${winner_username}</span> 率先答对成语「${answer}」,获得 ${reward_gold} 金币、${reward_exp} 经验!</span><span class="msg-time">(${timeStr})</span>`;
const isWinner = winner_username === (window.chatContext?.username || "");
if (isWinner) {
@@ -259,15 +259,9 @@ export function bindIdiomQuizControls() {
}
});
// 猜成语结果消息中的用户名可点击 → 打开用户名片
document.addEventListener("click", (e) => {
const nameEl = e.target.closest("[data-idiom-winner]");
if (!nameEl) return;
const username = nameEl.getAttribute("data-idiom-winner") || "";
if (username && typeof window.openUserCard === "function") {
window.openUserCard(username);
}
});
// ── 猜成语结果消息中的用户名可点击 → 打开用户名片
// 注:单击/双击已由 right-panel.js 的全局 [data-chat-message-user] 事件委托统一处理
}
// ── 挂载到 window ──