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.
155 lines
5.4 KiB
155 lines
5.4 KiB
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Activity;
|
|
use App\Models\ActivitySession;
|
|
use App\Models\ActivitySignup;
|
|
use App\Models\ActivitySignupCheckin;
|
|
use App\Support\ApiResponse;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class ActivitySignupController extends Controller
|
|
{
|
|
use ApiResponse;
|
|
|
|
public function index(Request $request, int $activity): JsonResponse
|
|
{
|
|
Activity::query()->findOrFail($activity);
|
|
$sessionId = $request->query('activity_session_id');
|
|
$checkinStatus = $request->query('checkin_status');
|
|
|
|
$query = ActivitySignup::query()->where('activity_id', $activity)->orderByDesc('id');
|
|
|
|
if ($kw = $request->query('keyword')) {
|
|
$query->where(function ($q) use ($kw) {
|
|
$q->where('name', 'like', "%{$kw}%")
|
|
->orWhere('mobile', 'like', "%{$kw}%")
|
|
->orWhere('company', 'like', "%{$kw}%");
|
|
});
|
|
}
|
|
|
|
if ($sessionId) {
|
|
$sid = (int) $sessionId;
|
|
if ((string) $checkinStatus === '1') {
|
|
$query->whereHas('checkins', function ($q) use ($sid) {
|
|
$q->where('activity_session_id', $sid)->whereNotNull('checked_in_at');
|
|
});
|
|
} elseif ((string) $checkinStatus === '0') {
|
|
$query->whereDoesntHave('checkins', function ($q) use ($sid) {
|
|
$q->where('activity_session_id', $sid)->whereNotNull('checked_in_at');
|
|
});
|
|
}
|
|
}
|
|
|
|
$paginator = $query
|
|
->with(['checkins' => function ($q) use ($sessionId) {
|
|
if ($sessionId) {
|
|
$q->where('activity_session_id', (int) $sessionId);
|
|
}
|
|
}])
|
|
->paginate((int) $request->query('page_size', 20))
|
|
->withQueryString();
|
|
|
|
$paginator->getCollection()->transform(
|
|
fn (ActivitySignup $r) => $this->serialize($r, $sessionId ? (int) $sessionId : null)
|
|
);
|
|
|
|
return $this->paginated($paginator);
|
|
}
|
|
|
|
public function store(Request $request, int $activity): JsonResponse
|
|
{
|
|
Activity::query()->findOrFail($activity);
|
|
$data = $request->validate([
|
|
'activity_session_id' => ['nullable', 'integer', 'exists:activity_sessions,id'],
|
|
'name' => ['required', 'string', 'max:64'],
|
|
'mobile' => ['required', 'string', 'max:32'],
|
|
'company' => ['nullable', 'string', 'max:128'],
|
|
]);
|
|
|
|
if (! empty($data['activity_session_id'])) {
|
|
$sid = (int) $data['activity_session_id'];
|
|
$ok = ActivitySession::query()->where('activity_id', $activity)->where('id', $sid)->exists();
|
|
if (! $ok) {
|
|
return $this->fail('场次不属于该活动', 422);
|
|
}
|
|
}
|
|
|
|
$signup = ActivitySignup::query()->create([
|
|
'activity_id' => $activity,
|
|
'activity_session_id' => $data['activity_session_id'] ?? null,
|
|
'name' => $data['name'],
|
|
'mobile' => $data['mobile'],
|
|
'company' => $data['company'] ?? null,
|
|
'signed_up_at' => now(),
|
|
'status' => 1,
|
|
]);
|
|
|
|
return $this->ok(['id' => $signup->id], '报名已登记');
|
|
}
|
|
|
|
public function destroy(int $activity, int $signup): JsonResponse
|
|
{
|
|
$model = ActivitySignup::query()->where('activity_id', $activity)->findOrFail($signup);
|
|
$model->delete();
|
|
|
|
return $this->ok(null, '已删除');
|
|
}
|
|
|
|
public function checkin(Request $request, int $activity, int $signup): JsonResponse
|
|
{
|
|
Activity::query()->findOrFail($activity);
|
|
$model = ActivitySignup::query()->where('activity_id', $activity)->findOrFail($signup);
|
|
|
|
$data = $request->validate([
|
|
'activity_session_id' => ['required', 'integer', 'exists:activity_sessions,id'],
|
|
]);
|
|
|
|
$sessionId = (int) $data['activity_session_id'];
|
|
$ok = ActivitySession::query()->where('activity_id', $activity)->where('id', $sessionId)->exists();
|
|
if (! $ok) {
|
|
return $this->fail('场次不属于该活动', 422);
|
|
}
|
|
|
|
ActivitySignupCheckin::query()->updateOrCreate(
|
|
[
|
|
'activity_signup_id' => $model->id,
|
|
'activity_session_id' => $sessionId,
|
|
],
|
|
['checked_in_at' => now()]
|
|
);
|
|
|
|
return $this->ok(null, '签到成功');
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
protected function serialize(ActivitySignup $r, ?int $sessionId = null): array
|
|
{
|
|
$sessionCheckedInAt = null;
|
|
if ($sessionId) {
|
|
$checkin = $r->relationLoaded('checkins')
|
|
? $r->checkins->first()
|
|
: $r->checkins()->where('activity_session_id', $sessionId)->first();
|
|
$sessionCheckedInAt = $checkin?->checked_in_at;
|
|
}
|
|
|
|
return [
|
|
'id' => $r->id,
|
|
'activity_id' => $r->activity_id,
|
|
'activity_session_id' => $r->activity_session_id,
|
|
'name' => $r->name,
|
|
'mobile' => $r->mobile,
|
|
'company' => $r->company,
|
|
'signed_up_at' => $r->signed_up_at?->toIso8601String(),
|
|
'status' => (int) $r->status,
|
|
'activity_session_id_filter' => $sessionId,
|
|
'session_checked_in_at' => $sessionCheckedInAt?->toIso8601String(),
|
|
];
|
|
}
|
|
}
|