2b69686795
- 新增404页面,优化未找到页面体验,避免被搜索引擎索引 - 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理 - 实现/article、/case、/product及/page动态路由兼容列表与详情展示 - 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置 - 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持 - 模板增强支持CMS单页内容加载及SEO信息动态设置 - 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import type { AppProduct, TenantContext } from '~/types'
|
|
|
|
/**
|
|
* 获取当前应用产品信息(AppProduct)
|
|
*
|
|
* SSR:优先从 event.context.tenant.appProduct 读取(中间件已查询)
|
|
* 客户端:从 SSR 注入的 useState 读取;若为空则调用 /api/app/info 补查
|
|
*/
|
|
export function useApp() {
|
|
const appInfo = useState<AppProduct | null>('app-info', () => null)
|
|
const loading = useState<boolean>('app-loading', () => false)
|
|
const error = useState<string | null>('app-error', () => null)
|
|
|
|
// SSR 时直接从中间件识别结果注入,避免额外请求
|
|
if (import.meta.server && !appInfo.value) {
|
|
const event = useRequestEvent()
|
|
const ctx = event?.context?.tenant as TenantContext | undefined
|
|
if (ctx?.appProduct) {
|
|
appInfo.value = ctx.appProduct
|
|
}
|
|
}
|
|
|
|
/** 主动获取应用信息(客户端兜底 / 手动刷新) */
|
|
async function fetchAppInfo() {
|
|
if (appInfo.value) return appInfo.value
|
|
loading.value = true
|
|
error.value = null
|
|
try {
|
|
const res = await $fetch<AppProduct | null>('/api/app/info')
|
|
appInfo.value = res
|
|
return res
|
|
} catch (e: any) {
|
|
error.value = e?.message || '获取应用信息失败'
|
|
return null
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
/** 应用名称 */
|
|
const appName = computed(() => appInfo.value?.productName || '')
|
|
/** 应用编码 */
|
|
const appCode = computed(() => appInfo.value?.productCode || '')
|
|
/** 绑定域名 */
|
|
const appDomain = computed(() => appInfo.value?.domain || '')
|
|
/** 应用 Logo */
|
|
const appLogo = computed(() => appInfo.value?.logo || '')
|
|
/** 应用图标(站点小图标,用于 Header/Footer Logo 回退) */
|
|
const appIcon = computed(() => appInfo.value?.icon || '')
|
|
/**
|
|
* 关联模板目录名(template-XX):【code 优先,主键兜底】
|
|
* templateCode 与前端模板目录一一对应;templateId 主键存在跳号错位风险,仅兜底。
|
|
* 为空时返回 '' 由上层回退默认模板。
|
|
*/
|
|
const appTemplateId = computed(() =>
|
|
resolveTemplateKey(appInfo.value?.templateCode, appInfo.value?.templateId)
|
|
)
|
|
/** 是否已过期 */
|
|
const appExpired = computed(() => {
|
|
const t = appInfo.value?.expirationTime
|
|
if (!t) return false
|
|
return new Date(t).getTime() < Date.now()
|
|
})
|
|
|
|
return {
|
|
appInfo,
|
|
loading,
|
|
error,
|
|
fetchAppInfo,
|
|
appName,
|
|
appCode,
|
|
appDomain,
|
|
appLogo,
|
|
appIcon,
|
|
appTemplateId,
|
|
appExpired
|
|
}
|
|
}
|