with(['creator:id,username']) ->whereIn('status', $this->summaryStatuses($request)) ->orderByRaw($this->summaryStatusOrder($request)) ->orderByDesc('starts_at') ->first(); $record = null; if ($event) { $record = $event->records()->where('user_id', $request->user()->id)->first(); } return response()->json([ 'event' => $event ? $this->transformEvent($event, $record) : null, ]); } /** * 返回最近的活动列表以及当前用户的领取记录。 */ public function history(Request $request): JsonResponse { $events = BaccaratLossCoverEvent::query() ->with(['creator:id,username', 'records' => function ($query) use ($request) { $query->where('user_id', $request->user()->id); }]) ->latest('starts_at') ->limit(20) ->get() ->map(function (BaccaratLossCoverEvent $event) { $record = $event->records->first(); return $this->transformEvent($event, $record); }); return response()->json([ 'events' => $events, ]); } /** * 领取指定活动的补偿金币。 */ public function claim(Request $request, BaccaratLossCoverEvent $event): JsonResponse { $result = $this->lossCoverService->claim($event, $request->user()); return response()->json($result); } /** * 将活动与个人记录整理为前端更容易消费的结构。 */ private function transformEvent(BaccaratLossCoverEvent $event, mixed $record): array { return [ 'id' => $event->id, 'title' => $event->title, 'description' => $event->description, 'status' => $event->status, 'status_label' => $event->statusLabel(), 'starts_at' => $event->starts_at?->toIso8601String(), 'ends_at' => $event->ends_at?->toIso8601String(), 'claim_deadline_at' => $event->claim_deadline_at?->toIso8601String(), 'participant_count' => $event->participant_count, 'compensable_user_count' => $event->compensable_user_count, 'total_loss_amount' => $event->total_loss_amount, 'total_claimed_amount' => $event->total_claimed_amount, 'creator_username' => $event->creator?->username ?? '管理员', 'my_record' => $record ? [ 'total_bet_amount' => $record->total_bet_amount, 'total_win_payout' => $record->total_win_payout, 'total_loss_amount' => $record->total_loss_amount, 'compensation_amount' => $record->compensation_amount, 'claim_status' => $record->claim_status, 'claim_status_label' => $record->claimStatusLabel(), 'claimed_amount' => $record->claimed_amount, 'claimed_at' => $record->claimed_at?->toIso8601String(), ] : null, ]; } /** * 按调用场景返回活动摘要允许出现的状态集合。 * * “当前活动”页签只展示未开始、进行中或结算中的活动, * 避免把已结束但仍可领取的历史活动误显示在当前页签里。 * * @return list */ private function summaryStatuses(Request $request): array { if ($request->string('scene')->toString() === 'overview') { return ['active', 'settlement_pending', 'scheduled']; } return ['active', 'settlement_pending', 'claimable', 'scheduled']; } /** * 按调用场景生成活动状态排序规则。 */ private function summaryStatusOrder(Request $request): string { if ($request->string('scene')->toString() === 'overview') { return "CASE status WHEN 'active' THEN 0 WHEN 'settlement_pending' THEN 1 WHEN 'scheduled' THEN 2 ELSE 3 END"; } return "CASE status WHEN 'active' THEN 0 WHEN 'settlement_pending' THEN 1 WHEN 'claimable' THEN 2 WHEN 'scheduled' THEN 3 ELSE 4 END"; } }