1.优化下注接口/api/game/betPlace

2.优化后台/admin/config/gameConfig中新增压注筹码配置
This commit is contained in:
2026-05-14 10:37:21 +08:00
parent c7fc754573
commit 932a433613
10 changed files with 392 additions and 41 deletions

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace app\api\controller;
use app\common\library\game\BetChips;
use app\common\library\game\ZiHuaDictionary;
use app\common\model\BetOrder;
use app\common\model\GameRecord;
@@ -57,12 +58,14 @@ class Game extends MobileBase
'lock_at' => $lockAt,
'open_at' => $openAt,
],
'bet_config' => [
'pick_max_number_count' => $this->getPickMaxNumberCount(),
'chips' => ['1.00', '5.00', '10.00', '25.00', '50.00', '100.00'],
'min_bet_per_number' => $this->getConfigValue('min_bet_per_number', '0.0100'),
'max_bet_per_number' => $this->getConfigValue('max_bet_per_number', '10000.0000'),
],
'bet_config' => array_merge(
[
'pick_max_number_count' => $this->getPickMaxNumberCount(),
'min_bet_per_number' => $this->getConfigValue('min_bet_per_number', '0.0100'),
'max_bet_per_number' => $this->getConfigValue('max_bet_per_number', '10000.0000'),
],
BetChips::lobbyChipsPayload()
),
'dictionary' => $items,
'user_snapshot' => [
'coin' => $user->coin,
@@ -119,7 +122,7 @@ class Game extends MobileBase
/**
* 兼容旧路由:/api/game/betPlace
* 新语义与 place_bet 一致:bet_amount 作为“单注金额”
* 与 placeBet 一致:须传筹码标识 bet_id16单注金额取自后台 game_config 的 bet_chips
*/
public function betPlace(Request $request): Response
{
@@ -127,8 +130,7 @@ class Game extends MobileBase
}
/**
* 提交下注:入参为 period_no + numbers + single_bet_amount + idempotency_key。
* 兼容前端传参 bet_amount作为 single_bet_amount 同义字段)。
* 提交下注:入参为 period_no + numbers + bet_id16对应 lobbyInit.bet_config.chips 的键)+ idempotency_key。
*/
public function placeBet(Request $request): Response
{
@@ -138,9 +140,14 @@ class Game extends MobileBase
}
$periodNo = trim((string) $request->post('period_no', ''));
$numbersRaw = $request->post('numbers', '');
$singleBetAmount = trim((string) ($request->post('single_bet_amount', $request->post('bet_amount', ''))));
$idempotencyKey = trim((string) $request->post('idempotency_key', ''));
if ($periodNo === '' || $singleBetAmount === '' || $idempotencyKey === '') {
$chipPick = $this->resolveBetChipFromRequest($request);
if (isset($chipPick['error'])) {
return $chipPick['error'];
}
$betChipId = $chipPick['bet_id'];
$singleBetAmount = $chipPick['amount'];
if ($periodNo === '' || $idempotencyKey === '') {
return $this->mobileError(1001, 'Missing parameters');
}
if (!is_numeric($singleBetAmount) || bccomp($singleBetAmount, '0', 2) <= 0) {
@@ -275,6 +282,7 @@ class Game extends MobileBase
'user_id' => $userId,
'period_no' => $period->period_no,
'numbers' => $numbers,
'bet_id' => $betChipId,
'single_bet_amount' => $singleAmount,
'numbers_count' => count($numbers),
'total_amount' => $totalAmount,
@@ -291,6 +299,7 @@ class Game extends MobileBase
'order_no' => $orderNo,
'period_no' => $period->period_no,
'status' => 'accepted',
'bet_id' => $betChipId,
'single_bet_amount' => $singleAmount,
'numbers_count' => count($numbers),
'locked_balance' => '0.00',
@@ -321,9 +330,13 @@ class Game extends MobileBase
$periodNo = trim((string) $request->post('period_no', ''));
$numbersRaw = $request->post('numbers', '');
$singleBetAmount = trim((string) ($request->post('single_bet_amount', $request->post('bet_amount', ''))));
$rounds = $this->intValue($request->post('rounds', 1));
if ($periodNo === '' || $singleBetAmount === '' || $rounds < 1) {
$chipPick = $this->resolveBetChipFromRequest($request);
if (isset($chipPick['error'])) {
return $chipPick['error'];
}
$singleBetAmount = $chipPick['amount'];
if ($periodNo === '' || $rounds < 1) {
return $this->mobileError(1001, 'Missing parameters');
}
if (!is_numeric($singleBetAmount) || bccomp($singleBetAmount, '0', 2) <= 0) {
@@ -340,6 +353,7 @@ class Game extends MobileBase
GameWebSocketEventBus::publish('auto.spin.progress', [
'user_id' => $userIdValue,
'period_no' => $periodNo,
'bet_id' => $chipPick['bet_id'],
'rounds' => $rounds,
'remaining_rounds' => $rounds,
'completed_rounds' => 0,
@@ -351,6 +365,7 @@ class Game extends MobileBase
'auto_mode' => true,
'period_no' => $periodNo,
'numbers' => $numbers,
'bet_id' => $chipPick['bet_id'],
'single_bet_amount' => bcadd($singleBetAmount, '0', 2),
'rounds' => $rounds,
'remaining_rounds' => $rounds,
@@ -376,7 +391,7 @@ class Game extends MobileBase
'order_no' => (string) $item->id,
'period_no' => $item->period_no,
'numbers' => $item->pick_numbers ?? [],
// 整笔压注金额(与请求 bet_amount 语义一致
// 整笔压注金额(本笔总扣款
'bet_amount' => $item->total_amount,
'total_amount' => $item->total_amount,
'result_number' => null,
@@ -456,6 +471,28 @@ class Game extends MobileBase
return 'finished';
}
/**
* @return array{bet_id: int, amount: string}|array{error: Response}
*/
private function resolveBetChipFromRequest(Request $request): array
{
$betIdRaw = $request->post('bet_id', '');
if ($betIdRaw === '' || $betIdRaw === null) {
return ['error' => $this->mobileError(1001, 'Missing parameters')];
}
$betId = filter_var($betIdRaw, FILTER_VALIDATE_INT);
if ($betId === false || $betId < 1 || $betId > 6) {
return ['error' => $this->mobileError(1003, 'Invalid parameter value')];
}
$resolved = BetChips::resolveFromHotData();
$amount = BetChips::amountForBetId($betId, $resolved['map']);
if ($amount === null) {
return ['error' => $this->mobileError(1003, 'Invalid parameter value')];
}
return ['bet_id' => $betId, 'amount' => $amount];
}
/**
* 单注最多可选号码个数:`game_config.config_key = pick_max_number_count`
*/

View File

@@ -25,12 +25,15 @@ return [
'Register only supports phone' => 'Register only supports phone',
'Invite code required' => 'Invite code is required',
'Invite code not bound to channel' => 'This invite code is not bound to a valid channel',
'Channel disabled' => 'Channel is disabled',
'Account already registered' => 'This phone number is already registered. Please sign in.',
'Please enter the correct mobile number' => 'Please enter the correct mobile number',
'Registered successfully but login failed' => 'Registered successfully but login failed',
'Incorrect account or password' => 'Incorrect account or password',
'Login status has expired' => 'Login status has expired',
'Game period does not exist' => 'Game period does not exist',
'Game is paused' => 'Game is paused',
'Bet amount out of range' => 'Bet amount out of range',
'Betting is closed' => 'Betting is closed',
'Insufficient balance' => 'Insufficient balance',
'Duplicate request' => 'Duplicate request',

View File

@@ -57,12 +57,15 @@ return [
'Register only supports phone' => '注册仅支持手机号',
'Invite code required' => '请填写邀请码',
'Invite code not bound to channel' => '该邀请码未绑定有效渠道',
'Channel disabled' => '渠道已关闭',
'Account already registered' => '该手机号已注册,请直接登录',
'Please enter the correct mobile number' => '请输入正确的手机号',
'Registered successfully but login failed' => '注册成功但登录失败',
'Incorrect account or password' => '账号或密码错误',
'Login status has expired' => '登录状态已过期',
'Game period does not exist' => '对局不存在',
'Game is paused' => '游戏已暂停(维护或已关闭运行开关)',
'Bet amount out of range' => '单注金额超出允许范围',
'Betting is closed' => '已封盘,禁止下注',
'Insufficient balance' => '余额不足',
'Duplicate request' => '重复请求(幂等冲突)',