85 lines
2.6 KiB
PHP
85 lines
2.6 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api\V1\Admin\Auth;
|
||
|
||
use App\Models\AdminUser;
|
||
use App\Lottery\ErrorCode;
|
||
use Illuminate\Support\Str;
|
||
use App\Support\ApiResponse;
|
||
use Illuminate\Http\JsonResponse;
|
||
use App\Http\Controllers\Controller;
|
||
use Illuminate\Support\Facades\Hash;
|
||
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 extends Controller
|
||
{
|
||
public function __invoke(AdminLoginRequest $request, AdminCaptchaService $captcha): JsonResponse
|
||
{
|
||
$locale = $request->lotteryLocale();
|
||
|
||
$data = $request->validated();
|
||
|
||
if (! $captcha->verify($data['captcha_key'], $data['captcha_code'])) {
|
||
return ApiResponse::error(
|
||
trans('admin.invalid_captcha', [], $locale),
|
||
ErrorCode::AdminCaptchaInvalid->value,
|
||
null,
|
||
422,
|
||
);
|
||
}
|
||
|
||
$normalizedAccount = Str::lower(trim($data['account']));
|
||
|
||
/** @var AdminUser|null $admin */
|
||
$admin = AdminUser::query()->where('username', $normalizedAccount)->first();
|
||
|
||
$passwordOk = $admin !== null && Hash::check($data['password'], $admin->password);
|
||
|
||
if (! $passwordOk) {
|
||
/** 统一措辞,弱化枚举用户 */
|
||
return ApiResponse::error(
|
||
trans('admin.invalid_credentials', [], $locale),
|
||
ErrorCode::AdminCredentialsInvalid->value,
|
||
null,
|
||
401,
|
||
);
|
||
}
|
||
|
||
if ((int) $admin->status !== 0) {
|
||
return ApiResponse::error(
|
||
trans('admin.account_disabled', [], $locale),
|
||
ErrorCode::AdminAccountDisabled->value,
|
||
null,
|
||
403,
|
||
);
|
||
}
|
||
|
||
$ttlDays = (int) config('lottery.admin_api.token_ttl_days', 7);
|
||
$plainToken = $admin->createToken(
|
||
'admin-api',
|
||
['*'],
|
||
now()->addDays(max(1, $ttlDays)),
|
||
)->plainTextToken;
|
||
|
||
$admin->forceFill(['last_login_at' => now()])->save();
|
||
|
||
return ApiResponse::success([
|
||
'token' => $plainToken,
|
||
'token_type' => 'Bearer',
|
||
'admin' => [
|
||
'id' => $admin->id,
|
||
'username' => $admin->username,
|
||
'nickname' => $admin->name,
|
||
'email' => $admin->email,
|
||
'permissions' => $admin->fresh()->adminPermissionSlugs(),
|
||
],
|
||
]);
|
||
}
|
||
}
|