"use client" import { useEffect, useState } from "react" import { MainNav } from "@/components/main-nav" import { SearchBar } from "@/components/search-bar" import { ThemeToggle } from "@/components/theme-toggle" import { ShoppingCart } from "@/components/shopping-cart" import { UserNav } from "@/components/user-nav" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { useSearchParams } from "next/navigation" import { Card, CardContent } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { useToast } from "@/components/ui/use-toast" import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination" import Link from "next/link" import { ShoppingCartIcon, BookOpen, Search, Filter, BookOpenCheck, TrendingUp } from "lucide-react" import { useCart } from "@/context/cart-context" import { fetchWithAuth } from "@/lib/api" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { motion } from "framer-motion" import { Badge } from "@/components/ui/badge" import { notify } from "@/lib/event-bus" interface Book { bookId: number title: string isbn: string price: number stock: number publishDate: string publisherName: string description: string coverImage: string author: string[] } interface BooksResponse { pageNum: number pageSize: number total: number data: Book[] } export default function BooksPage() { const [books, setBooks] = useState(null) const [loading, setLoading] = useState(true) const [currentPage, setCurrentPage] = useState(1) const { toast } = useToast() const { addToCart } = useCart() const searchParams = useSearchParams() const searchQuery = searchParams?.get("search") || "" const [activeTab, setActiveTab] = useState("all") const [sortBy, setSortBy] = useState("default") useEffect(() => { const fetchBooks = async () => { setLoading(true) try { let url = `book/all?pageNum=${currentPage}&pageSize=8` // 如果有搜索查询,使用搜索接口 if (searchQuery) { url = `book/search/title?title=${encodeURIComponent(searchQuery)}&pageNum=${currentPage}&pageSize=8` } else if (activeTab === "new") { // 获取最新图书(按出版日期排序) url = `book/all?pageNum=${currentPage}&pageSize=8&sort=publishDate` } else if (activeTab === "popular") { // 这里假设后端有一个接口可以获取热门图书 url = `book/popular?pageNum=${currentPage}&pageSize=8` } const response = await fetchWithAuth(url) const result = await response.json() if (result.code === 0) { // 根据排序选项处理数据 const sortedData = [...result.data.data] if (sortBy === "priceAsc") { sortedData.sort((a, b) => a.price - b.price) } else if (sortBy === "priceDesc") { sortedData.sort((a, b) => b.price - a.price) } else if (sortBy === "dateDesc") { sortedData.sort((a, b) => new Date(b.publishDate).getTime() - new Date(a.publishDate).getTime()) } setBooks({ ...result.data, data: sortedData, }) } else { toast({ variant: "destructive", title: "获取图书失败", description: result.msg || "无法获取图书信息", }) } } catch (error) { toast({ variant: "destructive", title: "获取图书失败", description: "服务器连接错误,请稍后再试", }) } finally { setLoading(false) } } fetchBooks() }, [currentPage, toast, searchQuery, activeTab, sortBy]) const handlePageChange = (page: number) => { setCurrentPage(page) window.scrollTo({ top: 0, behavior: "smooth" }) } const handleAddToCart = (book: Book) => { addToCart({ id: book.bookId, title: book.title, price: book.price, quantity: 1, coverImage: book.coverImage || "/placeholder.svg?height=100&width=80", }) // 使用事件总线通知 notify({ title: "已添加到购物车", message: book.title, type: "success", duration: 3000, }) } const handleTabChange = (value: string) => { setActiveTab(value) setCurrentPage(1) // 重置页码 } const handleSortChange = (value: string) => { setSortBy(value) } return (

{searchQuery ? (
搜索结果: {searchQuery}
) : ( "图书列表" )}

handleSortChange("default")} className="flex items-center cursor-pointer" > 默认排序 handleSortChange("priceAsc")} className="flex items-center cursor-pointer" > 价格从低到高 handleSortChange("priceDesc")} className="flex items-center cursor-pointer" > 价格从高到低 handleSortChange("dateDesc")} className="flex items-center cursor-pointer" > 最新出版
{searchQuery ? (

找到 {books?.total || 0} 条结果

) : (

浏览我们的图书收藏,按不同类别查看

)}
{!searchQuery && ( 全部图书 最新上架 热门图书 {renderBookList()} {renderBookList()} {renderBookList()} )} {searchQuery && renderBookList()}

© {new Date().getFullYear()} 图书管理系统. 保留所有权利.

) function renderBookList() { if (loading) { return (
{Array.from({ length: 8 }).map((_, index) => (
))}
) } if (!books || books.data.length === 0) { return (

{searchQuery ? "未找到相关图书" : "暂无图书"}

{searchQuery ? "请尝试其他搜索词" : "请稍后再来查看"}

{searchQuery && ( )}
) } return (
{books.data.map((book, index) => (
{book.title}

{book.title}

{book.author.join(", ")}

¥{book.price.toFixed(2)}
))}
{books.total > books.pageSize && ( { e.preventDefault() if (currentPage > 1) handlePageChange(currentPage - 1) }} className={currentPage === 1 ? "pointer-events-none opacity-50" : ""} /> {Array.from({ length: Math.min(5, Math.ceil(books.total / books.pageSize)) }).map((_, index) => { let pageNumber = currentPage - 2 + index if (pageNumber < 1) pageNumber = index + 1 if (pageNumber > Math.ceil(books.total / books.pageSize)) pageNumber = Math.ceil(books.total / books.pageSize) - (4 - index) return ( { e.preventDefault() handlePageChange(pageNumber) }} isActive={currentPage === pageNumber} > {pageNumber} ) })} { e.preventDefault() if (currentPage < Math.ceil(books.total / books.pageSize)) { handlePageChange(currentPage + 1) } }} className={ currentPage >= Math.ceil(books.total / books.pageSize) ? "pointer-events-none opacity-50" : "" } /> )}
) } }