first commit
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="onepage-container">
|
||||
<Header />
|
||||
<div class="headtop"></div>
|
||||
<div v-if="loading" class="loading">
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
<span>加载中...</span>
|
||||
</div>
|
||||
<div v-else-if="error" class="error">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<p>{{ error }}</p>
|
||||
<button @click="loadOnePage" class="retry-btn">重试</button>
|
||||
</div>
|
||||
<div v-else-if="onePage" class="content">
|
||||
<div class="page-wrapper" v-html="onePage.content"></div>
|
||||
</div>
|
||||
<div v-else class="not-found">
|
||||
<i class="fas fa-file-alt"></i>
|
||||
<p>单页内容不存在</p>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import Header from '../components/header.vue'
|
||||
import Footer from '../components/footer.vue'
|
||||
import { getOnePageByPath } from '@/api/index'
|
||||
|
||||
interface OnePage {
|
||||
id: number
|
||||
title: string
|
||||
content: string
|
||||
path: string
|
||||
sort: number
|
||||
status: 0 | 1
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
const error = ref('')
|
||||
const onePage = ref<OnePage | null>(null)
|
||||
|
||||
// 根据路由路径获取单页内容
|
||||
const loadOnePage = async () => {
|
||||
const path = route.path
|
||||
if (!path || path === '/') {
|
||||
router.push('/404')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查当前路由是否已匹配到其他组件(type 2 的页面)
|
||||
// 如果已匹配到具体组件,说明不是单页,不应该由单页组件处理
|
||||
const matchedRoute = route.matched[route.matched.length - 1]
|
||||
if (matchedRoute && matchedRoute.name && matchedRoute.name !== 'OnePage') {
|
||||
// 如果匹配到的不是 OnePage,说明是其他路由(如 type 2 的页面),不应该处理
|
||||
// 但通配符路由会匹配所有路径,所以需要检查 meta
|
||||
if (matchedRoute.meta && matchedRoute.meta.menuType === 2) {
|
||||
router.push('/404')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
error.value = ''
|
||||
|
||||
try {
|
||||
const result = await getOnePageByPath(path)
|
||||
if (result.code === 200 && result.data) {
|
||||
onePage.value = result.data
|
||||
} else {
|
||||
// 如果单页不存在,重定向到404
|
||||
router.push('/404')
|
||||
}
|
||||
} catch (err: any) {
|
||||
// 如果请求失败,重定向到404
|
||||
router.push('/404')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOnePage()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.onepage-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// 头部占位符,高度与固定头部一致(80px)
|
||||
.headtop {
|
||||
height: 80px;
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
.loading,
|
||||
.error,
|
||||
.not-found {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 60vh;
|
||||
gap: 16px;
|
||||
color: #666;
|
||||
padding: 40px 20px;
|
||||
flex: 1;
|
||||
|
||||
i {
|
||||
font-size: 48px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
i {
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
padding: 10px 20px;
|
||||
background-color: #3973ff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: #66b1ff;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
min-height: 0; // 允许 flex 子元素缩小
|
||||
|
||||
.page-wrapper {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
position: relative; // 确保定位上下文正确
|
||||
|
||||
// 确保单页内容样式正确显示
|
||||
:deep(*) {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 确保单页内容中的下拉菜单不受前端导航栏样式影响
|
||||
// 只针对单页内容中的下拉菜单,不影响前端导航栏
|
||||
:deep(.dropdown-menu:not(.site-header-dropdown-menu)) {
|
||||
position: relative !important;
|
||||
top: auto !important;
|
||||
left: auto !important;
|
||||
right: auto !important;
|
||||
width: auto !important;
|
||||
z-index: auto !important;
|
||||
}
|
||||
|
||||
// 确保单页内容中的元素不会影响前端导航栏的下拉菜单
|
||||
:deep(*) {
|
||||
z-index: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user