Files
urldb/web/composables/useSeo.ts

193 lines
6.5 KiB
TypeScript
Raw Normal View History

2025-11-12 00:57:41 +08:00
import { ref } from 'vue'
import { useRoute } from '#imports'
2025-11-18 15:28:08 +08:00
import { usePublicSystemConfigApi } from './useApi'
2025-07-11 02:30:57 +08:00
interface SystemConfig {
id: number
site_title: string
site_description: string
keywords: string
author: string
copyright: string
auto_process_ready_resources: boolean
auto_process_interval: number
page_size: number
maintenance_mode: boolean
created_at: string
updated_at: string
}
export const useSeo = () => {
const systemConfig = ref<SystemConfig | null>(null)
2025-11-13 00:34:26 +08:00
const { getPublicSystemConfig } = usePublicSystemConfigApi()
2025-07-11 02:30:57 +08:00
// 获取系统配置
const fetchSystemConfig = async () => {
try {
2025-11-13 00:34:26 +08:00
const response = await getPublicSystemConfig() as any
2025-07-11 02:30:57 +08:00
console.log('系统配置响应:', response)
if (response && response.success && response.data) {
systemConfig.value = response.data
} else if (response && response.data) {
// 兼容非标准格式
systemConfig.value = response.data
}
} catch (error) {
console.error('获取系统配置失败:', error)
}
}
// 生成页面标题
const generateTitle = (pageTitle: string) => {
2025-11-12 08:39:25 +08:00
if (systemConfig.value && systemConfig.value.site_title) {
2025-07-11 02:30:57 +08:00
return `${systemConfig.value.site_title} - ${pageTitle}`
}
2025-07-21 00:43:07 +08:00
return `${pageTitle} - 老九网盘资源数据库`
2025-07-11 02:30:57 +08:00
}
// 生成页面元数据
const generateMeta = (customMeta?: Record<string, string>) => {
const defaultMeta = {
2025-11-12 08:39:25 +08:00
description: (systemConfig.value && systemConfig.value.site_description) || '专业的老九网盘资源数据库',
keywords: (systemConfig.value && systemConfig.value.keywords) || '网盘,资源管理,文件分享',
author: (systemConfig.value && systemConfig.value.author) || '系统管理员',
copyright: (systemConfig.value && systemConfig.value.copyright) || '© 2024 老九网盘资源数据库'
2025-07-11 02:30:57 +08:00
}
return {
...defaultMeta,
...customMeta
}
}
2025-11-12 00:57:41 +08:00
// 生成动态OG图片URL
2025-11-18 15:28:08 +08:00
const generateOgImageUrl = (keyOrTitle: string, descriptionOrEmpty: string = '', theme: string = 'default') => {
2025-11-12 00:57:41 +08:00
// 获取运行时配置
const config = useRuntimeConfig()
const ogApiUrl = config.public.ogApiUrl || '/api/og-image'
// 构建URL参数
const params = new URLSearchParams()
2025-11-18 15:28:08 +08:00
// 检测第一个参数是key还是title通过长度和格式判断
// 如果是较短的字符串且符合key格式通常是字母数字组合则当作key处理
if (keyOrTitle.length <= 50 && /^[a-zA-Z0-9_-]+$/.test(keyOrTitle)) {
// 作为key参数使用
params.set('key', keyOrTitle)
} else {
// 作为title参数使用
params.set('title', keyOrTitle)
if (descriptionOrEmpty) {
// 限制描述长度
const trimmedDesc = descriptionOrEmpty.length > 200 ? descriptionOrEmpty.substring(0, 200) + '...' : descriptionOrEmpty
params.set('description', trimmedDesc)
}
2025-11-12 00:57:41 +08:00
}
2025-11-12 08:39:25 +08:00
params.set('site_name', (systemConfig.value && systemConfig.value.site_title) || '老九网盘资源数据库')
2025-11-12 00:57:41 +08:00
params.set('theme', theme)
params.set('width', '1200')
params.set('height', '630')
// 如果是相对路径,添加当前域名
if (ogApiUrl.startsWith('/')) {
if (process.client) {
const origin = window.location.origin
return `${origin}${ogApiUrl}?${params.toString()}`
}
// 服务端渲染时使用配置的API基础URL
const apiBase = config.public.apiBase || 'http://localhost:8080'
return `${apiBase}${ogApiUrl}?${params.toString()}`
}
return `${ogApiUrl}?${params.toString()}`
}
// 生成动态SEO元数据
2025-11-13 00:34:26 +08:00
const generateDynamicSeo = (pageTitle: string, customMeta?: Record<string, string>, routeQuery?: Record<string, any>, useRawTitle: boolean = false) => {
const title = useRawTitle ? pageTitle : generateTitle(pageTitle)
2025-07-11 02:30:57 +08:00
const meta = generateMeta(customMeta)
2025-11-12 00:57:41 +08:00
const route = routeQuery || useRoute()
2025-07-11 02:30:57 +08:00
2025-11-12 00:57:41 +08:00
// 根据路由参数生成动态描述
const searchKeyword = route.query?.search as string || ''
const platformId = route.query?.platform as string || ''
let dynamicDescription = meta.description
if (searchKeyword && platformId) {
dynamicDescription = `${platformId}中搜索"${searchKeyword}"的相关资源。${meta.description}`
} else if (searchKeyword) {
dynamicDescription = `搜索"${searchKeyword}"的相关资源。${meta.description}`
}
// 动态关键词
let dynamicKeywords = meta.keywords
if (searchKeyword) {
dynamicKeywords = `${searchKeyword},${meta.keywords}`
}
// 生成动态OG图片URL
const theme = searchKeyword ? 'blue' : platformId ? 'green' : 'default'
const ogImageUrl = generateOgImageUrl(title, dynamicDescription, theme)
return {
2025-07-11 02:30:57 +08:00
title,
2025-11-12 00:57:41 +08:00
description: dynamicDescription,
keywords: dynamicKeywords,
ogTitle: title,
ogDescription: dynamicDescription,
ogType: 'website',
ogImage: ogImageUrl,
2025-11-13 00:34:26 +08:00
ogSiteName: (systemConfig.value && systemConfig.value.site_title) || '老九网盘资源数据库',
2025-11-12 00:57:41 +08:00
twitterCard: 'summary_large_image',
robots: 'index, follow'
}
}
// 设置页面SEO - 使用Nuxt3最佳实践
const setPageSeo = (pageTitle: string, customMeta?: Record<string, string>, routeQuery?: Record<string, any>) => {
2025-11-13 00:34:26 +08:00
// 检测标题是否已包含站点名(以避免重复)
const isTitleFormatted = systemConfig.value && pageTitle.includes(systemConfig.value.site_title || '');
const seoData = generateDynamicSeo(pageTitle, customMeta, routeQuery, isTitleFormatted)
2025-11-12 00:57:41 +08:00
useSeoMeta({
title: seoData.title,
description: seoData.description,
keywords: seoData.keywords,
ogTitle: seoData.ogTitle,
ogDescription: seoData.ogDescription,
ogType: seoData.ogType,
ogImage: seoData.ogImage,
2025-11-13 00:34:26 +08:00
ogSiteName: seoData.ogSiteName,
2025-11-12 00:57:41 +08:00
twitterCard: seoData.twitterCard,
robots: seoData.robots
})
}
// 设置服务端SEO适用于不需要在客户端更新的元数据
const setServerSeo = (pageTitle: string, customMeta?: Record<string, string>) => {
if (import.meta.server) {
const title = generateTitle(pageTitle)
const meta = generateMeta(customMeta)
useServerSeoMeta({
title: title,
description: meta.description,
keywords: meta.keywords,
robots: 'index, follow'
})
}
2025-07-11 02:30:57 +08:00
}
return {
systemConfig,
fetchSystemConfig,
generateTitle,
generateMeta,
2025-11-12 00:57:41 +08:00
generateOgImageUrl,
generateDynamicSeo,
setPageSeo,
setServerSeo
2025-07-11 02:30:57 +08:00
}
}