Files
hjc-web/app/composables/useFeatures.ts
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

143 lines
5.0 KiB
TypeScript
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.
import { computed } from 'vue'
import { useSite } from './useSite'
import type { FeatureItem, FeatureSectionSetting, HomeBlocks } from '~/types'
/**
* 首页「优势模块」统一数据来源
*
* 配置来自后台 cms_website_setting.features(经 getSiteInfo 合并进 siteInfo.setting),
* 为 JSON 字符串。未配置 / 解析失败时回退到各模板自己的默认数据(defaultFeatures)。
*
* 兼容策略:
* - 完全未配置(siteSetting.features 不存在)→ 显示 defaultFeatures,标题走兜底
* - 已配置且 enabled=false → enabled=false,上层 v-if 隐藏整块
* - 已配置但 items 为空 → 回退到 defaultFeatures(避免空白区)
* - items 超过 4 个 → 截断到 4 个(后台也限制最多 4 个)
*
* 2026-08-05 新增「首页区块总览」新结构:
* { hero, advantages, products, cases, news, banner, cta }
* 同时保留对旧结构(顶层 enabled/title/subtitle/items/heroFeatures)的兼容。
*
* @param defaultFeatures 模板默认卡片(各模板 FeatureSection 传入自己的硬编码项)
*/
export function useFeatures(defaultFeatures: FeatureItem[] = []) {
const { siteSetting } = useSite()
const config = computed<FeatureSectionSetting | null>(() => {
const raw = siteSetting.value?.features
if (!raw) return null
try {
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw
if (parsed && typeof parsed === 'object') return parsed as FeatureSectionSetting
return null
} catch {
return null
}
})
/** 是否已配置(用于区分「后台显式关闭」与「未接入」) */
const configured = computed(() => !!config.value)
/**
* 判断是否为新结构(区块化)
* 新结构至少包含 hero 或 advantages 字段。
*/
const isBlockMode = computed(() => {
const c = config.value
if (!c) return false
return !!(c.hero || c.advantages)
})
/** 是否显示优势模块:未配置默认显示;已配置以 enabled 为准(默认 true */
const enabled = computed(() => {
const c = config.value
if (!c) return true
// 新结构:读 advantages.enabled;旧结构:读顶层 enabled
if (isBlockMode.value) {
return c.advantages?.enabled !== false
}
return c.enabled !== false
})
const title = computed(() => {
const c = config.value
if (!c) return '我们的优势'
if (isBlockMode.value) return c.advantages?.title || '我们的优势'
return c.title || '我们的优势'
})
const subtitle = computed(() => {
const c = config.value
if (!c) return ''
if (isBlockMode.value) return c.advantages?.subtitle || ''
return c.subtitle || ''
})
const items = computed<FeatureItem[]>(() => {
const c = config.value
const cfgItems = isBlockMode.value ? c?.advantages?.items : c?.items
if (!cfgItems || !Array.isArray(cfgItems) || cfgItems.length === 0) {
return defaultFeatures
}
return cfgItems.slice(0, 4).map((it) => ({
title: it?.title || '',
desc: it?.desc || '',
icon: it?.icon || 'box'
}))
})
/** Hero 首屏右侧特性卡片文案(纯文本),空数组时上层回退模板默认值 */
const heroFeatures = computed<string[]>(() => {
const c = config.value
const hf = isBlockMode.value ? c?.hero?.features : c?.heroFeatures
if (!hf || !Array.isArray(hf) || hf.length === 0) return []
return hf.slice(0, 4).map((s) => String(s ?? '').trim()).filter(Boolean)
})
/**
* 首页各区块显示开关。
* 未配置(或旧结构)时,除预留位 products/cases/news/banner/cta 默认 false 外,
* hero 与 advantages 默认 truenews/cta 在 template-01 有实际内容,旧结构下默认 true。
*/
const homeBlocks = computed<Required<Pick<HomeBlocks, 'hero' | 'advantages' | 'products' | 'cases' | 'news' | 'banner' | 'cta'>>>(() => {
const c = config.value
const defaults = {
hero: true,
advantages: true,
products: false,
cases: false,
news: true,
banner: true,
cta: true
}
if (!c) return defaults
if (isBlockMode.value) {
return {
hero: c.hero?.enabled !== false,
advantages: c.advantages?.enabled !== false,
// 产品/案例为预留位,默认不显示,需后台显式开启
products: c.products?.enabled === true,
cases: c.cases?.enabled === true,
// 新闻/CTA 为多数模板首页实际区块,默认显示,除非后台显式关闭
news: c.news?.enabled !== false,
banner: c.banner?.enabled !== false,
cta: c.cta?.enabled !== false
}
}
// 旧结构:只有 advantages/hero 的语义;保留 news/cta 默认显示以兼容存量站点
return {
hero: c.enabled !== false,
advantages: c.enabled !== false,
products: false,
cases: false,
news: true,
banner: true,
cta: true
}
})
return { configured, enabled, title, subtitle, items, heroFeatures, homeBlocks, isBlockMode }
}