3 changed files with 166 additions and 174 deletions
@ -1,191 +1,183 @@ |
|||||
'use client'; |
'use client'; |
||||
import Link from 'next/link'; |
import Link from 'next/link'; |
||||
import Image from 'next/image'; |
import Image from 'next/image'; |
||||
import { useSiteInfoValue } from '@/hooks/useSiteInfo'; |
|
||||
import { CmsNavigation } from '@/api/cms/cmsNavigation/model'; |
|
||||
|
import {useSiteInfoValue} from '@/hooks/useSiteInfo'; |
||||
|
import {CmsNavigation} from '@/api/cms/cmsNavigation/model'; |
||||
import Container from '@/components/layout/Container'; |
import Container from '@/components/layout/Container'; |
||||
|
|
||||
const Footer = () => { |
const Footer = () => { |
||||
const { siteInfo, bottomNavs } = useSiteInfoValue(); |
|
||||
const currentYear = new Date().getFullYear(); |
|
||||
|
const {siteInfo, bottomNavs} = useSiteInfoValue(); |
||||
|
const currentYear = new Date().getFullYear(); |
||||
|
|
||||
// 按父级分组底部导航
|
|
||||
const groupedNavs = bottomNavs.reduce((groups: Record<string, CmsNavigation[]>, nav: CmsNavigation) => { |
|
||||
if (nav.parentId === 0) { |
|
||||
// 顶级菜单作为分组标题
|
|
||||
groups[nav.title || 'default'] = bottomNavs.filter((child: CmsNavigation) => child.parentId === nav.navigationId); |
|
||||
} |
|
||||
return groups; |
|
||||
}, {}); |
|
||||
|
// 按父级分组底部导航
|
||||
|
const groupedNavs = bottomNavs.reduce((groups: Record<string, CmsNavigation[]>, nav: CmsNavigation) => { |
||||
|
if (nav.parentId === 0) { |
||||
|
// 顶级菜单作为分组标题
|
||||
|
groups[nav.title || 'default'] = bottomNavs.filter((child: CmsNavigation) => child.parentId === nav.navigationId); |
||||
|
} |
||||
|
return groups; |
||||
|
}, {}); |
||||
|
|
||||
// 如果没有底部导航数据,显示默认的静态菜单
|
|
||||
const defaultFooterLinks = { |
|
||||
'产品服务': [ |
|
||||
{ title: '网站建设', path: '/products/website' }, |
|
||||
{ title: '移动应用', path: '/products/mobile' }, |
|
||||
{ title: '系统开发', path: '/products/system' }, |
|
||||
{ title: '电商平台', path: '/products/ecommerce' }, |
|
||||
], |
|
||||
'解决方案': [ |
|
||||
{ title: '企业数字化', path: '/solutions/digital' }, |
|
||||
{ title: '教育信息化', path: '/solutions/education' }, |
|
||||
{ title: '智慧城市', path: '/solutions/smart-city' }, |
|
||||
{ title: '工业互联网', path: '/solutions/industry' }, |
|
||||
], |
|
||||
'技术支持': [ |
|
||||
{ title: '技术文档', path: '/docs' }, |
|
||||
{ title: '开发指南', path: '/guide' }, |
|
||||
{ title: 'API参考', path: '/api' }, |
|
||||
{ title: '常见问题', path: '/faq' }, |
|
||||
], |
|
||||
'关于我们': [ |
|
||||
{ title: '公司介绍', path: '/about' }, |
|
||||
{ title: '新闻动态', path: '/news' }, |
|
||||
{ title: '招聘信息', path: '/careers' }, |
|
||||
{ title: '联系我们', path: '/contact' }, |
|
||||
], |
|
||||
}; |
|
||||
|
// 如果没有底部导航数据,显示默认的静态菜单
|
||||
|
const defaultFooterLinks = { |
||||
|
'产品服务': [ |
||||
|
{title: '网站建设', path: '/products/website'}, |
||||
|
{title: '移动应用', path: '/products/mobile'}, |
||||
|
{title: '系统开发', path: '/products/system'}, |
||||
|
{title: '电商平台', path: '/products/ecommerce'}, |
||||
|
], |
||||
|
'解决方案': [ |
||||
|
{title: '企业数字化', path: '/solutions/digital'}, |
||||
|
{title: '教育信息化', path: '/solutions/education'}, |
||||
|
{title: '智慧城市', path: '/solutions/smart-city'}, |
||||
|
{title: '工业互联网', path: '/solutions/industry'}, |
||||
|
], |
||||
|
'技术支持': [ |
||||
|
{title: '技术文档', path: '/docs'}, |
||||
|
{title: '开发指南', path: '/guide'}, |
||||
|
{title: 'API参考', path: '/api'}, |
||||
|
{title: '常见问题', path: '/faq'}, |
||||
|
], |
||||
|
'关于我们': [ |
||||
|
{title: '公司介绍', path: '/about'}, |
||||
|
{title: '新闻动态', path: '/news'}, |
||||
|
{title: '招聘信息', path: '/careers'}, |
||||
|
{title: '联系我们', path: '/contact'}, |
||||
|
], |
||||
|
}; |
||||
|
|
||||
// 使用接口数据或默认数据
|
|
||||
const footerLinks = Object.keys(groupedNavs).length > 0 ? groupedNavs : defaultFooterLinks; |
|
||||
console.log(footerLinks,'footerLinks') |
|
||||
|
// 使用接口数据或默认数据
|
||||
|
const footerLinks = Object.keys(groupedNavs).length > 0 ? groupedNavs : defaultFooterLinks; |
||||
|
|
||||
return ( |
|
||||
<footer className="bg-gray-900 text-white"> |
|
||||
<Container className="py-12"> |
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8"> |
|
||||
{/* 网站信息 */} |
|
||||
<div className="lg:col-span-1"> |
|
||||
<div className="flex items-center space-x-2 mb-4"> |
|
||||
{siteInfo?.websiteLogo && ( |
|
||||
<Image |
|
||||
src={siteInfo.websiteLogo} |
|
||||
alt={siteInfo.websiteName || '网站Logo'} |
|
||||
width={107} |
|
||||
height={24} |
|
||||
className="h-8 w-auto filter brightness-0 invert" |
|
||||
/> |
|
||||
)} |
|
||||
{/*<span className="text-xl font-bold">*/} |
|
||||
{/* {siteInfo?.websiteName || '网站名称'}*/} |
|
||||
{/*</span>*/} |
|
||||
</div> |
|
||||
|
return ( |
||||
|
<footer className="bg-gray-900 text-white mt-12"> |
||||
|
<Container> |
||||
|
<div className={'h-8'}></div> |
||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-8"> |
||||
|
{/* 网站信息 */} |
||||
|
<div className="lg:col-span-1"> |
||||
|
<div className="flex items-center space-x-2 mb-4"> |
||||
|
{siteInfo?.websiteLogo && ( |
||||
|
<Image |
||||
|
src={siteInfo.websiteLogo} |
||||
|
alt={siteInfo.websiteName || '网站Logo'} |
||||
|
width={107} |
||||
|
height={24} |
||||
|
className="h-8 w-auto filter brightness-0 invert" |
||||
|
/> |
||||
|
)} |
||||
|
</div> |
||||
|
|
||||
{siteInfo?.comments && ( |
|
||||
<p className="text-gray-400 text-sm mb-4 leading-relaxed"> |
|
||||
{siteInfo.comments} |
|
||||
</p> |
|
||||
)} |
|
||||
|
<div className="space-y-2 text-sm text-gray-400"> |
||||
|
{siteInfo?.phone && ( |
||||
|
<div className="flex items-center space-x-2"> |
||||
|
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"> |
||||
|
<path |
||||
|
d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"/> |
||||
|
</svg> |
||||
|
<span>{siteInfo.phone}</span> |
||||
|
</div> |
||||
|
)} |
||||
|
|
||||
<div className="space-y-2 text-sm text-gray-400"> |
|
||||
{siteInfo?.phone && ( |
|
||||
<div className="flex items-center space-x-2"> |
|
||||
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"> |
|
||||
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z" /> |
|
||||
</svg> |
|
||||
<span>{siteInfo.phone}</span> |
|
||||
</div> |
|
||||
)} |
|
||||
|
{siteInfo?.email && ( |
||||
|
<div className="flex items-center space-x-2"> |
||||
|
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"> |
||||
|
<path |
||||
|
d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"/> |
||||
|
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"/> |
||||
|
</svg> |
||||
|
<span>{siteInfo.email}</span> |
||||
|
</div> |
||||
|
)} |
||||
|
|
||||
{siteInfo?.email && ( |
|
||||
<div className="flex items-center space-x-2"> |
|
||||
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"> |
|
||||
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" /> |
|
||||
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" /> |
|
||||
</svg> |
|
||||
<span>{siteInfo.email}</span> |
|
||||
</div> |
|
||||
)} |
|
||||
|
{siteInfo?.address && ( |
||||
|
<div className="flex items-start space-x-2"> |
||||
|
<svg className="w-4 h-4 mt-0.5" fill="currentColor" viewBox="0 0 20 20"> |
||||
|
<path fillRule="evenodd" |
||||
|
d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" |
||||
|
clipRule="evenodd"/> |
||||
|
</svg> |
||||
|
<span className="leading-relaxed">{siteInfo.address}</span> |
||||
|
</div> |
||||
|
)} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
{siteInfo?.address && ( |
|
||||
<div className="flex items-start space-x-2"> |
|
||||
<svg className="w-4 h-4 mt-0.5" fill="currentColor" viewBox="0 0 20 20"> |
|
||||
<path fillRule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clipRule="evenodd" /> |
|
||||
</svg> |
|
||||
<span className="leading-relaxed">{siteInfo.address}</span> |
|
||||
|
{/* 动态底部导航菜单 */} |
||||
|
{Object.entries(footerLinks).map(([groupTitle, links]) => ( |
||||
|
<div key={groupTitle}> |
||||
|
<h3 className="text-lg font-semibold mb-4">{groupTitle}</h3> |
||||
|
<ul className="space-y-2"> |
||||
|
{links.map((link: CmsNavigation | { title: string; path: string }, index: number) => ( |
||||
|
<li key={index}> |
||||
|
<Link |
||||
|
href={link.path || '#'} |
||||
|
className="text-gray-400 hover:text-white transition-colors duration-200 text-sm" |
||||
|
target={'target' in link && link.target === '_blank' ? '_blank' : undefined} |
||||
|
rel={'target' in link && link.target === '_blank' ? 'noopener noreferrer' : undefined} |
||||
|
> |
||||
|
{link.title} |
||||
|
</Link> |
||||
|
</li> |
||||
|
))} |
||||
|
</ul> |
||||
|
</div> |
||||
|
))} |
||||
</div> |
</div> |
||||
)} |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
{/* 动态底部导航菜单 */} |
|
||||
{Object.entries(footerLinks).map(([groupTitle, links]) => ( |
|
||||
<div key={groupTitle}> |
|
||||
<h3 className="text-lg font-semibold mb-4">{groupTitle}</h3> |
|
||||
<ul className="space-y-2"> |
|
||||
{links.map((link: CmsNavigation | { title: string; path: string }, index: number) => ( |
|
||||
<li key={index}> |
|
||||
<Link |
|
||||
href={link.path || '#'} |
|
||||
className="text-gray-400 hover:text-white transition-colors duration-200 text-sm" |
|
||||
target={'target' in link && link.target === '_blank' ? '_blank' : undefined} |
|
||||
rel={'target' in link && link.target === '_blank' ? 'noopener noreferrer' : undefined} |
|
||||
> |
|
||||
{link.title} |
|
||||
</Link> |
|
||||
</li> |
|
||||
))} |
|
||||
</ul> |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
|
{/* 底部版权信息 */} |
||||
|
<div className="border-t border-gray-800 mt-8 pt-8 pb-12"> |
||||
|
<div className="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0"> |
||||
|
<div className="text-sm text-gray-400"> |
||||
|
<p className={'my-1'}> |
||||
|
© {currentYear} {siteInfo?.websiteName || '网站名称'} 保留所有权利 |
||||
|
</p> |
||||
|
{siteInfo?.icpNo && ( |
||||
|
<p> |
||||
|
<a |
||||
|
href="https://beian.miit.gov.cn/" |
||||
|
target="_blank" |
||||
|
rel="noopener noreferrer" |
||||
|
className="hover:text-white transition-colors" |
||||
|
> |
||||
|
{siteInfo.icpNo} |
||||
|
</a> |
||||
|
</p> |
||||
|
)} |
||||
|
{siteInfo?.policeNo && ( |
||||
|
<p> |
||||
|
<a |
||||
|
href="http://www.beian.gov.cn/" |
||||
|
target="_blank" |
||||
|
rel="noopener noreferrer" |
||||
|
className="hover:text-white transition-colors" |
||||
|
> |
||||
|
{siteInfo.policeNo} |
||||
|
</a> |
||||
|
</p> |
||||
|
)} |
||||
|
</div> |
||||
|
|
||||
{/* 底部版权信息 */} |
|
||||
<div className="border-t border-gray-800 mt-8 pt-8"> |
|
||||
<div className="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0"> |
|
||||
<div className="text-sm text-gray-400"> |
|
||||
<p> |
|
||||
© {currentYear} {siteInfo?.websiteName || '网站名称'}. 保留所有权利. |
|
||||
</p> |
|
||||
{siteInfo?.icpNo && ( |
|
||||
<p className="mt-1"> |
|
||||
<a |
|
||||
href="https://beian.miit.gov.cn/" |
|
||||
target="_blank" |
|
||||
rel="noopener noreferrer" |
|
||||
className="hover:text-white transition-colors" |
|
||||
> |
|
||||
{siteInfo.icpNo} |
|
||||
</a> |
|
||||
</p> |
|
||||
)} |
|
||||
{siteInfo?.policeNo && ( |
|
||||
<p className="mt-1"> |
|
||||
<a |
|
||||
href="http://www.beian.gov.cn/" |
|
||||
target="_blank" |
|
||||
rel="noopener noreferrer" |
|
||||
className="hover:text-white transition-colors" |
|
||||
> |
|
||||
{siteInfo.policeNo} |
|
||||
</a> |
|
||||
</p> |
|
||||
)} |
|
||||
</div> |
|
||||
|
|
||||
{/* 社交媒体链接 */} |
|
||||
<div className="flex space-x-4"> |
|
||||
<a href="#" className="text-gray-400 hover:text-white transition-colors"> |
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> |
|
||||
<path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
<a href="#" className="text-gray-400 hover:text-white transition-colors"> |
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> |
|
||||
<path d="M22.46 6c-.77.35-1.6.58-2.46.69.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21 16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56.84-.6 1.56-1.36 2.14-2.23z"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
<a href="#" className="text-gray-400 hover:text-white transition-colors"> |
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> |
|
||||
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> |
|
||||
</svg> |
|
||||
</a> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</Container> |
|
||||
</footer> |
|
||||
); |
|
||||
|
{/* 社交媒体链接 */} |
||||
|
<div className="flex space-x-4 py-16"> |
||||
|
<a href="#" className="text-gray-400 hover:text-white transition-colors"> |
||||
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> |
||||
|
<path |
||||
|
d="M22.46 6c-.77.35-1.6.58-2.46.69.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21 16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56.84-.6 1.56-1.36 2.14-2.23z"/> |
||||
|
</svg> |
||||
|
</a> |
||||
|
<a href="#" className="text-gray-400 hover:text-white transition-colors"> |
||||
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> |
||||
|
<path |
||||
|
d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> |
||||
|
</svg> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className={'h-8'}></div> |
||||
|
</Container> |
||||
|
</footer> |
||||
|
); |
||||
}; |
}; |
||||
|
|
||||
export default Footer; |
export default Footer; |
||||
|
Loading…
Reference in new issue