import React, { useState, useEffect, useMemo } from 'react'; import { BookOpen, BrainCircuit, CheckCircle2, XCircle, RotateCcw, ChevronRight, Award, ChevronLeft, Sparkles, LayoutDashboard, Search, Calculator, TrendingUp, AlertCircle, DollarSign, Activity, Menu, X } from 'lucide-react'; // ========================================== // 数据源配置 (Data Sources) // ========================================== // 1. 闪卡题库 (精选核心) const FLASHCARDS = [ { id: 1, category: "基础术语", q: "基础漏斗模型的四个核心步骤是什么?", a: "曝光 (Impression) ➔ 点击 (Click) ➔ 访问/加购 (Visit/Add to Cart) ➔ 成交 (Orders)" }, { id: 2, category: "核心指标", q: "CTR (点击率) 的及格线和优秀线分别是多少?", a: "及格线:≥ 1%\n优秀线:≥ 2%\n(反映素材或封面的吸引力)" }, { id: 3, category: "核心指标", q: "什么是 CVR?及格线是多少?", a: "CVR (转化率) = 成交量 ÷ 点击量 × 100%。\n反映商品价格、详情页、评价的转化能力。及格线通常在 1.5%~3%。" }, { id: 4, category: "核心指标", q: "什么是保本 ROI (投资回报率)?", a: "花出去的钱和赚回来的钱持平的临界点。例如保本线为 1.35,低于 1.35 就是亏损,必须马上优化!" }, { id: 5, category: "核心指标", q: "真实 ROI 的计算公式里,除了广告费还包含哪些成本?", a: "真实 ROI = GMV ÷ (广告费 + 商品成本 + 平台费/佣金 + 运费/退货损耗)" }, { id: 6, category: "基础术语", q: "CPA (单次成交成本) 的安全线应该怎么定?", a: "CPA 越低越好。通常要求 CPA ≤ 目标利润的 50% 或 ≤ 客单价(AOV) × 30% 为安全线。" }, { id: 7, category: "基础术语", q: "ROAS (广告花费回报率) 怎么算?及格线是多少?", a: "ROAS = GMV ÷ 广告花费。\n及格线:≥ 2.0\n优质线:≥ 3.0" }, { id: 8, category: "TikTok策略", q: "TikTok 投放的“双轮驱动法”是什么?", a: "自然流 (免费) 测素材找方向 ➕ 付费流 (广告) 放大爆款获取规模化 GMV。" }, { id: 9, category: "故障排查", q: "急救SOP:当天见效的“重新启动消耗 3 板斧”是什么?", a: "换素材 (5-10条新) ➕ 提预算 (≥$50/天) ➕ 放宽定向 (Broad 优先)。" }, { id: 10, category: "优化决策", q: "“大盘竞争加剧”时(如双11),CPM 会发生什么变化?", a: "CPM (千次曝光成本) 会大幅上涨。同等预算下,买到的流量会变少,消耗变慢。" } ]; // 2. 测试题库 const QUIZ_QUESTIONS = [ { id: 1, question: "今天刚建的 TikTok 计划,跑半天 CTR 只有 0.6%,你最应该做的是?", options: ["马上增加每日预算", "去优化商品详情页", "停止该计划,换更有吸引力的素材", "缩小定向人群只投女性"], correct: 2, explanation: "CTR 0.6% 远低于及格线 1%,说明用户根本不愿点击。核心原因是素材(前3秒)不够吸睛,必须立刻换素材。" }, { id: 2, question: "看着 GMV 暴涨,但月底一算却亏了。最大可能是什么?", options: ["没关注点击率", "系统出错", "没算准真实 ROI 和保本线", "客单价太高"], correct: 2, explanation: "GMV 是营业额,不代表利润。必须扣除商品成本、运费、平台费算真实 ROI,低于保本线就是赔本赚吆喝。" }, { id: 3, question: "素材的 CVR(转化率)很低只有 0.5%,问题出在哪?", options: ["视频封面太丑", "落地页/价格/评论不行", "前3秒没钩子", "出价太低"], correct: 1, explanation: "CVR低意味着“进来了但不买”。说明流量承接极差,必须优化商品价格、卖点图或刷好评。" }, { id: 4, question: "大促期间(如双11),关于 ROI 的策略哪句话是正确的?", options: ["ROI 必须比平时更高", "ROI 可以低于保本线去抢流量", "ROI 可适当降低但必须≥保本线", "大促不看ROI只看GMV"], correct: 2, explanation: "大促期间流量贵且竞争激烈,为抢占份额可适当降低 ROI 预期,但底线是必须保本,绝对不能“亏本冲量”导致资金断裂。" }, { id: 5, question: "日常预算分配“352原则”中,30% 的预算永远应该留给谁?", options: ["老爆款计划", "品牌日常防御", "测试新素材和新定向", "达人坑位费"], correct: 2, explanation: "30% 是测试预算,保证账户有源源不断的新鲜血液(新素材),防止老素材衰减后无广告可投。" } ]; // 3. 术语词典库 (Dictionary) const DICTIONARY_TERMS = [ { term: "CTR", full: "Click Through Rate", zh: "点击率", formula: "点击量 ÷ 曝光量 × 100%", desc: "衡量广告素材或封面吸引力的核心指标。反映了多少人看了广告后愿意点进来。", tips: "电商大盘合格线通常为 1%,优秀为 2%以上。如果 CTR 太低,别犹豫,立刻换素材(前3秒钩子/封面)。" }, { term: "CVR", full: "Conversion Rate", zh: "转化率", formula: "成交单量 ÷ 点击量 × 100%", desc: "衡量流量承接能力的指标。反映了点进来的用户中,有多少人最终掏钱买了。", tips: "如果 CTR 很高但 CVR 很低,说明“挂羊头卖狗肉”或价格太贵、评价太差。需要优化落地页、降价或补充好评。" }, { term: "CPA", full: "Cost Per Action", zh: "单次成交成本 (获客成本)", formula: "广告总花费 ÷ 成交单量", desc: "你为了卖出一单商品,平均需要花多少广告费。", tips: "CPA 必须低于你的单均毛利润!建议控制在客单价(AOV)的 30% 以内为安全线。" }, { term: "ROI", full: "Return On Investment", zh: "投资回报率", formula: "(总收入 - 总成本) ÷ 总成本 × 100%", desc: "衡量生意到底“赚没赚钱”的终极指标。这里的成本需包含广告费、商品成本、物流、平台佣金等所有开支。", tips: "投放前一定要算出你的“保本 ROI”。低于保本线就是卖一单亏一单,必须及时止损。" }, { term: "ROAS", full: "Return On Ad Spend", zh: "广告花费回报率", formula: "GMV (总营业额) ÷ 广告花费", desc: "专门衡量“广告花钱效率”的指标。花1块钱广告能带来多少钱的营业额。", tips: "通常 ROAS ≥ 2.0 为及格,≥ 3.0 为优质。它不代表利润,只代表广告的带货效率。" }, { term: "GMV", full: "Gross Merchandise Volume", zh: "商品交易总额 (营业额)", formula: "订单数 × 客单价", desc: "用户实际支付的订单总金额汇总,不扣除任何成本。", tips: "新手最容易踩的坑就是“只看 GMV 不看 ROI”,导致虚假繁荣,最后一看账本亏本了。" }, { term: "AOV", full: "Average Order Value", zh: "平均客单价", formula: "GMV ÷ 成交订单数", desc: "每个下单的客户平均花了多少钱。", tips: "提升 AOV 是对抗流量变贵的利器。可以通过满减、买二送一、组合套餐来拉高客单价。" }, { term: "CPM", full: "Cost Per Mille", zh: "千次展现成本", formula: "广告花费 ÷ 曝光量 × 1000", desc: "让你的广告被 1000 个人看到需要花多少钱。反映了大盘流量的竞争激烈程度。", tips: "大促期间(双11)CPM 必然飙升。如果你的素材不够好,买量成本会极其高昂。" }, { term: "Broad", full: "Broad Targeting", zh: "宽泛定向 (通投)", formula: "N/A", desc: "不限制年龄、性别、兴趣等条件,把寻找目标用户的任务全权交给平台算法。", tips: "在 TikTok 等强算法平台,Broad 定向往往比精准定向效果更好,能让系统有足够空间找到转化人群。" }, { term: "LAL / Lookalike", full: "Lookalike Audience", zh: "相似受众", formula: "N/A", desc: "提供一批种子用户(如买过你东西的人),系统会自动在全网帮你寻找行为标签相似的人群。", tips: "当你现有的受众包“洗”不动了(频次变高,CTR下降),拉一个优质的 LAL 包是扩量最好的办法。" } ]; const shuffleArray = (array) => [...array].sort(() => Math.random() - 0.5); // ========================================== // 主应用组件 // ========================================== export default function App() { const [currentView, setCurrentView] = useState('dashboard'); // dashboard, flashcards, quiz, dictionary, calculator const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); // --- 全局统计状态 (模拟进度保存) --- const [stats, setStats] = useState({ cardsMastered: 0, cardsReviewed: 0, highestQuizScore: 0, quizzesTaken: 0 }); // --- 闪卡状态 --- const [fcQueue, setFcQueue] = useState([]); const [fcMasteredThisSession, setFcMasteredThisSession] = useState(0); const [fcTotal, setFcTotal] = useState(0); const [isFlipped, setIsFlipped] = useState(false); const [fcComplete, setFcComplete] = useState(false); // --- 测试状态 --- const QUIZ_SESSION_LIMIT = 5; const [quizQueue, setQuizQueue] = useState([]); const [currentQuizIdx, setCurrentQuizIdx] = useState(0); const [quizScore, setQuizScore] = useState(0); const [quizComplete, setQuizComplete] = useState(false); const [selectedOption, setSelectedOption] = useState(null); const [showExplanation, setShowExplanation] = useState(false); // --- 词典状态 --- const [searchTerm, setSearchTerm] = useState(''); // --- 闪卡逻辑 --- const startFlashcards = () => { const shuffled = shuffleArray(FLASHCARDS); setFcQueue(shuffled); setFcTotal(shuffled.length); setFcMasteredThisSession(0); setFcComplete(false); setIsFlipped(false); setCurrentView('flashcards'); setIsMobileMenuOpen(false); }; const handleFcNext = (status) => { let newQueue = [...fcQueue]; const currentCard = newQueue.shift(); if (status === 'mastered') { setFcMasteredThisSession(prev => prev + 1); setStats(s => ({ ...s, cardsMastered: s.cardsMastered + 1 })); } else { newQueue.push(currentCard); setStats(s => ({ ...s, cardsReviewed: s.cardsReviewed + 1 })); } setFcQueue(newQueue); setIsFlipped(false); if (newQueue.length === 0) setFcComplete(true); }; // --- 测试逻辑 --- const startQuiz = () => { const shuffledSubset = shuffleArray(QUIZ_QUESTIONS).slice(0, QUIZ_SESSION_LIMIT); setQuizQueue(shuffledSubset); setCurrentQuizIdx(0); setQuizScore(0); setQuizComplete(false); setSelectedOption(null); setShowExplanation(false); setCurrentView('quiz'); setIsMobileMenuOpen(false); }; const handleOptionSelect = (idx) => { if (showExplanation) return; setSelectedOption(idx); setShowExplanation(true); if (idx === quizQueue[currentQuizIdx].correct) { setQuizScore(prev => prev + 1); } }; const handleQuizNext = () => { setSelectedOption(null); setShowExplanation(false); if (currentQuizIdx < quizQueue.length - 1) { setCurrentQuizIdx(prev => prev + 1); } else { setQuizComplete(true); setStats(s => ({ ...s, quizzesTaken: s.quizzesTaken + 1, highestQuizScore: Math.max(s.highestQuizScore, quizScore + (selectedOption === quizQueue[currentQuizIdx].correct ? 1 : 0)) })); } }; // ========================================== // 子视图渲染器 // ========================================== // 1. 仪表盘首页 (Dashboard) const renderDashboard = () => (
{/* 欢迎模块 */}

