'净亏邀请奖励', 8 => '首充奖励', 9 => '转盘活动']; } public static function defaults(int $type): array { $common = ['turnover_ratio' => '0.00']; return $common + match ($type) { 7 => ['loss_amount' => '500.00', 'invite_count' => 3, 'reward_amount' => '500.00'], 8 => ['min_deposit' => '100.00', 'reward_amount' => '10.00'], 9 => ['completion_probability' => '20.00', 'online_seconds' => 3600, 'deposit_amount' => '3000.00', 'team_deposit_amount' => '500.00', 'bet_amount' => '5000.00', 'team_bet_amount' => '3000.00'], default => [], }; } public static function normalize(int $type, array $input): array { $defaults = self::defaults($type); Validator::make(['params' => $input], ['params' => ['array:' . implode(',', array_keys($defaults))]])->validate(); $data = array_replace($defaults, $input); $rules = []; foreach ($data as $key => $value) { $rules[$key] = match ($key) { 'invite_count' => ['required', 'integer', 'min:1', 'max:1000'], 'online_seconds' => ['required', 'integer', 'min:60', 'max:86400'], 'completion_probability' => ['required', 'numeric', 'between:0,100', 'regex:/^\d{1,3}(\.\d{1,2})?$/'], 'turnover_ratio' => ['required', 'numeric', 'between:0,10000', 'regex:/^\d{1,5}(\.\d{1,2})?$/'], default => ['required', 'numeric', 'gt:0', 'regex:/^\d{1,12}(\.\d{1,2})?$/'], }; } Validator::make($data, $rules)->validate(); foreach ($data as $key => $value) $data[$key] = in_array($key, ['invite_count', 'online_seconds'], true) ? (int)$value : bcadd((string)$value, '0', 2); return $data; } public static function draw(int $coins, bool $complete, string $probability, ?callable $random = null): array { $random ??= fn (int $min, int $max) => random_int($min, $max); $remaining = 66600 - $coins; if ($remaining <= 0) throw new \LogicException('请先领取本轮奖金'); $hit = $complete && $random(1, 10000) <= (int)bcmul($probability, '100', 0); if ($hit) return ['prize_index' => 0, 'amount_cents' => $remaining, 'reached' => true]; // Choose eligible sectors before drawing. A fixed face value is never truncated. $eligible = [0]; foreach (self::PRIZES as $i => $amount) if ($i && (int)$amount * 100 < $remaining) $eligible[] = $i; $index = $eligible[$random(0, count($eligible) - 1)]; $amount = $index === 0 ? $random(0, $remaining - 1) : (int)self::PRIZES[$index] * 100; return ['prize_index' => $index, 'amount_cents' => $amount, 'reached' => false]; } }