diff --git a/app/[...slug]/page.jsx b/app/[...slug]/page.jsx
index e8dc7cd..9568683 100644
--- a/app/[...slug]/page.jsx
+++ b/app/[...slug]/page.jsx
@@ -4,6 +4,7 @@ import { getSiteSettings } from "@/utlis/siteSettings";
import { notFound } from 'next/navigation';
import DynamicListPage from "@/components/common/DynamicListPage";
import { Suspense } from 'react';
+import { getPageData, getAllSlugs } from "@/utlis/data";
const LoadingSpinner = () => (
@@ -11,39 +12,24 @@ const LoadingSpinner = () => (
);
-export const revalidate = 3600;
+export const revalidate = 10;
export const dynamicParams = true;
export async function generateStaticParams() {
- try {
- const res = await fetch(`${process.env.SITE_URL}/api/get-all-slugs`);
- if (!res.ok) {
- throw new Error(`Failed to fetch slugs: ${res.status}`);
- }
- const slugs = await res.json();
- if (!Array.isArray(slugs)) {
- console.error("generateStaticParams: received non-array from /api/get-all-slugs", slugs);
- return [];
- }
- return slugs.map(slug => ({
- slug: slug,
- }));
- } catch (error) {
- console.error("Could not generate static params:", error);
- return [];
- }
+ const slugs = await getAllSlugs();
+ return slugs.map(slug => ({
+ slug: slug,
+ }));
}
export async function generateMetadata({ params }) {
const resolvedParams = await params;
const slugArr = resolvedParams.slug;
- const res = await fetch(`${process.env.SITE_URL}/api/get-page-data`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ slug_list: slugArr })
+ const { data, error, page_info } = await getPageData({
+ slug_list: slugArr,
+ downloadFiles: false // Do not download files for metadata
});
- const json = await res.json();
- const { data, error, page_info } = json;
+
if (error) {
return {
title: error.title || 'Page Error',
@@ -70,13 +56,12 @@ export default async function DynamicPage({ params }) {
const pageSize = Number(siteSettings.page_size) || 12;
// 始终获取第一页的数据用于静态生成
- const res = await fetch(`${process.env.SITE_URL}/api/get-page-data`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ slug_list: slugArr, page: 1, page_size: pageSize })
+ const { data, error, total } = await getPageData({
+ slug_list: slugArr,
+ page: 1,
+ page_size: pageSize,
+ downloadFiles: true // Download files for page rendering
});
- const result = await res.json();
- const { data, error, total } = result;
if (error) {
notFound();
diff --git a/app/api/get-all-slugs/route.js b/app/api/get-all-slugs/route.js
deleted file mode 100644
index 2433fb1..0000000
--- a/app/api/get-all-slugs/route.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import axios from 'axios';
-
-const JINGROW_SERVER_URL = process.env.JINGROW_SERVER_URL;
-
-export async function GET() {
- try {
- const response = await axios.get(
- `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_all_slugs`
- );
-
- const slugs = response.data.message?.data;
-
- if (!Array.isArray(slugs)) {
- console.error('API did not return an array of slugs:', response.data);
- return Response.json({ error: '返回的slugs格式不正确' }, { status: 500 });
- }
-
- return Response.json(slugs);
- } catch (error) {
- console.error('Error fetching slugs:', error.message, error?.response?.data);
- return Response.json(
- { error: '获取slugs失败', detail: error?.response?.data || error.message },
- { status: 500 }
- );
- }
-}
\ No newline at end of file
diff --git a/app/api/get-page-data/route.js b/app/api/get-page-data/route.js
deleted file mode 100644
index 501ec37..0000000
--- a/app/api/get-page-data/route.js
+++ /dev/null
@@ -1,125 +0,0 @@
-import axios from 'axios';
-import fs from 'fs';
-import path from 'path';
-
-const JINGROW_SERVER_URL = process.env.JINGROW_SERVER_URL;
-const PUBLIC_FILES_DIR = path.join(process.cwd(), 'public/files');
-
-if (!fs.existsSync(PUBLIC_FILES_DIR)) {
- fs.mkdirSync(PUBLIC_FILES_DIR, { recursive: true });
-}
-
-async function downloadToLocal(fileUrl) {
- try {
- let fullUrl = fileUrl;
- if (!/^https?:\/\//.test(fileUrl)) {
- fullUrl = `${JINGROW_SERVER_URL}${fileUrl}`;
- }
- const fileName = path.basename(fullUrl.split('?')[0]);
- const localPath = path.join(PUBLIC_FILES_DIR, fileName);
- const localUrl = `/files/${fileName}`;
- if (!fs.existsSync(localPath)) {
- const response = await axios.get(fullUrl, { responseType: 'stream' });
- await new Promise((resolve, reject) => {
- const writer = fs.createWriteStream(localPath);
- response.data.pipe(writer);
- writer.on('finish', resolve);
- writer.on('error', reject);
- });
- }
- return localUrl;
- } catch (e) {
- return fileUrl;
- }
-}
-
-// 提取富文本中的所有图片链接
-function extractImageUrlsFromHtml(html) {
- if (!html) return [];
- const regex = /
]+src=["']([^"'>]+)["']/g;
- const urls = [];
- let match;
- while ((match = regex.exec(html)) !== null) {
- urls.push(match[1]);
- }
- return urls;
-}
-
-// 替换富文本中的图片链接为本地路径
-async function replaceImageUrlsInHtml(html) {
- if (!html) return html;
- const regex = /
]+)src=["']([^"'>]+)["']/g;
- return await html.replace(regex, async (match, pre, url) => {
- const localUrl = await downloadToLocal(url);
- return `
{
+ const writer = fs.createWriteStream(localPath);
+ response.data.pipe(writer);
+ writer.on('finish', resolve);
+ writer.on('error', (error) => {
+ console.error(`Error writing file ${localPath}:`, error);
+ // Don't reject, just resolve and return original url later
+ fs.unlink(localPath, () => resolve());
+ });
+ });
+ }
+ return localUrl;
+ } catch (e) {
+ console.error(`Failed to download ${fileUrl}:`, e.message);
+ return fileUrl; // Return original url on error
+ }
+}
+
+function extractImageUrlsFromHtml(html) {
+ if (!html) return [];
+ const regex = /
]+src=["']([^"'>]+)["']/g;
+ const urls = [];
+ let match;
+ while ((match = regex.exec(html)) !== null) {
+ urls.push(match[1]);
+ }
+ return urls;
+}
+
+async function processDataItem(item, downloadFiles) {
+ if (!downloadFiles) return item;
+
+ if (item.image) {
+ item.image = await downloadToLocal(item.image);
+ }
+ if (item.image_1) {
+ item.image_1 = await downloadToLocal(item.image_1);
+ }
+ if (item.image_2) {
+ item.image_2 = await downloadToLocal(item.image_2);
+ }
+ if (item.video_src) {
+ item.video_src = await downloadToLocal(item.video_src);
+ }
+ if (item.file_src) {
+ item.file_src = await downloadToLocal(item.file_src);
+ }
+
+ if (item.items && Array.isArray(item.items)) {
+ for (const subItem of item.items) {
+ if (subItem.item_image) {
+ subItem.item_image = await downloadToLocal(subItem.item_image);
+ }
+ if (subItem.item_video_src) {
+ subItem.item_video_src = await downloadToLocal(subItem.item_video_src);
+ }
+ if (subItem.item_icon) {
+ subItem.item_icon = await downloadToLocal(subItem.item_icon);
+ }
+ }
+ }
+
+ for (const key of ['content', 'additional_content', 'description', 'p1', 'p2', 'p3']) {
+ if (item[key]) {
+ const urls = extractImageUrlsFromHtml(item[key]);
+ let html = item[key];
+ for (const url of urls) {
+ const localUrl = await downloadToLocal(url);
+ html = html.replaceAll(url, localUrl);
+ }
+ item[key] = html;
+ }
+ }
+ return item;
+}
+
+export async function getPageData({
+ slug_list,
+ page = 1,
+ page_size,
+ downloadFiles = false
+}) {
+ try {
+ if (!Array.isArray(slug_list)) {
+ throw new Error('slug_list must be an array');
+ }
+
+ const params = { slug_list: JSON.stringify(slug_list), page };
+ if (page_size) params.page_size = page_size;
+
+ const response = await axios.get(
+ `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_page_data`,
+ { params }
+ );
+
+ const message = response.data.message;
+ if (message?.error) {
+ const errorMsg = typeof message.error === 'object' ? JSON.stringify(message.error) : message.error;
+ throw new Error(errorMsg);
+ }
+
+ let data = message?.data;
+
+ if (Array.isArray(data)) {
+ if(downloadFiles) {
+ data = await Promise.all(data.map(item => processDataItem(item, downloadFiles)));
+ }
+ } else if (data) {
+ data = await processDataItem(data, downloadFiles);
+ }
+
+ return {
+ data: message.data,
+ total: message.total,
+ page_info: message.page_info,
+ };
+ } catch (error) {
+ console.error("Error in getPageData:", error);
+ return { error: { message: error.message, detail: error?.response?.data || null } };
+ }
+}
+
+export async function getAllSlugs() {
+ try {
+ const response = await axios.get(
+ `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_all_slugs`
+ );
+ const slugs = response.data.message?.data;
+ if (!Array.isArray(slugs)) {
+ console.error('API did not return an array of slugs:', response.data);
+ return [];
+ }
+ // Filter out slugs that represent the root page, as it's handled by app/page.jsx
+ const filteredSlugs = slugs.filter(slug => {
+ if (!Array.isArray(slug) || slug.length === 0) {
+ return false;
+ }
+ // Exclude slugs like [''] or ['/'] which are for the homepage
+ if (slug.length === 1 && (slug[0] === '' || slug[0] === '/')) {
+ return false;
+ }
+ return true;
+ });
+ return filteredSlugs;
+ } catch (error) {
+ console.error('Error fetching slugs:', error);
+ return [];
+ }
+}
\ No newline at end of file