'boolean', 'cost' => 'integer', 'fortune_date' => 'date', ]; } /** * 占卜用户关联。 */ public function user(): BelongsTo { return $this->belongsTo(User::class); } /** * 查询指定用户今日占卜次数。 */ public static function todayCount(int $userId): int { return static::query() ->where('user_id', $userId) ->where('fortune_date', today()) ->count(); } /** * 查询指定用户今日最新一条占卜记录。 */ public static function todayLatest(int $userId): ?static { return static::query() ->where('user_id', $userId) ->where('fortune_date', today()) ->latest() ->first(); } /** * 根据概率配置随机抽取一个签文等级。 * * @param array $config 游戏配置参数 * @return string 签文等级:jackpot | good | normal | bad | curse */ public static function rollGrade(array $config): string { $jackpotChance = (int) ($config['jackpot_chance'] ?? 5); $goodChance = (int) ($config['good_chance'] ?? 20); $badChance = (int) ($config['bad_chance'] ?? 20); $curseChance = (int) ($config['curse_chance'] ?? 5); // normal 占剩余概率 $normalChance = max(0, 100 - $jackpotChance - $goodChance - $badChance - $curseChance); $rand = random_int(1, 100); return match (true) { $rand <= $jackpotChance => 'jackpot', $rand <= $jackpotChance + $goodChance => 'good', $rand <= $jackpotChance + $goodChance + $normalChance => 'normal', $rand <= $jackpotChance + $goodChance + $normalChance + $badChance => 'bad', default => 'curse', }; } /** * 根据签文等级随机抽取签文内容。 * * @param string $grade 签文等级 * @return array{text: string, buff_desc: string} 签文文字和加成描述 */ public static function rollFortune(string $grade): array { $library = self::fortuneLibrary(); $pool = $library[$grade] ?? $library['normal']; $entry = $pool[array_rand($pool)]; return $entry; } /** * 签文库:各等级预设签文(共 55 条)。 * * @return array> */ private static function fortuneLibrary(): array { return [ // ─── 上上签(5条)────────────────────────────────────── 'jackpot' => [ ['text' => '龙凤呈祥,万事皆宜。天降鸿运,财源广进!', 'buff_desc' => '✨ 今日金币获取 +30%,经验获取 +20%'], ['text' => '紫气东来,鸿运当头。凡事顺遂,财运亨通!', 'buff_desc' => '✨ 今日金币获取 +30%,魅力增长 +50%'], ['text' => '吉星高照,百事大吉。此乃天赐良机,把握之!', 'buff_desc' => '✨ 今日全属性获取 +25%'], ['text' => '神明庇佑,万难消散。今日出行,无往不利!', 'buff_desc' => '✨ 今日金币获取 +40%'], ['text' => '天时地利人和,三才俱备。大展宏图,正此时也!', 'buff_desc' => '✨ 今日经验获取 +50%,金币 +20%'], ], // ─── 上签(10条)────────────────────────────────────── 'good' => [ ['text' => '春风得意马蹄疾,一日看尽长安花。好运正来,进取可得!', 'buff_desc' => '🌸 今日金币获取 +15%'], ['text' => '风调雨顺,五谷丰登。诸事顺利,喜事临门。', 'buff_desc' => '🌸 今日经验获取 +20%'], ['text' => '柳暗花明又一村,峰回路转现坦途。坚持便是胜利!', 'buff_desc' => '🌸 今日金币及经验各 +10%'], ['text' => '心想事成,万事如意。凡有所求,皆可如愿。', 'buff_desc' => '🌸 今日金币获取 +15%'], ['text' => '鱼跃龙门,一步登天。今日努力,事半功倍!', 'buff_desc' => '🌸 今日经验获取 +25%'], ['text' => '花好月圆,良辰美景。诸事大吉,百福临门。', 'buff_desc' => '🌸 今日魅力增长 +30%'], ['text' => '云开雾散见朝阳,前路光明万里长。好运常伴,前途无量!', 'buff_desc' => '🌸 今日金币获取 +20%'], ['text' => '锦上添花,好事成双。今日诸事皆宜,勇往直前!', 'buff_desc' => '🌸 今日全属性 +10%'], ['text' => '马到成功,旗开得胜。积极行动,收获满满!', 'buff_desc' => '🌸 今日经验获取 +15%'], ['text' => '福星高照,喜气洋洋。和气生财,贵人相助!', 'buff_desc' => '🌸 今日金币 +18%,魅力 +20%'], ], // ─── 中签(20条)────────────────────────────────────── 'normal' => [ ['text' => '守株待兔不如主动出击,时机稍纵即逝,把握当下。', 'buff_desc' => null], ['text' => '平平淡淡才是真,安分守己自太平。此乃中签,宜静不宜动。', 'buff_desc' => null], ['text' => '水至清则无鱼,人至察则无徒。凡事保持平常心。', 'buff_desc' => null], ['text' => '船到桥头自然直,车到山前必有路。莫要忧虑,顺其自然。', 'buff_desc' => null], ['text' => '路漫漫其修远兮,吾将上下而求索。持之以恒,终见曙光。', 'buff_desc' => null], ['text' => '千里之行,始于足下。今日无大凶无大吉,稳中求进。', 'buff_desc' => null], ['text' => '谋事在人,成事在天。尽力而为,其余顺其自然。', 'buff_desc' => null], ['text' => '不以物喜,不以己悲。心态平和,自有一番天地。', 'buff_desc' => null], ['text' => '厚积薄发,积柔成刚。今日蓄力,来日爆发。', 'buff_desc' => null], ['text' => '勤能补拙,笨鸟先飞。平庸亦可,持续努力方为上策。', 'buff_desc' => null], ['text' => '事无大小,做好眼前即是。此签平稳,无风雨亦无彩虹。', 'buff_desc' => null], ['text' => '知足者常乐,贪多者多失。今日知足,便是福气。', 'buff_desc' => null], ['text' => '中庸之道,乃处世良方。不争不抢,随缘自在。', 'buff_desc' => null], ['text' => '晴天要备雨伞,好时要留余地。居安思危,防患未然。', 'buff_desc' => null], ['text' => '静水流深,沉默有力。今日低调行事,暗中蓄势。', 'buff_desc' => null], ['text' => '月有阴晴圆缺,人有悲欢离合。此乃常态,坦然接受。', 'buff_desc' => null], ['text' => '三人行,必有我师。今日宜多学习,少出风头。', 'buff_desc' => null], ['text' => '凡事量力而行,不可强求。今日随缘,顺其自然。', 'buff_desc' => null], ['text' => '忍一时风平浪静,退一步海阔天空。宽容待人,必有回报。', 'buff_desc' => null], ['text' => '心静自然凉,此乃中签之意,平安即是福。', 'buff_desc' => null], ], // ─── 下签(10条)────────────────────────────────────── 'bad' => [ ['text' => '乌云当头,诸事不顺。今日宜静守,切莫轻举妄动。', 'buff_desc' => '😞 今日金币获取 -10%'], ['text' => '时运不济,命途多舛。凡事三思而后行,小心为上。', 'buff_desc' => '😞 今日经验获取 -10%'], ['text' => '逆水行舟,举步维艰。今日诸事宜谨慎,避免重大决策。', 'buff_desc' => '😞 今日金币获取 -10%'], ['text' => '阴云密布,好运暂退。宜韬光养晦,待时机再出。', 'buff_desc' => '😞 今日全属性 -5%'], ['text' => '事与愿违,心力交瘁。今日多加休息,来日再战。', 'buff_desc' => '😞 今日经验获取 -15%'], ['text' => '小人横行,道路坎坷。今日言多必失,祸从口出,慎言!', 'buff_desc' => '😞 今日金币 -10%,魅力 -10%'], ['text' => '财帛散尽,才识运归。今日不宜大额消费,节俭为上。', 'buff_desc' => '😞 今日金币获取 -15%'], ['text' => '阳光总在风雨后,苦尽甘来是常事。今日忍耐,明日可期。', 'buff_desc' => '😞 今日经验获取 -10%'], ['text' => '暗箭难防,处处小心。今日谨慎行事,切勿冒进。', 'buff_desc' => '😞 今日全属性 -8%'], ['text' => '屋漏偏逢连夜雨,行路偏遇顶头风。逆境磨砺,坚持即胜。', 'buff_desc' => '😞 今日金币获取 -12%'], ], // ─── 大凶签(5条)────────────────────────────────────── 'curse' => [ ['text' => '大凶!鬼门大开,诸事皆凶。今日宜闭门避祸,切忌妄动!', 'buff_desc' => '💀 今日金币获取 -25%,经验 -20%'], ['text' => '凶星临头,百事皆忌。今日万事不顺,速速祈神化解!', 'buff_desc' => '💀 今日金币获取 -30%'], ['text' => '阴煞临身,大凶兆也!今日诸事皆休,静待天命。', 'buff_desc' => '💀 今日全属性 -20%'], ['text' => '问此签,凶也大凶。如遇困境,切勿强行克服,顺势而为!', 'buff_desc' => '💀 今日经验获取 -30%,金币 -20%'], ['text' => '天机不可泄露,然此签示警。今日三灾八难,小心谨慎,化凶为吉!', 'buff_desc' => '💀 今日金币获取 -25%,魅力 -15%'], ], ]; } /** * 返回签文等级对应的中文名称。 */ public function gradeLabel(): string { return match ($this->grade) { 'jackpot' => '上上签', 'good' => '上签', 'normal' => '中签', 'bad' => '下签', 'curse' => '大凶签', default => '未知', }; } /** * 返回签文等级对应的颜色(前端展示用)。 */ public function gradeColor(): string { return match ($this->grade) { 'jackpot' => '#f59e0b', // 金色 'good' => '#10b981', // 翠绿 'normal' => '#6b7280', // 灰色 'bad' => '#f97316', // 橙色 'curse' => '#ef4444', // 红色 default => '#6b7280', }; } }