重构footer和siteSettings
This commit is contained in:
parent
260bce7b28
commit
71e3b90a6b
@ -1,6 +1,6 @@
|
|||||||
import Banner from "@/components/banner/Banner";
|
import Banner from "@/components/banner/Banner";
|
||||||
import Category from "@/components/sidebar/Category";
|
import Category from "@/components/sidebar/Category";
|
||||||
import { getSiteSettings } from "@/utils/siteSettings";
|
import { getSiteSettings } from "@/utils/data";
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import DynamicListPage from "@/components/common/DynamicListPage";
|
import DynamicListPage from "@/components/common/DynamicListPage";
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
@ -35,21 +35,43 @@ export async function generateMetadata({ params }) {
|
|||||||
slug_list: slugArr,
|
slug_list: slugArr,
|
||||||
downloadFiles: false // Do not download files for metadata
|
downloadFiles: false // Do not download files for metadata
|
||||||
});
|
});
|
||||||
|
const siteSettings = await getSiteSettings();
|
||||||
|
const siteTitle = siteSettings.site_title || '';
|
||||||
|
const siteName = siteSettings.site_name || '';
|
||||||
|
const siteNameInPageTitles = siteSettings.site_name_in_page_titles || 'None';
|
||||||
|
|
||||||
|
let title = '';
|
||||||
if (error) {
|
if (error) {
|
||||||
|
title = error.title || 'Page Error';
|
||||||
return {
|
return {
|
||||||
title: error.title || 'Page Error',
|
title,
|
||||||
description: error.message || '',
|
description: error.message || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (Array.isArray(data) && page_info) {
|
if (Array.isArray(data) && page_info) {
|
||||||
|
title = page_info.meta_title || page_info.title || '';
|
||||||
|
if (siteName && title) {
|
||||||
|
if (siteNameInPageTitles === 'After') {
|
||||||
|
title = `${title} - ${siteName}`;
|
||||||
|
} else if (siteNameInPageTitles === 'Before') {
|
||||||
|
title = `${siteName} - ${title}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
title: page_info.meta_title || page_info.title || '',
|
title,
|
||||||
description: page_info.meta_description || '',
|
description: page_info.meta_description || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
title = data?.meta_title || data?.title || '';
|
||||||
|
if (siteName && title) {
|
||||||
|
if (siteNameInPageTitles === 'After') {
|
||||||
|
title = `${title} - ${siteName}`;
|
||||||
|
} else if (siteNameInPageTitles === 'Before') {
|
||||||
|
title = `${siteName} - ${title}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
title: data?.meta_title || data?.title || '',
|
title,
|
||||||
description: data?.meta_description || '',
|
description: data?.meta_description || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -57,8 +79,7 @@ export async function generateMetadata({ params }) {
|
|||||||
export default async function DynamicPage({ params, searchParams }) {
|
export default async function DynamicPage({ params, searchParams }) {
|
||||||
const resolvedParams = await params;
|
const resolvedParams = await params;
|
||||||
const slugArr = resolvedParams.slug;
|
const slugArr = resolvedParams.slug;
|
||||||
|
const siteSettings = await getSiteSettings();
|
||||||
const siteSettings = await getSiteSettings(process.env.SITE_URL);
|
|
||||||
const pageSize = Number(siteSettings.page_size) || 12;
|
const pageSize = Number(siteSettings.page_size) || 12;
|
||||||
|
|
||||||
// 始终获取第一页的数据用于静态生成
|
// 始终获取第一页的数据用于静态生成
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
import Hero from "@/components/homes/home-15/Hero";
|
import Hero from "@/components/homes/home-15/Hero";
|
||||||
import SwiperItems from "@/components/homes/home-15/SwiperItems";
|
import SwiperItems from "@/components/homes/home-15/SwiperItems";
|
||||||
import CategoryItems from "@/components/homes/home-15/CategoryItems";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { getSiteSettings } from "@/utils/siteSettings";
|
import { getSiteSettings } from "@/utils/data";
|
||||||
|
|
||||||
// Using a static value to comply with Next.js 15 build requirements.
|
// Using a static value to comply with Next.js 15 build requirements.
|
||||||
// On-demand revalidation will be handled via the API route.
|
// On-demand revalidation will be handled via the API route.
|
||||||
export const revalidate = 3600;
|
export const revalidate = 3600;
|
||||||
|
|
||||||
export async function generateMetadata() {
|
export async function generateMetadata() {
|
||||||
const siteUrl = process.env.SITE_URL;
|
const data = await getSiteSettings();
|
||||||
const data = await getSiteSettings(siteUrl);
|
|
||||||
const siteTitle = data.site_title || "";
|
const siteTitle = data.site_title || "";
|
||||||
const siteDescription = data.site_description || "";
|
const siteDescription = data.site_description || "";
|
||||||
const siteName = data.site_name || "";
|
const siteName = data.site_name || "";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Banner from "@/components/banner/Banner";
|
import Banner from "@/components/banner/Banner";
|
||||||
import Category from "@/components/sidebar/Category";
|
import Category from "@/components/sidebar/Category";
|
||||||
import { getSiteSettings } from "@/utils/siteSettings";
|
import { getSiteSettings } from "@/utils/data";
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import DynamicListPage from "@/components/common/DynamicListPage";
|
import DynamicListPage from "@/components/common/DynamicListPage";
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
@ -21,21 +21,43 @@ export async function generateMetadata({ params }) {
|
|||||||
const slug = resolvedParams.slug || [];
|
const slug = resolvedParams.slug || [];
|
||||||
const slugArr = [baseSlug, ...(Array.isArray(slug) ? slug : [slug])];
|
const slugArr = [baseSlug, ...(Array.isArray(slug) ? slug : [slug])];
|
||||||
const { data, error, page_info } = await getPageData({ slug_list: slugArr });
|
const { data, error, page_info } = await getPageData({ slug_list: slugArr });
|
||||||
|
const siteSettings = await getSiteSettings();
|
||||||
|
const siteTitle = siteSettings.site_title || '';
|
||||||
|
const siteName = siteSettings.site_name || '';
|
||||||
|
const siteNameInPageTitles = siteSettings.site_name_in_page_titles || 'None';
|
||||||
|
|
||||||
|
let title = '';
|
||||||
if (error) {
|
if (error) {
|
||||||
|
title = error.title || 'Page Error';
|
||||||
return {
|
return {
|
||||||
title: error.title || 'Page Error',
|
title,
|
||||||
description: error.message || '',
|
description: error.message || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (Array.isArray(data) && page_info) {
|
if (Array.isArray(data) && page_info) {
|
||||||
|
title = page_info.meta_title || page_info.title || '';
|
||||||
|
if (siteName && title) {
|
||||||
|
if (siteNameInPageTitles === 'After') {
|
||||||
|
title = `${title} - ${siteName}`;
|
||||||
|
} else if (siteNameInPageTitles === 'Before') {
|
||||||
|
title = `${siteName} - ${title}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
title: page_info.meta_title || page_info.title || '',
|
title,
|
||||||
description: page_info.meta_description || '',
|
description: page_info.meta_description || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
title = data?.meta_title || data?.title || '';
|
||||||
|
if (siteName && title) {
|
||||||
|
if (siteNameInPageTitles === 'After') {
|
||||||
|
title = `${title} - ${siteName}`;
|
||||||
|
} else if (siteNameInPageTitles === 'Before') {
|
||||||
|
title = `${siteName} - ${title}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
title: data?.meta_title || data?.title || '',
|
title,
|
||||||
description: data?.meta_description || '',
|
description: data?.meta_description || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -45,7 +67,7 @@ export default async function Page({ params, searchParams }) {
|
|||||||
const slug = resolvedParams.slug || [];
|
const slug = resolvedParams.slug || [];
|
||||||
const slugArr = [baseSlug, ...(Array.isArray(slug) ? slug : [slug])];
|
const slugArr = [baseSlug, ...(Array.isArray(slug) ? slug : [slug])];
|
||||||
|
|
||||||
const siteSettings = await getSiteSettings(process.env.SITE_URL);
|
const siteSettings = await getSiteSettings();
|
||||||
const pageSize = Number(siteSettings.page_size) || 12;
|
const pageSize = Number(siteSettings.page_size) || 12;
|
||||||
|
|
||||||
const { data, error, total } = await getPageData({
|
const { data, error, total } = await getPageData({
|
||||||
|
|||||||
@ -1,17 +1,11 @@
|
|||||||
'use client';
|
import React from "react";
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import SocialLinks from "@/components/contact/SocialLinks";
|
import SocialLinks from "@/components/contact/SocialLinks";
|
||||||
import { getSiteSettings } from "@/utils/siteSettings";
|
import { getSiteSettings } from "@/utils/data";
|
||||||
import MenuList from "./MenuList";
|
import MenuList from "./MenuList";
|
||||||
import Contact from "@/components/contact/Contact";
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
export default function Footer15() {
|
export default async function Footer() {
|
||||||
const [siteSettings, setSiteSettings] = useState({});
|
const siteSettings = await getSiteSettings();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getSiteSettings().then(setSiteSettings);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="!text-[#333333] z-0">
|
<footer className="!text-[#333333] z-0">
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import SocialLinks from "@/components/contact/SocialLinks";
|
import SocialLinks from "@/components/contact/SocialLinks";
|
||||||
import { getSiteSettings } from "@/utils/siteSettings";
|
import { getSiteSettings } from "@/utils/data";
|
||||||
import MenuList from "./MenuList";
|
import MenuList from "./MenuList";
|
||||||
import Contact from "@/components/contact/Contact";
|
import Contact from "@/components/contact/Contact";
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
'use client';
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import Link from "next/link";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import LoginButton from "./LoginButton";
|
import LoginButton from "./LoginButton";
|
||||||
import SocialLinks from "../contact/SocialLinks";
|
import SocialLinks from "../contact/SocialLinks";
|
||||||
import { getSiteSettings } from "@/utils/siteSettings";
|
import { getSiteSettings } from "@/utils/data";
|
||||||
|
|
||||||
export default async function Header() {
|
export default async function Header() {
|
||||||
const siteSettings = await getSiteSettings();
|
const siteSettings = await getSiteSettings();
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Link from "next/link";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import LanguageSelect from "./LanguageSelect";
|
import LanguageSelect from "./LanguageSelect";
|
||||||
import SocialLinks from "../contact/SocialLinks";
|
import SocialLinks from "../contact/SocialLinks";
|
||||||
import { getSiteSettings } from "@/utils/siteSettings";
|
import { getSiteSettings } from "@/utils/data";
|
||||||
|
|
||||||
export default function Header15() {
|
export default function Header15() {
|
||||||
const [siteSettings, setSiteSettings] = useState({});
|
const [siteSettings, setSiteSettings] = useState({});
|
||||||
|
|||||||
@ -5,6 +5,10 @@ const nextConfig = {
|
|||||||
unoptimized: true,
|
unoptimized: true,
|
||||||
},
|
},
|
||||||
allowedDevOrigins,
|
allowedDevOrigins,
|
||||||
|
env: {
|
||||||
|
JINGROW_SERVER_URL: process.env.JINGROW_SERVER_URL,
|
||||||
|
// 你还可以加其他需要暴露到前端的变量
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
@ -9,6 +9,17 @@ if (!fs.existsSync(PUBLIC_FILES_DIR)) {
|
|||||||
fs.mkdirSync(PUBLIC_FILES_DIR, { recursive: true });
|
fs.mkdirSync(PUBLIC_FILES_DIR, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 直接内置鉴权头部生成函数,避免跨文件依赖
|
||||||
|
function get_jingrow_api_headers() {
|
||||||
|
// 这里应根据实际情况实现获取token等逻辑
|
||||||
|
const apiKey = process.env.JINGROW_API_KEY;
|
||||||
|
const apiSecret = process.env.JINGROW_API_SECRET;
|
||||||
|
return {
|
||||||
|
'Authorization': `token ${apiKey}:${apiSecret}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export async function downloadToLocal(fileUrl) {
|
export async function downloadToLocal(fileUrl) {
|
||||||
if (!fileUrl) return fileUrl;
|
if (!fileUrl) return fileUrl;
|
||||||
try {
|
try {
|
||||||
@ -269,4 +280,20 @@ export async function getMenuData() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { error: error.message, detail: error?.response?.data || null };
|
return { error: error.message, detail: error?.response?.data || null };
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getSiteSettings() {
|
||||||
|
try {
|
||||||
|
const res = await axios.get(
|
||||||
|
`${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_site_settings`,
|
||||||
|
{ headers: get_jingrow_api_headers() }
|
||||||
|
);
|
||||||
|
return res.data?.message?.data || {
|
||||||
|
site_name: "Jsite"
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
site_name: "Jsite"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,27 +1,23 @@
|
|||||||
// utils for global site settings
|
export async function getSiteSettings() {
|
||||||
let cache = null;
|
const JINGROW_SERVER_URL = process.env.JINGROW_SERVER_URL;
|
||||||
let lastFetch = 0;
|
const apiKey = process.env.JINGROW_API_KEY;
|
||||||
const CACHE_TTL = 1000 * 60 * 15; // 15分钟缓存
|
const apiSecret = process.env.JINGROW_API_SECRET;
|
||||||
|
const url = `${JINGROW_SERVER_URL}/api/method/jsite.api.v1.get_site_settings`;
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取全局站点设置,自动缓存,支持SSR/CSR
|
|
||||||
* @param {string} [siteUrl] SSR时建议传入完整siteUrl,CSR可省略
|
|
||||||
* @returns {Promise<Object>} 站点设置对象
|
|
||||||
*/
|
|
||||||
export async function getSiteSettings(siteUrl) {
|
|
||||||
if (cache && Date.now() - lastFetch < CACHE_TTL) {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
const url = siteUrl
|
|
||||||
? `${siteUrl}/api/get-site-settings`
|
|
||||||
: '/api/get-site-settings';
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(url);
|
const controller = new AbortController();
|
||||||
|
const timeout = setTimeout(() => controller.abort(), 3000);
|
||||||
|
const res = await fetch(url, {
|
||||||
|
signal: controller.signal,
|
||||||
|
headers: {
|
||||||
|
'Authorization': `token ${apiKey}:${apiSecret}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clearTimeout(timeout);
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
cache = json.data || {};
|
return json.message?.data || {};
|
||||||
lastFetch = Date.now();
|
|
||||||
return cache;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {};
|
return { site_name: "Jsite", mobile: "", tel: "", email: "" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user