import React, { useState } from 'react'; import { mockMembershipPlans, mockApps, mockModels } from '@/mock/data'; import type { MembershipPlan } from '@/types'; const SVGIcon: React.FC<{ children: React.ReactNode; size?: number }> = ({ children, size = 16 }) => ( {children} ); const levelColors = [ { bg: 'var(--color-bg-tertiary)', accent: 'var(--color-text-secondary)', label: '免费版' }, { bg: 'var(--color-accent-light)', accent: 'var(--color-accent)', label: '专业版' }, { bg: '#FFF7E6', accent: '#E8922C', label: '企业版' }, ]; const typeLabels: Record = { skill: 'Skill', agent: 'Agent', mcp: 'MCP' }; const typeBadgeColors: Record = { skill: 'badge-success', agent: 'badge-info', mcp: 'badge-warning' }; // 所有收费应用 (price > 0, published) const allPaidApps = mockApps.filter(a => a.price > 0 && a.status === 'published'); // 所有收费模型 const allPaidModels = mockModels.filter(m => m.status === 'paid'); const Membership: React.FC = () => { const [plans, setPlans] = useState(mockMembershipPlans); const [editingPlan, setEditingPlan] = useState(null); const [showModal, setShowModal] = useState(false); const [autoDowngrade, setAutoDowngrade] = useState(true); const [autoRenew, setAutoRenew] = useState(true); const [form, setForm] = useState({ name: '', level: 0, durationType: 'month' as 'month' | 'quarter' | 'year', price: 0, dailyFreeTokens: 0, features: [] as string[], freeAppIds: [] as string[], freeModelIds: [] as string[], }); const [newFeature, setNewFeature] = useState(''); const handleEdit = (plan: MembershipPlan) => { setEditingPlan(plan); setForm({ name: plan.name, level: plan.level, durationType: plan.durationType, price: plan.price, dailyFreeTokens: plan.dailyFreeTokens, features: [...plan.features], freeAppIds: [...(plan.freeAppIds || [])], freeModelIds: [...(plan.freeModelIds || [])], }); setShowModal(true); }; const handleSave = () => { if (editingPlan) { setPlans(prev => prev.map(p => p.id === editingPlan.id ? { ...p, ...form } : p)); } setShowModal(false); setEditingPlan(null); }; const addFeature = () => { if (newFeature.trim()) { setForm({ ...form, features: [...form.features, newFeature.trim()] }); setNewFeature(''); } }; const removeFeature = (idx: number) => { setForm({ ...form, features: form.features.filter((_, i) => i !== idx) }); }; const toggleAppId = (appId: string) => { setForm(prev => ({ ...prev, freeAppIds: prev.freeAppIds.includes(appId) ? prev.freeAppIds.filter(id => id !== appId) : [...prev.freeAppIds, appId], })); }; const toggleModelId = (modelId: string) => { setForm(prev => ({ ...prev, freeModelIds: prev.freeModelIds.includes(modelId) ? prev.freeModelIds.filter(id => id !== modelId) : [...prev.freeModelIds, modelId], })); }; // 根据 freeAppIds 获取应用名称列表(用于卡片展示) const getFreeAppNames = (plan: MembershipPlan): string[] => { return (plan.freeAppIds || []).map(id => allPaidApps.find(a => a.id === id)?.name).filter(Boolean) as string[]; }; const getFreeModelNames = (plan: MembershipPlan): string[] => { return (plan.freeModelIds || []).map(id => allPaidModels.find(m => m.id === id)?.name).filter(Boolean) as string[]; }; return (

会员管理

{/* Plan Cards */}
{plans.map((plan, idx) => { const colors = levelColors[idx] || levelColors[0]; const freeAppNames = getFreeAppNames(plan); const freeModelNames = getFreeModelNames(plan); return (
{colors.label}

{plan.name}

{/* Pricing */}
月付
{plan.price} 元
季付
{Math.round(plan.price * 3 * 0.85)} 元
年付
{Math.round(plan.price * 12 * 0.7)} 元
{/* Features */}
会员权益
    {plan.features.map((f, i) => (
  • {f}
  • ))}
{/* Free tokens */}
每日免费额度: {plan.dailyFreeTokens.toLocaleString()} Token
{/* Free apps & models summary */} {plan.level > 0 && (
{freeAppNames.length > 0 && (
免费应用({freeAppNames.length}): {freeAppNames.join(', ')}
)} {freeModelNames.length > 0 && (
免费模型({freeModelNames.length}): {freeModelNames.join(', ')}
)}
)}
); })}
{/* Automation Rules */}

自动化规则配置

到期自动降级
会员到期后自动降级为免费版
自动续费默认开启
新会员订阅默认开启自动续费
{/* Global Free Application List */}

当前各等级会员免费应用总览

{allPaidApps.map(app => { const freePlans = plans.filter(p => (p.freeAppIds || []).includes(app.id)); return ( ); })}
应用名称 类型 来源 价格 免费等级
{app.name} {typeLabels[app.type] || app.type.toUpperCase()} {app.source === 'official' ? '官方' : '用户'} {app.price} 元 {freePlans.length > 0 ? freePlans.map(p => ( {p.name} )) : 无 }
{/* Global Free Model List */}

当前各等级会员免费大模型总览

{allPaidModels.map(model => { const freePlans = plans.filter(p => (p.freeModelIds || []).includes(model.id)); return ( ); })}
模型名称 提供商 每百万Token价格 免费等级
{model.name} {model.providerName} {model.pricePerMillionTokens} 元 {freePlans.length > 0 ? freePlans.map(p => ( {p.name} )) : 无 }
{/* Edit Modal */} {showModal && (
{ setShowModal(false); setEditingPlan(null); }}>
e.stopPropagation()}>

编辑 {editingPlan?.name}

setForm({ ...form, price: Number(e.target.value) })} />
setForm({ ...form, dailyFreeTokens: Number(e.target.value) })} />
{form.features.map((f, i) => ( {f} ))}
setNewFeature(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); addFeature(); } }} placeholder="输入权益名称,回车添加" style={{ flex: 1 }} />
{/* Free Applications Selection */}
{allPaidApps.length === 0 && (
暂无收费应用
)} {allPaidApps.map(app => { const checked = form.freeAppIds.includes(app.id); return ( ); })}
已选 {form.freeAppIds.length}/{allPaidApps.length} 个应用
{/* Free Models Selection */}
{allPaidModels.length === 0 && (
暂无收费模型
)} {allPaidModels.map(model => { const checked = form.freeModelIds.includes(model.id); return ( ); })}
已选 {form.freeModelIds.length}/{allPaidModels.length} 个模型
)}
); }; export default Membership;