refactor:拆分 API 路由与请求校验,统一 final 类和代码风格

This commit is contained in:
2026-05-13 11:54:40 +08:00
parent 5d2dbdbe1d
commit 805847954d
281 changed files with 1886 additions and 1308 deletions

View File

@@ -2,9 +2,9 @@
namespace App\Support;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
/**
* 后台标准列表:`items` + `meta`current_page / per_page / total / last_page

View File

@@ -3,12 +3,12 @@
namespace App\Support;
use App\Models\OddsItem;
use App\Models\OddsVersion;
use App\Models\PlayConfigItem;
use App\Models\PlayConfigVersion;
use App\Models\PlayType;
use App\Models\OddsVersion;
use App\Models\RiskCapItem;
use App\Models\PlayConfigItem;
use App\Models\RiskCapVersion;
use App\Models\PlayConfigVersion;
/** 后台 API阶段 4 运营配置序列化(与其它 Admin*Controller 手写数组风格一致)。 */
final class AdminConfigPresenter

View File

@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace App\Support;
use App\Lottery\ErrorCode;
use Illuminate\Http\Request;
/**
* 【管理后台业务文案翻译辅助类】
*
* lang/{locale}/admin.php 等语言包取字符串,供 JSON 里「msg」字段使用。
* LotteryMessage 对应,专门处理管理端错误消息。
*/
final class AdminMessage
{
/**
* 取通用管理后台错误的用户可见文案lang/{locale}/admin.php
*
* @param string $key 语言包键名,如 'unauthenticated', 'permission_denied'
*/
public static function get(Request $request, string $key): string
{
$fallback = (string) config('lottery.locales.fallback', 'en');
$locale = (string) ($request->attributes->get('lottery_locale') ?? LotteryLocale::resolve($request));
$fullKey = 'admin.'.$key;
$msg = trans($fullKey, [], $locale);
if ($msg !== $fullKey) {
return $msg;
}
return trans($fullKey, [], $fallback);
}
/**
* 取错误码对应的用户可见文案。
*
* @param int $code {@see ErrorCode} 管理端段81108114
*/
public static function errorCode(Request $request, int $code): string
{
$fallback = (string) config('lottery.locales.fallback', 'en');
$locale = (string) ($request->attributes->get('lottery_locale') ?? LotteryLocale::resolve($request));
$key = 'admin.'.$code;
$msg = trans($key, [], $locale);
if ($msg !== $key) {
return $msg;
}
return trans($key, [], $fallback);
}
}

View File

@@ -2,12 +2,13 @@
namespace App\Support;
use App\Lottery\ErrorCode;
use Illuminate\Http\JsonResponse;
/**
* 对外 API 统一 JSON 结构:{ code, msg, data }
*
* - `code=0` {@see \App\Lottery\ErrorCode::Success};非 0 `ErrorCode` docs/04 §10。
* - `code=0` {@see ErrorCode::Success};非 0 `ErrorCode` docs/04 §10。
* - error() HTTP 状态可与 code 独立(如鉴权失败 401 + code 8001)。
*/
final class ApiResponse

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace App\Support;
use App\Models\Player;
use Illuminate\Http\Request;
/**
* 币种码解析工具。
*
* 统一处理 Query/Body 中的 currency 参数,支持回退到玩家默认币种或全局配置。
*/
final class CurrencyResolver
{
/**
* 从请求或玩家/配置回退解析币种码。
*
* @param Request $request 请求对象
* @param Player|null $player 玩家对象(用于回退)
* @param string $key 参数名(默认 currency
* @param string|null $default 默认币种码(不传则使用 player->default_currency config
*/
public static function resolve(
Request $request,
?Player $player = null,
string $key = 'currency',
?string $default = null,
): string {
$raw = $request->input($key) ?? $request->query($key);
if (is_string($raw) && $raw !== '') {
$code = strtoupper(substr(trim($raw), 0, 16));
} else {
$fallback = $default
?? $player?->default_currency
?? config('lottery.default_currency', 'NPR');
$code = strtoupper(substr(trim((string) $fallback), 0, 16));
}
return $code;
}
/**
* 验证币种码格式是否合法。
*
* 合法格式1-16 位字母数字,全大写。
*/
public static function isValid(string $code): bool
{
return preg_match('/^[A-Z0-9]{1,16}$/', $code) === 1;
}
/**
* 解析并验证币种码,无效时返回 null
*/
public static function resolveOrNull(
Request $request,
?Player $player = null,
string $key = 'currency',
?string $default = null,
): ?string {
$code = self::resolve($request, $player, $key, $default);
return self::isValid($code) ? $code : null;
}
}

View File

@@ -4,8 +4,8 @@ namespace App\Support;
use App\Models\Currency;
use App\Models\OddsItem;
use App\Models\OddsVersion;
use App\Models\PlayType;
use App\Models\OddsVersion;
use Illuminate\Support\Facades\DB;
/**

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace App\Support;
use Illuminate\Http\Request;
/**
* 分页请求参数解析 trait
*
* 统一处理 `page``per_page`/`size` 参数的合法化。
*/
trait PaginationTrait
{
/**
* 解析并限制每页条数。
*
* @param Request $request 请求对象
* @param string $key 参数名(默认 per_page
* @param int $default 默认值
* @param int $max 最大值上限
*/
protected function perPage(Request $request, string $key = 'per_page', int $default = 20, int $max = 50): int
{
$value = (int) $request->query($key, $request->query('size', $default));
return max(1, min($max, $value));
}
/**
* 解析当前页码(强制至少为 1)。
*/
protected function page(Request $request, string $key = 'page', int $default = 1): int
{
return max(1, (int) $request->query($key, $default));
}
/**
* 解析分页元数据数组。
*
* @return array{page: int, per_page: int}
*/
protected function paginationMeta(Request $request, int $defaultPerPage = 20, int $maxPerPage = 50): array
{
return [
'page' => $this->page($request),
'per_page' => $this->perPage($request, 'per_page', $defaultPerPage, $maxPerPage),
];
}
}