import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Image from 'next/image'; import Link from 'next/link'; import { useAuth } from '@/hooks/useAuth'; import MainLayout from '@/components/layouts/MainLayout'; import CommentSection from '@/components/article/CommentSection'; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Skeleton } from "@/components/ui/skeleton"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Loader2, Lock, Download, Calendar, User as UserIcon, Tag as TagIcon, Share2, Crown, FileText, Eye, ShoppingCart, Copy, Check, Box, HardDrive } from 'lucide-react'; import { format } from 'date-fns'; import { zhCN } from 'date-fns/locale'; import { toast } from 'sonner'; interface Article { _id: string; 文章标题: string; 封面图: string; 摘要: string; 正文内容: string; 作者ID: { 用户名: string; 头像: string; }; 分类ID: { _id: string; 分类名称: string; }; 标签ID列表: { 标签名称: string; }[]; 价格: number; 支付方式: 'points' | 'cash' | 'membership_free'; 资源属性?: { 下载链接: string; 提取码: string; 解压密码: string; 隐藏内容: string; 版本号?: string; 文件大小?: string; 扩展属性?: { 属性名: string; 属性值: string }[]; }; createdAt: string; 统计数据: { 阅读数: number; 销量: number; }; } export default function ArticleDetail() { const router = useRouter(); const { id } = router.query; const { user } = useAuth(); const [article, setArticle] = useState
(null); const [recentArticles, setRecentArticles] = useState([]); const [loading, setLoading] = useState(true); const [hasAccess, setHasAccess] = useState(false); const [purchasing, setPurchasing] = useState(false); const [copiedField, setCopiedField] = useState(null); useEffect(() => { if (id) { fetchArticle(); fetchRecentArticles(); } }, [id]); const fetchArticle = async () => { try { const res = await fetch(`/api/articles/${id}`); if (res.ok) { const data = await res.json(); setArticle(data.article); setHasAccess(data.hasAccess); } else { toast.error('文章不存在或已被删除'); router.push('/'); } } catch (error) { console.error('Failed to fetch article', error); } finally { setLoading(false); } }; const fetchRecentArticles = async () => { try { const res = await fetch('/api/articles?limit=5'); if (res.ok) { const data = await res.json(); // Filter out current article if present const filtered = data.articles.filter((a: Article) => a._id !== id); setRecentArticles(filtered.slice(0, 5)); } } catch (error) { console.error('Failed to fetch recent articles', error); } }; const handlePurchase = async () => { if (!user) { router.push(`/auth/login?redirect=${encodeURIComponent(router.asPath)}`); return; } if (!article) return; // If price is 0, it should be accessible, but just in case if (article.价格 === 0) return; setPurchasing(true); try { const res = await fetch('/api/orders/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: 'buy_resource', itemId: article._id, paymentMethod: 'alipay', // Default to alipay for now returnUrl: window.location.href // Pass current page URL for redirect after payment }), }); if (res.ok) { const data = await res.json(); // Redirect to Alipay window.location.href = data.payUrl; } else { const data = await res.json(); toast.error(data.message || '创建订单失败'); } } catch (error) { toast.error('网络错误,请稍后重试'); } finally { setPurchasing(false); } }; const handleShare = () => { const url = window.location.href; navigator.clipboard.writeText(url).then(() => { toast.success('链接已复制到剪贴板'); }).catch(() => { toast.error('复制失败'); }); }; const copyToClipboard = (text: string, field: string) => { navigator.clipboard.writeText(text).then(() => { setCopiedField(field); toast.success('复制成功'); setTimeout(() => setCopiedField(null), 2000); }).catch(() => { toast.error('复制失败'); }); }; if (loading) { return (
); } if (!article) return null; return ( t.标签名称).join(',') }} >
{/* Main Content - Left Column (70%) */}
{/* Article Header */}
{article.分类ID?.分类名称 || '未分类'} {article.标签ID列表?.map((tag, index) => ( {tag.标签名称} ))}

{article.文章标题}

{article.作者ID?.用户名 || '匿名'}
{format(new Date(article.createdAt), 'yyyy-MM-dd', { locale: zhCN })}
{article.统计数据?.阅读数 || 0} 阅读
{/* Cover Image */} {article.封面图 && (
{article.文章标题}
)} {/* Article Content */}
{/* Comments Section */}
{/* Sidebar - Right Column (30%) */}
{/* Resource Card */}

资源下载

资源价格
{article.价格 > 0 ? `¥${article.价格}` : '免费'} {article.价格 > 0 && / 永久}
{/* Resource Attributes (Version, Size, etc.) */} {article.资源属性 && (
{article.资源属性.版本号 && (
版本: {article.资源属性.版本号}
)} {article.资源属性.文件大小 && (
大小: {article.资源属性.文件大小}
)} {article.资源属性.扩展属性?.map((attr, idx) => (
{attr.属性名}: {attr.属性值}
))}
)} {hasAccess ? (
您已拥有此资源权限
{article.资源属性 && (
{article.资源属性.提取码 && (
提取码: {article.资源属性.提取码}
)} {article.资源属性.解压密码 && (
解压密码: {article.资源属性.解压密码}
)} {article.资源属性.隐藏内容 && (
付费内容
{article.资源属性.隐藏内容}
)}
)}
) : (
{article.支付方式 === 'membership_free' ? (
会员免费下载 (点击开通)
) : (
开通会员享受折扣
)}
)}
{article.统计数据?.阅读数 || 0}
浏览次数
{article.统计数据?.销量 || 0}
最近售出
{/* Recent Posts Card */} 近期推荐
{recentArticles.length > 0 ? ( recentArticles.map((item, _index) => (
{item.封面图 ? ( {item.文章标题} ) : (
)}

{item.文章标题}

{format(new Date(item.createdAt), 'MM-dd')}
)) ) : (
暂无推荐
)}
); }