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; $query->where('activity_session_id', $sid); 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 */ 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(), ]; } }