where('competition_id', $competition->id) ->whereKey($data['audience_session_id']) ->lockForUpdate() ->first(); if ($session === null) { throw ValidationException::withMessages([ 'audience_session_id' => ['场次不存在'], ]); } if (! $session->enabled) { throw ValidationException::withMessages([ 'audience_session_id' => ['该场次暂未开放报名'], ]); } $now = now()->timezone(BizDateTime::TIMEZONE); $status = $session->windowStatus($now); if ($status === AudienceSession::STATUS_NOT_STARTED) { throw ValidationException::withMessages([ 'audience_session_id' => ['该场次尚未开始报名'], ]); } if ($status === AudienceSession::STATUS_EXPIRED) { throw ValidationException::withMessages([ 'audience_session_id' => ['该场次报名已截止'], ]); } $already = AudienceRegistration::query() ->where('audience_session_id', $session->id) ->where('user_id', $user->id) ->exists(); if ($already) { throw ValidationException::withMessages([ 'audience_session_id' => ['您已报名该场次'], ]); } $count = AudienceRegistration::query() ->where('audience_session_id', $session->id) ->count(); if ($count >= (int) $session->capacity) { throw ValidationException::withMessages([ 'audience_session_id' => ['该场次已满额'], ]); } return AudienceRegistration::query()->create([ 'competition_id' => $competition->id, 'audience_session_id' => $session->id, 'user_id' => $user->id, 'name' => $data['name'], 'phone' => trim((string) $user->mobile), 'company' => $this->nullableText($data['company'] ?? null), 'job' => $this->nullableText($data['job'] ?? null), 'purpose' => $data['purpose'], 'registered_at' => now(), ]); }); } private function nullableText(mixed $value): ?string { $s = trim((string) ($value ?? '')); return $s === '' ? null : $s; } }