feat: 看视频奖励改用 UserCurrencyService 写日志,新增 VIDEO_REWARD 枚举
This commit is contained in:
@@ -132,6 +132,9 @@ enum CurrencySource: string
|
|||||||
/** 五子棋 PvE 入场费返还(平局时返还) */
|
/** 五子棋 PvE 入场费返还(平局时返还) */
|
||||||
case GOMOKU_REFUND = 'gomoku_refund';
|
case GOMOKU_REFUND = 'gomoku_refund';
|
||||||
|
|
||||||
|
/** 看视频赚金币与经验奖励 */
|
||||||
|
case VIDEO_REWARD = 'video_reward';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回该来源的中文名称,用于后台统计展示。
|
* 返回该来源的中文名称,用于后台统计展示。
|
||||||
*/
|
*/
|
||||||
@@ -175,6 +178,7 @@ enum CurrencySource: string
|
|||||||
self::GOMOKU_ENTRY_FEE => '五子棋入场费',
|
self::GOMOKU_ENTRY_FEE => '五子棋入场费',
|
||||||
self::GOMOKU_WIN => '五子棋获胜奖励',
|
self::GOMOKU_WIN => '五子棋获胜奖励',
|
||||||
self::GOMOKU_REFUND => '五子棋入场费返还',
|
self::GOMOKU_REFUND => '五子棋入场费返还',
|
||||||
|
self::VIDEO_REWARD => '看视频奖励',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\LevelCache;
|
use App\Enums\CurrencySource;
|
||||||
|
use App\Events\MessageSent;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Services\ChatStateService;
|
||||||
|
use App\Services\UserCurrencyService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -19,7 +22,8 @@ use Illuminate\Support\Facades\Redis;
|
|||||||
class EarnController extends Controller
|
class EarnController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(
|
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. 开始发放奖励并增加次数
|
// 3. 增加今日次数计数
|
||||||
// 增量前可能需要锁机制,但简单的 incr 在并发也不容易超量很多,且有限流
|
|
||||||
$newCount = Redis::incr($dailyCountKey);
|
$newCount = Redis::incr($dailyCountKey);
|
||||||
|
|
||||||
// 设置每日次数键在同一天结束时过期,留一点余量
|
|
||||||
if ($newCount === 1) {
|
if ($newCount === 1) {
|
||||||
Redis::expire($dailyCountKey, 86400 * 2);
|
Redis::expire($dailyCountKey, 86400 * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 配置:单次 5000 金币,500 经验
|
// 4. 配置:单次 5000 金币,500 经验
|
||||||
$rewardCoins = 5000;
|
$rewardCoins = 5000;
|
||||||
$rewardExp = 500;
|
$rewardExp = 500;
|
||||||
|
$roomId = (int) $request->input('room_id', 0);
|
||||||
|
|
||||||
$user->increment('jjb', $rewardCoins);
|
// 参照钓鱼逻辑:通过 UserCurrencyService 写日志并变更金币/经验
|
||||||
$user->increment('exp_num', $rewardExp);
|
$this->currencyService->change(
|
||||||
$user->refresh(); // 刷新模型以获取 increment 后的最新字段值
|
$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);
|
Redis::setex($cooldownKey, $this->cooldownSeconds, 1);
|
||||||
|
|
||||||
// 4. 检查是否升级
|
// 6. 广播全服系统消息
|
||||||
$levelUp = false;
|
|
||||||
$newLevelName = '';
|
|
||||||
|
|
||||||
// 我们利用现有的 levelCache 或者根据 exp_num 和当前 user_level 判断
|
|
||||||
// 因为这是一个常见的游戏房逻辑,通常判断用户当前经验是否大于下一级的经验要求
|
|
||||||
// 简化起见,如果需要严格触发升级系统,可参考已有的升华逻辑。
|
|
||||||
// (在此处简化为:只要给了经验,前端自然显示就好。部分框架逻辑可能不需要在此检查升降,而是下一次进入发言时自动算)
|
|
||||||
|
|
||||||
$roomId = (int) $request->input('room_id', 0);
|
|
||||||
if ($roomId > 0) {
|
if ($roomId > 0) {
|
||||||
$promoTag = ' <span onclick="window.dispatchEvent(new CustomEvent(\'open-earn-panel\'))" '
|
$promoTag = ' <span onclick="window.dispatchEvent(new CustomEvent(\'open-earn-panel\'))" '
|
||||||
.'style="display:inline-block;margin-left:6px;padding:1px 7px;background:#e9e4f5;'
|
.'style="display:inline-block;margin-left:6px;padding:1px 7px;background:#e9e4f5;'
|
||||||
@@ -114,7 +117,7 @@ class EarnController extends Controller
|
|||||||
];
|
];
|
||||||
|
|
||||||
$this->chatState->pushMessage($roomId, $sysMsg);
|
$this->chatState->pushMessage($roomId, $sysMsg);
|
||||||
broadcast(new \App\Events\MessageSent($roomId, $sysMsg));
|
broadcast(new MessageSent($roomId, $sysMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
$remainingToday = $this->maxDailyLimit - $newCount;
|
$remainingToday = $this->maxDailyLimit - $newCount;
|
||||||
@@ -122,7 +125,7 @@ class EarnController extends Controller
|
|||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => true,
|
'success' => true,
|
||||||
'message' => "观看完毕!获得 {$rewardCoins} 金币 + {$rewardExp} 经验。今日还可观看 {$remainingToday} 次。",
|
'message' => "观看完毕!获得 {$rewardCoins} 金币 + {$rewardExp} 经验。今日还可观看 {$remainingToday} 次。",
|
||||||
'new_jjb' => $user->jjb, // refresh 后的真实值
|
'new_jjb' => $user->jjb,
|
||||||
'level_up' => false,
|
'level_up' => false,
|
||||||
'new_level_name' => '',
|
'new_level_name' => '',
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user