import { prisma } from "@/lib/prisma"; import { notFound } from "next/navigation"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { FavoriteButton } from "@/components/common/FavoriteButton"; import { ReviewSection } from "@/components/common/ReviewSection"; const pricingLabel: Record = { free: "免费", freemium: "免费增值", paid: "付费", subscription: "订阅", }; const pricingColor: Record = { free: "bg-emerald-50 text-emerald-700 border border-emerald-200", freemium: "bg-blue-50 text-blue-700 border border-blue-200", paid: "bg-amber-50 text-amber-700 border border-amber-200", subscription: "bg-purple-50 text-purple-700 border border-purple-200", }; const pricingIcon: Record = { free: "M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z", freemium: "M13 10V3L4 14h7v7l9-11h-7z", paid: "M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z", subscription: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15", }; const tagColors = [ "border-blue-200 bg-blue-50 text-blue-700", "border-purple-200 bg-purple-50 text-purple-700", "border-emerald-200 bg-emerald-50 text-emerald-700", "border-amber-200 bg-amber-50 text-amber-700", "border-pink-200 bg-pink-50 text-pink-700", "border-cyan-200 bg-cyan-50 text-cyan-700", "border-indigo-200 bg-indigo-50 text-indigo-700", "border-rose-200 bg-rose-50 text-rose-700", ]; interface PageProps { params: { slug: string }; } export async function generateMetadata({ params }: PageProps) { const tool = await prisma.tool.findUnique({ where: { slug: params.slug, status: "published" }, select: { name: true, description: true }, }); if (!tool) { return { title: "工具不存在" }; } return { title: `${tool.name} - 追光AI工具详情`, description: tool.description, }; } export default async function ToolDetailPage({ params }: PageProps) { const tool = await prisma.tool.findUnique({ where: { slug: params.slug, status: "published" }, select: { id: true, name: true, slug: true, description: true, logoUrl: true, websiteUrl: true, pricingModel: true, pricingDetail: true, features: true, tags: true, viewCount: true, createdAt: true, updatedAt: true, category: { select: { id: true, name: true, slug: true } }, }, }); if (!tool) { notFound(); } prisma.tool.update({ where: { id: tool.id }, data: { viewCount: { increment: 1 } }, }).catch(() => {}); const session = await getServerSession(authOptions); let favorited = false; if (session?.user?.id) { const fav = await prisma.favorite.findFirst({ where: { userId: parseInt(session.user.id), toolId: tool.id }, select: { id: true }, }); favorited = !!fav; } const favoriteCount = await prisma.favorite.count({ where: { toolId: tool.id }, }); const displayViewCount = tool.viewCount + 1; const features = (Array.isArray(tool.features) ? tool.features as string[] : []); const tags = (Array.isArray(tool.tags) ? tool.tags as string[] : []); return (
{tool.logoUrl ? ( ) : (
{tool.name.charAt(0)}
)}

{tool.name}

{tool.category && ( {tool.category.name} )} {pricingLabel[tool.pricingModel] || tool.pricingModel} {tool.pricingDetail && ( {tool.pricingDetail} )} {displayViewCount} 次浏览 {favoriteCount} 人收藏

简介

{tool.description || "暂无简介"}

{features.length > 0 && (

功能特性

    {features.map((f: string, i: number) => (
  • {f}
  • ))}
)} {tags.length > 0 && (

标签

{tags.map((t: string, i: number) => ( {t} ))}
)}
收录时间: {new Date(tool.createdAt).toLocaleDateString("zh-CN")} {tool.updatedAt !== tool.createdAt && ( 更新时间: {new Date(tool.updatedAt).toLocaleDateString("zh-CN")} )}
); }