123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- <template>
- <div class="py-8">
- <div class="container-custom">
- <h1 class="text-3xl font-bold mb-8">{{ $t('contact.title') }}</h1>
-
- <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
- <!-- 联系表单 -->
- <div class="bg-white border border-gray-200 rounded-lg overflow-hidden">
- <div class="p-8">
- <h2 class="text-2xl font-semibold mb-6">给我们留言</h2>
-
- <ErrorBoundary :error="error">
- <form @submit.prevent="submitForm">
- <div class="mb-4">
- <label for="name" class="block text-gray-700 font-medium mb-2">{{ $t('contact.name') }}</label>
- <input
- type="text"
- id="name"
- v-model="formData.name"
- class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
- :class="{ 'border-red-500': formErrors.name }"
- required
- >
- <p v-if="formErrors.name" class="mt-1 text-sm text-red-600">{{ formErrors.name }}</p>
- </div>
-
- <div class="mb-4">
- <label for="email" class="block text-gray-700 font-medium mb-2">{{ $t('contact.email') }}</label>
- <input
- type="email"
- id="email"
- v-model="formData.email"
- class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
- :class="{ 'border-red-500': formErrors.email }"
- required
- >
- <p v-if="formErrors.email" class="mt-1 text-sm text-red-600">{{ formErrors.email }}</p>
- </div>
-
- <div class="mb-6">
- <label for="message" class="block text-gray-700 font-medium mb-2">{{ $t('contact.message') }}</label>
- <textarea
- id="message"
- v-model="formData.message"
- class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 h-32"
- :class="{ 'border-red-500': formErrors.message }"
- required
- ></textarea>
- <p v-if="formErrors.message" class="mt-1 text-sm text-red-600">{{ formErrors.message }}</p>
- </div>
-
- <div>
- <button
- type="submit"
- class="btn btn-primary w-full"
- :disabled="isLoading"
- >
- <span v-if="isLoading" class="flex items-center justify-center">
- <span class="animate-spin h-4 w-4 border-2 border-white rounded-full border-t-transparent mr-2"></span>
- 提交中...
- </span>
- <span v-else>{{ $t('contact.submit') }}</span>
- </button>
- </div>
-
- <div v-if="submitSuccess" class="mt-4 p-3 bg-green-50 text-green-800 rounded-md">
- 消息已成功发送,我们会尽快与您联系。
- </div>
- </form>
- </ErrorBoundary>
- </div>
- </div>
-
- <!-- 联系信息 -->
- <div class="bg-white border border-gray-200 rounded-lg overflow-hidden">
- <div class="p-8">
- <h2 class="text-2xl font-semibold mb-6">联系方式</h2>
-
- <div class="space-y-6">
- <div class="flex items-start">
- <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-blue-100 text-blue-600 rounded-full">
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
- <path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd" />
- </svg>
- </div>
- <div class="ml-4">
- <h3 class="text-lg font-medium text-gray-900">地址</h3>
- <p class="mt-1 text-gray-600">
- 中国上海市浦东新区张江高科技园区<br>
- 科技大道123号
- </p>
- </div>
- </div>
-
- <div class="flex items-start">
- <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-blue-100 text-blue-600 rounded-full">
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
- <path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z" />
- </svg>
- </div>
- <div class="ml-4">
- <h3 class="text-lg font-medium text-gray-900">电话</h3>
- <p class="mt-1 text-gray-600">+86 123 456 7890</p>
- </div>
- </div>
-
- <div class="flex items-start">
- <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-blue-100 text-blue-600 rounded-full">
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
- <path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" />
- <path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" />
- </svg>
- </div>
- <div class="ml-4">
- <h3 class="text-lg font-medium text-gray-900">邮箱</h3>
- <p class="mt-1 text-gray-600">contact@example.com</p>
- </div>
- </div>
-
- <div class="flex items-start">
- <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-blue-100 text-blue-600 rounded-full">
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd" />
- </svg>
- </div>
- <div class="ml-4">
- <h3 class="text-lg font-medium text-gray-900">工作时间</h3>
- <p class="mt-1 text-gray-600">
- 周一至周五: 9:00 - 18:00<br>
- 周六、周日: 休息
- </p>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
-
- <script setup lang="ts">
- /**
- * 联系我们页面
- * 提供联系表单和联系信息
- */
- import { ref, reactive } from 'vue';
- import { useErrorHandler } from '~/composables/useErrorHandler';
-
- const { error, isLoading, wrapAsync } = useErrorHandler();
- const submitSuccess = ref(false);
-
- // 表单数据
- const formData = reactive({
- name: '',
- email: '',
- message: ''
- });
-
- // 表单错误
- const formErrors = reactive({
- name: '',
- email: '',
- message: ''
- });
-
- /**
- * 验证表单输入
- * @returns 表单是否有效
- */
- function validateForm(): boolean {
- let isValid = true;
-
- // 重置错误
- formErrors.name = '';
- formErrors.email = '';
- formErrors.message = '';
-
- // 验证姓名
- if (!formData.name.trim()) {
- formErrors.name = '请输入您的姓名';
- isValid = false;
- }
-
- // 验证邮箱
- if (!formData.email.trim()) {
- formErrors.email = '请输入您的邮箱';
- isValid = false;
- } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
- formErrors.email = '请输入有效的邮箱地址';
- isValid = false;
- }
-
- // 验证消息
- if (!formData.message.trim()) {
- formErrors.message = '请输入您的消息';
- isValid = false;
- }
-
- return isValid;
- }
-
- /**
- * 提交表单
- */
- async function submitForm() {
- // 重置成功状态
- submitSuccess.value = false;
-
- // 验证表单
- if (!validateForm()) {
- return;
- }
-
- // 提交表单数据
- await wrapAsync(async () => {
- // 模拟API请求
- await new Promise(resolve => setTimeout(resolve, 1000));
-
- // 模拟成功响应
- submitSuccess.value = true;
-
- // 清空表单
- formData.name = '';
- formData.email = '';
- formData.message = '';
-
- return true;
- });
- }
-
- // SEO优化
- useHead({
- title: '联系我们 - Hanye',
- meta: [
- { name: 'description', content: '联系我们获取更多信息或咨询服务。我们期待收到您的留言。' }
- ]
- });
- </script>
|