"use client";
import { useEffect, useState } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation, Pagination, Grid } from "swiper/modules";
import Link from "next/link";
import Image from "next/image";
import PropTypes from "prop-types";
export default function SwiperItems({ pagetype = "", category = "", category_slug = "" , count = 8, columns = 4, rows = 1 }) {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchData() {
setLoading(true);
try {
const params = new URLSearchParams({ pagetype });
if (category) params.append("category", category);
if (count !== undefined && count !== null) params.append("count", count);
const res = await fetch(`/api/get-listview-data?${params.toString()}`);
const json = await res.json();
if (Array.isArray(json.data)) {
setPosts(json.data);
} else {
setPosts([]);
}
} catch (e) {
setPosts([]);
}
setLoading(false);
}
fetchData();
}, [pagetype, category, count]);
// 渲染卡片内容
function renderCardImage(post, idx) {
// 多图轮播
if (Array.isArray(post.images) && post.images.length > 1) {
return (
{post.images.map((img, i) => (
))}
);
}
// 视频
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 (
);
}
}
// 单图
const img = post.image || (Array.isArray(post.images) && post.images[0]);
if (img) {
return (
);
}
return null;
}
function getSummary(text, maxLen = 60) {
if (!text) return "";
// 中文:直接按字符截断
if (/[\u4e00-\u9fa5]/.test(text)) {
return text.length > maxLen ? text.slice(0, maxLen) + "..." : text;
}
// 英文:按字符截断,但不截断单词
if (text.length <= maxLen) return text;
let cut = text.slice(0, maxLen);
// 如果最后一个字符不是空格,向前找到最近的空格
if (!/\s/.test(text[maxLen])) {
const lastSpace = cut.lastIndexOf(" ");
if (lastSpace > 0) cut = cut.slice(0, lastSpace);
}
return cut + "...";
}
// 日期格式化函数,支持自定义是否显示时分秒
function formatDate(dateStr, options = {}) {
if (!dateStr) return "";
const d = new Date(dateStr);
if (isNaN(d.getTime())) return dateStr;
const { showTime = false } = options;
const yyyy = d.getFullYear();
const mm = String(d.getMonth() + 1).padStart(2, '0');
const dd = String(d.getDate()).padStart(2, '0');
let result = `${yyyy}-${mm}-${dd}`;
if (showTime) {
const hh = String(d.getHours()).padStart(2, '0');
const min = String(d.getMinutes()).padStart(2, '0');
const ss = String(d.getSeconds()).padStart(2, '0');
result += ` ${hh}:${min}:${ss}`;
}
return result;
}
return (
{loading ? (
加载中...
) : posts.length === 0 ? (
暂无数据
) : (
1 ? 2 : 1 } },
992: { slidesPerView: columns, grid: { rows } },
}}
>
{posts.map((post, idx) => (
{/* 图片/轮播/视频部分 */}
{renderCardImage(post, idx)}
查看详情
{/* 文字内容 */}
{getSummary(post.subtitle)}
{/* 底部信息 */}
-
{formatDate(post.creation)}
{post.author && (
-
{post.author}
)}
{typeof post.comments === 'number' && (
-
{post.comments}
)}
{typeof post.likes === 'number' && (
-
{post.likes}
)}
))}
)}
);
}
SwiperItems.propTypes = {
pagetype: PropTypes.string,
category: PropTypes.string,
count: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
columns: PropTypes.number,
category_slug: PropTypes.string,
rows: PropTypes.number,
};