Files
hjc-web/app/templates/template-10/components/Footer.vue
T
gxwebsoft 2b69686795 feat(app): 添加多模板关于我们页面及相关路由和404页面
- 新增404页面,优化未找到页面体验,避免被搜索引擎索引
- 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理
- 实现/article、/case、/product及/page动态路由兼容列表与详情展示
- 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置
- 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持
- 模板增强支持CMS单页内容加载及SEO信息动态设置
- 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
2026-09-08 12:13:44 +08:00

160 lines
7.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<footer class="bg-[var(--t10-footer-bg)] text-[var(--t10-footer-text)]">
<div class="t10-container py-12 lg:py-16">
<!-- 上排Logo 联系信息 + 链接列 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-10 lg:gap-8">
<!-- 公司信息 -->
<div class="lg:col-span-2">
<SiteBrand
link-class="inline-flex items-center gap-2 mb-5"
:logo="siteLogo"
:icon="siteIcon"
:name="siteName"
logo-class="h-[44px] w-auto max-w-[220px] object-contain brightness-0 invert"
icon-class="h-8 w-auto object-contain brightness-0 invert"
name-class="text-xl font-bold text-white truncate max-w-[220px]"
>
<template #fallback-icon>
<span class="text-xl font-bold text-white">C-MVP</span>
</template>
</SiteBrand>
<ul class="space-y-3 text-sm">
<li v-if="phone" class="flex items-start gap-3">
<svg class="w-4 h-4 mt-0.5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
</svg>
<a :href="`tel:${phone}`" class="hover:text-white transition-colors">{{ phone }}</a>
</li>
<li v-if="email" class="flex items-start gap-3">
<svg class="w-4 h-4 mt-0.5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
<a :href="`mailto:${email}`" class="hover:text-white transition-colors break-all">{{ email }}</a>
</li>
<li v-if="siteUrl" class="flex items-start gap-3">
<svg class="w-4 h-4 mt-0.5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
</svg>
<a :href="siteUrl" target="_blank" rel="noopener" class="hover:text-white transition-colors break-all">{{ siteUrl }}</a>
</li>
<li v-if="address" class="flex items-start gap-3">
<svg class="w-4 h-4 mt-0.5 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span>{{ address }}</span>
</li>
</ul>
</div>
<!-- 链接列 -->
<div v-for="col in linkColumns" :key="col.title">
<h3 class="text-white font-semibold mb-5">{{ col.title }}</h3>
<ul class="space-y-2.5 text-sm">
<li v-for="link in col.links" :key="link.navigationId || link.path">
<NuxtLink
:to="getNavLink(link)"
:target="link.target === '_blank' ? '_blank' : undefined"
class="hover:text-white transition-colors"
>
{{ link.title }}
</NuxtLink>
</li>
</ul>
</div>
</div>
<!-- 分隔线 -->
<div class="mt-12 pt-8 border-t border-white/15">
<div class="flex flex-col md:flex-row items-center justify-between gap-4 text-xs text-center md:text-left">
<span>{{ copyright || `Copyright © ${new Date().getFullYear()} ${siteName || ''} 版权所有` }}</span>
<div class="flex flex-wrap items-center justify-center gap-x-4 gap-y-2">
<a
v-if="icpNo"
href="https://beian.miit.gov.cn"
target="_blank"
rel="nofollow"
class="hover:text-white transition-colors"
>{{ icpNo }}</a>
<a
v-if="siteInfo?.policeNo"
:href="policeUrl"
target="_blank"
rel="nofollow"
class="hover:text-white transition-colors"
>{{ siteInfo.policeNo }}</a>
<a
rel="nofollow"
href="https://site.websoft.top"
target="_blank"
class="hover:text-white transition-colors"
>Powered by ·企业官网</a>
</div>
</div>
</div>
</div>
</footer>
</template>
<script setup lang="ts">
/**
* 模板 10 - Footer 组件(创芯存储科技蓝风格)
* 科技蓝底 + 公司信息 + 四列链接 + 备案版权
*/
import type { CmsNavigation } from '~/types'
const {
siteInfo, siteName, siteLogo, siteIcon,
phone, email, address, copyright, icpNo,
navigations, allNavigations, fetchSiteInfo
} = useSite()
await fetchSiteInfo()
const siteUrl = computed(() => {
const url = siteInfo.value?.domain || ''
if (!url) return ''
return url.startsWith('http') ? url : `https://${url}`
})
const policeUrl = computed(() => {
const no = String(siteInfo.value?.policeNo || '')
const code = no.replace(/\D/g, '')
return code
? `https://beian.mps.gov.cn/#/query/webSearch?code=${code}`
: 'https://beian.mps.gov.cn/'
})
/** 按模型或标题智能分组链接 */
const linkColumns = computed(() => {
const navs = navigations.value || []
const all = allNavigations.value || []
const cols: { title: string, links: CmsNavigation[] }[] = []
const findByModel = (model: string) => all.filter((n) => n.model === model && (n.parentId || 0) === 0).slice(0, 6)
const findByKeyword = (...keywords: string[]) => {
return navs.filter((n) => keywords.some((k) => n.title.includes(k))).slice(0, 6)
}
const products = findByModel('product')
if (products.length) cols.push({ title: products[0]?.title || '产品中心', links: products[0]?.children?.slice(0, 6) || [products[0]].filter(Boolean) })
const cases = findByModel('case')
if (cases.length) cols.push({ title: cases[0]?.title || '行业解决方案', links: cases[0]?.children?.slice(0, 6) || [cases[0]].filter(Boolean) })
const aboutLinks = findByKeyword('关于', '资讯', '联系', '加入')
if (aboutLinks.length) cols.push({ title: '关于我们', links: aboutLinks })
const partnerLinks = findByKeyword('合作', '伙伴', '服务')
if (partnerLinks.length) cols.push({ title: '合作伙伴', links: partnerLinks })
// 兜底:用底部导航补足列数
if (cols.length < 3) {
const bottom = (navs || []).filter((n) => n.model !== 'index').slice(0, 6)
if (bottom.length) cols.push({ title: '快速链接', links: bottom })
}
return cols
})
</script>