你好,投放操盘手

欢迎来到你的专属电商投放研习社。在这里,你可以查询术语、计算收益、通过科学测试掌握上百条优化策略。

{/* 数据总览 */}
{[ { label: '已掌握知识点', val: stats.cardsMastered, icon: }, { label: '复习次数', val: stats.cardsReviewed, icon: }, { label: '测试最高分', val: `${stats.highestQuizScore}/${QUIZ_SESSION_LIMIT}`, icon: }, { label: '完成测试数', val: stats.quizzesTaken, icon: }, ].map((stat, i) => (
{stat.icon} {stat.label}
{stat.val}
))}
{/* 快捷入口 */}

核心工具箱

); // 2. 专业术语词典 (Dictionary) const renderDictionary = () => { const filteredTerms = DICTIONARY_TERMS.filter(t => t.term.toLowerCase().includes(searchTerm.toLowerCase()) || t.zh.includes(searchTerm) || t.desc.includes(searchTerm) ); return (

专业术语词典

setSearchTerm(e.target.value)} className="w-full pl-12 pr-4 py-3 rounded-2xl border border-slate-200 shadow-sm focus:ring-2 focus:ring-purple-500 focus:border-purple-500 outline-none transition-all text-slate-700 bg-white" />
{filteredTerms.length > 0 ? filteredTerms.map((t, idx) => (

{t.term}

{t.zh}

{t.full}

{t.formula !== 'N/A' && (
{t.formula}
)}

解释:{t.desc}

导师建议: {t.tips}
)) : (

没有找到相关术语

)}
); }; // 3. 投放健康度计算器 (Calculator) const CalculatorView = () => { const [inputs, setInputs] = useState({ spend: '', impress: '', clicks: '', orders: '', gmv: '', productCost: '', otherCost: '' }); const handleChange = (e) => setInputs({ ...inputs, [e.target.name]: Number(e.target.value) || '' }); const results = useMemo(() => { const s = inputs.spend || 0, i = inputs.impress || 0, c = inputs.clicks || 0, o = inputs.orders || 0, g = inputs.gmv || 0; const pc = inputs.productCost || 0, oc = inputs.otherCost || 0; const ctr = i ? (c / i) * 100 : 0; const cvr = c ? (o / c) * 100 : 0; const cpa = o ? s / o : 0; const cpm = i ? (s / i) * 1000 : 0; const aov = o ? g / o : 0; const roas = s ? g / s : 0; const totalCost = s + pc + oc; const profit = g - totalCost; const roi = totalCost ? (profit / totalCost) * 100 : 0; return { ctr, cvr, cpa, cpm, aov, roas, profit, roi, totalCost }; }, [inputs]); // 状态评级组件 const MetricCard = ({ title, value, unit, desc, health }) => { let color = 'text-slate-800', bg = 'bg-white', icon = null; if (health === 'good') { color = 'text-emerald-600'; bg = 'bg-emerald-50 border-emerald-100'; icon = '🟢'; } if (health === 'warn') { color = 'text-amber-600'; bg = 'bg-amber-50 border-amber-100'; icon = '🟡'; } if (health === 'bad') { color = 'text-red-600'; bg = 'bg-red-50 border-red-100'; icon = '🔴'; } return (
{title} {icon}
{value} {unit}
); }; return (

一键诊断计算器

{/* 输入区 */}

请输入后台数据

{[ { name: 'impress', label: '曝光量 (展现)', icon: '👁️' }, { name: 'clicks', label: '点击量', icon: '👆' }, { name: 'orders', label: '成交单量', icon: '📦' }, { name: 'spend', label: '广告花费 ($/¥)', icon: '💸' }, { name: 'gmv', label: '总交易额 GMV', icon: '💰' }, { name: 'productCost', label: '商品总成本', icon: '🏭' }, ].map((fld) => (
))}
{/* 输出/诊断区 */}

最终净利润 (Profit)

0 ? 'text-emerald-400' : results.profit < 0 ? 'text-red-400' : 'text-white'}`}> {results.profit > 0 ? '+' : ''}{results.profit.toFixed(2)}
真实 ROI
= 0 ? 'text-emerald-400' : 'text-red-400'}`}>{results.roi.toFixed(2)}%
ROAS (广告投产)
= 2 ? 'text-emerald-400' : results.roas > 0 ? 'text-amber-400' : 'text-white'}`}>{results.roas.toFixed(2)}
= 1.5 ? 'good' : results.ctr >= 1 ? 'warn' : 'bad'} /> = 3 ? 'good' : results.cvr >= 1.5 ? 'warn' : 'bad'} />
{/* 智能诊断建议 */} {(results.ctr > 0 || results.roas > 0) && (
AI 诊断建议:
    {results.roi < 0 &&
  • 当前整体处于亏损状态,请立刻检查广告花费或调整商品定价。
  • } {results.roi > 0 &&
  • 当前实现盈利!模型健康,可尝试复制计划并小幅提升预算放量。
  • } {results.ctr > 0 && results.ctr < 1 &&
  • CTR 低于 1%,说明广告素材毫无吸引力,建议立刻更换素材或优化视频前3秒。
  • } {results.cvr > 0 && results.cvr < 1.5 &&
  • CVR 低于 1.5%,流量承接极差,用户只看不买,建议优化落地页、商品价格或补充评论
  • } {results.cpa > results.profit && results.profit > 0 &&
  • 警告:虽然赚钱,但获客成本(CPA)偏高,利润空间被严重压缩。
  • }
)}
); }; // 4. 闪卡渲染逻辑 (保留原有算法,升级UI) const renderFlashcards = () => { if (fcComplete) { return (

挑战成功!

你已成功将 {fcTotal} 个硬核知识点刻入肌肉记忆。

); } if (fcQueue.length === 0) return null; const card = fcQueue[0]; const progress = (fcMasteredThisSession / fcTotal) * 100; return (
待攻克: {fcQueue.length} | 已掌握: {fcMasteredThisSession}
setIsFlipped(!isFlipped)} style={{ perspective: '1000px' }} >
🏷️ {card.category} {!isFlipped ? (

{card.q}

点击卡片回想答案

) : (
{card.a.split('\n').map((line, i) => {line}
)}
)}
); }; // 5. 测试渲染逻辑 (保留原有算法,升级UI) const renderQuiz = () => { if (quizComplete) { return (

特训完成!

得分:{quizScore} / {QUIZ_SESSION_LIMIT}

); } if (quizQueue.length === 0) return null; const question = quizQueue[currentQuizIdx]; const progress = (currentQuizIdx / QUIZ_SESSION_LIMIT) * 100; return (
题号 {currentQuizIdx + 1} / {QUIZ_SESSION_LIMIT}

{question.question}

{question.options.map((opt, idx) => { let btnClass = "w-full text-left p-5 rounded-2xl border-2 transition-all flex items-start "; if (!showExplanation) { btnClass += "border-slate-100 hover:border-orange-300 hover:bg-orange-50 hover:shadow-md text-slate-700 font-medium"; } else { if (idx === question.correct) btnClass += "border-emerald-500 bg-emerald-50 text-emerald-900 font-bold shadow-md"; else if (idx === selectedOption) btnClass += "border-red-400 bg-red-50 text-red-900 font-medium opacity-80"; else btnClass += "border-slate-50 bg-slate-50 text-slate-400 opacity-50"; } return ( ); })}
{showExplanation && (

导师解析

{question.explanation}

)} {showExplanation && ( )}
); }; // ========================================== // 主界面框架 (Sidebar + Content) // ========================================== const NavItem = ({ view, icon: Icon, label, colorClass }) => ( ); return (