From 5d0e2a82ffef1d3063bee42568c2ef4ed8cc34d5 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Wed, 4 Mar 2026 15:35:30 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=8E=A5=E5=8F=A3]=E6=96=B0=E5=A2=9E=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=BD=A9=E9=87=91=E6=B1=A0=EF=BC=8C=E8=B4=AD=E4=B9=B0?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E6=AC=A1=E6=95=B0=EF=BC=88=E8=B4=AD=E4=B9=B0?= =?UTF-8?q?=E6=8A=BD=E5=A5=96=E5=88=B8=EF=BC=89=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/app/api/controller/GameController.php | 67 ++++++++++++ server/app/api/logic/GameLogic.php | 101 +++++++++++++++++++ server/config/route.php | 2 + 3 files changed, 170 insertions(+) create mode 100644 server/app/api/controller/GameController.php create mode 100644 server/app/api/logic/GameLogic.php diff --git a/server/app/api/controller/GameController.php b/server/app/api/controller/GameController.php new file mode 100644 index 0000000..7875d50 --- /dev/null +++ b/server/app/api/controller/GameController.php @@ -0,0 +1,67 @@ +header('user-token'); + if (empty($token)) { + $auth = $request->header('authorization'); + if ($auth && stripos($auth, 'Bearer ') === 0) { + $token = trim(substr($auth, 7)); + } + } + if (empty($token)) { + return $this->fail('请携带 user-token'); + } + $userId = UserLogic::getUserIdFromToken($token); + if ($userId === null) { + return $this->fail('user-token 无效或已过期'); + } + + $count = (int) $request->post('count', 0); + if (!in_array($count, [1, 5, 10], true)) { + return $this->fail('购买抽奖券错误'); + } + + try { + $logic = new GameLogic(); + $data = $logic->buyLotteryTickets($userId, $count); + return $this->success($data); + } catch (\plugin\saiadmin\exception\ApiException $e) { + return $this->fail($e->getMessage()); + } + } + + /** + * 获取彩金池(中奖配置表) + * GET /api/game/lotteryPool + * header: auth-token + * 返回 DiceRewardConfig 列表(彩金池/中奖配置) + */ + public function lotteryPool(Request $request): Response + { + $list = DiceRewardConfig::order('id', 'asc')->select()->toArray(); + return $this->success($list); + } +} diff --git a/server/app/api/logic/GameLogic.php b/server/app/api/logic/GameLogic.php new file mode 100644 index 0000000..a9082aa --- /dev/null +++ b/server/app/api/logic/GameLogic.php @@ -0,0 +1,101 @@ + [消耗coin, 购买次数paid, 赠送次数free] + * 仅支持 1、5、10 档 + */ +class GameLogic +{ + public const PACKAGES = [ + 1 => ['coin' => 100, 'paid' => 1, 'free' => 0], // 1次/100coin + 5 => ['coin' => 500, 'paid' => 5, 'free' => 1], // 5张/500coin(5购买+1赠送,共6次) + 10 => ['coin' => 1000, 'paid' => 10, 'free' => 3], // 10张/1000coin(10购买+3赠送,共13次) + ]; + + /** 钱包流水类型:购买抽奖次数 */ + public const WALLET_TYPE_BUY_DRAW = 2; + + /** + * 购买抽奖券 + * @param int $playerId 玩家ID(即 user_id) + * @param int $count 购买档位:1 / 5 / 10 + * @return array 更新后的 coin, total_draw_count, paid_draw_count, free_draw_count + */ + public function buyLotteryTickets(int $playerId, int $count): array + { + if (!isset(self::PACKAGES[$count])) { + throw new ApiException('购买抽奖券错误'); + } + $pack = self::PACKAGES[$count]; + $cost = $pack['coin']; + $addPaid = $pack['paid']; + $addFree = $pack['free']; + $addTotal = $addPaid + $addFree; + + $player = DicePlayer::find($playerId); + if (!$player) { + throw new ApiException('用户不存在'); + } + $coinBefore = (float) $player->coin; + if ($coinBefore < $cost) { + throw new ApiException('平台币不足'); + } + + $coinAfter = $coinBefore - $cost; + $totalBefore = (int) ($player->total_draw_count ?? 0); + $paidBefore = (int) ($player->paid_draw_count ?? 0); + $freeBefore = (int) ($player->free_draw_count ?? 0); + + Db::transaction(function () use ( + $player, + $playerId, + $cost, + $coinBefore, + $coinAfter, + $addTotal, + $addPaid, + $addFree, + $totalBefore, + $paidBefore, + $freeBefore + ) { + $player->coin = $coinAfter; + $player->total_draw_count = $totalBefore + $addTotal; + $player->paid_draw_count = $paidBefore + $addPaid; + $player->free_draw_count = $freeBefore + $addFree; + $player->save(); + + DicePlayerWalletRecord::create([ + 'player_id' => $playerId, + 'coin' => -$cost, + 'type' => self::WALLET_TYPE_BUY_DRAW, + 'wallet_before' => $coinBefore, + 'wallet_after' => $coinAfter, + 'total_draw_count' => $addTotal, + 'paid_draw_count' => $addPaid, + 'free_draw_count' => $addFree, + 'remark' => "购买抽奖券{$addTotal}次(付费{$addPaid}次+赠送{$addFree}次)", + ]); + }); + + $updated = DicePlayer::find($playerId); + $userArr = $updated->hidden(['password'])->toArray(); + UserCache::setUser($playerId, $userArr); + + return [ + 'coin' => (float) $updated->coin, + 'total_draw_count' => (int) $updated->total_draw_count, + 'paid_draw_count' => (int) $updated->paid_draw_count, + 'free_draw_count' => (int) $updated->free_draw_count, + ]; + } +} diff --git a/server/config/route.php b/server/config/route.php index af61584..0d3c4c3 100644 --- a/server/config/route.php +++ b/server/config/route.php @@ -23,6 +23,8 @@ Route::group('/api', function () { Route::post('/user/logout', [app\api\controller\UserController::class, 'logout']); Route::get('/user/info', [app\api\controller\UserController::class, 'info']); Route::get('/user/balance', [app\api\controller\UserController::class, 'balance']); + Route::post('/game/buyLotteryTickets', [app\api\controller\GameController::class, 'buyLotteryTickets']); + Route::get('/game/lotteryPool', [app\api\controller\GameController::class, 'lotteryPool']); })->middleware([CheckApiAuthMiddleware::class]);