$row) { if (!is_array($row)) { throw new \RuntimeException('档位奖励表单第' . strval($idx + 1) . '条格式错误'); } $g = $row['grid_number'] ?? null; if (!is_numeric($g)) { throw new \RuntimeException('档位奖励表单第' . strval($idx + 1) . '条点数无效'); } $gi = intval(strval($g)); if ($gi < 5 || $gi > 30) { throw new \RuntimeException('档位奖励表单点数须在 5~30'); } $byGrid[$gi] = $row; } $cells = []; for ($i = 0; $i < 26; $i++) { $g = 5 + $i; if (!isset($byGrid[$g])) { throw new \RuntimeException('档位奖励表单缺少点数 ' . strval($g)); } $cells[$i] = self::normalizeCell($byGrid[$g], $i + 1); } self::assertLeopardOk($cells); $batch = []; for ($d = 5; $d <= 30; $d++) { $start = $d - 5; $endCw = ($start + $d) % 26; $x = $start - $d; $endCcw = $x >= 0 ? $x : 26 + $start - $d; $batch[] = self::buildInsertRow($gameChannelId, 0, $d, $start, $endCw, $cells[$endCw]); $batch[] = self::buildInsertRow($gameChannelId, 1, $d, $start, $endCcw, $cells[$endCcw]); } $now = time(); foreach ($batch as $k => $_) { $batch[$k]['create_time'] = $now; $batch[$k]['update_time'] = $now; } Db::startTrans(); try { Db::name('game_reward_weight')->where('game_channel_id', $gameChannelId)->delete(); Db::name('game_reward_weight')->insertAll($batch); Db::commit(); } catch (Throwable $e) { Db::rollback(); $msg = $e->getMessage(); if (str_contains($msg, 'game_reward_weight') || str_contains($msg, "doesn't exist")) { throw new \RuntimeException('写入失败:请确认已创建数据表 game_reward_weight 并已执行迁移。' . $msg); } throw $e; } } /** * @param list $cells */ private static function assertLeopardOk(array $cells): void { foreach (self::LEOPARD as $d) { $start = $d - 5; $endCw = ($start + $d) % 26; $x = $start - $d; $endCcw = $x >= 0 ? $x : 26 + $start - $d; foreach ([$endCw, $endCcw] as $idx) { $t = $cells[$idx]['tier']; if ($t === 'T4' || $t === 'T5') { throw new \RuntimeException( '豹子点数 ' . strval($d) . ' 的落点不能为 T4/T5,请先在档位表中调整后再生成权重对照' ); } } } } /** * @param array $row * @return array{ui_text: string, real_ev: float, tier: string, remark: string} */ private static function normalizeCell(array $row, int $rowNo): array { $ui = $row['ui_text'] ?? null; $ev = $row['real_ev'] ?? null; $tier = $row['tier'] ?? null; if (!is_string($ui) || trim($ui) === '') { throw new \RuntimeException('档位奖励表单第' . strval($rowNo) . '条显示文本不能为空'); } if ($ev === null || $ev === '' || !is_numeric($ev)) { throw new \RuntimeException('档位奖励表单第' . strval($rowNo) . '条实际中奖无效'); } if (!is_string($tier) || !in_array($tier, ['T1', 'T2', 'T3', 'T4', 'T5'], true)) { throw new \RuntimeException('档位奖励表单第' . strval($rowNo) . '条档位无效'); } $remark = $row['remark'] ?? ''; $remarkStr = is_string($remark) ? $remark : ''; return [ 'ui_text' => $ui, 'real_ev' => floatval(strval($ev)), 'tier' => $tier, 'remark' => $remarkStr, ]; } /** * @param array{ui_text: string, real_ev: float, tier: string, remark: string} $cell * @return array */ private static function buildInsertRow( int $gameChannelId, int $direction, int $gridNumber, int $startIndex, int $endIndex, array $cell ): array { return [ 'game_channel_id' => $gameChannelId, 'direction' => $direction, 'grid_number' => $gridNumber, 'start_index' => $startIndex, 'end_index' => $endIndex, 'ui_text' => $cell['ui_text'], 'real_ev' => $cell['real_ev'], 'tier' => $cell['tier'], 'type' => self::tierToType($cell['tier']), 'remark' => $cell['remark'], 'weight' => 1, ]; } private static function tierToType(string $tier): int { return match ($tier) { 'T1' => 3, 'T2' => 2, 'T3' => -1, 'T4' => -2, 'T5' => 1, }; } }