1.重构实时消息WebSocket连接
2.MySQL备份
This commit is contained in:
@@ -14,7 +14,6 @@ use app\common\model\DepositOrder;
|
||||
use app\common\model\GameConfig;
|
||||
use app\common\model\WithdrawOrder;
|
||||
use app\common\service\DepositOrderExpireService;
|
||||
use app\common\service\UserPushService;
|
||||
use support\Response;
|
||||
use support\think\Db;
|
||||
use Throwable;
|
||||
@@ -332,7 +331,7 @@ class Finance extends MobileBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟第三方异步通知:验签后调用 DepositSettlement::settle 入账,并推送 wallet.changed。
|
||||
* 模拟第三方异步通知:验签后调用 DepositSettlement::settle 入账。
|
||||
*/
|
||||
public function depositMockNotify(Request $request): Response
|
||||
{
|
||||
@@ -373,19 +372,6 @@ class Finance extends MobileBase
|
||||
null,
|
||||
'channel_code=' . $pc
|
||||
);
|
||||
$uid = intval(strval($order->user_id));
|
||||
if ($uid > 0) {
|
||||
$coinAfter = is_string($result['balance_after'] ?? null) ? $result['balance_after'] : strval($result['balance_after'] ?? '0');
|
||||
$credit = is_string($result['credit'] ?? null) ? $result['credit'] : strval($result['credit'] ?? '0');
|
||||
UserPushService::publish($uid, UserPushService::EVT_WALLET_CHANGED, [
|
||||
'reason' => 'deposit',
|
||||
'ref_type' => 'deposit_order',
|
||||
'ref_id' => (string) $orderId,
|
||||
'order_no' => $orderNo,
|
||||
'delta' => $credit,
|
||||
'balance_after' => $coinAfter,
|
||||
]);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
return $this->mobileError(2000, $e->getMessage());
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use app\common\model\UserWalletRecord;
|
||||
use app\common\service\GameHotDataCoordinator;
|
||||
use app\common\service\GameHotDataRedis;
|
||||
use app\common\service\GameRecordService;
|
||||
use app\common\service\UserPushService;
|
||||
use app\common\service\GameWebSocketEventBus;
|
||||
use support\think\Db;
|
||||
use Webman\Http\Request;
|
||||
use support\Response;
|
||||
@@ -139,12 +139,27 @@ class Game extends MobileBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交下注:入参极简——period_no + numbers + bet_amount(整笔总金额) + idempotency_key。
|
||||
*
|
||||
* 下注判定:开奖号码 ∈ pick_numbers 即算中奖,赔付按整笔 total_amount × odds 计算
|
||||
* (派彩 = 压注总额 × 连胜奖励表 odds_factor;streak_at_bet 为下注时快照)。
|
||||
* 与前端文档对齐:/api/game/current_status
|
||||
*/
|
||||
public function currentStatus(Request $request): Response
|
||||
{
|
||||
return $this->periodCurrent($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 兼容旧路由:/api/game/betPlace
|
||||
* 新语义与 place_bet 一致:bet_amount 作为“单注金额”。
|
||||
*/
|
||||
public function betPlace(Request $request): Response
|
||||
{
|
||||
return $this->placeBet($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交下注:入参为 period_no + numbers + single_bet_amount + idempotency_key。
|
||||
* 兼容前端传参 bet_amount(作为 single_bet_amount 同义字段)。
|
||||
*/
|
||||
public function placeBet(Request $request): Response
|
||||
{
|
||||
$response = $this->initializeMobile($request);
|
||||
if ($response !== null) {
|
||||
@@ -152,16 +167,14 @@ class Game extends MobileBase
|
||||
}
|
||||
$periodNo = trim((string) $request->post('period_no', ''));
|
||||
$numbersRaw = $request->post('numbers', '');
|
||||
$betAmount = trim((string) $request->post('bet_amount', ''));
|
||||
$singleBetAmount = trim((string) ($request->post('single_bet_amount', $request->post('bet_amount', ''))));
|
||||
$idempotencyKey = trim((string) $request->post('idempotency_key', ''));
|
||||
if ($periodNo === '' || $betAmount === '' || $idempotencyKey === '') {
|
||||
if ($periodNo === '' || $singleBetAmount === '' || $idempotencyKey === '') {
|
||||
return $this->mobileError(1001, 'Missing parameters');
|
||||
}
|
||||
if (!is_numeric($betAmount) || bccomp($betAmount, '0', 2) <= 0) {
|
||||
if (!is_numeric($singleBetAmount) || bccomp($singleBetAmount, '0', 2) <= 0) {
|
||||
return $this->mobileError(1003, 'Invalid parameter value');
|
||||
}
|
||||
$totalAmount = bcadd($betAmount, '0', 2);
|
||||
|
||||
$numbers = $this->parseBetNumbersFromRequest($numbersRaw);
|
||||
if ($numbers === []) {
|
||||
return $this->mobileError(1003, 'Invalid parameter value');
|
||||
@@ -170,6 +183,9 @@ class Game extends MobileBase
|
||||
if (count($numbers) > $maxSelect) {
|
||||
return $this->mobileError(1003, 'Invalid parameter value');
|
||||
}
|
||||
$singleAmount = bcadd($singleBetAmount, '0', 2);
|
||||
$numberCount = (string) count($numbers);
|
||||
$totalAmount = bcmul($singleAmount, $numberCount, 2);
|
||||
|
||||
if (!GameRecordService::isLiveRuntimeEnabled()) {
|
||||
return $this->mobileError(3001, 'Game is paused');
|
||||
@@ -273,19 +289,28 @@ class Game extends MobileBase
|
||||
}
|
||||
|
||||
GameHotDataCoordinator::afterUserCommitted($userId);
|
||||
UserPushService::publish($userId, UserPushService::EVT_BET_ACCEPTED, [
|
||||
'order_no' => $orderNo,
|
||||
'period_no' => (string) $period->period_no,
|
||||
'status' => 'accepted',
|
||||
'balance_after' => $after,
|
||||
'total_amount' => $totalAmount,
|
||||
'current_streak' => $streakAtBet,
|
||||
GameWebSocketEventBus::publish('bet.accepted', [
|
||||
'user_id' => $userId,
|
||||
'period_no' => $period->period_no,
|
||||
'numbers' => $numbers,
|
||||
'single_bet_amount' => $singleAmount,
|
||||
'numbers_count' => count($numbers),
|
||||
'total_amount' => $totalAmount,
|
||||
'balance_after' => $after,
|
||||
'accepted_at' => time(),
|
||||
]);
|
||||
GameWebSocketEventBus::publish('wallet.changed', [
|
||||
'user_id' => $userId,
|
||||
'balance_after' => $after,
|
||||
'biz_type' => 'bet',
|
||||
'changed_at' => time(),
|
||||
]);
|
||||
|
||||
return $this->mobileSuccess([
|
||||
'order_no' => $orderNo,
|
||||
'period_no' => $period->period_no,
|
||||
'status' => 'accepted',
|
||||
'single_bet_amount' => $singleAmount,
|
||||
'numbers_count' => count($numbers),
|
||||
'locked_balance' => '0.00',
|
||||
'balance_after' => $after,
|
||||
'current_streak' => $streakAtBet,
|
||||
@@ -295,6 +320,61 @@ class Game extends MobileBase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动托管(无推送模式):先落托管配置,实际执行仍由客户端轮询 current_status 驱动。
|
||||
*/
|
||||
public function autoSpin(Request $request): Response
|
||||
{
|
||||
$response = $this->initializeMobile($request);
|
||||
if ($response !== null) {
|
||||
return $response;
|
||||
}
|
||||
$action = trim((string) $request->post('action', 'start'));
|
||||
if ($action === 'stop') {
|
||||
return $this->mobileSuccess([
|
||||
'status' => 'stopped',
|
||||
'auto_mode' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
$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) {
|
||||
return $this->mobileError(1001, 'Missing parameters');
|
||||
}
|
||||
if (!is_numeric($singleBetAmount) || bccomp($singleBetAmount, '0', 2) <= 0) {
|
||||
return $this->mobileError(1003, 'Invalid parameter value');
|
||||
}
|
||||
$numbers = $this->parseBetNumbersFromRequest($numbersRaw);
|
||||
if ($numbers === []) {
|
||||
return $this->mobileError(1003, 'Invalid parameter value');
|
||||
}
|
||||
$userIdValue = filter_var($this->auth->id ?? null, FILTER_VALIDATE_INT);
|
||||
if ($userIdValue === false) {
|
||||
$userIdValue = 0;
|
||||
}
|
||||
GameWebSocketEventBus::publish('auto.spin.progress', [
|
||||
'user_id' => $userIdValue,
|
||||
'period_no' => $periodNo,
|
||||
'rounds' => $rounds,
|
||||
'remaining_rounds' => $rounds,
|
||||
'completed_rounds' => 0,
|
||||
'status' => 'scheduled',
|
||||
'server_time' => time(),
|
||||
]);
|
||||
return $this->mobileSuccess([
|
||||
'status' => 'scheduled',
|
||||
'auto_mode' => true,
|
||||
'period_no' => $periodNo,
|
||||
'numbers' => $numbers,
|
||||
'single_bet_amount' => bcadd($singleBetAmount, '0', 2),
|
||||
'rounds' => $rounds,
|
||||
'remaining_rounds' => $rounds,
|
||||
]);
|
||||
}
|
||||
|
||||
public function betMyOrders(Request $request): Response
|
||||
{
|
||||
$response = $this->initializeMobile($request);
|
||||
|
||||
Reference in New Issue
Block a user