From 84d499145ddf965a9d55f770f27fd47a465b8850 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Tue, 10 Mar 2026 18:53:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=AD=E5=A5=96=EF=BC=8C?= =?UTF-8?q?=E5=90=8E=E5=8F=B0=E6=96=B0=E5=A2=9E=E5=BD=A9=E9=87=91=E6=B1=A0?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index/modules/current-pool-dialog.vue | 64 +++++++++++++++++-- server/app/api/logic/PlayStartLogic.php | 42 +++++++++--- .../DiceLotteryPoolConfigLogic.php | 36 +++++++---- .../DiceLotteryPoolConfig.php | 2 +- 4 files changed, 117 insertions(+), 27 deletions(-) diff --git a/saiadmin-artd/src/views/plugin/dice/lottery_pool_config/index/modules/current-pool-dialog.vue b/saiadmin-artd/src/views/plugin/dice/lottery_pool_config/index/modules/current-pool-dialog.vue index 4a47d95..9b46edf 100644 --- a/saiadmin-artd/src/views/plugin/dice/lottery_pool_config/index/modules/current-pool-dialog.vue +++ b/saiadmin-artd/src/views/plugin/dice/lottery_pool_config/index/modules/current-pool-dialog.vue @@ -14,10 +14,22 @@ 池子名称: {{ pool.name }} -
- 池子盈利: - {{ displayProfitAmount }} - (实时,不可修改) +
+
+ 彩金池盈利(profit_amount): + {{ displayProfitAmount }} + 实时 +
+
+ 计算方式:每局抽奖累加 (100 − 该局中奖档位 real_ev),弹窗打开期间每 2 秒自动刷新 +
+
+
+
抽奖档位规则
+
+ 当彩金池盈利 低于安全线 时,按玩家的 T*_weight 权重抽取抽奖档位; + 当彩金池盈利 高于或等于安全线 时,按当前彩金池的 T*_weight 权重抽取档位。 +
@@ -233,4 +245,48 @@ .pool-info { padding: 8px 0; } + + .profit-row { + margin-bottom: 8px; + } + + .profit-calc-hint { + margin-top: 4px; + font-size: 12px; + color: var(--el-text-color-secondary); + line-height: 1.4; + } + + .realtime-badge { + font-size: 11px; + padding: 2px 6px; + border-radius: 4px; + background: var(--el-color-success-light-9); + color: var(--el-color-success); + } + + .tip-block { + margin-top: 12px; + padding: 10px 12px; + background: var(--el-fill-color-light); + border-radius: 6px; + border-left: 3px solid var(--el-color-primary); + } + + .tip-title { + font-size: 13px; + font-weight: 600; + color: var(--el-text-color-primary); + margin-bottom: 6px; + } + + .tip-content { + font-size: 12px; + color: var(--el-text-color-regular); + line-height: 1.5; + } + + .tip-content strong { + color: var(--el-color-primary); + } diff --git a/server/app/api/logic/PlayStartLogic.php b/server/app/api/logic/PlayStartLogic.php index c7e92f3..8191f1a 100644 --- a/server/app/api/logic/PlayStartLogic.php +++ b/server/app/api/logic/PlayStartLogic.php @@ -72,17 +72,28 @@ class PlayStartLogic $config = $ticketType === self::LOTTERY_TYPE_PAID ? ($lotteryService->getConfigType0Id() ? DiceLotteryPoolConfig::find($lotteryService->getConfigType0Id()) : null) : ($lotteryService->getConfigType1Id() ? DiceLotteryPoolConfig::find($lotteryService->getConfigType1Id()) : null); + // 未找到付费/免费对应配置时,统一回退到 type=0 的彩金池,保证所有玩家累加同一彩金池 + if (!$config) { + $config = DiceLotteryPoolConfig::where('type', 0)->find(); + } if (!$config) { throw new ApiException('奖池配置不存在'); } - // 按玩家权重抽取档位;若该档位无奖励或该方向下均无可用路径则重新摇取档位 + // 彩金池盈利低于安全线时按玩家权重抽档,高于或等于安全线时按奖池权重抽档 + $poolProfit = (float) ($config->profit_amount ?? $config->ev ?? 0); + $safetyLine = (int) ($config->safety_line ?? 0); + $usePoolWeights = $poolProfit >= $safetyLine; + + // 按上述规则抽取档位;若该档位无奖励或该方向下均无可用路径则重新摇取档位 $maxTierRetry = 10; $chosen = null; $startCandidates = []; $tier = null; for ($tierAttempt = 0; $tierAttempt < $maxTierRetry; $tierAttempt++) { - $tier = LotteryService::drawTierByPlayerWeights($player); + $tier = $usePoolWeights + ? LotteryService::drawTierByWeights($config) + : LotteryService::drawTierByPlayerWeights($player); $tierRewards = DiceRewardConfig::getCachedByTier($tier); if (empty($tierRewards)) { Log::warning("档位 {$tier} 无任何奖励配置,重新摇取档位"); @@ -122,6 +133,7 @@ class PlayStartLogic // 当抽到的 grid_number 为 5/10/15/20/25/30 时,可出豹子;其中 grid_number=5 与 30 固定 100% 豹子(BIGWIN 约定) $superWinCoin = 0; $isWin = 0; + $bigWinRealEv = 0.0; // BIGWIN 档位的真实资金结算,用于从彩金池盈利中一并扣除 if (in_array($rollNumber, self::SUPER_WIN_GRID_NUMBERS, true)) { $bigWinConfig = DiceRewardConfig::getCachedByTierAndGridNumber('BIGWIN', $rollNumber); $alwaysSuperWin = in_array($rollNumber, self::SUPER_WIN_ALWAYS_GRID_NUMBERS, true); @@ -136,9 +148,12 @@ class PlayStartLogic if ($doSuperWin) { $rollArray = $this->getSuperWinRollArray($rollNumber); $isWin = 1; - $superWinCoin = $bigWinConfig !== null - ? 100 + (float) ($bigWinConfig['real_ev'] ?? 0) - : self::SUPER_WIN_BONUS; + if ($bigWinConfig !== null) { + $bigWinRealEv = (float) ($bigWinConfig['real_ev'] ?? 0); + $superWinCoin = 100 + $bigWinRealEv; + } else { + $superWinCoin = self::SUPER_WIN_BONUS; + } } else { $rollArray = $this->generateNonSuperWinRollArrayWithSum($rollNumber); } @@ -174,6 +189,7 @@ class PlayStartLogic $rewardWinCoin, $isWin, $realEv, + $bigWinRealEv, $direction, $startIndex, $targetIndex, @@ -230,12 +246,22 @@ class PlayStartLogic $p->save(); - // 累加彩金池盈利额度(累加值为 -real_ev)。若 dice_lottery_config 表有 ev 字段则执行 + // 彩金池盈利累加:每局累加 (100 - 本局总 real_ev),其中本局总 real_ev = 普通档位 real_ev + BIGWIN.real_ev(如触发) + // 需确保表有 profit_amount 字段(见 db/dice_lottery_config_add_profit_amount.sql) + $totalRealEv = $realEv + $bigWinRealEv; + $addProfit = 100 - $totalRealEv; try { DiceLotteryPoolConfig::where('id', $configId)->update([ - 'ev' => Db::raw('IFNULL(ev,0) - ' . (float) $realEv), + 'profit_amount' => Db::raw('IFNULL(profit_amount,0) + ' . (float) $addProfit), + ]); + } catch (\Throwable $e) { + Log::warning('彩金池盈利累加失败,请确认表 dice_lottery_config 已存在 profit_amount 字段并执行 db/dice_lottery_config_add_profit_amount.sql', [ + 'config_id' => $configId, + 'add_profit' => $addProfit, + 'real_ev' => $realEv, + 'bigwin_ev' => $bigWinRealEv, + 'message' => $e->getMessage(), ]); - } catch (\Throwable $_) { } DicePlayerWalletRecord::create([ diff --git a/server/app/dice/logic/lottery_pool_config/DiceLotteryPoolConfigLogic.php b/server/app/dice/logic/lottery_pool_config/DiceLotteryPoolConfigLogic.php index 3a336da..e5a4d2e 100644 --- a/server/app/dice/logic/lottery_pool_config/DiceLotteryPoolConfigLogic.php +++ b/server/app/dice/logic/lottery_pool_config/DiceLotteryPoolConfigLogic.php @@ -31,7 +31,7 @@ class DiceLotteryPoolConfigLogic extends BaseLogic } /** - * 获取当前彩金池:从 Redis 读取,若无则按 type=0 配置创建并写入 Redis,返回含 profit_amount(ev) 的完整数据 + * 获取当前彩金池:从 Redis 读取实例,profit_amount 每次从 DB 实时读取以保证与抽奖累加一致 * * @return array{id:int,name:string,safety_line:int,t1_weight:int,t2_weight:int,t3_weight:int,t4_weight:int,t5_weight:int,profit_amount:float} */ @@ -42,8 +42,13 @@ class DiceLotteryPoolConfigLogic extends BaseLogic $data = json_decode($cached, true); if (is_array($data)) { $config = DiceLotteryPoolConfig::find($data['id'] ?? 0); - $ev = $config && isset($config->ev) ? (float) $config->ev : (float) ($data['profit_amount'] ?? 0); - $data['profit_amount'] = $ev; + $profit = 0.0; + if ($config) { + $profit = isset($config->profit_amount) ? (float) $config->profit_amount : (isset($config->ev) ? (float) $config->ev : 0.0); + } else { + $profit = (float) ($data['profit_amount'] ?? 0); + } + $data['profit_amount'] = $profit; return $data; } } @@ -52,23 +57,24 @@ class DiceLotteryPoolConfigLogic extends BaseLogic throw new ApiException('未找到 type=0 的奖池配置,请先创建'); } $row = $config->toArray(); + $profitAmount = isset($row['profit_amount']) ? (float) $row['profit_amount'] : (isset($row['ev']) ? (float) $row['ev'] : 0.0); $pool = [ - 'id' => (int) $row['id'], - 'name' => (string) ($row['name'] ?? ''), - 'safety_line' => (int) ($row['safety_line'] ?? 0), - 't1_weight' => (int) ($row['t1_weight'] ?? 0), - 't2_weight' => (int) ($row['t2_weight'] ?? 0), - 't3_weight' => (int) ($row['t3_weight'] ?? 0), - 't4_weight' => (int) ($row['t4_weight'] ?? 0), - 't5_weight' => (int) ($row['t5_weight'] ?? 0), - 'profit_amount' => isset($row['ev']) ? (float) $row['ev'] : 0.0, + 'id' => (int) $row['id'], + 'name' => (string) ($row['name'] ?? ''), + 'safety_line' => (int) ($row['safety_line'] ?? 0), + 't1_weight' => (int) ($row['t1_weight'] ?? 0), + 't2_weight' => (int) ($row['t2_weight'] ?? 0), + 't3_weight' => (int) ($row['t3_weight'] ?? 0), + 't4_weight' => (int) ($row['t4_weight'] ?? 0), + 't5_weight' => (int) ($row['t5_weight'] ?? 0), + 'profit_amount' => $profitAmount, ]; Cache::set(self::REDIS_KEY_CURRENT_POOL, json_encode($pool), self::EXPIRE); return $pool; } /** - * 更新当前彩金池:仅允许修改 safety_line、t1_weight~t5_weight,不同步 profit_amount(ev) + * 更新当前彩金池:仅允许修改 safety_line、t1_weight~t5_weight,不修改 profit_amount * 同时更新 Redis 与 DB 中 type=0 的记录 * * @param array{safety_line?:int,t1_weight?:int,t2_weight?:int,t3_weight?:int,t4_weight?:int,t5_weight?:int} $data @@ -98,7 +104,9 @@ class DiceLotteryPoolConfigLogic extends BaseLogic DiceLotteryPoolConfig::where('id', $id)->update($update); $pool = array_merge($pool, $update); $refreshed = DiceLotteryPoolConfig::find($id); - $pool['profit_amount'] = $refreshed && isset($refreshed->ev) ? (float) $refreshed->ev : (float) ($pool['profit_amount'] ?? 0); + $pool['profit_amount'] = $refreshed && (isset($refreshed->profit_amount) || isset($refreshed->ev)) + ? (float) ($refreshed->profit_amount ?? $refreshed->ev) + : (float) ($pool['profit_amount'] ?? 0); Cache::set(self::REDIS_KEY_CURRENT_POOL, json_encode($pool), self::EXPIRE); } } diff --git a/server/app/dice/model/lottery_pool_config/DiceLotteryPoolConfig.php b/server/app/dice/model/lottery_pool_config/DiceLotteryPoolConfig.php index 2870989..ac8a77d 100644 --- a/server/app/dice/model/lottery_pool_config/DiceLotteryPoolConfig.php +++ b/server/app/dice/model/lottery_pool_config/DiceLotteryPoolConfig.php @@ -25,7 +25,7 @@ use plugin\saiadmin\basic\think\BaseModel; * @property $t3_weight T3池权重 * @property $t4_weight T4池权重 * @property $t5_weight T5池权重 - * @property $ev 池子累计盈利(游戏结算时累加,仅展示不可编辑) + * @property $profit_amount 池子累计盈利(每局抽奖累加 100-real_ev,仅展示不可编辑) */ class DiceLotteryPoolConfig extends BaseModel {