'rebate_rules', 'backflow' => 'backflow_rules']; public static function categories(): array { return ShareDefaults::categories(); } public static function get(string $type): array { $table = self::table($type); $categories = $rules = []; foreach (self::categories() as $value => $label) { $categories[] = ['value' => $value, 'label' => $label]; $rules[$value] = []; } $query = DB::table($table)->orderBy('category'); if ($type === 'rebate') $query->orderBy('level')->orderBy('min_effective_amount'); else $query->orderBy('min_loss_amount'); foreach ($query->get() as $row) { if (!array_key_exists($row->category, $rules)) continue; $rules[$row->category][] = self::present($type, $row); } $result = ['type' => $type, 'categories' => $categories, 'rules' => $rules]; if ($type === 'rebate') { $result['levels'] = DB::table('level')->orderBy('level')->get(['level', 'level_name']) ->map(fn ($row) => ['level' => (int) $row->level, 'level_name' => (string) $row->level_name])->all(); } return $result; } public static function save(string $type, array $params): array { $table = self::table($type); $plain = 'regex:/^\d{1,12}(?:\.\d{1,4})?$/D'; $money = 'regex:/^\d{1,12}(?:\.\d{1,2})?$/D'; $amount = ['required', 'numeric', $money, 'min:0']; $rules = ['category' => ['required', 'string', Rule::in(array_keys(self::categories()))], 'rules' => ['present', 'array', 'max:200'], 'rules.*' => ['array'], 'rules.*.turnover_multiple' => ['required', 'numeric', $money, 'min:0', 'max:999999']]; if ($type === 'rebate') { $rules['rules.*.level'] = ['required', 'integer', Rule::in(DB::table('level')->pluck('level')->map(fn ($v) => (int) $v)->all())]; $rules['rules.*.min_effective_amount'] = $amount; $rules['rules.*.percentage'] = ['required', 'numeric', $plain, 'min:0', 'max:100']; } else { $rules['rules.*.min_loss_amount'] = $amount; $rules['rules.*.reward_amount'] = $amount; } $params = validator($params, $rules, [], ['rules.*.level' => '会员等级', 'rules.*.percentage' => '返回百分比', 'rules.*.min_effective_amount' => '有效投注', 'rules.*.min_loss_amount' => '亏损金额', 'rules.*.reward_amount' => '奖励金额', 'rules.*.turnover_multiple' => '需要打码量'])->validate(); $rows = $seen = []; $now = now(); foreach ($params['rules'] as $rule) { $row = ['category' => $params['category'], 'turnover_multiple' => self::decimal($rule['turnover_multiple']), 'created_at' => $now, 'updated_at' => $now]; if ($type === 'rebate') { $row += ['level' => (int) $rule['level'], 'min_effective_amount' => self::decimal($rule['min_effective_amount']), 'percentage' => bcadd((string) $rule['percentage'], '0', 4)]; $key = $row['level'] . '|' . $row['min_effective_amount']; } else { $row += ['min_loss_amount' => self::decimal($rule['min_loss_amount']), 'reward_amount' => self::decimal($rule['reward_amount'])]; $key = $row['min_loss_amount']; } if (isset($seen[$key])) { throw ValidationException::withMessages(['rules' => $type === 'rebate' ? '同一会员等级的有效投注门槛不能重复' : '亏损金额门槛不能重复']); } $seen[$key] = true; $rows[] = $row; } DB::transaction(function () use ($table, $params, $rows) { DB::table($table)->where('category', $params['category'])->delete(); if ($rows) DB::table($table)->insert($rows); }); return self::get($type); } /** Rules of one type grouped by category, highest threshold first, for settlement. */ public static function tiers(string $type): array { $tiers = []; $threshold = $type === 'rebate' ? 'min_effective_amount' : 'min_loss_amount'; foreach (DB::table(self::table($type))->orderByDesc($threshold)->get() as $row) { $tiers[$row->category][] = self::present($type, $row); } return $tiers; } private static function present(string $type, object $row): array { $data = ['id' => (int) $row->id, 'category' => (string) $row->category]; if ($type === 'rebate') { $data += ['level' => (int) $row->level, 'min_effective_amount' => self::decimal($row->min_effective_amount), 'percentage' => bcadd((string) $row->percentage, '0', 4)]; } else { $data += ['min_loss_amount' => self::decimal($row->min_loss_amount), 'reward_amount' => self::decimal($row->reward_amount)]; } return $data + ['turnover_multiple' => self::decimal($row->turnover_multiple)]; } private static function decimal($value): string { return bcadd((string) $value, '0', 2); } private static function table(string $type): string { if (!isset(self::TABLES[$type])) throw new InvalidArgumentException('奖励类型错误'); return self::TABLES[$type]; } }