1.新增获取充值/提现配置接口/api/finance/depositWithdrawConfig
2.优化充值和提现方式
This commit is contained in:
81
app/common/service/DepositOrderExpireService.php
Normal file
81
app/common/service/DepositOrderExpireService.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use support\think\Db;
|
||||
|
||||
/**
|
||||
* 充值待支付订单超时处理:
|
||||
* - 同用户最多允许 3 笔待支付订单
|
||||
* - 待支付订单创建后 60 秒未支付,自动标记为失败并写失败原因
|
||||
*/
|
||||
final class DepositOrderExpireService
|
||||
{
|
||||
public const MAX_PENDING_DEPOSIT = 3;
|
||||
public const EXPIRE_SECONDS = 60;
|
||||
|
||||
/**
|
||||
* 超时失效处理。
|
||||
*
|
||||
* @param int|null $userId 仅处理某用户;null 表示不过滤用户
|
||||
* @param string|null $orderNo 仅处理某订单;null 表示不过滤订单
|
||||
*
|
||||
* @return int 本次转失败的订单数
|
||||
*/
|
||||
public static function expirePendingOrders(?int $userId = null, ?string $orderNo = null): int
|
||||
{
|
||||
$expireBefore = time() - self::EXPIRE_SECONDS;
|
||||
$query = Db::name('deposit_order')
|
||||
->where('status', 0)
|
||||
->where('create_time', '<=', $expireBefore);
|
||||
if ($userId !== null && $userId > 0) {
|
||||
$query->where('user_id', $userId);
|
||||
}
|
||||
if ($orderNo !== null && $orderNo !== '') {
|
||||
$query->where('order_no', $orderNo);
|
||||
}
|
||||
$rows = $query->field(['id', 'remark'])->select()->toArray();
|
||||
if ($rows === []) {
|
||||
return 0;
|
||||
}
|
||||
$now = time();
|
||||
$affectedCount = 0;
|
||||
foreach ($rows as $row) {
|
||||
$id = isset($row['id']) && is_numeric($row['id']) ? intval($row['id']) : 0;
|
||||
if ($id <= 0) {
|
||||
continue;
|
||||
}
|
||||
$oldRemark = isset($row['remark']) && is_string($row['remark']) ? trim($row['remark']) : '';
|
||||
$reason = '[timeout] unpaid over ' . self::EXPIRE_SECONDS . 's';
|
||||
$remark = $oldRemark === '' ? $reason : mb_substr($oldRemark . ' | ' . $reason, 0, 255);
|
||||
$affected = Db::name('deposit_order')
|
||||
->where('id', $id)
|
||||
->where('status', 0)
|
||||
->update([
|
||||
'status' => 2,
|
||||
'remark' => $remark,
|
||||
'update_time' => $now,
|
||||
]);
|
||||
if (is_numeric($affected) && intval($affected) > 0) {
|
||||
$affectedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return $affectedCount;
|
||||
}
|
||||
|
||||
public static function pendingCountByUserId(int $userId): int
|
||||
{
|
||||
if ($userId <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Db::name('deposit_order')
|
||||
->where('user_id', $userId)
|
||||
->where('status', 0)
|
||||
->count();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ final class GameBetSettleService
|
||||
}
|
||||
|
||||
$win = self::computeWinAmount($bet, $resultNumber);
|
||||
$jackpot = '0.0000';
|
||||
$jackpot = '0.00';
|
||||
|
||||
$affected = Db::name('bet_order')
|
||||
->where('id', $betId)
|
||||
@@ -78,10 +78,10 @@ final class GameBetSettleService
|
||||
self::creditUserBetFlow($bet, $now);
|
||||
|
||||
if ($userId > 0) {
|
||||
if (bccomp($win, '0', 4) > 0) {
|
||||
if (bccomp($win, '0', 2) > 0) {
|
||||
$userOutcome[$userId]['had_win'] = true;
|
||||
}
|
||||
if (bccomp($win, '0', 4) > 0 && StreakWinReward::isJackpotForStreakAtBet((int) ($bet['streak_at_bet'] ?? 0))) {
|
||||
if (bccomp($win, '0', 2) > 0 && StreakWinReward::isJackpotForStreakAtBet((int) ($bet['streak_at_bet'] ?? 0))) {
|
||||
$jackpotNotify[$userId] = true;
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ final class GameBetSettleService
|
||||
}
|
||||
|
||||
$balanceAfter = (string) (Db::name('user')->where('id', $userId)->value('coin') ?? '0');
|
||||
if (bccomp($win, '0', 4) > 0) {
|
||||
if (bccomp($win, '0', 2) > 0) {
|
||||
$paid = self::creditUserPayout($bet, $betId, $win, $now);
|
||||
if ($paid !== null) {
|
||||
$balanceAfter = $paid;
|
||||
@@ -102,17 +102,17 @@ final class GameBetSettleService
|
||||
if (!isset($aggregateByUser[$userId])) {
|
||||
$aggregateByUser[$userId] = [
|
||||
'period_no' => $periodNo,
|
||||
'total_win' => '0.0000',
|
||||
'total_win' => '0.00',
|
||||
'balance_after' => $balanceAfter,
|
||||
'orders' => [],
|
||||
];
|
||||
}
|
||||
$aggregateByUser[$userId]['total_win'] = bcadd($aggregateByUser[$userId]['total_win'], $win, 4);
|
||||
$aggregateByUser[$userId]['total_win'] = bcadd($aggregateByUser[$userId]['total_win'], $win, 2);
|
||||
$aggregateByUser[$userId]['balance_after'] = $balanceAfter;
|
||||
$aggregateByUser[$userId]['orders'][] = [
|
||||
'order_no' => (string) $betId,
|
||||
'win_amount' => $win,
|
||||
'hit' => bccomp($win, '0', 4) > 0,
|
||||
'hit' => bccomp($win, '0', 2) > 0,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ final class GameBetSettleService
|
||||
'balance_after' => $agg['balance_after'],
|
||||
]);
|
||||
|
||||
if (bccomp($agg['total_win'], '0', 4) > 0) {
|
||||
if (bccomp($agg['total_win'], '0', 2) > 0) {
|
||||
UserPushService::publish((int) $userId, UserPushService::EVT_WALLET_CHANGED, [
|
||||
'reason' => 'payout',
|
||||
'ref_type' => 'game_period',
|
||||
@@ -167,7 +167,7 @@ final class GameBetSettleService
|
||||
continue;
|
||||
}
|
||||
$agg = $aggregateByUser[$uid];
|
||||
if (bccomp($agg['total_win'], '0', 4) <= 0) {
|
||||
if (bccomp($agg['total_win'], '0', 2) <= 0) {
|
||||
continue;
|
||||
}
|
||||
$jackpotHits[] = [
|
||||
@@ -187,7 +187,7 @@ final class GameBetSettleService
|
||||
public static function settlePendingForEndedRecords(): int
|
||||
{
|
||||
$rows = Db::name('game_record')
|
||||
->where('status', 4)
|
||||
->where('status', 2)
|
||||
->whereNotNull('result_number')
|
||||
->field(['id', 'result_number'])
|
||||
->order('id', 'asc')
|
||||
@@ -237,13 +237,13 @@ final class GameBetSettleService
|
||||
$pickNumbers = [];
|
||||
}
|
||||
if (!in_array($resultNumber, array_map('intval', $pickNumbers), true)) {
|
||||
return '0.0000';
|
||||
return '0.00';
|
||||
}
|
||||
$total = (string) ($bet['total_amount'] ?? '0');
|
||||
$streak = (int) ($bet['streak_at_bet'] ?? 0);
|
||||
$odds = StreakWinReward::totalOddsMultiplierForStreakAtBet($streak);
|
||||
|
||||
return bcmul($total, $odds, 4);
|
||||
return bcmul($total, $odds, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,8 +263,8 @@ final class GameBetSettleService
|
||||
if ($total === '' || !is_numeric($total)) {
|
||||
return;
|
||||
}
|
||||
$flow = bcadd($total, '0', 4);
|
||||
if (bccomp($flow, '0', 4) <= 0) {
|
||||
$flow = bcadd($total, '0', 2);
|
||||
if (bccomp($flow, '0', 2) <= 0) {
|
||||
return;
|
||||
}
|
||||
Db::name('user')
|
||||
@@ -299,7 +299,7 @@ final class GameBetSettleService
|
||||
}
|
||||
|
||||
$before = (string) ($user['coin'] ?? '0');
|
||||
$after = bcadd($before, $winAmount, 4);
|
||||
$after = bcadd($before, $winAmount, 2);
|
||||
|
||||
Db::name('user_wallet_record')->insert([
|
||||
'user_id' => $userId,
|
||||
|
||||
@@ -207,12 +207,12 @@ final class GameLiveService
|
||||
for ($n = 1; $n <= self::DRAW_NUMBER_MAX; $n++) {
|
||||
$loss = self::estimateLossForNumber($bets, $n);
|
||||
$candidates[] = ['number' => $n, 'estimated_loss' => $loss];
|
||||
if ($bestLoss === null || bccomp((string) $loss, (string) $bestLoss, 4) < 0) {
|
||||
if ($bestLoss === null || bccomp((string) $loss, (string) $bestLoss, 2) < 0) {
|
||||
$bestLoss = $loss;
|
||||
$bestNumbers = [$n];
|
||||
continue;
|
||||
}
|
||||
if (bccomp((string) $loss, (string) $bestLoss, 4) === 0) {
|
||||
if (bccomp((string) $loss, (string) $bestLoss, 2) === 0) {
|
||||
$bestNumbers[] = $n;
|
||||
}
|
||||
}
|
||||
@@ -225,7 +225,7 @@ final class GameLiveService
|
||||
}
|
||||
|
||||
$finalNumber = $manualNumber ?? $bestNumber;
|
||||
$finalLoss = '0.0000';
|
||||
$finalLoss = '0.00';
|
||||
if ($finalNumber !== null) {
|
||||
$finalLoss = self::estimateLossForNumber($bets, $finalNumber);
|
||||
}
|
||||
@@ -558,7 +558,7 @@ final class GameLiveService
|
||||
if ($betId <= 0) {
|
||||
continue;
|
||||
}
|
||||
if ($userId <= 0 || bccomp($total, '0', 4) <= 0) {
|
||||
if ($userId <= 0 || bccomp($total, '0', 2) <= 0) {
|
||||
Db::name('bet_order')->where('id', $betId)->where('status', 1)->update([
|
||||
'status' => 3,
|
||||
'update_time' => $now,
|
||||
@@ -566,7 +566,7 @@ final class GameLiveService
|
||||
continue;
|
||||
}
|
||||
$before = (string) (Db::name('user')->where('id', $userId)->value('coin') ?? '0');
|
||||
$after = bcadd($before, $total, 4);
|
||||
$after = bcadd($before, $total, 2);
|
||||
$u = Db::name('user')->where('id', $userId)->where('coin', $before)->update([
|
||||
'coin' => $after,
|
||||
'update_time' => $now,
|
||||
@@ -836,12 +836,12 @@ final class GameLiveService
|
||||
$bestNumbers = [];
|
||||
for ($n = 1; $n <= self::DRAW_NUMBER_MAX; $n++) {
|
||||
$loss = self::estimateLossForNumber($bets, $n);
|
||||
if ($bestLoss === null || bccomp((string) $loss, (string) $bestLoss, 4) < 0) {
|
||||
if ($bestLoss === null || bccomp((string) $loss, (string) $bestLoss, 2) < 0) {
|
||||
$bestLoss = $loss;
|
||||
$bestNumbers = [$n];
|
||||
continue;
|
||||
}
|
||||
if (bccomp((string) $loss, (string) $bestLoss, 4) === 0) {
|
||||
if (bccomp((string) $loss, (string) $bestLoss, 2) === 0) {
|
||||
$bestNumbers[] = $n;
|
||||
}
|
||||
}
|
||||
@@ -878,7 +878,7 @@ final class GameLiveService
|
||||
|
||||
private static function estimateLossForNumber(array $bets, int $number): string
|
||||
{
|
||||
$payout = '0.0000';
|
||||
$payout = '0.00';
|
||||
foreach ($bets as $bet) {
|
||||
$pickNumbers = $bet['pick_numbers'];
|
||||
if (is_string($pickNumbers)) {
|
||||
@@ -894,8 +894,8 @@ final class GameLiveService
|
||||
$total = (string) ($bet['total_amount'] ?? '0');
|
||||
$streak = (int) ($bet['streak_at_bet'] ?? 0);
|
||||
$odds = StreakWinReward::totalOddsMultiplierForStreakAtBet($streak);
|
||||
$orderPayout = bcmul($total, $odds, 4);
|
||||
$payout = bcadd($payout, $orderPayout, 4);
|
||||
$orderPayout = bcmul($total, $odds, 2);
|
||||
$payout = bcadd($payout, $orderPayout, 2);
|
||||
}
|
||||
return $payout;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ final class GameRecordStatService
|
||||
|
||||
if ($status !== 4) {
|
||||
Db::name('game_record')->where('id', $recordId)->update([
|
||||
'platform_profit_amount' => '0.0000',
|
||||
'platform_profit_amount' => '0.00',
|
||||
'winner_user_count' => 0,
|
||||
'update_time' => $now,
|
||||
]);
|
||||
@@ -45,8 +45,8 @@ final class GameRecordStatService
|
||||
$resultNum = (int) $resultRaw;
|
||||
|
||||
$bets = Db::name('bet_order')->where('period_id', $recordId)->select()->toArray();
|
||||
$totalBet = '0.0000';
|
||||
$totalPayout = '0.0000';
|
||||
$totalBet = '0.00';
|
||||
$totalPayout = '0.00';
|
||||
$winnerUserIds = [];
|
||||
|
||||
foreach ($bets as $bet) {
|
||||
@@ -55,16 +55,16 @@ final class GameRecordStatService
|
||||
continue;
|
||||
}
|
||||
$tb = (string) ($bet['total_amount'] ?? '0');
|
||||
$totalBet = bcadd($totalBet, $tb, 4);
|
||||
$totalBet = bcadd($totalBet, $tb, 2);
|
||||
|
||||
if ($st === 2) {
|
||||
$payout = bcadd((string) ($bet['win_amount'] ?? '0'), (string) ($bet['jackpot_extra_amount'] ?? '0'), 4);
|
||||
$payout = bcadd((string) ($bet['win_amount'] ?? '0'), (string) ($bet['jackpot_extra_amount'] ?? '0'), 2);
|
||||
} else {
|
||||
$payout = self::estimatePayoutForBet($bet, $resultNum);
|
||||
}
|
||||
|
||||
$totalPayout = bcadd($totalPayout, $payout, 4);
|
||||
if (bccomp($payout, '0', 4) > 0) {
|
||||
$totalPayout = bcadd($totalPayout, $payout, 2);
|
||||
if (bccomp($payout, '0', 2) > 0) {
|
||||
$uid = (int) ($bet['user_id'] ?? 0);
|
||||
if ($uid > 0) {
|
||||
$winnerUserIds[$uid] = true;
|
||||
@@ -72,7 +72,7 @@ final class GameRecordStatService
|
||||
}
|
||||
}
|
||||
|
||||
$profit = bcsub($totalBet, $totalPayout, 4);
|
||||
$profit = bcsub($totalBet, $totalPayout, 2);
|
||||
|
||||
Db::name('game_record')->where('id', $recordId)->update([
|
||||
'platform_profit_amount' => $profit,
|
||||
@@ -96,12 +96,12 @@ final class GameRecordStatService
|
||||
$pickNumbers = [];
|
||||
}
|
||||
if (!in_array($resultNumber, array_map('intval', $pickNumbers), true)) {
|
||||
return '0.0000';
|
||||
return '0.00';
|
||||
}
|
||||
$total = (string) ($bet['total_amount'] ?? '0');
|
||||
$streak = (int) ($bet['streak_at_bet'] ?? 0);
|
||||
$odds = StreakWinReward::totalOddsMultiplierForStreakAtBet($streak);
|
||||
|
||||
return bcmul($total, $odds, 4);
|
||||
return bcmul($total, $odds, 2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user