import CloseSvg from '@/components/CustomIcon/icons/close.svg'; import { getSubscription } from '@/services/user/portal'; import { useQuery } from '@tanstack/react-query'; import { Dialog, DialogContent, DialogTitle } from '@workspace/ui/components/dialog'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@workspace/ui/components/tabs'; import Image from 'next/image'; import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; // 定义数据类型 interface SubscriptionData { id: string; name: string; price: number; originalPrice: number; duration: string; features: { traffic: string; duration: string; onlineIPs: string; connections: string; bandwidth: string; nodes: string; stability: number; // 星级 1-5 }; } // 套餐卡片组件 const PlanCard = ({ plan, isSelected }: { plan: SubscriptionData; isSelected?: boolean }) => { return (
{/* 套餐名称 */}

{plan.name}

{/* 价格区域 */}
¥{plan.originalPrice} ${plan.price} /月

年付享受8折优惠

{/* 订阅按钮 */} {/* 功能列表 */}
可用流量: {plan.features.traffic}
套餐时长: {plan.features.duration}
在线IP: {plan.features.onlineIPs}
在线连接数: {plan.features.connections}
峰值带宽: {plan.features.bandwidth}
可用节点: {plan.features.nodes}
网络稳定指数:
{Array.from({ length: plan.features.stability }, (_, i) => ( ))}
); }; export interface OfferDialogRef { show: () => void; hide: () => void; } const OfferDialog = forwardRef((props, ref) => { const [open, setOpen] = useState(false); // 使用 useQuery 来管理请求 const { data, isLoading, error, refetch } = useQuery({ queryKey: ['subscription'], queryFn: async () => { try { const response = await getSubscription({ skipErrorHandler: true }); // 确保返回有效的数组,避免 undefined const list = response.data?.data?.list || []; return list as SubscriptionData[]; } catch (err) { // 自定义错误处理 console.error('获取订阅数据失败:', err); // 返回空数组而不是抛出错误,避免 queryFn 返回 undefined return [] as SubscriptionData[]; } }, enabled: false, // 初始不执行,手动控制 retry: 1, // 失败时重试1次 }); // 监听对话框打开状态,触发请求 useEffect(() => { if (open) { refetch(); // 对话框打开时重新获取数据 } }, [open, refetch]); useImperativeHandle(ref, () => ({ show: () => setOpen(true), hide: () => setOpen(false), })); // 处理数据 const processedData = data?.map((item) => ({ ...item, displayPrice: `¥${item.price}`, displayDuration: item.duration === 'year' ? '年付' : '月付', })) || []; // 如果没有数据,使用模拟数据 const mockData: SubscriptionData[] = [ { id: '1', name: 'Basic Plan', price: 8, originalPrice: 10, duration: 'year', isPopular: false, features: { traffic: '140G', duration: '30天', onlineIPs: '3个', connections: '300', bandwidth: '200Mbps', nodes: '15个', stability: 3, }, }, { id: '2', name: 'Standard Plan', price: 24, originalPrice: 30, duration: 'year', features: { traffic: '160G', duration: '30天', onlineIPs: '3个', connections: '300', bandwidth: '300Mbps', nodes: '15个', stability: 4, }, }, { id: '3', name: 'Pro Plan', price: 48, originalPrice: 60, duration: 'year', isPopular: false, features: { traffic: '180G', duration: '30天', onlineIPs: '3个', connections: '300', bandwidth: '500Mbps', nodes: '29个', stability: 5, }, }, ]; // 使用真实数据或模拟数据 const displayData = mockData; // 按类型分组数据 const yearlyPlans = displayData.filter((item) => item.duration === 'year'); const monthlyPlans = displayData.filter((item) => item.duration === 'month'); console.log(processedData); return ( } closeClassName={ 'right-6 top-6 font-bold text-black opacity-100 focus:ring-0 focus:ring-offset-0' } > 选择套餐
选择最适合您的服务套餐
年付套餐 月付套餐 {isLoading ? (

加载中...

) : error ? (

加载失败,请重试

) : yearlyPlans.length > 0 ? (
{/* 卡片容器 */}
{yearlyPlans.map((plan, index) => ( ))}
) : (

暂无年付套餐

)}
{isLoading ? (

加载中...

) : error ? (

加载失败,请重试

) : monthlyPlans.length > 0 ? (
{/* 连接线 */}
{/* 卡片容器 */}
{monthlyPlans.map((plan, index) => ( ))}
) : (

暂无月付套餐

)}
); }); export default OfferDialog;