import React, { useState, useMemo } from 'react'; import { Card, Row, Col, Switch, Tag, Typography, Space, Button, Modal, Progress, Divider, Alert, Tabs, Table, message, Statistic, Timeline, Badge, Tooltip, Radio, Empty, Steps, theme, ConfigProvider } from 'antd'; import type { ColumnsType } from 'antd/es/table'; import { CrownOutlined, RobotOutlined, ShopOutlined, GlobalOutlined, LineChartOutlined, ApiOutlined, CheckCircleOutlined, CloseCircleOutlined, ThunderboltOutlined, StarOutlined, ArrowUpOutlined, ArrowDownOutlined, InfoCircleOutlined, GiftOutlined, SafetyOutlined, RocketOutlined, TeamOutlined, ClockCircleOutlined, DollarOutlined, CheckSquareOutlined, CloseSquareOutlined, RightOutlined, } from '@ant-design/icons'; import { useUser, FEATURES, ROLE_CONFIG } from '@/contexts/UserContext'; const { Title, Text, Paragraph } = Typography; interface FeatureConfig { key: string; name: string; description: string; icon: React.ReactNode; requiredPlan: string[]; benefits: string[]; limitations?: string[]; popularity?: number; category: 'core' | 'advanced' | 'enterprise'; } const FEATURE_CONFIGS: FeatureConfig[] = [ { key: FEATURES.AI_OPERATIONS, name: 'AI运营中心', description: '智能运营助手,自动化执行日常运营任务', icon: , requiredPlan: ['basic', 'pro', 'enterprise'], benefits: [ '自动选品推荐', '智能定价策略', '自动上下架', 'AI决策日志追踪', '策略市场访问', ], limitations: [ '免费版: 每日仅3次AI调用', '基础版: 每日100次AI调用', '专业版: 无限AI调用', ], popularity: 95, category: 'core', }, { key: FEATURES.AUTO_PRICING, name: '自动定价', description: '基于市场数据和竞争分析的智能定价系统', icon: , requiredPlan: ['pro', 'enterprise'], benefits: [ '实时竞品价格监控', '动态定价策略', '利润率自动优化', '价格预警通知', ], limitations: [ '基础版: 仅查看定价建议', '专业版: 自动执行定价', ], popularity: 88, category: 'advanced', }, { key: FEATURES.MULTI_SHOP, name: '多店铺管理', description: '统一管理多个电商平台的店铺', icon: , requiredPlan: ['basic', 'pro', 'enterprise'], benefits: [ '跨平台商品同步', '统一库存管理', '多店铺数据报表', '批量操作支持', ], limitations: [ '免费版: 仅支持1个店铺', '基础版: 最多3个店铺', '专业版: 最多10个店铺', '企业版: 无限店铺', ], popularity: 92, category: 'core', }, { key: FEATURES.B2B_TRADE, name: 'B2B贸易', description: '企业级批发贸易管理功能', icon: , requiredPlan: ['basic', 'pro', 'enterprise'], benefits: [ '供应商管理', '批量订单处理', 'B2B专属定价', '合同管理', ], popularity: 75, category: 'core', }, { key: FEATURES.INDEPENDENT_SITE, name: '独立站', description: '创建和管理独立电商网站', icon: , requiredPlan: ['pro', 'enterprise'], benefits: [ '自定义品牌站点', '独立域名绑定', 'SEO优化工具', '独立支付集成', ], popularity: 65, category: 'advanced', }, { key: FEATURES.ADVANCED_ANALYTICS, name: '高级数据分析', description: '深度数据分析和可视化报表', icon: , requiredPlan: ['pro', 'enterprise'], benefits: [ '自定义报表', '数据导出', '趋势预测', '竞品分析报告', ], limitations: [ '基础版: 仅基础报表', '专业版: 完整分析功能', ], popularity: 80, category: 'advanced', }, { key: FEATURES.API_ACCESS, name: 'API访问', description: '开放API接口,支持系统集成', icon: , requiredPlan: ['enterprise'], benefits: [ 'RESTful API', 'Webhook支持', 'SDK下载', '技术文档', ], popularity: 55, category: 'enterprise', }, ]; const PLAN_DETAILS = { free: { name: '免费版', price: 0, color: '#d9d9d9', gradient: 'linear-gradient(135deg, #d9d9d9 0%, #bfbfbf 100%)', features: ['基础商品管理', '订单管理', '基础报表'], limitations: ['1个店铺', '每日3次AI调用', '无API访问'], recommended: false, popular: false, icon: , description: '适合个人用户和小规模卖家', }, basic: { name: '基础版', price: 99, color: '#1890ff', gradient: 'linear-gradient(135deg, #1890ff 0%, #096dd9 100%)', features: ['多店铺管理(3个)', 'AI运营(100次/日)', 'B2B贸易', '基础定价建议'], limitations: ['无独立站', '无API访问'], recommended: true, popular: true, icon: , description: '适合成长中的电商卖家', }, pro: { name: '专业版', price: 299, color: '#faad14', gradient: 'linear-gradient(135deg, #faad14 0%, #d48806 100%)', features: ['多店铺管理(10个)', '无限AI调用', '自动定价', '独立站', '高级分析'], limitations: ['无API访问'], recommended: false, popular: false, icon: , description: '适合专业电商运营团队', }, enterprise: { name: '企业版', price: 999, color: '#722ed1', gradient: 'linear-gradient(135deg, #722ed1 0%, #531dab 100%)', features: ['无限店铺', '全部功能', 'API访问', '专属客服', '定制开发'], limitations: [], recommended: false, popular: false, icon: , description: '适合大型企业和定制化需求', }, }; const USAGE_DATA = { aiCalls: { used: 45, total: 100, plan: 'basic' }, shops: { used: 2, total: 3, plan: 'basic' }, storage: { used: 75, total: 100, unit: 'GB', plan: 'basic' }, }; interface PlanComparisonData { key: string; name: string; icon: React.ReactNode; description: string; popularity: number; category: 'core' | 'advanced' | 'enterprise'; free: boolean; basic: boolean; pro: boolean; enterprise: boolean; current: boolean; } const SubscriptionManage: React.FC = () => { const { currentUser, hasFeature, isPaidUser, getPlanLabel } = useUser(); const [previewFeature, setPreviewFeature] = useState(null); const [simulatedPlan, setSimulatedPlan] = useState(null); const [billingCycle, setBillingCycle] = useState<'monthly' | 'yearly'>('monthly'); const [selectedTab, setSelectedTab] = useState('overview'); const currentPlan = currentUser.subscription?.plan || 'free'; const handleFeaturePreview = (feature: FeatureConfig) => { setPreviewFeature(feature); }; const handleSimulatePlan = (plan: string) => { setSimulatedPlan(plan); message.success(`已切换到${PLAN_DETAILS[plan as keyof typeof PLAN_DETAILS].name}预览模式`); }; const handleUpgrade = (plan: string) => { message.info(`升级到${PLAN_DETAILS[plan as keyof typeof PLAN_DETAILS].name}功能开发中`); }; const isFeatureAvailable = (featureKey: string) => { if (simulatedPlan) { const feature = FEATURE_CONFIGS.find(f => f.key === featureKey); return feature?.requiredPlan.includes(simulatedPlan) ?? false; } return hasFeature(featureKey); }; const getDiscount = () => { return billingCycle === 'yearly' ? 20 : 0; }; const getAnnualPrice = (monthlyPrice: number) => { const annualPrice = monthlyPrice * 12; const discount = getDiscount(); return Math.round(annualPrice * (1 - discount / 100)); }; const getDisplayPrice = (price: number) => { if (billingCycle === 'yearly') { return Math.round(price * (1 - getDiscount() / 100)); } return price; }; const planComparisonData = useMemo((): PlanComparisonData[] => { return FEATURE_CONFIGS.map(feature => ({ key: feature.key, name: feature.name, icon: feature.icon, description: feature.description, popularity: feature.popularity || 0, category: feature.category, free: feature.requiredPlan.includes('free'), basic: feature.requiredPlan.includes('basic'), pro: feature.requiredPlan.includes('pro'), enterprise: feature.requiredPlan.includes('enterprise'), current: isFeatureAvailable(feature.key), })); }, [simulatedPlan]); const upgradePath = useMemo(() => { const planOrder = ['free', 'basic', 'pro', 'enterprise']; const currentIndex = planOrder.indexOf(currentPlan); return planOrder.slice(currentIndex + 1); }, [currentPlan]); const renderPlanCard = (planKey: string, plan: any) => ( handleSimulatePlan(planKey)} >
{plan.icon}
{plan.name} {plan.recommended && ( 推荐 )} {currentPlan === planKey && ( 当前套餐 )} {simulatedPlan === planKey && currentPlan !== planKey && ( 预览中 )}
{billingCycle === 'yearly' && planKey !== 'free' && (
¥{plan.price * 12}/年 省{getDiscount()}%
)} ¥{getDisplayPrice(plan.price)} <Text type="secondary" style={{ fontSize: '14px', fontWeight: 'normal' }}> /{billingCycle === 'yearly' ? '年' : '月'} </Text> {billingCycle === 'yearly' && planKey !== 'free' && ( 平均 ¥{Math.round(getDisplayPrice(plan.price) / 12)}/月 )}
{plan.description}
{plan.features.slice(0, 4).map((f: string, i: number) => (
{f}
))} {plan.features.length > 4 && ( +{plan.features.length - 4} 更多功能 )}
{plan.limitations.length > 0 && (
{plan.limitations.slice(0, 2).map((l: string, i: number) => (
{l}
))}
)}
); const renderUsageOverview = () => ( AI调用次数 } value={USAGE_DATA.aiCalls.used} suffix={`/ ${USAGE_DATA.aiCalls.total}`} valueStyle={{ color: '#1890ff' }} /> = 80 ? 'exception' : 'normal'} strokeColor={USAGE_DATA.aiCalls.used >= 80 ? '#ff4d4f' : '#1890ff'} /> 剩余 {USAGE_DATA.aiCalls.total - USAGE_DATA.aiCalls.used} 次 店铺数量 } value={USAGE_DATA.shops.used} suffix={`/ ${USAGE_DATA.shops.total}`} valueStyle={{ color: '#52c41a' }} /> 剩余 {USAGE_DATA.shops.total - USAGE_DATA.shops.used} 个 存储空间 } value={USAGE_DATA.storage.used} suffix={`/ ${USAGE_DATA.storage.total} ${USAGE_DATA.storage.unit}`} valueStyle={{ color: '#faad14' }} /> = 80 ? 'exception' : 'normal'} strokeColor={USAGE_DATA.storage.used >= 80 ? '#ff4d4f' : '#faad14'} /> 剩余 {USAGE_DATA.storage.total - USAGE_DATA.storage.used} {USAGE_DATA.storage.unit} ); const renderFeatureComparison = () => { const columns: ColumnsType = [ { title: '功能', dataIndex: 'name', key: 'name', width: 200, render: (name: string, record: PlanComparisonData) => ( {record.icon} {name} {record.description}
{record.popularity}% 热度
), }, { title: '免费版', key: 'free', align: 'center' as const, render: (_: any, record: PlanComparisonData) => record.free ? : , }, { title: '基础版', key: 'basic', align: 'center' as const, render: (_: any, record: PlanComparisonData) => record.basic ? : , }, { title: '专业版', key: 'pro', align: 'center' as const, render: (_: any, record: PlanComparisonData) => record.pro ? : , }, { title: '企业版', key: 'enterprise', align: 'center' as const, render: (_: any, record: PlanComparisonData) => record.enterprise ? : , }, { title: '当前状态', key: 'status', align: 'center' as const, render: (_: any, record: PlanComparisonData) => ( {record.current ? '已开通' : '未开通'} ), }, { title: '操作', key: 'action', width: 100, align: 'center' as const, render: (_: any, record: PlanComparisonData) => ( ), }, ]; return ( record.current ? 'highlight-row' : ''} /> ); }; const renderUpgradePath = () => { const steps = upgradePath.map((planKey, index) => ({ title: PLAN_DETAILS[planKey as keyof typeof PLAN_DETAILS].name, description: PLAN_DETAILS[planKey as keyof typeof PLAN_DETAILS].description, icon: PLAN_DETAILS[planKey as keyof typeof PLAN_DETAILS].icon, })); return ( {upgradePath.map((planKey, index) => { const plan = PLAN_DETAILS[planKey as keyof typeof PLAN_DETAILS]; const additionalFeatures = FEATURE_CONFIGS.filter(f => f.requiredPlan.includes(planKey) && !isFeatureAvailable(f.key) ); return ( {plan.name} ¥{getDisplayPrice(plan.price)}/{billingCycle === 'yearly' ? '年' : '月'} {plan.description}
新增功能: {additionalFeatures.slice(0, 3).map(f => ( {f.name} ))} {additionalFeatures.length > 3 && ( +{additionalFeatures.length - 3} )}
); })} ); }; return (
<CrownOutlined style={{ marginRight: '8px', color: '#faad14' }} /> 订阅管理中心 管理您的订阅计划和付费功能,预览不同套餐的功能差异 setBillingCycle(e.target.value)} size="large" > 月付 年付 {getDiscount() > 0 && ( 省{getDiscount()}% )} } closable style={{ marginBottom: '24px', borderRadius: '8px' }} /> 套餐概览 ), children: ( <> {Object.entries(PLAN_DETAILS).map(([key, plan]) => renderPlanCard(key, plan) )} {renderUsageOverview()}
{getPlanLabel()} 当前套餐 {currentUser.subscription?.expiresAt ? `到期时间: ${currentUser.subscription.expiresAt}` : '永久有效'}
{currentUser.subscription?.features.length || 0} 已开通功能
{FEATURE_CONFIGS.filter(f => !hasFeature(f.key)).length} 可升级功能
), }, { key: 'comparison', label: ( 功能对比 ), children: ( {renderFeatureComparison()} ), }, { key: 'upgrade', label: ( 升级路径 ), children: renderUpgradePath(), }, ]} /> {previewFeature?.icon} {previewFeature?.name} } open={!!previewFeature} onCancel={() => setPreviewFeature(null)} footer={[ , !isFeatureAvailable(previewFeature?.key || '') && ( ), ]} width={700} > {previewFeature && (
{previewFeature.description} 功能权益 {previewFeature.benefits.map((b: string, i: number) => (
{b}
))}
{previewFeature.limitations && ( 版本限制 {previewFeature.limitations.map((l: string, i: number) => (
• {l}
))}
)} 所需套餐 {previewFeature.requiredPlan.map((p: string) => ( {PLAN_DETAILS[p as keyof typeof PLAN_DETAILS]?.name} ))}
{isFeatureAvailable(previewFeature.key) ? ( ) : ( )} {isFeatureAvailable(previewFeature.key) ? '✓ 您已拥有此功能' : '✗ 需要升级套餐'}
{previewFeature.popularity && (
用户使用热度: `${percent}%`} />
)}
)}
); }; export default SubscriptionManage;