user(); // 活动是否在领取有效期内 if (! $event->isClaimable()) { return response()->json(['ok' => false, 'message' => '活动已结束或已过期。']); } // 查找该用户的领取记录(批量插入时已生成) $claim = HolidayClaim::query() ->where('event_id', $event->id) ->where('user_id', $user->id) ->lockForUpdate() ->first(); if (! $claim) { return response()->json(['ok' => false, 'message' => '您不在本次福利名单内,或活动已结束。']); } // 防止重复领取(claimed_at 为 null 表示未领取) // 由于批量 insert 时直接写入 claimed_at,需要增加一个 is_claimed 字段 // 这里用数据库唯一约束保障幂等性:直接返回已领取的提示 return DB::transaction(function () use ($event, $claim, $user): JsonResponse { // 金币入账 $this->currency->change( $user, 'gold', $claim->amount, CurrencySource::HOLIDAY_BONUS, "节日福利:{$event->name}", ); // 更新活动统计(只在首次领取时) HolidayEvent::query() ->where('id', $event->id) ->increment('claimed_amount', $claim->amount); // 删除领取记录(以此标记"已领取",防止重复调用) $claim->delete(); // 检查是否已全部领完 if ($event->max_claimants > 0) { $remaining = HolidayClaim::where('event_id', $event->id)->count(); if ($remaining === 0) { $event->update(['status' => 'completed']); } } return response()->json([ 'ok' => true, 'message' => "🎉 恭喜!已领取 {$claim->amount} 金币!", 'amount' => $claim->amount, ]); }); } /** * 查询当前用户在指定活动中的待领取状态。 */ public function status(Request $request, HolidayEvent $event): JsonResponse { $user = $request->user(); $claim = HolidayClaim::query() ->where('event_id', $event->id) ->where('user_id', $user->id) ->first(); return response()->json([ 'claimable' => $claim !== null && $event->isClaimable(), 'amount' => $claim?->amount ?? 0, 'expires_at' => $event->expires_at?->toIso8601String(), ]); } }