feat(app): 添加多模板关于我们页面及相关路由和404页面

- 新增404页面,优化未找到页面体验,避免被搜索引擎索引
- 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理
- 实现/article、/case、/product及/page动态路由兼容列表与详情展示
- 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置
- 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持
- 模板增强支持CMS单页内容加载及SEO信息动态设置
- 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
This commit is contained in:
2026-09-08 12:13:44 +08:00
commit 2b69686795
381 changed files with 59891 additions and 0 deletions
+153
View File
@@ -0,0 +1,153 @@
<template>
<ClientOnly>
<Teleport to="body">
<Transition name="consult-fade">
<div
v-if="isOpen"
class="fixed inset-0 z-[100] flex items-center justify-center p-4"
@click.self="closeConsult"
>
<!-- 遮罩 -->
<div class="absolute inset-0 bg-black/50 backdrop-blur-sm" />
<!-- 弹窗卡片 -->
<Transition name="consult-pop" appear>
<div
v-if="isOpen"
class="relative bg-white rounded-2xl shadow-2xl w-full max-w-md p-6 sm:p-8 max-h-[90vh] overflow-y-auto"
role="dialog"
aria-modal="true"
aria-label="立即咨询"
>
<!-- 关闭按钮 -->
<button
type="button"
class="absolute top-4 right-4 w-8 h-8 flex items-center justify-center rounded-full text-gray-400 hover:text-gray-600 hover:bg-gray-100 transition-colors"
aria-label="关闭"
@click="closeConsult"
>
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<!-- 成功态 -->
<div v-if="submitted" class="text-center py-6">
<div class="w-14 h-14 mx-auto mb-4 rounded-full bg-green-100 flex items-center justify-center">
<svg class="w-7 h-7 text-green-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
</div>
<h3 class="text-lg font-bold text-gray-900 mb-2">提交成功</h3>
<p class="text-gray-600 text-sm">我们会尽快与您联系请保持电话畅通</p>
</div>
<!-- 表单态 -->
<div v-else>
<div class="mb-6 pr-8">
<h2 class="text-xl font-bold text-gray-900 mb-1">立即咨询</h2>
<p class="text-sm text-gray-500">留下您的联系方式我们将尽快与您联系</p>
</div>
<ContactForm
type="consult"
content-label="需求"
submit-text="立即提交"
:content-required="false"
:preset-content="presetNeed"
:source="source"
accent="#1a6dff"
@success="onSuccess"
/>
</div>
</div>
</Transition>
</div>
</Transition>
</Teleport>
</ClientOnly>
</template>
<script setup lang="ts">
/**
* 全站咨询弹窗
* 通过 useConsult() 控制开关,内部复用共享 ContactForm(与 /contact 功能对齐:
* 手机号段校验、蜜罐、滑块验证码(按后台配置)、频率限制、去重、提交)。
* 挂载在 layouts/default.vue,全站可用。
*/
import ContactForm from './ContactForm.vue'
const { isOpen, presetNeed, source, closeConsult } = useConsult()
const submitted = ref(false)
let successTimer: ReturnType<typeof setTimeout> | null = null
// 打开时锁定背景滚动;关闭时复位成功态
watch(isOpen, (open) => {
if (open) {
submitted.value = false
if (import.meta.client) {
document.body.style.overflow = 'hidden'
}
} else {
if (import.meta.client) {
document.body.style.overflow = ''
}
}
})
// ESC 关闭
function onKeydown(e: KeyboardEvent) {
if (e.key === 'Escape' && isOpen.value) closeConsult()
}
// 提交成功后显示成功态,2.5s 自动关闭
function onSuccess() {
submitted.value = true
successTimer = setTimeout(() => {
if (submitted.value) {
submitted.value = false
closeConsult()
}
}, 2500)
}
onMounted(() => {
window.addEventListener('keydown', onKeydown)
})
onBeforeUnmount(() => {
window.removeEventListener('keydown', onKeydown)
if (successTimer) clearTimeout(successTimer)
if (import.meta.client) {
document.body.style.overflow = ''
}
})
</script>
<style scoped>
.consult-fade-enter-active,
.consult-fade-leave-active {
transition: opacity 0.2s ease;
}
.consult-fade-enter-from,
.consult-fade-leave-to {
opacity: 0;
}
.consult-pop-enter-active {
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.25s ease;
}
.consult-pop-leave-active {
transition: transform 0.2s ease, opacity 0.2s ease;
}
.consult-pop-enter-from {
transform: scale(0.95) translateY(10px);
opacity: 0;
}
.consult-pop-leave-to {
transform: scale(0.95);
opacity: 0;
}
</style>