*/ public static function getCachedList(): array { $inst = self::getCachedInstance(); return $inst['list'] ?? []; } /** * 重新从数据库加载并写入缓存(DiceRewardConfig 新增/修改/删除后调用),构建列表与索引 * 实例化结果含完整行(含 weight),供 playStart 从缓存中查找 BIGWIN 的 weight 按概率抽奖 */ public static function refreshCache(): void { $list = (new self())->order('id', 'asc')->select()->toArray(); $byTier = []; $byTierGrid = []; $bySEndIndex = []; $byNEndIndex = []; foreach ($list as $row) { $tier = isset($row['tier']) ? (string) $row['tier'] : ''; if ($tier !== '') { // 过滤 tier=BIGWIN:不参与档位抽奖,仅豹子时通过 getCachedByTierAndGridNumber('BIGWIN', ...) 使用 if ($tier !== 'BIGWIN') { if (!isset($byTier[$tier])) { $byTier[$tier] = []; } $byTier[$tier][] = $row; } $gridNum = isset($row['grid_number']) ? (int) $row['grid_number'] : 0; if (!isset($byTierGrid[$tier])) { $byTierGrid[$tier] = []; } if (!isset($byTierGrid[$tier][$gridNum])) { $byTierGrid[$tier][$gridNum] = $row; } } $sEnd = isset($row['s_end_index']) ? (int) $row['s_end_index'] : 0; if (!isset($bySEndIndex[$sEnd])) { $bySEndIndex[$sEnd] = []; } $bySEndIndex[$sEnd][] = $row; $nEnd = isset($row['n_end_index']) ? (int) $row['n_end_index'] : 0; if (!isset($byNEndIndex[$nEnd])) { $byNEndIndex[$nEnd] = []; } $byNEndIndex[$nEnd][] = $row; } $minRealEv = empty($list) ? 0.0 : (float) min(array_column($list, 'real_ev')); self::$instance = [ 'list' => $list, 'by_tier' => $byTier, 'by_tier_grid' => $byTierGrid, 'by_s_end_index' => $bySEndIndex, 'by_n_end_index' => $byNEndIndex, 'min_real_ev' => $minRealEv, ]; Cache::set(self::CACHE_KEY_INSTANCE, self::$instance, self::CACHE_TTL); } /** 空实例结构 */ private static function buildEmptyInstance(): array { return [ 'list' => [], 'by_tier' => [], 'by_tier_grid' => [], 'by_s_end_index' => [], 'by_n_end_index' => [], 'min_real_ev' => 0.0, ]; } /** * 从缓存实例按档位 + 色子点数取一条奖励配置(用于超级大奖 tier=BIGWIN + grid_number=roll_number) * 返回行含 weight(0-100):playStart 据此概率抽奖,weight=100 表示摇到该 roll_number 时 100% 中超级大奖 * @param string $tier 档位,如 BIGWIN * @param int $gridNumber 色子点数(摇出总和 roll_number) * @return array|null 配置行(含 weight、real_ev 等)或 null */ public static function getCachedByTierAndGridNumber(string $tier, int $gridNumber): ?array { $inst = self::getCachedInstance(); $byTierGrid = $inst['by_tier_grid'] ?? []; $tierData = $byTierGrid[$tier] ?? []; $row = $tierData[$gridNumber] ?? null; return is_array($row) ? $row : null; } /** * 从缓存取最小 real_ev */ public static function getCachedMinRealEv(): float { $inst = self::getCachedInstance(); return (float) ($inst['min_real_ev'] ?? 0.0); } /** * 从缓存按档位取奖励列表 * @return array */ public static function getCachedByTier(string $tier): array { $inst = self::getCachedInstance(); $byTier = $inst['by_tier'] ?? []; return $byTier[$tier] ?? []; } /** * 从缓存按顺时针结束索引取列表(s_end_index = id 的配置) * @return array */ public static function getCachedBySEndIndex(int $id): array { $inst = self::getCachedInstance(); $by = $inst['by_s_end_index'] ?? []; return $by[$id] ?? []; } /** * 从缓存按逆时针结束索引取列表(n_end_index = id 的配置) * @return array */ public static function getCachedByNEndIndex(int $id): array { $inst = self::getCachedInstance(); $by = $inst['by_n_end_index'] ?? []; return $by[$id] ?? []; } /** * 清除当前请求内实例(如测试或需强制下次读缓存时调用) */ public static function clearRequestInstance(): void { self::$instance = null; } /** 保存后刷新缓存 */ 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) { if ($value !== '' && $value !== null) { $query->where('grid_number', '>=', $value); } } /** 色子点数上限 */ public function searchGridNumberMaxAttr($query, $value) { if ($value !== '' && $value !== null) { $query->where('grid_number', '<=', $value); } } /** 前端显示文本模糊 */ public function searchUiTextAttr($query, $value) { if ($value !== '' && $value !== null) { $query->where('ui_text', 'like', '%' . $value . '%'); } } /** 真实资金结算下限 */ public function searchRealEvMinAttr($query, $value) { if ($value !== '' && $value !== null) { $query->where('real_ev', '>=', $value); } } /** 真实资金结算上限 */ public function searchRealEvMaxAttr($query, $value) { if ($value !== '' && $value !== null) { $query->where('real_ev', '<=', $value); } } /** 所属档位 */ public function searchTierAttr($query, $value) { if ($value !== '' && $value !== null) { $query->where('tier', '=', $value); } } /** 权重下限(仅 tier=BIGWIN 时有意义) */ public function searchWeightMinAttr($query, $value) { if ($value !== '' && $value !== null) { $query->where('weight', '>=', $value); } } /** 权重上限 */ public function searchWeightMaxAttr($query, $value) { if ($value !== '' && $value !== null) { $query->where('weight', '<=', $value); } } }