86 lines
2.9 KiB
PHP
86 lines
2.9 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api\V1\Wallet;
|
||
|
||
use App\Models\Player;
|
||
use App\Lottery\ErrorCode;
|
||
use App\Models\PlayerWallet;
|
||
use App\Support\ApiResponse;
|
||
use Illuminate\Http\Request;
|
||
use App\Support\CurrencyResolver;
|
||
use Illuminate\Http\JsonResponse;
|
||
use App\Http\Controllers\Controller;
|
||
|
||
/**
|
||
* 【玩家】查询彩票侧钱包余额。
|
||
*
|
||
* 路由:`GET /api/v1/wallet/balance`,需 middleware `lottery.player`。
|
||
* PRD:`01-产品文档.md` §10.1.1;金额单位为最小货币 bigint(参见 `docs/04` §8)。
|
||
*
|
||
* 【行为要点】
|
||
* - 币种:优先 Query `currency`,否则使用玩家 `default_currency`,再回退 `config('lottery.default_currency')`
|
||
* - 若尚无 `player_wallets` 记录:按 `wallet_type=lottery` + 币种 **首次开立**一行(余额 0),便于新玩家直接进入查询
|
||
* - `available_balance`:`balance - frozen_balance`,表示当前可用于下注的整数最小货币单位(不为负)
|
||
* - `main_balance`:主站钱包余额占位,接入主站 API 后再返回实数;当前固定 `null`
|
||
*/
|
||
final class WalletBalanceController extends Controller
|
||
{
|
||
private const WALLET_TYPE_LOTTERY = 'lottery';
|
||
|
||
public function __invoke(Request $request): JsonResponse
|
||
{
|
||
$player = $request->lotteryPlayer();
|
||
abort_if($player === null, 500, 'lottery_player missing');
|
||
|
||
$currencyCode = $this->resolveCurrencyCode($request, $player);
|
||
if ($currencyCode instanceof JsonResponse) {
|
||
return $currencyCode;
|
||
}
|
||
|
||
$wallet = PlayerWallet::query()->firstOrCreate(
|
||
[
|
||
'player_id' => $player->id,
|
||
'wallet_type' => self::WALLET_TYPE_LOTTERY,
|
||
'currency_code' => $currencyCode,
|
||
],
|
||
[
|
||
'balance' => 0,
|
||
'frozen_balance' => 0,
|
||
'status' => 0,
|
||
'version' => 0,
|
||
],
|
||
);
|
||
|
||
$balance = (int) $wallet->balance;
|
||
$frozen = (int) $wallet->frozen_balance;
|
||
|
||
return ApiResponse::success([
|
||
'balance' => $balance,
|
||
'available_balance' => max(0, $balance - $frozen),
|
||
'main_balance' => null,
|
||
'currency_code' => $wallet->currency_code,
|
||
'wallet_type' => $wallet->wallet_type,
|
||
'frozen_balance' => $frozen,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* @return string|JsonResponse 合法币种码或错误响应({@see ErrorCode::WalletInvalidCurrency})
|
||
*/
|
||
private function resolveCurrencyCode(Request $request, Player $player): string|JsonResponse
|
||
{
|
||
$code = CurrencyResolver::resolve($request, $player, 'currency');
|
||
|
||
if (! CurrencyResolver::isValid($code)) {
|
||
return ApiResponse::error(
|
||
__('wallet.invalid_currency'),
|
||
ErrorCode::WalletInvalidCurrency->value,
|
||
null,
|
||
400,
|
||
);
|
||
}
|
||
|
||
return $code;
|
||
}
|
||
}
|