feat: 页脚优先展示后台配置的页脚 Logo
- CmsSiteInfo 加 websiteFooterLogo 类型 - useSite 新增 siteFooterLogo(websiteFooterLogo 优先,回退 siteLogo);siteLogo/siteFooterLogo 统一过 ensureFullUrl, 兼容本地存储相对路径(/api/file 代理)与完整 OSS URL - template-01~08/10 共 9 个模板 Footer 的 SiteBrand 改用 siteFooterLogo;template-09 页脚无品牌区保持不变 - 未配置页脚 Logo 时行为与旧版完全一致(回退站点 Logo)
This commit is contained in:
@@ -121,9 +121,24 @@ export function useSite() {
|
||||
return override || siteInfo.value?.websiteName || appName.value || ''
|
||||
})
|
||||
|
||||
/** 站点 Logo(优先应用信息,回退 CMS 站点信息) */
|
||||
/**
|
||||
* 站点 Logo(优先应用信息,回退 CMS 站点信息)
|
||||
* 统一 ensureFullUrl 补全:本地存储上传的相对路径(如 /20260925/xxx.png)
|
||||
* 转为 /api/file/ 代理地址;完整 http(s) URL 原样返回。
|
||||
*/
|
||||
const siteLogo = computed(() => {
|
||||
return appLogo.value || siteInfo.value?.websiteLogo || ''
|
||||
const raw = appLogo.value || siteInfo.value?.websiteLogo || ''
|
||||
return raw ? ensureFullUrl(raw) : ''
|
||||
})
|
||||
|
||||
/**
|
||||
* 页脚 Logo(仅用于 Footer 品牌展示,与顶部导航 Logo 分离)
|
||||
* 优先级:后台「网站设置 → 站点信息」上传的 websiteFooterLogo > 站点 Logo(siteLogo)。
|
||||
* 后台未单独上传页脚 Logo 时回退站点 Logo,保持旧行为不变。
|
||||
*/
|
||||
const siteFooterLogo = computed(() => {
|
||||
const raw = siteInfo.value?.websiteFooterLogo || ''
|
||||
return raw ? ensureFullUrl(raw) : siteLogo.value
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -255,6 +270,7 @@ export function useSite() {
|
||||
showHeaderSearch,
|
||||
siteName,
|
||||
siteLogo,
|
||||
siteFooterLogo,
|
||||
siteIcon,
|
||||
siteKeywords,
|
||||
phone,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="sm:col-span-2 lg:col-span-1">
|
||||
<SiteBrand
|
||||
link-class="mb-4"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-8 w-auto max-w-[200px] object-contain"
|
||||
@@ -118,7 +118,7 @@
|
||||
*/
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const { siteInfo, siteName, siteLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const { siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
|
||||
/** 快速链接:取顶级导航中非首页且无子菜单的项 */
|
||||
const quickLinks = computed<CmsNavigation[]>(() => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="sm:col-span-2 lg:col-span-1">
|
||||
<SiteBrand
|
||||
link-class="mb-4"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-8 w-auto max-w-[200px] object-contain"
|
||||
@@ -118,7 +118,7 @@
|
||||
*/
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const { siteInfo, siteName, siteLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const { siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
|
||||
/** 快速链接:取顶级导航中非首页且无子菜单的项 */
|
||||
const quickLinks = computed<CmsNavigation[]>(() => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="max-w-xs">
|
||||
<SiteBrand
|
||||
link-class="mb-2"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-8 w-auto max-w-[180px] object-contain"
|
||||
@@ -80,7 +80,7 @@
|
||||
*/
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const { siteInfo, siteName, siteLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, copyright, wxQrcode, icpNo, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const { siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, copyright, wxQrcode, icpNo, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
|
||||
/** 快速链接:取顶级导航中非首页且无子菜单的项 */
|
||||
const quickLinks = computed<CmsNavigation[]>(() => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="max-w-xs">
|
||||
<SiteBrand
|
||||
link-class="mb-2"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-8 w-auto max-w-[180px] object-contain"
|
||||
@@ -80,7 +80,7 @@
|
||||
*/
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const { siteInfo, siteName, siteLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, copyright, wxQrcode, icpNo, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const { siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, copyright, wxQrcode, icpNo, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
|
||||
/** 快速链接:取顶级导航中非首页且无子菜单的项 */
|
||||
const quickLinks = computed<CmsNavigation[]>(() => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="sm:col-span-2 lg:col-span-1">
|
||||
<SiteBrand
|
||||
link-class="mb-4"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
default-name="品牌官网"
|
||||
@@ -119,7 +119,7 @@
|
||||
*/
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const { siteInfo, siteName, siteLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const { siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
|
||||
/** 快速链接:取顶级导航中非首页且无子菜单的项 */
|
||||
const quickLinks = computed<CmsNavigation[]>(() => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="sm:col-span-2 lg:col-span-1">
|
||||
<SiteBrand
|
||||
link-class="mb-4"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-9 w-auto max-w-[200px] object-contain"
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { CmsNavigation } from '~/types'
|
||||
const { siteInfo, siteName, siteLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const { siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, icpNo, copyright, wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const quickLinks = computed<CmsNavigation[]>(() => {
|
||||
const navs = bottomNavigations.value || []
|
||||
return navs.filter((nav) => nav.model !== 'index').slice(0, 6)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="lg:col-span-3">
|
||||
<SiteBrand
|
||||
link-class="mb-4"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-8 w-auto max-w-[200px] object-contain"
|
||||
@@ -135,7 +135,7 @@
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const {
|
||||
siteInfo, siteName, siteLogo, siteIcon, siteConfig,
|
||||
siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig,
|
||||
bottomNavigations, phone, email, address, icpNo, copyright,
|
||||
wxQrcode, slogan, officialWebsite, officialWebsiteUrl, socialLinks
|
||||
} = useSite()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="max-w-xs">
|
||||
<SiteBrand
|
||||
link-class="mb-2"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-8 w-auto max-w-[180px] object-contain"
|
||||
@@ -80,7 +80,7 @@
|
||||
*/
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const { siteInfo, siteName, siteLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, copyright, wxQrcode, icpNo, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
const { siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon, siteConfig, bottomNavigations, phone, email, address, copyright, wxQrcode, icpNo, slogan, officialWebsite, officialWebsiteUrl, socialLinks } = useSite()
|
||||
|
||||
/** 快速链接:取顶级导航中非首页且无子菜单的项 */
|
||||
const quickLinks = computed<CmsNavigation[]>(() => {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="lg:col-span-2">
|
||||
<SiteBrand
|
||||
link-class="inline-flex items-center gap-2 mb-5"
|
||||
:logo="siteLogo"
|
||||
:logo="siteFooterLogo"
|
||||
:icon="siteIcon"
|
||||
:name="siteName"
|
||||
logo-class="h-[44px] w-auto max-w-[220px] object-contain brightness-0 invert"
|
||||
@@ -104,7 +104,7 @@
|
||||
import type { CmsNavigation } from '~/types'
|
||||
|
||||
const {
|
||||
siteInfo, siteName, siteLogo, siteIcon,
|
||||
siteInfo, siteName, siteLogo, siteFooterLogo, siteIcon,
|
||||
phone, email, address, copyright, icpNo,
|
||||
navigations, allNavigations, fetchSiteInfo
|
||||
} = useSite()
|
||||
|
||||
@@ -72,6 +72,8 @@ export interface CmsSiteInfo {
|
||||
websiteIcon?: string
|
||||
websiteLogo?: string
|
||||
websiteDarkLogo?: string
|
||||
/** 页脚 Logo(后台「网站设置 → 站点信息」上传,仅用于页脚品牌展示;空则回退 websiteLogo) */
|
||||
websiteFooterLogo?: string
|
||||
websiteType?: string
|
||||
/**
|
||||
* 模板主键(cms_website.template_id → app_template.id)
|
||||
|
||||
Reference in New Issue
Block a user