You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
5.3 KiB
145 lines
5.3 KiB
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Activity;
|
|
use App\Models\TicketGrabEvent;
|
|
use App\Models\VerifyPortalCredential;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
|
|
class VerifyPortalAuthController extends Controller
|
|
{
|
|
/**
|
|
* 登录页展示用:根据短码或旧 portal 参数解析活动/抢票名称(无需登录)。
|
|
*/
|
|
public function portalPreview(Request $request): JsonResponse
|
|
{
|
|
$code = strtolower(trim((string) $request->query('portal_code', '')));
|
|
$portalToken = trim((string) $request->query('portal_token', ''));
|
|
|
|
$activity = null;
|
|
$tg = null;
|
|
|
|
if ($code !== '') {
|
|
$activity = Activity::query()->where('verify_portal_code', $code)->first();
|
|
if (! $activity) {
|
|
$tg = TicketGrabEvent::query()->where('verify_portal_code', $code)->first();
|
|
}
|
|
} elseif ($portalToken !== '' && strlen($portalToken) >= 32) {
|
|
$activity = Activity::query()->where('verify_portal_token', $portalToken)->first();
|
|
if (! $activity) {
|
|
$tg = TicketGrabEvent::query()->where('verify_portal_token', $portalToken)->first();
|
|
}
|
|
}
|
|
|
|
if (! $activity && ! $tg) {
|
|
return response()->json(['message' => '无效的核销入口'], 404);
|
|
}
|
|
|
|
$title = $activity ? (string) $activity->title : (string) $tg->title;
|
|
|
|
return response()->json(['event_title' => $title]);
|
|
}
|
|
|
|
public function login(Request $request): JsonResponse
|
|
{
|
|
$data = $request->validate([
|
|
'portal_code' => ['nullable', 'string', 'max:16'],
|
|
'portal_token' => ['nullable', 'string', 'max:64'],
|
|
'username' => ['required', 'string', 'max:64'],
|
|
'password' => ['required', 'string', 'max:72'],
|
|
]);
|
|
|
|
$code = strtolower(trim((string) ($data['portal_code'] ?? '')));
|
|
$portalToken = trim((string) ($data['portal_token'] ?? ''));
|
|
|
|
if ($code === '' && ($portalToken === '' || strlen($portalToken) < 32)) {
|
|
return response()->json(['message' => '请提供核销入口短码或有效入口参数'], 422);
|
|
}
|
|
|
|
$activity = null;
|
|
$tg = null;
|
|
|
|
if ($code !== '') {
|
|
$activity = Activity::query()->where('verify_portal_code', $code)->first();
|
|
if (! $activity) {
|
|
$tg = TicketGrabEvent::query()->where('verify_portal_code', $code)->first();
|
|
}
|
|
} elseif ($portalToken !== '' && strlen($portalToken) >= 32) {
|
|
$activity = Activity::query()->where('verify_portal_token', $portalToken)->first();
|
|
if (! $activity) {
|
|
$tg = TicketGrabEvent::query()->where('verify_portal_token', $portalToken)->first();
|
|
}
|
|
}
|
|
|
|
if ($activity) {
|
|
$kind = VerifyPortalCredential::KIND_ACTIVITY;
|
|
$portalId = (int) $activity->id;
|
|
} elseif ($tg) {
|
|
$kind = VerifyPortalCredential::KIND_TICKET_GRAB;
|
|
$portalId = (int) $tg->id;
|
|
} else {
|
|
return response()->json(['message' => '无效的核销入口'], 404);
|
|
}
|
|
|
|
$cred = VerifyPortalCredential::query()
|
|
->where('portal_kind', $kind)
|
|
->where('portal_id', $portalId)
|
|
->where('username', $data['username'])
|
|
->first();
|
|
|
|
if (! $cred || ! Hash::check($data['password'], $cred->password)) {
|
|
return response()->json(['message' => '账号或密码错误'], 422);
|
|
}
|
|
|
|
if (! $cred->portalAcceptsVerification()) {
|
|
return response()->json(['message' => '活动已结束,无法登录核销'], 422);
|
|
}
|
|
|
|
$cred->tokens()->delete();
|
|
$expiresAt = now()->addMonths(6);
|
|
$plain = $cred->createToken('verify-portal', ['verify-portal'], $expiresAt)->plainTextToken;
|
|
|
|
return response()->json([
|
|
'token' => $plain,
|
|
'auth_mode' => 'verify_portal',
|
|
'portal_kind' => $kind,
|
|
'portal_id' => $portalId,
|
|
]);
|
|
}
|
|
|
|
public function me(Request $request): JsonResponse
|
|
{
|
|
$cred = $request->user();
|
|
if (! $cred instanceof VerifyPortalCredential) {
|
|
return response()->json(['message' => '非核销门户登录态'], 403);
|
|
}
|
|
|
|
if (! $cred->portalAcceptsVerification()) {
|
|
$cred->tokens()->delete();
|
|
|
|
return response()->json(['message' => '活动已结束,核销已失效'], 403);
|
|
}
|
|
|
|
$cred->load('venue:id,name');
|
|
$title = '';
|
|
if ($cred->portal_kind === VerifyPortalCredential::KIND_ACTIVITY) {
|
|
$title = (string) Activity::query()->where('id', $cred->portal_id)->value('title');
|
|
} else {
|
|
$title = (string) TicketGrabEvent::query()->where('id', $cred->portal_id)->value('title');
|
|
}
|
|
|
|
return response()->json([
|
|
'auth_mode' => 'verify_portal',
|
|
'portal_kind' => $cred->portal_kind,
|
|
'portal_id' => $cred->portal_id,
|
|
'username' => $cred->username,
|
|
'venue' => $cred->venue ? ['id' => $cred->venue->id, 'name' => $cred->venue->name] : null,
|
|
'event_title' => $title,
|
|
]);
|
|
}
|
|
}
|