2025-05-23 16:00:15 +08:00

453 lines
17 KiB
Vue

<template>
<div>
<!-- 页面标题 -->
<HeroBanner
:titleKey="'contact.hero.title'"
:subtitleKey="'contact.hero.subtitle'"
bgImage="/images/bg/advantage.jpg"
>
<!-- 按钮或其他内容 -->
</HeroBanner>
<!-- 联系信息与表单 -->
<section class="py-20">
<div class="container">
<div class="grid md:grid-cols-3 gap-8">
<!-- 联系信息 -->
<div class="md:col-span-1">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-8 h-full">
<h2 class="text-2xl font-bold mb-6 text-primary dark:text-[#4da6ff]">
{{ $t("contact.info.title") }}
</h2>
<div class="space-y-6">
<div class="flex items-start">
<div
class="bg-primary/10 dark:bg-primary/20 rounded-full mr-3 flex items-center justify-center w-10 h-10"
>
<i class="fas fa-map-marker-alt text-primary dark:text-[#4da6ff] text-lg"></i>
</div>
<div>
<h3 class="font-medium text-lg mb-1 dark:text-white">
{{ $t("contact.info.address.title") }}
</h3>
<p class="text-gray-600 dark:text-gray-300">
{{ $t("contact.info.address.content") }}
</p>
</div>
</div>
<div class="flex items-start">
<div
class="bg-primary/10 dark:bg-primary/20 rounded-full mr-3 flex items-center justify-center w-10 h-10"
>
<i class="fas fa-envelope text-primary dark:text-[#4da6ff] text-lg"></i>
</div>
<div>
<h3 class="font-medium text-lg mb-1 dark:text-white">
{{ $t("contact.info.email.title") }}
</h3>
<p class="text-gray-600 dark:text-gray-300">{{ contact.email }}</p>
</div>
</div>
<div class="flex items-start">
<div
class="bg-primary/10 dark:bg-primary/20 rounded-full mr-3 flex items-center justify-center w-10 h-10"
>
<i class="fas fa-phone-alt text-primary dark:text-[#4da6ff] text-lg"></i>
</div>
<div>
<h3 class="font-medium text-lg mb-1 dark:text-white">
{{ $t("contact.info.phone.title") }}
</h3>
<p class="text-gray-600 dark:text-gray-300">
{{ $t("contact.info.phone.content") }}
</p>
</div>
</div>
<div class="flex items-start">
<div
class="bg-primary/10 dark:bg-primary/20 rounded-full mr-3 flex items-center justify-center w-10 h-10"
>
<i class="fas fa-clock text-primary dark:text-[#4da6ff] text-lg"></i>
</div>
<div>
<h3 class="font-medium text-lg mb-1 dark:text-white">
{{ $t("contact.info.hours.title") }}
</h3>
<p class="text-gray-600 dark:text-gray-300">
{{ $t("contact.info.hours.content") }}
</p>
</div>
</div>
</div>
<div class="mt-8">
<h3 class="font-medium text-lg mb-4 dark:text-white">
{{ $t("contact.info.social.title") }}
</h3>
<div class="flex space-x-4">
<a
:href="contact.instagram"
target="_blank"
rel="noopener noreferrer"
class="bg-primary/10 dark:bg-primary/20 w-10 h-10 rounded-full flex items-center justify-center text-primary dark:text-[#4da6ff] hover:bg-primary hover:text-white transition-colors duration-300"
>
<i class="fab fa-instagram"></i>
</a>
<a
:href="contact.twitter"
target="_blank"
rel="noopener noreferrer"
class="bg-primary/10 dark:bg-primary/20 w-10 h-10 rounded-full flex items-center justify-center text-primary dark:text-[#4da6ff] hover:bg-primary hover:text-white transition-colors duration-300"
>
<i class="fab fa-twitter"></i>
</a>
<a
:href="contact.telegram"
target="_blank"
rel="noopener noreferrer"
class="bg-primary/10 dark:bg-primary/20 w-10 h-10 rounded-full flex items-center justify-center text-primary dark:text-[#4da6ff] hover:bg-primary hover:text-white transition-colors duration-300"
>
<i class="fab fa-telegram"></i>
</a>
<a
:href="contact.facebook"
target="_blank"
rel="noopener noreferrer"
class="bg-primary/10 dark:bg-primary/20 w-10 h-10 rounded-full flex items-center justify-center text-primary dark:text-[#4da6ff] hover:bg-primary hover:text-white transition-colors duration-300"
>
<i class="fab fa-facebook"></i>
</a>
</div>
</div>
</div>
</div>
<!-- 联系表单 -->
<div class="md:col-span-2">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-8">
<h2 class="text-2xl font-bold mb-2 text-primary dark:text-[#4da6ff]">
{{ $t("contact.form.title") }}
</h2>
<p class="text-gray-600 dark:text-gray-300 mb-6">
{{ $t("contact.form.subtitle") }}
</p>
<form @submit.prevent="submitForm" class="space-y-6">
<div class="grid md:grid-cols-2 gap-6">
<div>
<label
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>{{ $t("contact.form.fields.name") }}</label
>
<input
type="text"
v-model="formData.name"
:placeholder="$t('contact.form.placeholders.name')"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent"
required
/>
</div>
<div>
<label
class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>{{ $t("contact.form.fields.email") }}</label
>
<input
type="email"
v-model="formData.email"
:placeholder="$t('contact.form.placeholders.email')"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent"
required
/>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">{{
$t("contact.form.fields.phone")
}}</label>
<input
type="tel"
v-model="formData.phone"
:placeholder="$t('contact.form.placeholders.phone')"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">{{
$t("contact.form.fields.company")
}}</label>
<input
type="text"
v-model="formData.company"
:placeholder="$t('contact.form.placeholders.company')"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent"
/>
</div>
<!-- //miguan -->
<input type="text" name="_gotcha" style="display: none" />
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">{{
$t("contact.form.fields.subject")
}}</label>
<select
v-model="formData.subject"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent"
required
>
<option value="" disabled>
{{ $t("contact.form.placeholders.subject") }}
</option>
<option
v-for="(option, index) in subjectOptions"
:key="index"
:value="option.value"
>
{{ option.label }}
</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">{{
$t("contact.form.fields.message")
}}</label>
<textarea
v-model="formData.message"
:placeholder="$t('contact.form.placeholders.message')"
class="w-full px-4 py-3 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent resize-none"
rows="5"
required
></textarea>
</div>
<div class="flex items-start">
<input
type="checkbox"
id="privacy"
v-model="formData.privacy"
class="mt-1 mr-2"
required
/>
<label for="privacy" class="text-sm text-gray-600 dark:text-gray-300">
{{ $t("contact.form.privacy") }}
<a href="/terms" class="text-secondary dark:text-[#6db8ff]">{{
$t("contact.form.privacyLink")
}}</a>
</label>
</div>
<div>
<button
type="submit"
class="w-full px-6 py-3 bg-primary text-white rounded-lg transition-colors duration-300 font-medium flex items-center justify-center"
:disabled="formSubmitting"
>
<span v-if="!formSubmitting">{{
$t("contact.form.submit")
}}</span>
<span v-else class="flex items-center">
<i class="fas fa-spinner fa-spin mr-2"></i>
{{ $t("contact.form.sending") }}
</span>
</button>
</div>
</form>
<!-- 成功消息 -->
<div
v-if="formSubmitted"
class="mt-6 p-4 bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-400 rounded-lg"
>
<div class="flex items-start">
<i
class="fas fa-check-circle text-green-500 dark:text-green-400 mt-1 mr-3 text-xl"
></i>
<div>
<p class="font-semibold">
{{ $t("contact.form.success.title") }}
</p>
<p class="text-sm mt-1">
{{ $t("contact.form.success.message") }}
</p>
</div>
</div>
</div>
<!-- 错误消息 -->
<div
v-if="formError"
class="mt-6 p-4 bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-400 rounded-lg"
>
<div class="flex items-start">
<i
class="fas fa-exclamation-circle text-red-500 dark:text-red-400 mt-1 mr-3 text-xl"
></i>
<div>
<p class="font-semibold">
{{ $t("contact.form.error.title") }}
</p>
<p class="text-sm mt-1">
{{ $t("contact.form.error.message") }}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 地图部分 -->
<section class="py-16 bg-gray-50 dark:bg-gray-900">
<div class="container">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold text-gray-900 dark:text-white mb-4">
{{ $t("contact.map.title") }}
</h2>
<p class="text-xl text-gray-600 dark:text-gray-300 max-w-3xl mx-auto">
{{ $t("contact.map.subtitle") }}
</p>
</div>
<div class="shadow-xl rounded-lg overflow-hidden h-96">
<ClientOnly>
<Map />
</ClientOnly>
</div>
</div>
</section>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch } from "vue";
import { useI18n } from "vue-i18n";
import Map from "~/components/Map.vue";
import SendForm from "~/public/js/SendForm";
const { t, locale } = useI18n();
import { contact } from "~/public/js/contact";
import { useHead } from "nuxt/app";
useHead({
title: () => t("meta.contact.title"),
meta: [
{ name: "description", content: () => t("meta.contact.description") },
{ name: "keywords", content: () => t("meta.contact.keywords") },
],
});
interface FormData {
name: string;
email: string;
phone: string;
company: string;
subject: string;
message: string;
privacy: boolean;
}
interface FaqItem {
question: string;
answer: string;
isOpen: boolean;
}
// 表单数据
const formData = reactive<FormData>({
name: "",
email: "",
phone: "",
company: "",
subject: "",
message: "",
privacy: false,
});
// 表单状态
const formSubmitting = ref(false);
const formSubmitted = ref(false);
const formError = ref(false);
// 主题选项
const subjectOptions = computed(() => [
{ value: "general", label: t("contact.form.subjects.general") },
{ value: "sales", label: t("contact.form.subjects.sales") },
{ value: "support", label: t("contact.form.subjects.support") },
{ value: "partnership", label: t("contact.form.subjects.partnership") },
]);
// 提交表单
const submitForm = async () => {
formSubmitting.value = true;
formError.value = false;
try {
// 准备邮件数据
const emailData = {
subject: `来自网站的联系表单: ${formData.subject}`,
body: `
姓名: ${formData.name}
邮箱: ${formData.email}
电话: ${formData.phone}
公司: ${formData.company}
主题: ${formData.subject}
消息内容:
${formData.message}
`,
};
// console.log('准备发送邮件数据:', emailData);
// 发送邮件请求
const response = await fetch(SendForm, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(emailData),
});
// 解析响应
let responseData;
try {
responseData = await response.json();
} catch (e) {
console.error("解析响应失败:", e);
throw new Error("无法解析服务器响应");
}
// 检查响应状态
if (!response.ok) {
const errorMsg = responseData.error || "未知错误";
throw new Error(`邮件发送失败: ${errorMsg}`);
}
// 成功处理
formSubmitted.value = true;
// 重置表单
Object.keys(formData).forEach((key) => {
const k = key as keyof FormData;
if (k === "privacy") {
formData[k] = false;
} else {
formData[k] = "";
}
});
} catch (error) {
// 错误处理
console.error("发送邮件时出错:", error);
formError.value = true;
} finally {
formSubmitting.value = false;
}
};
</script>