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,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Audit;
use App\Http\Controllers\Controller;
use App\Models\AuditLog;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/audit-logs 运营/客服查询审计留痕。

View File

@@ -2,9 +2,9 @@
namespace App\Http\Controllers\Api\V1\Admin\Auth;
use App\Services\AdminCaptchaService;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Services\AdminCaptchaService;
/**
* GET /api/v1/admin/auth/captcha

View File

@@ -2,38 +2,28 @@
namespace App\Http\Controllers\Api\V1\Admin\Auth;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Services\AdminCaptchaService;
use App\Lottery\ErrorCode;
use Illuminate\Support\Str;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use App\Services\AdminCaptchaService;
use App\Http\Requests\Admin\AdminLoginRequest;
/**
* POST /api/v1/admin/auth/login
*
* Body: account登录账号 username 对应ASCII 仅存小写比对、password、captcha_key、captcha_code。
*/
final class LoginController
final class LoginController extends Controller
{
public function __invoke(Request $request, AdminCaptchaService $captcha): JsonResponse
public function __invoke(AdminLoginRequest $request, AdminCaptchaService $captcha): JsonResponse
{
$locale = $request->lotteryLocale();
/** @var array{account:string,password:string,captcha_key:string,captcha_code:string} $data */
$data = validator($request->all(), [
'account' => ['required', 'string', 'min:2', 'max:64', 'regex:/^[a-zA-Z0-9._-]+$/u'],
'password' => ['required', 'string', 'max:256'],
'captcha_key' => ['required', 'string', 'uuid'],
'captcha_code' => ['required', 'string', 'max:32'],
], [], [
'account' => 'account',
'password' => 'password',
'captcha_key' => 'captcha_key',
'captcha_code' => 'captcha_code',
])->validate();
$data = $request->validated();
if (! $captcha->verify($data['captcha_key'], $data['captcha_code'])) {
return ApiResponse::error(

View File

@@ -2,17 +2,17 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use App\Models\OddsVersion;
use App\Services\Config\OddsStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Support\AdminConfigPresenter;
use App\Services\Config\OddsStreamService;
/** PUT /api/v1/admin/config/odds-versions/{id}/items */
final class OddsItemsReplaceController extends Controller

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\OddsVersion;
use App\Services\Config\OddsStreamService;
use App\Support\AdminApiList;
use App\Support\AdminConfigPresenter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
use App\Services\Config\OddsStreamService;
/** GET /api/v1/admin/config/odds-versions */
final class OddsVersionIndexController extends Controller

View File

@@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use App\Models\OddsVersion;
use App\Support\ApiResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Models\OddsVersion;
use App\Services\Config\OddsStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Services\Config\OddsStreamService;
/** POST /api/v1/admin/config/odds-versions/{id}/publish */
final class OddsVersionPublishController extends Controller

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\OddsVersion;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
/** GET /api/v1/admin/config/odds-versions/{id} */
final class OddsVersionShowController extends Controller

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Services\Config\OddsStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
use App\Services\Config\OddsStreamService;
/** POST /api/v1/admin/config/odds-versions */
final class OddsVersionStoreController extends Controller

View File

@@ -2,17 +2,17 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Models\PlayConfigVersion;
use App\Services\Config\PlayConfigStreamService;
use App\Support\AdminConfigPresenter;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Models\PlayConfigVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Support\AdminConfigPresenter;
use App\Services\Config\PlayConfigStreamService;
/** PUT /api/v1/admin/config/play-versions/{id}/items */
final class PlayConfigItemsReplaceController extends Controller

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\PlayConfigVersion;
use App\Services\Config\PlayConfigStreamService;
use App\Support\AdminApiList;
use App\Support\AdminConfigPresenter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use App\Models\PlayConfigVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
use App\Services\Config\PlayConfigStreamService;
/** GET /api/v1/admin/config/play-versions */
final class PlayConfigVersionIndexController extends Controller

View File

@@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\Request;
use App\Models\PlayConfigVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Models\PlayConfigVersion;
use App\Services\Config\PlayConfigStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Services\Config\PlayConfigStreamService;
/** POST /api/v1/admin/config/play-versions/{id}/publish */
final class PlayConfigVersionPublishController extends Controller

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\PlayConfigVersion;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use App\Models\PlayConfigVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
/** GET /api/v1/admin/config/play-versions/{id} */
final class PlayConfigVersionShowController extends Controller

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Services\Config\PlayConfigStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
use App\Services\Config\PlayConfigStreamService;
/** POST /api/v1/admin/config/play-versions — 新建草稿(默认克隆当前 active若无则按 play_types 生成)。 */
final class PlayConfigVersionStoreController extends Controller

View File

@@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\Request;
use App\Models\RiskCapVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Models\RiskCapVersion;
use App\Services\Config\RiskCapStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Services\Config\RiskCapStreamService;
/** PUT /api/v1/admin/config/risk-cap-versions/{id}/items */
final class RiskCapItemsReplaceController extends Controller

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\RiskCapVersion;
use App\Services\Config\RiskCapStreamService;
use App\Support\AdminApiList;
use App\Support\AdminConfigPresenter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use App\Models\RiskCapVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
use App\Services\Config\RiskCapStreamService;
/** GET /api/v1/admin/config/risk-cap-versions */
final class RiskCapVersionIndexController extends Controller

View File

@@ -2,16 +2,16 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\Request;
use App\Models\RiskCapVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\ConfigVersionStatus;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Models\RiskCapVersion;
use App\Services\Config\RiskCapStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Services\Config\RiskCapStreamService;
/** POST /api/v1/admin/config/risk-cap-versions/{id}/publish */
final class RiskCapVersionPublishController extends Controller

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\RiskCapVersion;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use App\Models\RiskCapVersion;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
/** GET /api/v1/admin/config/risk-cap-versions/{id} */
final class RiskCapVersionShowController extends Controller

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Config;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Services\Config\RiskCapStreamService;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
use App\Services\Config\RiskCapStreamService;
/** POST /api/v1/admin/config/risk-cap-versions */
final class RiskCapVersionStoreController extends Controller

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Dashboard;
use App\Http\Controllers\Controller;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Services\Admin\AdminDashboardSnapshotBuilder;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Services\Admin\AdminDashboardSnapshotBuilder;
/**
* GET /api/v1/admin/dashboard 首页仪表盘聚合数据(需登录;按权限返回子块)。

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Draw;
use App\Http\Controllers\Controller;
use App\Models\Draw;
use App\Models\SettlementBatch;
use App\Models\TicketItem;
use App\Models\TicketOrder;
use App\Support\ApiResponse;
use App\Models\SettlementBatch;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/draws/{draw}/finance-summary 单期投注/派彩汇总(客服/财务视角PRD §15.4)。

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Draw;
use App\Http\Controllers\Controller;
use App\Models\Draw;
use App\Support\AdminApiList;
use Carbon\Carbon;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\JsonResponse;
use App\Models\Draw;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
/**
* GET /api/v1/admin/draws 期号列表。

View File

@@ -2,12 +2,12 @@
namespace App\Http\Controllers\Api\V1\Admin\Draw;
use App\Http\Controllers\Controller;
use App\Models\Draw;
use App\Models\DrawResultBatch;
use App\Models\DrawResultItem;
use App\Support\ApiResponse;
use App\Models\DrawResultItem;
use App\Models\DrawResultBatch;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/draws/{draw}/result-batches 开奖批次与号码(审核/结果核对)。

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Draw;
use Carbon\Carbon;
use App\Models\Draw;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Lottery\DrawResultBatchStatus;
use App\Models\Draw;
use App\Services\Draw\DrawHallSnapshotBuilder;
use App\Support\ApiResponse;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
/**
* GET /api/v1/admin/draws/{draw} 当期状态明细(后台查看 DB 为准 + 大厅展示态预览)。

View File

@@ -2,20 +2,20 @@
namespace App\Http\Controllers\Api\V1\Admin\Draw;
use App\Http\Controllers\Controller;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Models\Draw;
use App\Models\DrawResultBatch;
use App\Services\Draw\DrawPublishService;
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Models\DrawResultBatch;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Services\Draw\DrawPublishService;
/**
* POST /api/v1/admin/draws/{draw}/result-batches/{batch}/publish 人工审核发布 RNG 批次。
*/
class DrawResultBatchPublishController extends Controller
final class DrawResultBatchPublishController extends Controller
{
public function __construct(
private readonly DrawPublishService $publishService,

View File

@@ -2,14 +2,14 @@
namespace App\Http\Controllers\Api\V1\Admin\Draw;
use App\Http\Controllers\Controller;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Models\Draw;
use App\Services\Settlement\SettlementOrchestrator;
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Services\Settlement\SettlementOrchestrator;
/**
* POST /api/v1/admin/draws/{draw}/settlement/run `settling` 期号执行结算(可关自动结算时手工触发)。

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Jackpot;
use App\Http\Controllers\Controller;
use App\Models\JackpotContribution;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Models\JackpotContribution;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/jackpot/contributions Jackpot 蓄水流水。

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Jackpot;
use App\Http\Controllers\Controller;
use App\Models\JackpotPayoutLog;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use App\Models\JackpotPayoutLog;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/jackpot/payout-logs Jackpot 派彩(爆池)记录。

View File

@@ -2,10 +2,10 @@
namespace App\Http\Controllers\Api\V1\Admin\Jackpot;
use App\Http\Controllers\Controller;
use App\Models\JackpotPool;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/jackpot/pools Jackpot 奖池配置列表。

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Jackpot;
use App\Http\Controllers\Controller;
use App\Models\JackpotPool;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* PUT /api/v1/admin/jackpot/pools/{pool} 更新奖池运营参数(蓄水比例、阈值等)。

View File

@@ -2,15 +2,15 @@
namespace App\Http\Controllers\Api\V1\Admin;
use App\Http\Controllers\Controller;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* Bearer Token 必填({@see EnsureAdminApi} + Sanctum确认 `/api/v1/admin` 鉴权链路可达。
* 路由GET /api/v1/admin/ping
*/
class PingController extends Controller
final class PingController extends Controller
{
public function __invoke(): JsonResponse
{

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin;
use App\Http\Controllers\Controller;
use App\Models\PlayType;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
/** GET /api/v1/admin/play-types */
final class PlayTypeIndexController extends Controller

View File

@@ -2,12 +2,12 @@
namespace App\Http\Controllers\Api\V1\Admin;
use App\Http\Controllers\Controller;
use App\Models\PlayType;
use App\Support\AdminConfigPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminConfigPresenter;
/** PATCH /api/v1/admin/play-types/{play_code} — 主目录层开关与展示名(不等同于版本化 items。 */
final class PlayTypePatchController extends Controller

View File

@@ -2,12 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Player;
use App\Http\Controllers\Controller;
use App\Models\Player;
use App\Models\TicketItem;
use App\Support\ApiResponse;
use App\Support\PaginationTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\AdminPlayerTicketItemsRequest;
/**
* GET /api/v1/admin/players/{player}/ticket-items 客服/财务按玩家查注单PRD §15.4)。
@@ -16,17 +17,16 @@ use Illuminate\Http\Request;
*/
final class AdminPlayerTicketItemsIndexController extends Controller
{
public function __invoke(Request $request, Player $player): JsonResponse
{
$validated = validator($request->query(), [
'page' => ['sometimes', 'integer', 'min:1'],
'per_page' => ['sometimes', 'integer', 'min:1', 'max:50'],
'draw_no' => ['sometimes', 'nullable', 'string', 'max:32'],
])->validate();
use PaginationTrait;
$perPage = max(1, min(50, (int) ($validated['per_page'] ?? 20)));
$page = max(1, (int) ($validated['page'] ?? 1));
$drawNo = isset($validated['draw_no']) ? trim((string) $validated['draw_no']) : '';
public function __invoke(AdminPlayerTicketItemsRequest $request, Player $player): JsonResponse
{
$perPage = $this->perPage($request, 'per_page', 20, 50);
$page = $this->page($request);
$drawNo = $request->validated('draw_no');
if (is_string($drawNo)) {
$drawNo = trim($drawNo);
}
$query = TicketItem::query()
->where('ticket_items.player_id', $player->id)

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Player;
use App\Http\Controllers\Controller;
use App\Models\Player;
use App\Models\PlayerWallet;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* 后台:按玩家查询钱包余额(`player_wallets` 全币种)。

View File

@@ -2,12 +2,12 @@
namespace App\Http\Controllers\Api\V1\Admin\Reconcile;
use App\Http\Controllers\Controller;
use App\Models\ReconcileItem;
use App\Models\ReconcileJob;
use Illuminate\Http\Request;
use App\Models\ReconcileItem;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
/** GET /api/v1/admin/reconcile-jobs/{reconcile_job}/items */
final class ReconcileItemIndexController extends Controller

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Reconcile;
use App\Http\Controllers\Controller;
use App\Models\ReconcileJob;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
/** GET /api/v1/admin/reconcile-jobs */
final class ReconcileJobIndexController extends Controller

View File

@@ -2,10 +2,10 @@
namespace App\Http\Controllers\Api\V1\Admin\Reconcile;
use App\Http\Controllers\Controller;
use App\Models\ReconcileJob;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/** GET /api/v1/admin/reconcile-jobs/{reconcile_job} */
final class ReconcileJobShowController extends Controller

View File

@@ -2,32 +2,23 @@
namespace App\Http\Controllers\Api\V1\Admin\Reconcile;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Services\Admin\AdminReconcileJobService;
use App\Support\ApiResponse;
use Carbon\Carbon;
use App\Models\AdminUser;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\Admin\AdminReconcileJobService;
use App\Http\Requests\Admin\ReconcileJobStoreRequest;
/** POST /api/v1/admin/reconcile-jobs */
final class ReconcileJobStoreController extends Controller
{
public function __invoke(Request $request, AdminReconcileJobService $service): JsonResponse
public function __invoke(ReconcileJobStoreRequest $request, AdminReconcileJobService $service): JsonResponse
{
/** @var AdminUser $admin */
$admin = $request->lotteryAdmin();
$data = validator($request->all(), [
'reconcile_type' => ['required', 'string', 'max:32'],
'period_start' => ['nullable', 'date'],
'period_end' => ['nullable', 'date', 'after_or_equal:period_start'],
'items' => ['nullable', 'array', 'max:5000'],
'items.*.side_a_ref' => ['nullable', 'string', 'max:128'],
'items.*.side_b_ref' => ['nullable', 'string', 'max:128'],
'items.*.difference_amount' => ['nullable', 'integer'],
'items.*.status' => ['nullable', 'string', 'max:32'],
])->validate();
$data = $request->validated();
$job = $service->createJob(
$admin,

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Reports;
use App\Http\Controllers\Controller;
use App\Models\ReportJob;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
/** GET /api/v1/admin/report-jobs */
final class ReportJobIndexController extends Controller

View File

@@ -2,10 +2,10 @@
namespace App\Http\Controllers\Api\V1\Admin\Reports;
use App\Http\Controllers\Controller;
use App\Models\ReportJob;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/** GET /api/v1/admin/report-jobs/{report_job} */
final class ReportJobShowController extends Controller

View File

@@ -2,26 +2,22 @@
namespace App\Http\Controllers\Api\V1\Admin\Reports;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Services\Admin\AdminReportJobService;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\Admin\AdminReportJobService;
use App\Http\Requests\Admin\ReportJobStoreRequest;
/** POST /api/v1/admin/report-jobs */
final class ReportJobStoreController extends Controller
{
public function __invoke(Request $request, AdminReportJobService $service): JsonResponse
public function __invoke(ReportJobStoreRequest $request, AdminReportJobService $service): JsonResponse
{
/** @var AdminUser $admin */
$admin = $request->lotteryAdmin();
$data = validator($request->all(), [
'report_type' => ['required', 'string', 'max:64'],
'export_format' => ['sometimes', 'string', 'in:csv,xlsx'],
'filter_json' => ['nullable', 'array'],
])->validate();
$data = $request->validated();
$job = $service->enqueue(
$admin,

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Risk;
use App\Http\Controllers\Controller;
use App\Models\Draw;
use App\Models\RiskPool;
use App\Support\AdminApiList;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
/**
* GET /api/v1/admin/draws/{draw}/risk-pools 按期号分页查询赔付池事实(售罄筛选、排序)。

View File

@@ -2,13 +2,13 @@
namespace App\Http\Controllers\Api\V1\Admin\Risk;
use App\Http\Controllers\Controller;
use App\Models\Draw;
use App\Models\RiskPoolLockLog;
use App\Support\AdminApiList;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use App\Models\RiskPoolLockLog;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
/**
* GET /api/v1/admin/draws/{draw}/risk-pool-lock-logs 风险池占用/释放流水(审计与监控)。

View File

@@ -21,7 +21,12 @@ final class AdminRiskPoolShowController extends Controller
public function __invoke(Request $request, Draw $draw, string $number_4d): JsonResponse
{
if (preg_match('/^[0-9]{4}$/', $number_4d) !== 1) {
return ApiResponse::error('normalized_number 须为 4 位数字', ErrorCode::ValidationFailed->value, null, 422);
return ApiResponse::error(
trans('api.validation_failed', [], $request->lotteryLocale()),
ErrorCode::ValidationFailed->value,
null,
422,
);
}
$pool = RiskPool::query()
@@ -30,7 +35,12 @@ final class AdminRiskPoolShowController extends Controller
->first();
if ($pool === null) {
return ApiResponse::error('该期尚无此号码的风险池记录', ErrorCode::NotFound->value, null, 404);
return ApiResponse::error(
trans('api.not_found', [], $request->lotteryLocale()),
ErrorCode::NotFound->value,
null,
404,
);
}
$p = AdminApiList::readPaging($request, 20, AdminApiList::MAX_PER_PAGE);

View File

@@ -2,12 +2,12 @@
namespace App\Http\Controllers\Api\V1\Admin\Settlement;
use App\Http\Controllers\Controller;
use App\Models\SettlementBatch;
use App\Models\TicketSettlementDetail;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use App\Models\SettlementBatch;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Models\TicketSettlementDetail;
/**
* GET /api/v1/admin/settlement-batches/{batch}/details 该批次下注单结算明细分页。

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\Settlement;
use App\Http\Controllers\Controller;
use App\Models\SettlementBatch;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use App\Models\SettlementBatch;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/settlement-batches 结算批次分页列表。

View File

@@ -2,10 +2,10 @@
namespace App\Http\Controllers\Api\V1\Admin\Settlement;
use App\Http\Controllers\Controller;
use App\Models\SettlementBatch;
use App\Support\ApiResponse;
use App\Models\SettlementBatch;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
/**
* GET /api/v1/admin/settlement-batches/{batch} 单批次摘要。

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Models\AdminRole;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
/** GET /api/v1/admin/admin-user-permission-catalog */
final class AdminPermissionCatalogController extends Controller

View File

@@ -2,14 +2,14 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Lottery\ErrorCode;
use App\Models\AdminUser;
use App\Services\AuditLogger;
use App\Support\AdminUserApiPresenter;
use App\Lottery\ErrorCode;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Services\AuditLogger;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminUserApiPresenter;
/** DELETE /api/v1/admin/admin-users/{admin_user} */
final class AdminUserDestroyController extends Controller

View File

@@ -2,12 +2,12 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Support\AdminApiList;
use App\Support\AdminUserApiPresenter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Support\AdminApiList;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminUserApiPresenter;
/** GET /api/v1/admin/admin-users */
final class AdminUserIndexController extends Controller

View File

@@ -2,27 +2,20 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Support\AdminPermissionBridge;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
use App\Support\AdminPermissionBridge;
use App\Http\Requests\Admin\AdminUserPermissionSyncRequest;
/** PUT /api/v1/admin/admin-users/{admin_user}/permissions */
final class AdminUserPermissionSyncController extends Controller
{
public function __invoke(Request $request, AdminUser $admin_user): JsonResponse
public function __invoke(AdminUserPermissionSyncRequest $request, AdminUser $admin_user): JsonResponse
{
/** @var array{permission_slugs:list<string>} $data */
$data = validator($request->all(), [
'permission_slugs' => ['required', 'array'],
'permission_slugs.*' => ['string', 'max:128', 'distinct', Rule::in(AdminPermissionBridge::allLegacySlugs())],
])->validate();
$slugs = array_values(array_unique($data['permission_slugs']));
$slugs = array_values(array_unique($request->validated('permissions')));
$siteId = AdminUser::defaultAdminSiteId();
$codes = [];

View File

@@ -2,25 +2,18 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\AdminUserRoleSyncRequest;
/** PUT /api/v1/admin/admin-users/{admin_user}/roles */
final class AdminUserRoleSyncController extends Controller
{
public function __invoke(Request $request, AdminUser $admin_user): JsonResponse
public function __invoke(AdminUserRoleSyncRequest $request, AdminUser $admin_user): JsonResponse
{
/** @var array{role_slugs:list<string>} $data */
$data = validator($request->all(), [
'role_slugs' => ['required', 'array'],
'role_slugs.*' => ['string', 'max:64', 'distinct', Rule::exists('admin_roles', 'slug')],
])->validate();
$slugs = array_values(array_unique($data['role_slugs']));
$slugs = array_values(array_unique($request->validated('role_slugs')));
$admin_user->syncRoleSlugsForDefaultSite($slugs);
$admin_user->load('roles');

View File

@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Support\AdminUserApiPresenter;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Support\AdminUserApiPresenter;
/** GET /api/v1/admin/admin-users/{admin_user} */
final class AdminUserShowController extends Controller

View File

@@ -2,55 +2,40 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Services\AuditLogger;
use App\Support\AdminUserApiPresenter;
use App\Support\ApiResponse;
use App\Services\AuditLogger;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Http\Controllers\Controller;
use App\Support\AdminUserApiPresenter;
use App\Http\Requests\Admin\AdminUserStoreRequest;
/** POST /api/v1/admin/admin-users */
/**
* 管理员用户创建。
*
* POST /api/v1/admin/admin-users
*/
final class AdminUserStoreController extends Controller
{
public function __invoke(Request $request): JsonResponse
public function __invoke(AdminUserStoreRequest $request): JsonResponse
{
/** @var AdminUser $actor */
$actor = $request->lotteryAdmin();
$payload = $request->all();
if (isset($payload['username']) && is_string($payload['username'])) {
$payload['username'] = Str::lower(trim($payload['username']));
}
if (array_key_exists('email', $payload) && $payload['email'] === '') {
$payload['email'] = null;
}
$data = validator($payload, [
'username' => ['required', 'string', 'min:2', 'max:64', 'regex:/^[a-zA-Z0-9._-]+$/u', 'unique:admin_users,username'],
'nickname' => ['required', 'string', 'max:128'],
'email' => ['nullable', 'string', 'email', 'max:255'],
'password' => ['required', 'string', 'min:8', 'max:256'],
'status' => ['sometimes', 'integer', 'in:0,1'],
'role_slugs' => ['required', 'array', 'min:1'],
'role_slugs.*' => ['string', 'max:64', 'distinct', 'exists:admin_roles,slug'],
])->validate();
$email = is_string($data['email'] ?? null) && trim($data['email']) !== ''
? trim($data['email'])
$email = is_string($request->validated('email'))
? trim($request->validated('email'))
: null;
$roleSlugs = array_values(array_unique($data['role_slugs']));
$roleSlugs = array_values(array_unique($request->validated('role_slugs')));
$user = DB::transaction(function () use ($data, $email, $roleSlugs): AdminUser {
$user = DB::transaction(function () use ($request, $email, $roleSlugs): AdminUser {
$created = AdminUser::query()->create([
'username' => $data['username'],
'name' => $data['nickname'],
'username' => $request->validated('username'),
'name' => $request->validated('nickname'),
'email' => $email,
'password' => $data['password'],
'status' => array_key_exists('status', $data) ? (int) $data['status'] : 0,
'password' => $request->validated('password'),
'status' => $request->validated('status', 0),
]);
$created->syncRoleSlugsForDefaultSite($roleSlugs);

View File

@@ -2,19 +2,18 @@
namespace App\Http\Controllers\Api\V1\Admin\User;
use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Services\AuditLogger;
use App\Support\AdminUserApiPresenter;
use App\Support\ApiResponse;
use App\Services\AuditLogger;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
use App\Support\AdminUserApiPresenter;
use App\Http\Requests\Admin\AdminUserUpdateRequest;
/** PUT /api/v1/admin/admin-users/{admin_user} */
final class AdminUserUpdateController extends Controller
{
public function __invoke(Request $request, AdminUser $admin_user): JsonResponse
public function __invoke(AdminUserUpdateRequest $request, AdminUser $admin_user): JsonResponse
{
/** @var AdminUser $actor */
$actor = $request->lotteryAdmin();
@@ -22,18 +21,7 @@ final class AdminUserUpdateController extends Controller
$admin_user->load('roles');
$before = AdminUserApiPresenter::listItem($admin_user);
$payload = $request->all();
if (array_key_exists('email', $payload) && $payload['email'] === '') {
$payload['email'] = null;
}
/** @var array{nickname?:string,email?:?string,password?:?string,status?:int} $data */
$data = validator($payload, [
'nickname' => ['sometimes', 'string', 'max:128'],
'email' => ['sometimes', 'nullable', 'string', 'email', 'max:255', Rule::unique('admin_users', 'email')->ignore($admin_user->id)],
'password' => ['sometimes', 'nullable', 'string', 'min:8', 'max:256'],
'status' => ['sometimes', 'integer', Rule::in([0, 1])],
])->validate();
$data = $request->validated();
$updates = [];
if (array_key_exists('nickname', $data)) {

View File

@@ -2,11 +2,12 @@
namespace App\Http\Controllers\Api\V1\Admin\Wallet;
use App\Http\Controllers\Controller;
use App\Models\TransferOrder;
use App\Support\ApiResponse;
use App\Models\TransferOrder;
use App\Support\PaginationTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\TransferOrderListRequest;
/**
* 后台:转账单列表(主站 彩票 {@see transfer_orders})。
@@ -25,26 +26,16 @@ use Illuminate\Http\Request;
*/
final class TransferOrderListController extends Controller
{
use PaginationTrait;
private const ALLOWED_STATUS = ['processing', 'success', 'failed', 'pending_reconcile'];
public function __invoke(Request $request): JsonResponse
public function __invoke(TransferOrderListRequest $request): JsonResponse
{
$validated = validator($request->query(), [
'page' => ['sometimes', 'integer', 'min:1'],
'per_page' => ['sometimes', 'integer', 'min:1', 'max:100'],
'size' => ['sometimes', 'integer', 'min:1', 'max:100'],
'player_id' => ['sometimes', 'nullable', 'integer', 'min:1'],
'player_account' => ['sometimes', 'nullable', 'string', 'max:128'],
'transfer_no' => ['sometimes', 'nullable', 'string', 'max:96'],
'external_ref_no' => ['sometimes', 'nullable', 'string', 'max:96'],
'created_from' => ['sometimes', 'nullable', 'date_format:Y-m-d'],
'created_to' => ['sometimes', 'nullable', 'date_format:Y-m-d'],
'status' => ['sometimes', 'nullable', 'string', 'max:256'],
])->validate();
$validated = $request->validated();
$perPage = (int) ($validated['per_page'] ?? $validated['size'] ?? 20);
$perPage = min(100, max(1, $perPage));
$page = max(1, (int) ($validated['page'] ?? 1));
$perPage = $this->perPage($request, 'per_page', 20, 100);
$page = $this->page($request);
$query = TransferOrder::query()
->with(['player:id,site_code,site_player_id,username,nickname'])

View File

@@ -2,11 +2,12 @@
namespace App\Http\Controllers\Api\V1\Admin\Wallet;
use App\Http\Controllers\Controller;
use App\Models\WalletTxn;
use App\Support\ApiResponse;
use App\Support\PaginationTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\WalletTransactionListRequest;
/**
* 后台:彩票钱包流水列表 {@see wallet_txns}
@@ -25,27 +26,16 @@ use Illuminate\Http\Request;
*/
final class WalletTransactionListController extends Controller
{
use PaginationTrait;
private const ALLOWED_STATUS = ['posted', 'pending_reconcile'];
public function __invoke(Request $request): JsonResponse
public function __invoke(WalletTransactionListRequest $request): JsonResponse
{
$validated = validator($request->query(), [
'page' => ['sometimes', 'integer', 'min:1'],
'per_page' => ['sometimes', 'integer', 'min:1', 'max:100'],
'size' => ['sometimes', 'integer', 'min:1', 'max:100'],
'player_id' => ['sometimes', 'nullable', 'integer', 'min:1'],
'player_account' => ['sometimes', 'nullable', 'string', 'max:128'],
'txn_no' => ['sometimes', 'nullable', 'string', 'max:96'],
'external_ref_no' => ['sometimes', 'nullable', 'string', 'max:96'],
'created_from' => ['sometimes', 'nullable', 'date_format:Y-m-d'],
'created_to' => ['sometimes', 'nullable', 'date_format:Y-m-d'],
'biz_type' => ['sometimes', 'nullable', 'string', 'max:64'],
'status' => ['sometimes', 'nullable', 'string', 'max:128'],
])->validate();
$validated = $request->validated();
$perPage = (int) ($validated['per_page'] ?? $validated['size'] ?? 20);
$perPage = min(100, max(1, $perPage));
$page = max(1, (int) ($validated['page'] ?? 1));
$perPage = $this->perPage($request, 'per_page', 20, 100);
$page = $this->page($request);
$query = WalletTxn::query()
->with(['player:id,site_code,site_player_id,username,nickname'])