From 3f97905ffacc7358e73e751785b174ec3ee426a9 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Mon, 1 Jun 2026 14:09:26 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BC=98=E5=8C=96=E4=B8=AD=E5=A5=96=EF=BC=8C?= =?UTF-8?q?=E5=BD=93=E4=BD=99=E9=A2=9D=E4=B8=8D=E8=B6=B3=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E6=83=A9=E7=BD=9A=E6=97=B6=EF=BC=8C=E7=9B=B4=E6=8E=A5=E6=89=A3?= =?UTF-8?q?=E5=AE=8C=E9=92=B1=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../locales/langs/en/dice/play_record.json | 1 + .../locales/langs/zh/dice/play_record.json | 1 + .../plugin/dice/play_record/index/index.vue | 7 ++ server/app/api/logic/PlayStartLogic.php | 74 +++++++++---------- .../dice/model/play_record/DicePlayRecord.php | 1 + 5 files changed, 47 insertions(+), 37 deletions(-) diff --git a/saiadmin-artd/src/locales/langs/en/dice/play_record.json b/saiadmin-artd/src/locales/langs/en/dice/play_record.json index 1cabec9..4e6f77c 100644 --- a/saiadmin-artd/src/locales/langs/en/dice/play_record.json +++ b/saiadmin-artd/src/locales/langs/en/dice/play_record.json @@ -84,6 +84,7 @@ "rollArray": "Roll Array", "rollNumber": "Roll Number", "rewardTier": "Reward Tier", + "remark": "Remark", "createTime": "Create Time", "updateTime": "Update Time" } diff --git a/saiadmin-artd/src/locales/langs/zh/dice/play_record.json b/saiadmin-artd/src/locales/langs/zh/dice/play_record.json index d947f68..0242bb8 100644 --- a/saiadmin-artd/src/locales/langs/zh/dice/play_record.json +++ b/saiadmin-artd/src/locales/langs/zh/dice/play_record.json @@ -84,6 +84,7 @@ "rollArray": "摇取点数", "rollNumber": "摇取点数和", "rewardTier": "中奖档位", + "remark": "备注", "createTime": "创建时间", "updateTime": "更新时间" } diff --git a/saiadmin-artd/src/views/plugin/dice/play_record/index/index.vue b/saiadmin-artd/src/views/plugin/dice/play_record/index/index.vue index 5aaa82a..0b18093 100644 --- a/saiadmin-artd/src/views/plugin/dice/play_record/index/index.vue +++ b/saiadmin-artd/src/views/plugin/dice/play_record/index/index.vue @@ -253,6 +253,13 @@ width: 100, formatter: (row: Record) => rewardTierFormatter(row) }, + { + prop: 'remark', + label: 'page.table.remark', + width: 200, + showOverflowTooltip: true, + formatter: (row: Record) => row?.remark || '-' + }, { prop: 'create_time', label: 'page.table.createTime', width: 170 }, { prop: 'update_time', label: 'page.table.updateTime', width: 170 }, { diff --git a/server/app/api/logic/PlayStartLogic.php b/server/app/api/logic/PlayStartLogic.php index 77758aa..4c538ff 100644 --- a/server/app/api/logic/PlayStartLogic.php +++ b/server/app/api/logic/PlayStartLogic.php @@ -50,6 +50,8 @@ class PlayStartLogic private const SUPER_WIN_GRID_NUMBERS = [5, 10, 15, 20, 25, 30]; /** 5 和 30 抽到即豹子,不参与 BIGWIN 权重判定;10/15/20/25 按 BIGWIN weight 判定是否豹子 */ private const SUPER_WIN_ALWAYS_GRID_NUMBERS = [5, 30]; + /** T4 惩罚格余额不足时写入游玩记录的备注 */ + private const REMARK_T4_INSUFFICIENT_BALANCE = '惩罚格奖励:玩家余额不足,已扣尽钱包剩余余额'; /** * 执行一局游戏 @@ -124,26 +126,8 @@ class PlayStartLogic // 付费抽奖:开始前扣除费用 ante * UNIT_COST $paidAmount = $ticketType === self::LOTTERY_TYPE_PAID ? round($ante * self::UNIT_COST, 2) : 0.0; - // 游玩前余额校验(按 T4 惩罚最大值兜底): - // 门槛 = paidAmount(压注*1) + abs(T4最小real_ev)*ante - $t4List = DiceRewardConfig::getCachedByTier('T4', $configDeptId); - $t4MinRealEv = null; - foreach ($t4List as $row) { - $ev = $row['real_ev'] ?? null; - if ($ev === null || $ev === '') { - continue; - } - $evFloat = filter_var($ev, FILTER_VALIDATE_FLOAT); - if ($evFloat === false) { - continue; - } - if ($t4MinRealEv === null || $evFloat < $t4MinRealEv) { - $t4MinRealEv = $evFloat; - } - } - $t4PenaltyAbs = $t4MinRealEv === null ? 0.0 : abs($t4MinRealEv) * $ante; - $needMinBalance = round($paidAmount + $t4PenaltyAbs, 2); - if ($coin < $needMinBalance) { + // 付费抽奖:余额不足单局费用(ante * UNIT_COST)时不允许开始;惩罚格不足部分在局内扣尽剩余余额 + if ($ticketType === self::LOTTERY_TYPE_PAID && $coin < $paidAmount) { throw new ApiException('余额不足'); } @@ -265,6 +249,7 @@ class PlayStartLogic $winCoin = round($superWinCoin + $rewardWinCoin, 2); // 赢取平台币 = 中大奖 + 摇色子中奖(豹子时 rewardWinCoin 已为 0) $record = null; + $settledWinCoin = $winCoin; $configId = (int) $config->id; $type0ConfigId = (int) $configType0->id; $rewardId = ($isWin === 1 && $superWinCoin > 0) ? 0 : $targetIndex; // 中豹子不记录原奖励配置 id @@ -293,9 +278,31 @@ class PlayStartLogic $rollArray, $isTierT5, $tier, - &$record + &$record, + &$settledWinCoin ) { $rewardTier = ($isWin === 1 && $superWinCoin > 0) ? 'BIGWIN' : (string) ($tier ?? ''); + + $p = DicePlayer::find($playerId); + if (!$p) { + throw new \RuntimeException('玩家不存在'); + } + $coinBefore = (float) $p->coin; + // 开始前先扣付费金额,再加中奖金额(免费抽奖 paid_amount=0) + $coinAfter = round($coinBefore - $paidAmount + $winCoin, 2); + $recordWinCoin = $winCoin; + $recordRewardWinCoin = $rewardWinCoin; + $playRecordRemark = null; + // T4 惩罚:扣完购券费用后若不足以支付全额惩罚,则扣尽钱包剩余余额并记录备注 + if ($rewardTier === 'T4' && $coinAfter < 0) { + $walletRemain = round($coinBefore - $paidAmount, 2); + $coinAfter = 0.0; + $recordWinCoin = round(-$walletRemain, 2); + $recordRewardWinCoin = $recordWinCoin; + $playRecordRemark = self::REMARK_T4_INSUFFICIENT_BALANCE; + } + $settledWinCoin = $recordWinCoin; + $record = DicePlayRecord::create([ 'player_id' => $playerId, 'dept_id' => $playerDeptId, @@ -305,9 +312,9 @@ class PlayStartLogic 'ante' => $ante, 'paid_amount' => $paidAmount, 'is_win' => $isWin, - 'win_coin' => $winCoin, + 'win_coin' => $recordWinCoin, 'super_win_coin' => $superWinCoin, - 'reward_win_coin' => $rewardWinCoin, + 'reward_win_coin' => $recordRewardWinCoin, 'direction' => $direction, 'reward_tier' => $rewardTier, 'start_index' => $startIndex, @@ -315,19 +322,9 @@ class PlayStartLogic 'roll_array' => is_array($rollArray) ? json_encode($rollArray) : $rollArray, 'roll_number' => is_array($rollArray) ? array_sum($rollArray) : 0, 'status' => self::RECORD_STATUS_SUCCESS, + 'remark' => $playRecordRemark, ]); - $p = DicePlayer::find($playerId); - if (!$p) { - throw new \RuntimeException('玩家不存在'); - } - $coinBefore = (float) $p->coin; - // 开始前先扣付费金额,再加中奖金额(免费抽奖 paid_amount=0) - $coinAfter = round($coinBefore - $paidAmount + $winCoin, 2); - // T4 惩罚兜底:扣完购券费用后若余额不足以承受本次惩罚(导致为负),统一按“余额不足”提示 - if ($rewardTier === 'T4' && $coinAfter < 0) { - throw new ApiException('余额不足'); - } $p->coin = $coinAfter; // 免费抽奖消耗:优先消耗 free_ticket.count,耗尽则清空 free_ticket;否则兼容旧 free_ticket_count if ($ticketType === self::LOTTERY_TYPE_FREE) { @@ -429,7 +426,7 @@ class PlayStartLogic // 彩金池累计盈利累加在 name=default 彩金池上: // 付费:每局按「本局赢取平台币 win_coin - 抽奖费用 paid_amount(ante*UNIT_COST)」 // 免费券:paid_amount=0,只计入 win_coin - $perPlayProfit = ($ticketType === self::LOTTERY_TYPE_PAID) ? ($winCoin - $paidAmount) : $winCoin; + $perPlayProfit = ($ticketType === self::LOTTERY_TYPE_PAID) ? ($recordWinCoin - $paidAmount) : $recordWinCoin; $addProfit = round($perPlayProfit, 2); try { DiceLotteryPoolConfig::where('id', $type0ConfigId)->update([ @@ -459,12 +456,15 @@ class PlayStartLogic } $walletBeforeDraw = $coinBefore - $paidAmount; - $drawRemark = ($winCoin >= 0 ? '抽奖中奖' : '抽奖惩罚') . '|play_record_id=' . $record->id; + $drawRemark = ($recordWinCoin >= 0 ? '抽奖中奖' : '抽奖惩罚') . '|play_record_id=' . $record->id; + if ($playRecordRemark !== null) { + $drawRemark .= '|' . $playRecordRemark; + } DicePlayerWalletRecord::create([ 'player_id' => $playerId, 'dept_id' => $playerDeptId, 'admin_id' => $adminId, - 'coin' => $winCoin, + 'coin' => $recordWinCoin, 'type' => self::WALLET_TYPE_DRAW, 'wallet_before' => round($walletBeforeDraw, 2), 'wallet_after' => $coinAfter, diff --git a/server/app/dice/model/play_record/DicePlayRecord.php b/server/app/dice/model/play_record/DicePlayRecord.php index 6a2ce27..1e78b96 100644 --- a/server/app/dice/model/play_record/DicePlayRecord.php +++ b/server/app/dice/model/play_record/DicePlayRecord.php @@ -31,6 +31,7 @@ use think\model\relation\BelongsTo; * @property $use_coins 消耗平台币(兼容字段:付费局=paid_amount,免费局=0) * @property $direction 方向:0=顺时针,1=逆时针 * @property $reward_tier 中奖档位:T1,T2,T3,T4,T5,BIGWIN + * @property $remark 备注(如惩罚格余额不足) * @property $lottery_id 奖池 * @property $start_index 起始索引 * @property $target_index 结束索引