feat(page): 添加文章详情和栏目列表页面

- 创建了 article/[id].vue 页面用于显示栏目下文章列表
- 实现了 item/[id].vue 页面用于展示文章详情内容
- 开发了 page/[id].vue 页面用于单页内容展示
- 集成了 RichText 组件用于安全渲染富文本内容
- 实现了面包屑导航和分页功能
- 添加了搜索和刷新功能
- 完善了 SEO 元数据设置
This commit is contained in:
2026-01-21 15:31:59 +08:00
parent 60c39cfec4
commit 90f3e999e2
6 changed files with 739 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
import { $fetch } from 'ofetch'
import { createError, defineEventHandler, getHeader, getQuery } from 'h3'
import { useRuntimeConfig } from '#imports'
// Frontend-friendly endpoint:
// GET /api/cms-navigation?parentId=xxxx
// Proxies to CMS modules API. Some deployments expose "/cms-navigation", others "/cms/cms-navigation".
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
const query = getQuery(event)
const modulesApiBase =
config.public.modulesApiBase || config.public.ApiBase || 'https://cms-api.websoft.top/api'
const tenantId =
getHeader(event, 'tenantid') ||
config.public.tenantId ||
config.public.TenantId ||
'10586'
const authorization = getHeader(event, 'authorization')
const headers = {
TenantId: String(tenantId),
...(authorization ? { Authorization: String(authorization) } : {})
}
const upstreamCandidates = ['/cms-navigation', '/cms/cms-navigation']
let lastError: any
for (const path of upstreamCandidates) {
try {
return await $fetch(path, { baseURL: modulesApiBase, headers, query })
} catch (error: any) {
lastError = error
}
}
throw createError({
statusCode: lastError?.statusCode || lastError?.response?.status || 502,
statusMessage: lastError?.statusMessage || 'Failed to fetch cms navigation'
})
})