From b5d04a867d3442ea7200126d7426d78c8805ce4d Mon Sep 17 00:00:00 2001 From: jingrow Date: Wed, 18 Jun 2025 14:31:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0PageItems=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/get-listview-data/route.js | 4 +- app/page.jsx | 4 +- components/homes/home-15/CategoryItems.jsx | 29 ++- components/homes/home-15/PageItems.jsx | 240 +++++++++++++++++++++ 4 files changed, 266 insertions(+), 11 deletions(-) create mode 100644 components/homes/home-15/PageItems.jsx diff --git a/app/api/get-listview-data/route.js b/app/api/get-listview-data/route.js index a00085d..ef1cb8e 100644 --- a/app/api/get-listview-data/route.js +++ b/app/api/get-listview-data/route.js @@ -6,12 +6,14 @@ export async function GET(request) { try { const { searchParams } = new URL(request.url); const pagetype = searchParams.get('pagetype'); + const category = searchParams.get('category'); + const count = searchParams.get('count'); if (!pagetype) { return Response.json({ error: '缺少pagetype参数' }, { status: 400 }); } const response = await axios.get( `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_listview_data`, - { params: { pagetype } } + { params: { pagetype, category, count } } ); const data = response.data.message?.data || []; return Response.json({ data }); diff --git a/app/page.jsx b/app/page.jsx index 6be8ba1..22c0562 100644 --- a/app/page.jsx +++ b/app/page.jsx @@ -2,6 +2,7 @@ import Faqs from "@/components/homes/home-15/Faqs"; import Gallery from "@/components/homes/home-15/Gallery"; import Features from "@/components/homes/home-15/Features"; import Hero from "@/components/homes/home-15/Hero"; +import PageItems from "@/components/homes/home-15/PageItems"; import CategoryItems from "@/components/homes/home-15/CategoryItems"; import React from "react"; import { getSiteSettings } from "@/utlis/siteSettings"; @@ -40,7 +41,8 @@ export default function Page() {
- + +
diff --git a/components/homes/home-15/CategoryItems.jsx b/components/homes/home-15/CategoryItems.jsx index 512d919..a4edce8 100644 --- a/components/homes/home-15/CategoryItems.jsx +++ b/components/homes/home-15/CategoryItems.jsx @@ -4,11 +4,12 @@ import { Swiper, SwiperSlide } from "swiper/react"; import { Navigation, Pagination } from "swiper/modules"; import Link from "next/link"; import Image from "next/image"; +import PropTypes from "prop-types"; const PAGE_SIZE = 8; // 每页8条,4列2行 const PAGE_SLUG = "case"; // 博客slug常量 -export default function CategoryItems() { +export default function CategoryItems({ pagetype = "", category = "", count = undefined }) { const [posts, setPosts] = useState([]); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); @@ -18,15 +19,16 @@ export default function CategoryItems() { async function fetchData() { setLoading(true); try { - const res = await fetch("/api/get-page-data", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ slug_list: [PAGE_SLUG], page: currentPage, page_size: PAGE_SIZE }), - }); + const params = new URLSearchParams({ pagetype }); + if (category) params.append("category", category); + if (count !== undefined && count !== null) params.append("count", count); + params.append("page", currentPage); + params.append("page_size", PAGE_SIZE); + const res = await fetch(`/api/get-listview-data?${params.toString()}`); const json = await res.json(); if (Array.isArray(json.data)) { setPosts(json.data); - setTotalPages(Math.ceil((json.total || 0) / PAGE_SIZE)); + setTotalPages(Math.ceil((json.total || json.data.length || 0) / PAGE_SIZE)); } else { setPosts([]); setTotalPages(1); @@ -38,7 +40,7 @@ export default function CategoryItems() { setLoading(false); } fetchData(); - }, [currentPage]); + }, [currentPage, pagetype, category, count]); // 分页控件 function PaginationComp() { @@ -171,7 +173,7 @@ export default function CategoryItems() {
- {post.category || post.categories || ""} + {post.category || ""}

@@ -229,3 +231,12 @@ export default function CategoryItems() {

); } + +CategoryItems.propTypes = { + pagetype: PropTypes.string, + category: PropTypes.string, + count: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number + ]), +}; diff --git a/components/homes/home-15/PageItems.jsx b/components/homes/home-15/PageItems.jsx new file mode 100644 index 0000000..142079f --- /dev/null +++ b/components/homes/home-15/PageItems.jsx @@ -0,0 +1,240 @@ +"use client"; +import { useEffect, useState } from "react"; +import { Swiper, SwiperSlide } from "swiper/react"; +import { Navigation, Pagination } from "swiper/modules"; +import Link from "next/link"; +import Image from "next/image"; + +export default function PageItems({ page_slug = "", page_size = 8, columns = 4 }) { + const [posts, setPosts] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [totalPages, setTotalPages] = useState(1); + const [loading, setLoading] = useState(false); + + // 静态映射,避免 Tailwind JIT 无法识别动态类名 + const colClass = { + 1: "lg:grid-cols-1", + 2: "lg:grid-cols-2", + 3: "lg:grid-cols-3", + 4: "lg:grid-cols-4", + 5: "lg:grid-cols-5", + 6: "lg:grid-cols-6", + }[columns] || "lg:grid-cols-4"; + + useEffect(() => { + async function fetchData() { + setLoading(true); + try { + const res = await fetch("/api/get-page-data", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ slug_list: [page_slug], page: currentPage, page_size }), + }); + const json = await res.json(); + if (Array.isArray(json.data)) { + setPosts(json.data); + setTotalPages(Math.ceil((json.total || 0) / page_size)); + } else { + setPosts([]); + setTotalPages(1); + } + } catch (e) { + setPosts([]); + setTotalPages(1); + } + setLoading(false); + } + fetchData(); + }, [currentPage, page_slug, page_size]); + + // 分页控件 + function PaginationComp() { + if (totalPages <= 1) return null; + return ( + + ); + } + + // 渲染卡片内容(只返回图片部分,结构在下方article里) + function renderCardImage(post, idx) { + // 多图轮播 + if (Array.isArray(post.images) && post.images.length > 1) { + return ( + + {post.images.map((img, i) => ( + + {post.title + + ))} + + ); + } + // 视频 + if (post.video_src || post.videoId) { + if (post.video_src && (post.video_src.endsWith('.mp4') || post.video_src.startsWith('/files/'))) { + return ( + + ); + } + const vid = post.videoId || (post.video_src && post.video_src.includes('youtube') ? post.video_src.split('embed/')[1] : null); + if (vid) { + return ( +