user(); // 会员等级按后台排序字段展示,方便用户对比不同档位权益。 $vipLevels = VipLevel::query() ->withCount('users') ->orderByDesc('sort_order') ->orderBy('id') ->get(); // 仅展示当前用户自己的购买记录,避免泄露其他会员订单信息。 $paymentLogs = $this->buildPaymentLogs($user->id); $paidOrders = VipPaymentOrder::query() ->where('user_id', $user->id) ->where('status', 'paid') ->count(); $totalAmount = (float) VipPaymentOrder::query() ->where('user_id', $user->id) ->where('status', 'paid') ->sum('amount'); $data = [ 'user' => [ 'id' => $user->id, 'username' => $user->username, 'is_vip' => $user->isVip(), 'vip_name' => $user->vipName(), 'hy_time' => $user->hy_time?->format('Y-m-d H:i'), 'vip_level_id' => $user->vip_level_id, 'can_customize' => $user->canCustomizeVipPresence(), 'custom_join_message' => $user->custom_join_message, 'custom_leave_message' => $user->custom_leave_message, 'custom_join_effect' => $user->custom_join_effect, 'custom_leave_effect' => $user->custom_leave_effect, 'vip_level' => $user->vipLevel ? [ 'id' => $user->vipLevel->id, 'name' => $user->vipLevel->name, 'icon' => $user->vipLevel->icon, 'color' => $user->vipLevel->color, 'join_effect' => $user->vipLevel->joinEffectKey(), 'join_banner' => $user->vipLevel->joinBannerStyleKey(), 'leave_effect' => $user->vipLevel->leaveEffectKey(), 'leave_banner' => $user->vipLevel->leaveBannerStyleKey(), 'join_templates' => $user->vipLevel->join_templates_array, 'leave_templates' => $user->vipLevel->leave_templates_array, ] : null, ], 'vipLevels' => $vipLevels->map(function ($vip) { return [ 'id' => $vip->id, 'name' => $vip->name, 'icon' => $vip->icon, 'color' => $vip->color, 'price' => $vip->price, 'duration_days' => $vip->duration_days, 'exp_multiplier' => $vip->exp_multiplier, 'jjb_multiplier' => $vip->jjb_multiplier, 'description' => $vip->description, ]; }), 'paymentLogs' => $paymentLogs->items(), 'vipPaymentEnabled' => Sysparam::getValue('vip_payment_enabled', '0') === '1', 'paidOrders' => $paidOrders, 'totalAmount' => $totalAmount, 'effectOptions' => [ 'none' => '无特效', 'fireworks' => '烟花', 'rain' => '下雨', 'lightning' => '闪电', 'snow' => '下雪', 'sakura' => '樱花飘落', 'meteors' => '流星', 'gold-rain' => '金币雨', 'hearts' => '爱心飘落', 'confetti' => '彩带庆典', 'fireflies' => '萤火虫', ], 'bannerStyleOptions' => [ 'aurora' => '鎏光星幕', 'storm' => '雷霆风暴', 'royal' => '王者金辉', 'cosmic' => '星穹幻彩', 'farewell' => '告别暮光', ], ]; if ($request->expectsJson()) { return response()->json([ 'status' => 'success', 'data' => $data, ]); } return view('vip.center', $data); } /** * 保存会员个人自定义欢迎语与离开语。 */ public function updatePresenceSettings(UpdateVipPresenceSettingsRequest $request): RedirectResponse|\Illuminate\Http\JsonResponse { $user = $request->user(); // 只有有效会员且当前等级允许自定义时,才允许保存专属语句。 if (! $user->canCustomizeVipPresence()) { if ($request->expectsJson()) { return response()->json([ 'status' => 'error', 'message' => '当前会员等级暂不支持自定义欢迎语和离开语。', ], 403); } return redirect() ->route('vip.center') ->with('error', '当前会员等级暂不支持自定义欢迎语和离开语。'); } $data = $request->validated(); // 空字符串统一转成 null,避免数据库保存无意义空白值。 $user->update([ 'custom_join_message' => $this->sanitizeNullableMessage($data['custom_join_message'] ?? null), 'custom_leave_message' => $this->sanitizeNullableMessage($data['custom_leave_message'] ?? null), 'custom_join_effect' => $data['custom_join_effect'] ?? null, 'custom_leave_effect' => $data['custom_leave_effect'] ?? null, ]); if ($request->expectsJson()) { return response()->json([ 'status' => 'success', 'message' => '设置已保存。', ]); } return redirect() ->route('vip.center') ->with('success', '设置已保存。'); } /** * 构建当前用户的购买记录分页数据 * * @param int $userId 当前登录用户 ID */ private function buildPaymentLogs(int $userId): LengthAwarePaginator { return VipPaymentOrder::query() ->with('vipLevel:id,name,color,icon') ->where('user_id', $userId) ->latest('id') ->paginate(10) ->withQueryString(); } /** * 将可空文案统一整理为数据库可保存的字符串。 */ private function sanitizeNullableMessage(?string $message): ?string { $message = trim((string) $message); return $message === '' ? null : $message; } }