|
|
@@ -0,0 +1,397 @@
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref } from 'vue'
|
|
|
+import { submitContactForm } from '@/api/contact'
|
|
|
+
|
|
|
+const formData = ref({
|
|
|
+ name: '',
|
|
|
+ tel: '',
|
|
|
+ company: '',
|
|
|
+ industry: '',
|
|
|
+ city: '',
|
|
|
+ email: '',
|
|
|
+ message: '',
|
|
|
+ subscribe: false,
|
|
|
+ terms: false
|
|
|
+})
|
|
|
+
|
|
|
+const errors = ref<Record<string, string>>({})
|
|
|
+const isSubmitting = ref(false)
|
|
|
+
|
|
|
+const industries = [
|
|
|
+ { value: 'surveying', label: '测绘' },
|
|
|
+ { value: 'electricalnetwork', label: '电网' },
|
|
|
+ { value: 'energy', label: '新能源' },
|
|
|
+ { value: 'firefighting', label: '消防应急' },
|
|
|
+ { value: 'environment-protect', label: '环保' },
|
|
|
+ { value: 'traffic', label: '交通' },
|
|
|
+ { value: 'science-education', label: '科教' },
|
|
|
+ { value: 'forestry', label: '林业' },
|
|
|
+ { value: 'hydraulic', label: '水利' },
|
|
|
+ { value: 'judicial', label: '司法' },
|
|
|
+ { value: 'law-enforcement', label: '公共安全' },
|
|
|
+ { value: 'government', label: '政府单位' },
|
|
|
+ { value: 'engineering-construction', label: '工程建筑' },
|
|
|
+ { value: 'city-management', label: '城市管理执法' },
|
|
|
+ { value: 'other', label: '其他' }
|
|
|
+]
|
|
|
+
|
|
|
+const validateForm = () => {
|
|
|
+ errors.value = {}
|
|
|
+
|
|
|
+ if (!formData.value.name) errors.value.name = '请输入姓名'
|
|
|
+ if (!formData.value.tel) errors.value.tel = '请输入电话'
|
|
|
+ if (!formData.value.company) errors.value.company = '请输入公司信息'
|
|
|
+ if (!formData.value.industry) errors.value.industry = '请选择行业'
|
|
|
+ if (!formData.value.email) errors.value.email = '请输入邮箱'
|
|
|
+ if (!formData.value.terms) errors.value.terms = '请接受条款'
|
|
|
+
|
|
|
+ return Object.keys(errors.value).length === 0
|
|
|
+}
|
|
|
+
|
|
|
+const submitForm = async () => {
|
|
|
+ if (!validateForm()) return
|
|
|
+
|
|
|
+ isSubmitting.value = true
|
|
|
+
|
|
|
+ try {
|
|
|
+ const result = await submitContactForm(formData.value)
|
|
|
+
|
|
|
+ if (result.success) {
|
|
|
+ alert('提交成功!我们将尽快与您联系。')
|
|
|
+ // 重置表单
|
|
|
+ formData.value = {
|
|
|
+ name: '',
|
|
|
+ tel: '',
|
|
|
+ company: '',
|
|
|
+ industry: '',
|
|
|
+ city: '上海市 上海市',
|
|
|
+ email: '',
|
|
|
+ message: '',
|
|
|
+ subscribe: false,
|
|
|
+ terms: false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ alert('提交失败,请稍后再试')
|
|
|
+ console.error(error)
|
|
|
+ } finally {
|
|
|
+ isSubmitting.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <section id="contact" class="contact-section">
|
|
|
+ <div class="text-box">
|
|
|
+ <h1 class="title">马上订购 —— One Myriad<span class="nowrap">开放平台</span></h1>
|
|
|
+ <p class="desc">
|
|
|
+ 如需申请产品演示或软件试用,请留下您的联系信息,我们的专属顾问会在 3 个工作日内和您联系。
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-box">
|
|
|
+ <form @submit.prevent="submitForm" autocomplete="off">
|
|
|
+ <!-- 表单字段实现 -->
|
|
|
+ <div class="form-group">
|
|
|
+ <div class="form-item">
|
|
|
+ <input
|
|
|
+ v-model="formData.name"
|
|
|
+ type="text"
|
|
|
+ id="name"
|
|
|
+ required
|
|
|
+ >
|
|
|
+ <label for="name">姓名 *</label>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <input
|
|
|
+ v-model="formData.tel"
|
|
|
+ type="tel"
|
|
|
+ id="tel"
|
|
|
+ required
|
|
|
+ >
|
|
|
+ <label for="tel">电话 *</label>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group">
|
|
|
+ <div class="form-item">
|
|
|
+ <input
|
|
|
+ v-model="formData.company"
|
|
|
+ type="text"
|
|
|
+ id="company"
|
|
|
+ required
|
|
|
+ >
|
|
|
+ <label for="company">公司 *</label>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group">
|
|
|
+ <div class="form-item">
|
|
|
+ <select
|
|
|
+ v-model="formData.industry"
|
|
|
+ id="industry"
|
|
|
+ required
|
|
|
+ >
|
|
|
+ <option value="" disabled selected>请选择行业</option>
|
|
|
+ <option
|
|
|
+ v-for="item in industries"
|
|
|
+ :key="item.value"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ {{ item.label }}
|
|
|
+ </option>
|
|
|
+ </select>
|
|
|
+ <label for="industry">行业 *</label>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <input
|
|
|
+ v-model="formData.city"
|
|
|
+ type="text"
|
|
|
+ id="city"
|
|
|
+ required
|
|
|
+ >
|
|
|
+ <label for="city">城市</label>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group">
|
|
|
+ <div class="form-item">
|
|
|
+ <input
|
|
|
+ v-model="formData.email"
|
|
|
+ type="email"
|
|
|
+ id="email"
|
|
|
+ required
|
|
|
+ >
|
|
|
+ <label for="email">邮箱 *</label>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group">
|
|
|
+ <div class="form-item">
|
|
|
+ <textarea
|
|
|
+ v-model="formData.message"
|
|
|
+ id="message"
|
|
|
+ ></textarea>
|
|
|
+ <label for="message">请输入您的需求...</label>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group checkbox-group">
|
|
|
+ <div class="checkbox-item">
|
|
|
+ <input
|
|
|
+ type="checkbox"
|
|
|
+ id="subscribe"
|
|
|
+ v-model="formData.subscribe"
|
|
|
+ >
|
|
|
+ <label for="subscribe">订阅产品资讯</label>
|
|
|
+ </div>
|
|
|
+ <!--<div class="checkbox-item">-->
|
|
|
+ <!-- <input-->
|
|
|
+ <!-- type="checkbox"-->
|
|
|
+ <!-- id="terms"-->
|
|
|
+ <!-- v-model="formData.terms"-->
|
|
|
+ <!-- required-->
|
|
|
+ <!-- >-->
|
|
|
+ <!-- <label for="terms">我已阅读并同意<a href="#">用户协议</a></label>-->
|
|
|
+ <!--</div>-->
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-group">
|
|
|
+ <button type="submit" class="submit-btn" :disabled="isSubmitting">
|
|
|
+ <span v-if="!isSubmitting">提交</span>
|
|
|
+ <span v-else>提交中...</span>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.contact-section {
|
|
|
+ padding: 64px 0;
|
|
|
+ background-color: #f9fafb;
|
|
|
+
|
|
|
+ .text-box {
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 40px;
|
|
|
+ max-width: 800px;
|
|
|
+ margin-left: auto;
|
|
|
+ margin-right: auto;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 32px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ color: #1f2937;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .desc {
|
|
|
+ font-size: 16px;
|
|
|
+ color: #6b7280;
|
|
|
+ line-height: 1.6;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-box {
|
|
|
+ max-width: 700px;
|
|
|
+ margin: 0 auto;
|
|
|
+ background: white;
|
|
|
+ padding: 40px;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
|
|
+
|
|
|
+ .form-group {
|
|
|
+ margin-bottom: 24px;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 16px;
|
|
|
+
|
|
|
+ .form-item {
|
|
|
+ position: relative;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ flex: 1 1 calc(50% - 8px);
|
|
|
+
|
|
|
+ @media (max-width: 768px) {
|
|
|
+ flex: 1 1 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.has-error {
|
|
|
+ input, select, textarea {
|
|
|
+ border-color: #ef4444;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ input, select, textarea {
|
|
|
+ width: 100%;
|
|
|
+ padding: 12px 16px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ transition: border-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
|
+
|
|
|
+ &:focus {
|
|
|
+ outline: none;
|
|
|
+ border-color: #409eff;
|
|
|
+ box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ input[type="email"] {
|
|
|
+ &:hover {
|
|
|
+ border-color: #c0c4cc;
|
|
|
+ }
|
|
|
+ &:focus {
|
|
|
+ border-color: #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ select {
|
|
|
+ appearance: none;
|
|
|
+ background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: right 12px center;
|
|
|
+ background-size: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ textarea {
|
|
|
+ resize: vertical;
|
|
|
+ min-height: 100px;
|
|
|
+ }
|
|
|
+
|
|
|
+ label {
|
|
|
+ position: absolute;
|
|
|
+ left: 16px;
|
|
|
+ top: 12px;
|
|
|
+ color: #9ca3af;
|
|
|
+ font-size: 14px;
|
|
|
+ transition: all 0.2s;
|
|
|
+ pointer-events: none;
|
|
|
+ background: white;
|
|
|
+ padding: 0 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ input:focus + label,
|
|
|
+ input:not(:placeholder-shown) + label,
|
|
|
+ select:focus + label,
|
|
|
+ select:not([value=""]) + label,
|
|
|
+ textarea:focus + label,
|
|
|
+ textarea:not(:placeholder-shown) + label {
|
|
|
+ top: -8px;
|
|
|
+ left: 12px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #2563eb;
|
|
|
+ background: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.checkbox-group {
|
|
|
+ margin-top: 32px;
|
|
|
+
|
|
|
+ .checkbox-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 12px;
|
|
|
+
|
|
|
+ input[type="checkbox"] {
|
|
|
+ width: auto;
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ label {
|
|
|
+ position: static;
|
|
|
+ color: #4b5563;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ a {
|
|
|
+ color: #2563eb;
|
|
|
+ text-decoration: none;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.has-error label {
|
|
|
+ color: #ef4444;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .error-message {
|
|
|
+ color: #ef4444;
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .submit-btn {
|
|
|
+ width: 100%;
|
|
|
+ background: #2563eb;
|
|
|
+ color: white;
|
|
|
+ padding: 12px;
|
|
|
+ border: none;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: background-color 0.2s;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #1d4ed8;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:disabled {
|
|
|
+ background: #93c5fd;
|
|
|
+ cursor: not-allowed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.nowrap {
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+</style>
|