From 540793c1522ad3eeb2c9433fd6be7f7c2d978965 Mon Sep 17 00:00:00 2001 From: lkddi Date: Fri, 3 Apr 2026 10:50:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=9C=8B=E8=A7=86=E9=A2=91=E5=A5=96?= =?UTF-8?q?=E5=8A=B1=E6=94=B9=E7=94=A8=20UserCurrencyService=20=E5=86=99?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=8C=E6=96=B0=E5=A2=9E=20VIDEO=5FREWARD?= =?UTF-8?q?=20=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Enums/CurrencySource.php | 4 ++ app/Http/Controllers/EarnController.php | 49 +++++++++++++------------ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/app/Enums/CurrencySource.php b/app/Enums/CurrencySource.php index f6d88b3..8bf92a6 100644 --- a/app/Enums/CurrencySource.php +++ b/app/Enums/CurrencySource.php @@ -132,6 +132,9 @@ enum CurrencySource: string /** 五子棋 PvE 入场费返还(平局时返还) */ case GOMOKU_REFUND = 'gomoku_refund'; + /** 看视频赚金币与经验奖励 */ + case VIDEO_REWARD = 'video_reward'; + /** * 返回该来源的中文名称,用于后台统计展示。 */ @@ -175,6 +178,7 @@ enum CurrencySource: string self::GOMOKU_ENTRY_FEE => '五子棋入场费', self::GOMOKU_WIN => '五子棋获胜奖励', self::GOMOKU_REFUND => '五子棋入场费返还', + self::VIDEO_REWARD => '看视频奖励', }; } } diff --git a/app/Http/Controllers/EarnController.php b/app/Http/Controllers/EarnController.php index 5b368d4..e638451 100644 --- a/app/Http/Controllers/EarnController.php +++ b/app/Http/Controllers/EarnController.php @@ -2,8 +2,11 @@ namespace App\Http\Controllers; -use App\Models\LevelCache; +use App\Enums\CurrencySource; +use App\Events\MessageSent; use App\Models\User; +use App\Services\ChatStateService; +use App\Services\UserCurrencyService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -19,7 +22,8 @@ use Illuminate\Support\Facades\Redis; class EarnController extends Controller { public function __construct( - private readonly \App\Services\ChatStateService $chatState + private readonly ChatStateService $chatState, + private readonly UserCurrencyService $currencyService, ) {} /** @@ -65,36 +69,35 @@ class EarnController extends Controller ]); } - // 3. 开始发放奖励并增加次数 - // 增量前可能需要锁机制,但简单的 incr 在并发也不容易超量很多,且有限流 + // 3. 增加今日次数计数 $newCount = Redis::incr($dailyCountKey); - - // 设置每日次数键在同一天结束时过期,留一点余量 if ($newCount === 1) { Redis::expire($dailyCountKey, 86400 * 2); } - // 配置:单次 5000 金币,500 经验 + // 4. 配置:单次 5000 金币,500 经验 $rewardCoins = 5000; $rewardExp = 500; + $roomId = (int) $request->input('room_id', 0); - $user->increment('jjb', $rewardCoins); - $user->increment('exp_num', $rewardExp); - $user->refresh(); // 刷新模型以获取 increment 后的最新字段值 + // 参照钓鱼逻辑:通过 UserCurrencyService 写日志并变更金币/经验 + $this->currencyService->change( + $user, 'gold', $rewardCoins, CurrencySource::VIDEO_REWARD, + "看视频赚取金币(第{$newCount}次)", $roomId, + ); - // 设置冷却时间 + $this->currencyService->change( + $user, 'exp', $rewardExp, CurrencySource::VIDEO_REWARD, + "看视频赚取经验(第{$newCount}次)", $roomId, + ); + + // 刷新模型以获取 service 原子更新后的最新字段值 + $user->refresh(); + + // 5. 设置冷却时间 Redis::setex($cooldownKey, $this->cooldownSeconds, 1); - // 4. 检查是否升级 - $levelUp = false; - $newLevelName = ''; - - // 我们利用现有的 levelCache 或者根据 exp_num 和当前 user_level 判断 - // 因为这是一个常见的游戏房逻辑,通常判断用户当前经验是否大于下一级的经验要求 - // 简化起见,如果需要严格触发升级系统,可参考已有的升华逻辑。 - // (在此处简化为:只要给了经验,前端自然显示就好。部分框架逻辑可能不需要在此检查升降,而是下一次进入发言时自动算) - - $roomId = (int) $request->input('room_id', 0); + // 6. 广播全服系统消息 if ($roomId > 0) { $promoTag = ' $user->jjb, // refresh 后的真实值 + 'new_jjb' => $user->jjb, 'level_up' => false, 'new_level_name' => '', ]);