map(fn ($item) => [ 'id' => $item->id, 'name' => $item->name, 'slug' => $item->slug, 'description' => $item->description, 'icon' => $item->icon, 'price' => $item->price, 'type' => $item->type, 'duration_days' => $item->duration_days, ]); return response()->json([ 'items' => $items, 'user_jjb' => $user->jjb ?? 0, 'active_week_effect' => $this->shopService->getActiveWeekEffect($user), 'has_rename_card' => $this->shopService->hasRenameCard($user), ]); } /** * 购买商品 * * 单次特效卡额外支持: * - recipient 接收者用户名(传 "all" 或留空则全员可见) * - message 公屏赠言(可选) * * @param Request $request 含 item_id, recipient?, message? */ public function buy(Request $request): JsonResponse { $request->validate(['item_id' => 'required|integer|exists:shop_items,id']); $item = ShopItem::find($request->item_id); if (! $item->is_active) { return response()->json(['status' => 'error', 'message' => '该商品已下架。'], 400); } $result = $this->shopService->buyItem(Auth::user(), $item); if (! $result['ok']) { return response()->json(['status' => 'error', 'message' => $result['message']], 400); } $response = ['status' => 'success', 'message' => $result['message']]; // ── 单次特效卡:广播给指定用户或全员 ──────────────────────── if (isset($result['play_effect'])) { $user = Auth::user(); $roomId = (int) $request->room_id; $recipient = trim($request->input('recipient', '')); // 空字符串 = 全员 $message = trim($request->input('message', '')); // recipient 为空或 "all" 表示全员 $targetUsername = ($recipient === '' || $recipient === 'all') ? null : $recipient; // 广播特效事件(全员频道) broadcast(new EffectBroadcast( roomId: $roomId, type: $result['play_effect'], operator: $user->username, targetUsername: $targetUsername, giftMessage: $message ?: null, ))->toOthers(); // 同时前端也需要播放(自己也要看到) $response['play_effect'] = $result['play_effect']; $response['target_username'] = $targetUsername; $response['gift_message'] = $message ?: null; // 公屏系统消息 if ($roomId > 0) { $icons = [ 'fireworks' => '🎆', 'rain' => '🌧', 'lightning' => '⚡', 'snow' => '❄️', ]; // 赠礼消息文案(改成“为XX触发了一场特效”) $icon = $icons[$result['play_effect']] ?? '✨'; $toStr = $targetUsername ? "【{$targetUsername}】" : '全体聊友'; $remarkPart = $message ? " 「{$message}」" : ''; $sysContent = "{$icon} {$user->username} 为 {$toStr} 燃放了一场【{$item->name}】特效!{$remarkPart}"; // 广播系统消息到公屏(字段名与前端 appendMessage() 保持一致) $sysMsgEvent = new MessageSent( roomId: $roomId, message: [ 'id' => 0, 'room_id' => $roomId, 'from_user' => '系统传音', // 触发金色左边框样式(已有处理分支) 'to_user' => '大家', 'content' => $sysContent, 'font_color' => '#cc6600', 'sent_at' => now()->format('H:i:s'), 'is_secret' => false, 'action' => null, ] ); broadcast($sysMsgEvent); } } // 返回最新金币余额 $response['jjb'] = Auth::user()->fresh()->jjb; return response()->json($response); } /** * 使用改名卡修改昵称 * * @param Request $request 含 new_name */ public function rename(Request $request): JsonResponse { $request->validate([ 'new_name' => 'required|string|min:1|max:10', ]); $result = $this->shopService->useRenameCard(Auth::user(), $request->new_name); if (! $result['ok']) { return response()->json(['status' => 'error', 'message' => $result['message']], 400); } return response()->json(['status' => 'success', 'message' => $result['message']]); } }