PinnovateCloud/pages/solutions.vue

393 lines
16 KiB
Vue
Raw Normal View History

2025-09-11 10:55:59 +08:00
<template>
<div>
<!-- AWS产品与服务 Banner -->
<section class="bg-white dark:bg-gray-900 py-16">
<div class="container mx-auto flex flex-col md:flex-row items-center justify-center gap-8">
<div class="md:w-1/2">
<h1 class="text-4xl font-bold text-[#333333] dark:text-white mb-4">{{ $t('solutions.banner.title') }}</h1>
<p class="text-lg text-gray-700 dark:text-gray-300 mb-2">{{ $t('solutions.banner.subtitle') }}</p>
<p class="text-gray-500 dark:text-gray-400 leading-relaxed">{{ $t('solutions.banner.desc') }}</p>
</div>
<div class="md:w-1/2 flex justify-center">
<img src="/images/solution/solution.png" alt="AWS云解决方案" class="w-full max-w-md object-contain rounded-lg dark:opacity-90" />
</div>
</div>
</section>
<!-- AWS开通流程 -->
<Process />
<!-- 企业上云解决方案 -->
<section class="py-16 bg-gray-50 dark:bg-gray-800">
<div class="container mx-auto">
<!-- Tab选择区 -->
<div class="flex flex-wrap justify-center mb-12 border-b dark:border-gray-700">
<button
v-for="(tab, index) in solutionTabs"
:key="index"
:class="[
'px-6 py-3 text-lg font-medium border-b-2 mx-2 transition-colors',
activeSolutionTab === tab.id
? 'border-primary text-primary dark:text-blue-400'
: 'border-transparent text-gray-600 dark:text-gray-400 hover:text-primary hover:border-primary/30 dark:hover:text-blue-400 dark:hover:border-blue-500/30'
]"
@click="activeSolutionTab = tab.id"
>
{{ $t(tab.label) }}
</button>
</div>
<!-- 内容区 -->
<div v-if="activeSolutionTab === 'all'" class="space-y-16">
<div v-for="(content, index) in solutionContents" :key="index" class="py-10 border-b border-gray-200 dark:border-gray-700 last:border-0">
<div
:class="[
'flex flex-col lg:flex-row gap-10 rounded-xl overflow-hidden',
index % 2 === 0 ? '' : 'lg:flex-row-reverse',
index % 2 === 0 ? 'bg-white dark:bg-gray-700 shadow-md' : 'bg-sky-50 dark:bg-gray-600 shadow-md'
]"
>
<!-- 左侧图片 -->
<div class="lg:w-2/5">
<img :src="content.img" :alt="$t(content.title)" class="w-full h-full object-cover dark:opacity-90" />
</div>
<!-- 右侧内容 -->
<div class="lg:w-3/5 p-8">
<h3 class="text-2xl font-bold mb-4 text-[#333333] dark:text-white">{{ $t(content.title) }}</h3>
<p class="text-gray-600 dark:text-gray-300 mb-6">{{ $t(content.description) }}</p>
<!-- 优势列表 -->
<div class="mb-8">
<h4 class="text-xl font-semibold mb-4 dark:text-gray-200">{{ $t('solutions.cloudSolution.advantages.title') }}</h4>
<div class="space-y-4">
<div v-for="(item, i) in content.advantages" :key="i" class="flex items-start">
<div class="w-6 h-6 rounded-full bg-primary/10 dark:bg-blue-400/20 flex items-center justify-center flex-shrink-0 mt-1 mr-3">
<svg class="w-4 h-4 text-primary dark:text-blue-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
</div>
<p class="text-gray-900 dark:text-gray-200">{{ $t(item) }}</p>
</div>
</div>
</div>
<!-- 咨询按钮 -->
<NuxtLink to="/contact">
<button class="px-6 py-3 bg-primary dark:bg-blue-600 text-white rounded-md inline-flex items-center hover:bg-primary/90 dark:hover:bg-blue-700 transition-colors shadow-sm">
{{ $t(content.btnText) }}
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
</svg>
</button>
</NuxtLink>
</div>
</div>
</div>
</div>
<!-- 单个标签页内容区域 -->
<div
v-if="activeSolutionTab !== 'all'"
class="flex flex-col lg:flex-row gap-10 bg-white dark:bg-gray-700 rounded-xl shadow-md overflow-hidden"
>
<!-- 左侧图片 -->
<div class="lg:w-2/5">
<img
:src="solutionContents.find(item => item.id === activeSolutionTab)?.img || ''"
:alt="$t(solutionContents.find(item => item.id === activeSolutionTab)?.title || '')"
class="w-full h-full object-cover dark:opacity-90"
/>
</div>
<!-- 右侧内容 -->
<div class="lg:w-3/5 p-8">
<h3 class="text-2xl font-bold mb-4 text-[#333333] dark:text-white">
{{ $t(solutionContents.find(item => item.id === activeSolutionTab)?.title || '') }}
</h3>
<p class="text-gray-600 dark:text-gray-300 mb-6">
{{ $t(solutionContents.find(item => item.id === activeSolutionTab)?.description || '') }}
</p>
<!-- 优势列表 -->
<div class="mb-8">
<h4 class="text-xl font-semibold mb-4 dark:text-gray-200">{{ $t('solutions.cloudSolution.advantages.title') }}</h4>
<div class="space-y-4">
<div
v-for="(item, i) in solutionContents.find(content => content.id === activeSolutionTab)?.advantages || []"
:key="i"
class="flex items-start"
>
<div class="w-6 h-6 rounded-full bg-primary/10 dark:bg-blue-400/20 flex items-center justify-center flex-shrink-0 mt-1 mr-3">
<svg class="w-4 h-4 text-primary dark:text-blue-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
</div>
<p class="text-gray-900 dark:text-gray-200">{{ $t(item) }}</p>
</div>
</div>
</div>
<!-- 咨询按钮 -->
<NuxtLink to="/contact">
<button class="px-6 py-3 bg-primary dark:bg-blue-600 text-white rounded-md inline-flex items-center hover:bg-primary/90 dark:hover:bg-blue-700 transition-colors shadow-sm">
{{ $t(solutionContents.find(item => item.id === activeSolutionTab)?.btnText || '') }}
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
</svg>
</button>
</NuxtLink>
</div>
</div>
</div>
</section>
<!-- 客户案例展示 -->
<section class="py-20 bg-white dark:bg-gray-900">
<div class="container">
<div class="max-w-4xl mx-auto text-center mb-16">
<h2 class="text-4xl font-bold text-[#333333] dark:text-white mb-4">{{ $t('solutions.cases.title') }}</h2>
<p class="text-xl text-gray-600 dark:text-gray-300 leading-relaxed">{{ $t('solutions.cases.subtitle') }}</p>
</div>
<div class="grid md:grid-cols-3 gap-8">
<div v-for="(case_item, index) in caseStudies" :key="index" class="bg-gray-50 dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1">
<img class="h-48 w-full object-cover dark:opacity-90" :src="case_item.src"></img>
<div class="p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold dark:text-white">{{ $t(case_item.titleKey) }}</h3>
<span class="px-3 py-1 bg-primary/10 dark:bg-blue-400/20 text-primary dark:text-blue-400 text-sm rounded-full">{{ $t(case_item.industryKey) }}</span>
</div>
<p class="text-gray-600 dark:text-gray-300 mb-6">{{ $t(case_item.descriptionKey) }}</p>
<NuxtLink to="/cases" class="inline-flex items-center text-primary dark:text-blue-400 hover:text-primary/90 dark:hover:text-blue-300 border border-primary dark:border-blue-500 px-4 py-2 rounded transition-colors">
{{ $t('solutions.cases.viewDetails') }}
<i class="fas fa-arrow-right ml-2"></i>
</NuxtLink>
</div>
</div>
</div>
</div>
</section>
<!-- 常见问题 -->
<section class="py-16 bg-gray-50 dark:bg-gray-800">
<div class="container">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold mb-4 dark:text-white">{{ $t('contact.faq.title') }}</h2>
<p class="text-xl text-gray-600 dark:text-gray-300 max-w-3xl mx-auto">{{ $t('contact.faq.subtitle') }}</p>
</div>
<div class="max-w-4xl mx-auto">
<div v-for="(faq, index) in faqs" :key="index" class="mb-6">
<button
@click="toggleFaq(index)"
class="w-full flex justify-between items-center p-6 bg-white dark:bg-gray-700 rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300"
>
<span class="text-lg font-medium text-left dark:text-white">{{ faq.question }}</span>
<i :class="['fas', faq.isOpen ? 'fa-minus' : 'fa-plus', 'text-primary dark:text-[#4da6ff]']"></i>
</button>
<div
v-show="faq.isOpen"
class="p-6 bg-white dark:bg-gray-700 border-t border-gray-100 dark:border-gray-600 rounded-b-lg shadow-md mt-1"
>
<p class="text-gray-600 dark:text-gray-300">{{ faq.answer }}</p>
</div>
</div>
</div>
</div>
</section>
<!-- 定制化解决方案 -->
<section class="bg-primary dark:bg-blue-800 text-white flex items-center justify-center" style="height: 390px;">
<div class="container text-center">
<h2 class="text-4xl font-bold mb-4">{{ $t('solutions.customSolution.title') || '需要定制化解决方案?' }}</h2>
<p class="text-xl mb-8 max-w-2xl mx-auto leading-relaxed">{{ $t('solutions.customSolution.description') || '我们的解决方案架构师将根据您的业务需求为您量身定制AWS云服务方案' }}</p>
<NuxtLink
to="/contact"
class="inline-flex items-center bg-white dark:bg-gray-800 text-primary dark:text-blue-400 px-8 py-4 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-300 text-lg font-semibold shadow-lg"
>
{{ $t('solutions.customSolution.button') || '免费咨询' }}
<i class="fas fa-arrow-right ml-2"></i>
</NuxtLink>
</div>
</section>
</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n';import { ref, watch } from 'vue';import { useHead } from 'nuxt/app';import Process from "~/components/Process.vue";const { t, locale } = useI18n();// 添加页面元数据useHead({ title: () => t('meta.solutions.title'), meta: [ { name: 'description', content: () => t('meta.solutions.description') }, { name: 'keywords', content: () => t('meta.solutions.keywords') } ]});
// 添加页面元数据
useHead({
title: () => t('meta.solutions.title'),
meta: [
{ name: 'description', content: () => t('meta.solutions.description') },
{ name: 'keywords', content: () => t('meta.solutions.keywords') }
]
});
// 新增解决方案Tab和内容
const activeSolutionTab = ref('all');
const solutionTabs = [
{ id: 'all', label: 'solutions.cloudSolution.tabs.all' },
{ id: 'enterprise', label: 'solutions.cloudSolution.tabs.enterprise' },
{ id: 'disaster', label: 'solutions.cloudSolution.tabs.disaster' },
{ id: 'bigdata', label: 'solutions.cloudSolution.tabs.bigdata' },
{ id: 'service', label: 'solutions.cloudSolution.tabs.service' }
];
const solutionContents = [
{
id: 'enterprise',
img: '/images/solution/case1.png',
title: 'solutions.cloudSolution.title',
description: 'solutions.cloudSolution.description',
advantages: [
'solutions.cloudSolution.advantages.items.0',
'solutions.cloudSolution.advantages.items.1',
'solutions.cloudSolution.advantages.items.2'
],
btnText: 'solutions.cloudSolution.consultBtn'
},
{
id: 'disaster',
img: '/images/solution/case2.png',
title: 'solutions.cloudSolution.disaster.title',
description: 'solutions.cloudSolution.disaster.description',
advantages: [
'solutions.cloudSolution.disaster.advantages.0',
'solutions.cloudSolution.disaster.advantages.1',
'solutions.cloudSolution.disaster.advantages.2'
],
btnText: 'solutions.cloudSolution.consultBtn'
},
{
id: 'bigdata',
img: '/images/solution/case3.png',
title: 'solutions.cloudSolution.bigdata.title',
description: 'solutions.cloudSolution.bigdata.description',
advantages: [
'solutions.cloudSolution.bigdata.advantages.0',
'solutions.cloudSolution.bigdata.advantages.1',
'solutions.cloudSolution.bigdata.advantages.2'
],
btnText: 'solutions.cloudSolution.consultBtn'
},
{
id: 'service',
img: '/images/solution/case4.png',
title: 'solutions.cloudSolution.service.title',
description: 'solutions.cloudSolution.service.description',
advantages: [
'solutions.cloudSolution.service.advantages.0',
'solutions.cloudSolution.service.advantages.1',
'solutions.cloudSolution.service.advantages.2'
],
btnText: 'solutions.cloudSolution.consultBtn'
}
];
// 客户案例
const caseStudies = [
{
titleKey: 'solutions.cases.items.0.title',
industryKey: 'solutions.cases.items.0.industry',
descriptionKey: 'solutions.cases.items.0.description',
src:"/images/solution/finance.png"
},
{
titleKey: 'solutions.cases.items.1.title',
industryKey: 'solutions.cases.items.1.industry',
descriptionKey: 'solutions.cases.items.1.description',
src:"/images/solution/e-commerce.png"
},
{
titleKey: 'solutions.cases.items.2.title',
industryKey: 'solutions.cases.items.2.industry',
descriptionKey: 'solutions.cases.items.2.description',
src:"/images/solution/medical_care.png"
}
];
// 常见问题
interface FaqItem {
question: string;
answer: string;
isOpen: boolean;
}
// FAQ数据
const faqs = ref<FaqItem[]>([
{
question: t('contact.faq.questions.q1'),
answer: t('contact.faq.answers.a1'),
isOpen: false
},
{
question: t('contact.faq.questions.q2'),
answer: t('contact.faq.answers.a2'),
isOpen: false
},
{
question: t('contact.faq.questions.q3'),
answer: t('contact.faq.answers.a3'),
isOpen: false
},
{
question: t('contact.faq.questions.q4'),
answer: t('contact.faq.answers.a4'),
isOpen: false
},
{
question: t('contact.faq.questions.q5'),
answer: t('contact.faq.answers.a5'),
isOpen: false
}
]);
// 更新FAQ数据的函数
const updateFaqs = () => {
faqs.value = [
{
question: t('contact.faq.questions.q1'),
answer: t('contact.faq.answers.a1'),
isOpen: false
},
{
question: t('contact.faq.questions.q2'),
answer: t('contact.faq.answers.a2'),
isOpen: false
},
{
question: t('contact.faq.questions.q3'),
answer: t('contact.faq.answers.a3'),
isOpen: false
},
{
question: t('contact.faq.questions.q4'),
answer: t('contact.faq.answers.a4'),
isOpen: false
},
{
question: t('contact.faq.questions.q5'),
answer: t('contact.faq.answers.a5'),
isOpen: false
}
];
};
// 初始化FAQ数据
updateFaqs();
// 监听语言变化更新FAQ数据
watch(locale, () => {
updateFaqs();
});
// 切换FAQ开关状态
const toggleFaq = (index: number) => {
faqs.value[index].isOpen = !faqs.value[index].isOpen;
};
</script>