"use client"; import { useState, useEffect, useCallback, ChangeEvent } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Progress } from "@/components/ui/progress"; import { useToast } from "@/hooks/use-toast"; import { fetchWithAuth } from "@/lib/api/client"; import { platformRulesApi, PlatformBrief, PlatformDetailResponse, ContentValidationResponse } from "@/lib/api/platform-rules"; interface OptimizedContent { title: string; content: string; platform: string; tips: string[]; stages?: Array<{ stage: string; status: string; word_count?: number; }>; } // 平台配置映射(含emoji图标) const platformIcons: Record = { zhihu: "📖", wechat: "📱", baijiahao: "📰", toutiao: "📢", xiaohongshu: "📕", default: "🌐", }; export default function ContentEditorPage() { const { toast } = useToast(); const [platforms, setPlatforms] = useState([]); const [platformDetail, setPlatformDetail] = useState(null); const [selectedPlatform, setSelectedPlatform] = useState("zhihu"); const [title, setTitle] = useState(""); const [content, setContent] = useState(""); const [optimizedContent, setOptimizedContent] = useState(null); const [validationResult, setValidationResult] = useState(null); const [loading, setLoading] = useState(true); const [validating, setValidating] = useState(false); const [optimizing, setOptimizing] = useState(false); const [optimizeProgress, setOptimizeProgress] = useState(0); useEffect(() => { loadPlatforms(); }, []); // 加载平台详情(当选中平台变化时) useEffect(() => { if (selectedPlatform) { loadPlatformDetail(selectedPlatform); } }, [selectedPlatform]); const loadPlatforms = async () => { try { setLoading(true); const response = await platformRulesApi.listPlatforms(); setPlatforms(response.platforms); } catch (error) { console.error("加载平台列表失败:", error); toast({ title: "加载失败", description: "无法加载平台列表,请刷新页面重试", variant: "destructive", }); } finally { setLoading(false); } }; const loadPlatformDetail = async (platformId: string) => { try { const detail = await platformRulesApi.getPlatformDetail(platformId); setPlatformDetail(detail); } catch (error) { console.error("加载平台详情失败:", error); setPlatformDetail(null); } }; const handleValidate = async () => { if (!content || !title) { toast({ title: "验证失败", description: "请先填写标题和内容", variant: "destructive", }); return; } try { setValidating(true); const result = await platformRulesApi.validateContent(selectedPlatform, content, title); setValidationResult(result); if (result.is_valid) { toast({ title: "验证通过", description: `内容得分: ${result.score}分`, }); } else { toast({ title: "验证未通过", description: `发现 ${result.issues.length} 个问题需要修复`, variant: "destructive", }); } } catch (error) { console.error("验证失败:", error); toast({ title: "验证失败", description: "内容验证过程中出现错误", variant: "destructive", }); } finally { setValidating(false); } }; const handleOptimize = async () => { if (!content || !title) { toast({ title: "优化失败", description: "请先填写标题和内容", variant: "destructive", }); return; } try { setOptimizing(true); setOptimizeProgress(0); // 阶段1: 去AI化 setOptimizeProgress(10); const deaiResult = await fetchWithAuth(`/api/v1/content/deai`, { method: "POST", body: JSON.stringify({ content, title }), }).catch(() => ({ content })); setOptimizeProgress(40); let processedContent = deaiResult.content || content; // 阶段2: 敏感词过滤 setOptimizeProgress(50); const sensitiveResult = await fetchWithAuth(`/api/v1/content/filter-sensitive`, { method: "POST", body: JSON.stringify({ content: processedContent, platform: selectedPlatform }), }).catch(() => ({ content: processedContent })); setOptimizeProgress(70); processedContent = sensitiveResult.content || processedContent; // 阶段3: SEO优化 setOptimizeProgress(80); const seoResult = await fetchWithAuth(`/api/v1/content/seo-optimize`, { method: "POST", body: JSON.stringify({ content: processedContent, title, platform: selectedPlatform }), }).catch(() => ({ content: processedContent })); setOptimizeProgress(90); processedContent = seoResult.content || processedContent; // 获取优化建议 const tips = await platformRulesApi.getOptimizationTips(selectedPlatform); setOptimizedContent({ title: title, content: processedContent, platform: selectedPlatform, tips: tips.tips || [], stages: [ { stage: "去AI化", status: "success" }, { stage: "敏感词过滤", status: "success" }, { stage: "SEO优化", status: "success" }, ], }); setOptimizeProgress(100); toast({ title: "优化完成", description: "内容已成功优化,可以复制使用了", }); } catch (error) { console.error("优化失败:", error); toast({ title: "优化失败", description: "内容优化过程中出现错误,已保留原始内容", variant: "destructive", }); // 保留原始内容作为后备 setOptimizedContent({ title: title, content: content, platform: selectedPlatform, tips: [], }); } finally { setOptimizing(false); } }; const handleCopyContent = useCallback((format: "html" | "markdown" | "text") => { if (!optimizedContent) { toast({ title: "复制失败", description: "请先执行优化操作", variant: "destructive", }); return; } let copyText = ""; switch (format) { case "html": copyText = `

${optimizedContent.title}

\n

${optimizedContent.content.replace(/\n\n/g, "

")}

`; break; case "markdown": copyText = `# ${optimizedContent.title}\n\n${optimizedContent.content}`; break; case "text": copyText = `${optimizedContent.title}\n\n${optimizedContent.content}`; break; } navigator.clipboard.writeText(copyText).then(() => { const formatLabels = { html: "HTML", markdown: "Markdown", text: "纯文本" }; toast({ title: "复制成功", description: `已复制为${formatLabels[format]}格式`, }); }).catch(() => { toast({ title: "复制失败", description: "无法访问剪贴板,请检查浏览器权限", variant: "destructive", }); }); }, [optimizedContent, toast]); if (loading) { return (
加载中...
); } return (

内容编辑器

创建和优化GEO内容

{/* 左侧: 编辑区 */}
内容编辑 编写和编辑内容
{/* 平台规则摘要 */} {platformDetail && (
{platformIcons[selectedPlatform] || platformIcons.default} {platformDetail.name} {platformDetail.content_style}
字数: {platformDetail.content_length.min}-{platformDetail.content_length.max} 推荐: {platformDetail.content_length.recommended}字 标题: {platformDetail.title_rules.min_length}-{platformDetail.title_rules.max_length}字 标签: {platformDetail.tag_rules.min_tags}-{platformDetail.tag_rules.max_tags}个 图片: 最多{platformDetail.max_images}张 AI敏感度: {platformDetail.ai_sensitivity.detection_level}
)}
) => setTitle(e.target.value)} />