From 931af70c36b724131cb0b819314a2a6e24a8d00f Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Fri, 6 Mar 2026 14:16:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96-=E5=AE=9E=E4=BE=8B=E5=8C=96?= =?UTF-8?q?=E5=A5=96=E5=8A=B1=E5=88=97=E8=A1=A8=E5=88=B0=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/app/api/controller/GameController.php | 4 +- server/app/api/logic/PlayStartLogic.php | 18 ++--- .../model/reward_config/DiceRewardConfig.php | 80 +++++++++++++++++++ 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/server/app/api/controller/GameController.php b/server/app/api/controller/GameController.php index bd07061..cd8dc27 100644 --- a/server/app/api/controller/GameController.php +++ b/server/app/api/controller/GameController.php @@ -57,7 +57,7 @@ class GameController extends OpenController */ public function lotteryPool(Request $request): Response { - $list = DiceRewardConfig::order('id', 'asc')->select()->toArray(); + $list = DiceRewardConfig::getCachedList(); return $this->success($list); } @@ -82,7 +82,7 @@ class GameController extends OpenController if (!$player) { return $this->fail('用户不存在', ReturnCode::NOT_FOUND); } - $minEv = (float) DiceRewardConfig::min('real_ev'); + $minEv = DiceRewardConfig::getCachedMinRealEv(); $minCoin = abs($minEv + 100); $coin = (float) $player->coin; if ($coin < $minCoin) { diff --git a/server/app/api/logic/PlayStartLogic.php b/server/app/api/logic/PlayStartLogic.php index c0943a5..924ff04 100644 --- a/server/app/api/logic/PlayStartLogic.php +++ b/server/app/api/logic/PlayStartLogic.php @@ -48,7 +48,7 @@ class PlayStartLogic throw new ApiException('用户不存在'); } - $minEv = (float) DiceRewardConfig::min('real_ev'); + $minEv = DiceRewardConfig::getCachedMinRealEv(); $minCoin = abs($minEv + self::MIN_COIN_EXTRA); $coin = (float) $player->coin; if ($coin < $minCoin) { @@ -80,18 +80,14 @@ class PlayStartLogic // 索引范围为 0~25 共 26 个格子 $boardSize = 26; - // 1. 根据抽到的档位,在 tier 相等的数据中任选一条,其 id 为结束索引 target_index - $tierRewards = DiceRewardConfig::where('tier', $tier)->select()->toArray(); + // 1. 根据抽到的档位,在 tier 相等的数据中任选一条,其 id 为结束索引 target_index(从缓存读取) + $tierRewards = DiceRewardConfig::getCachedByTier($tier); if (empty($tierRewards)) { Log::error("档位 {$tier} 无任何奖励配置"); throw new ApiException('该档位暂无奖励配置'); } $chosen = $tierRewards[array_rand($tierRewards)]; - $reward = DiceRewardConfig::find($chosen['id']); - if (!$reward) { - throw new ApiException('奖励配置不存在'); - } - $targetIndex = (int) $reward->id; + $targetIndex = (int) ($chosen['id'] ?? 0); $targetIndex = (($targetIndex % $boardSize) + $boardSize) % $boardSize; // 2. 根据结果反推起始点 start_index(由 target_index 与方向反算) @@ -111,14 +107,14 @@ class PlayStartLogic $startIndex, $targetIndex )); - $realEv = (float) $reward->real_ev; + $realEv = (float) ($chosen['real_ev'] ?? 0); $winCoin = 100 + $realEv; // 赢取平台币 = 100 + DiceRewardConfig.real_ev $record = null; $configId = (int) $config->id; - $rewardId = (int) $reward->id; + $rewardId = (int) ($chosen['id'] ?? 0); $configName = (string) ($config->name ?? ''); - $isTierT5 = (string) ($reward->tier ?? '') === 'T5'; + $isTierT5 = (string) ($chosen['tier'] ?? '') === 'T5'; try { Db::transaction(function () use ( $playerId, diff --git a/server/app/dice/model/reward_config/DiceRewardConfig.php b/server/app/dice/model/reward_config/DiceRewardConfig.php index 145333f..b840363 100644 --- a/server/app/dice/model/reward_config/DiceRewardConfig.php +++ b/server/app/dice/model/reward_config/DiceRewardConfig.php @@ -7,11 +7,13 @@ namespace app\dice\model\reward_config; use plugin\saiadmin\basic\think\BaseModel; +use support\think\Cache; /** * 奖励配置模型 * * dice_reward_config 奖励配置 + * 奖励列表为全玩家通用,保存时刷新缓存,游戏时优先读缓存。 * * @property $id ID * @property $grid_number 色子点数 @@ -24,6 +26,12 @@ use plugin\saiadmin\basic\think\BaseModel; */ class DiceRewardConfig extends BaseModel { + /** 缓存键:全玩家通用的奖励配置列表 */ + private const CACHE_KEY_LIST = 'dice:reward_config:list'; + + /** 缓存过期时间(秒),保存时会主动刷新故设较长 */ + private const CACHE_TTL = 86400 * 30; + /** * 数据表主键 * @var string @@ -36,6 +44,78 @@ class DiceRewardConfig extends BaseModel */ protected $table = 'dice_reward_config'; + /** + * 获取缓存的奖励列表(无则从库加载并写入缓存) + * @return array + */ + public static function getCachedList(): array + { + $list = Cache::get(self::CACHE_KEY_LIST); + if ($list !== null && is_array($list)) { + return $list; + } + self::refreshCache(); + $list = Cache::get(self::CACHE_KEY_LIST); + return is_array($list) ? $list : []; + } + + /** + * 重新从数据库加载并写入缓存(保存时调用) + */ + public static function refreshCache(): void + { + $list = (new self())->order('id', 'asc')->select()->toArray(); + Cache::set(self::CACHE_KEY_LIST, $list, self::CACHE_TTL); + } + + /** + * 从缓存取最小 real_ev + */ + public static function getCachedMinRealEv(): float + { + $list = self::getCachedList(); + if (empty($list)) { + return 0.0; + } + $vals = array_column($list, 'real_ev'); + $min = min($vals); + return (float) $min; + } + + /** + * 从缓存按档位取奖励列表 + * @return array + */ + public static function getCachedByTier(string $tier): array + { + $list = self::getCachedList(); + $rows = []; + foreach ($list as $row) { + if (isset($row['tier']) && (string) $row['tier'] === $tier) { + $rows[] = $row; + } + } + return $rows; + } + + /** 保存后刷新缓存 */ + public static function onAfterInsert($model): void + { + self::refreshCache(); + } + + /** 更新后刷新缓存 */ + public static function onAfterUpdate($model): void + { + self::refreshCache(); + } + + /** 删除后刷新缓存 */ + public static function onAfterDelete($model): void + { + self::refreshCache(); + } + /** 色子点数下限 */ public function searchGridNumberMinAttr($query, $value) {