Index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. <template>
  2. <div id="ContactUs">
  3. <!-- Banner -->
  4. <div class="banner container-fuild text-center">
  5. <h1>联系我们</h1>
  6. <p>期待与您合作,共创美好未来</p>
  7. </div>
  8. <div class="l-container l-section">
  9. <div class="contact-grid">
  10. <!-- 左侧联系信息 -->
  11. <div class="contact-info">
  12. <h2>联系方式</h2>
  13. <p class="info-description">如果您有任何问题或需求,欢迎通过以下方式联系我们</p>
  14. <div class="info-item">
  15. <div class="info-icon">
  16. <i class="glyphicon glyphicon-map-marker"></i>
  17. </div>
  18. <div class="info-content">
  19. <h4>公司地址</h4>
  20. <p>上海市徐汇区漕溪路 252 号银海大楼 C-406</p>
  21. </div>
  22. </div>
  23. <div class="info-item">
  24. <div class="info-icon">
  25. <i class="glyphicon glyphicon-earphone"></i>
  26. </div>
  27. <div class="info-content">
  28. <h4>联系电话</h4>
  29. <p>15086621233</p>
  30. </div>
  31. </div>
  32. <div class="info-item">
  33. <div class="info-icon">
  34. <i class="glyphicon glyphicon-envelope"></i>
  35. </div>
  36. <div class="info-content">
  37. <h4>电子邮箱</h4>
  38. <p>zhanyuhangkong@163.com</p>
  39. </div>
  40. </div>
  41. <div class="info-item">
  42. <div class="info-icon">
  43. <i class="glyphicon glyphicon-time"></i>
  44. </div>
  45. <div class="info-content">
  46. <h4>工作时间</h4>
  47. <p>周一至周五 9:00-18:00</p>
  48. </div>
  49. </div>
  50. <!-- 社交媒体 -->
  51. <div class="social-links">
  52. <h4>关注我们</h4>
  53. <div class="social-icons">
  54. <a href="#" class="social-icon wechat">
  55. <i class="glyphicon glyphicon-wechat"></i>
  56. </a>
  57. <a href="#" class="social-icon weibo">
  58. <i class="glyphicon glyphicon-globe"></i>
  59. </a>
  60. <a href="#" class="social-icon qq">
  61. <i class="glyphicon glyphicon-user"></i>
  62. </a>
  63. </div>
  64. </div>
  65. </div>
  66. <!-- 右侧表单 -->
  67. <div class="contact-form-wrapper">
  68. <h2>在线留言</h2>
  69. <p class="form-description">填写以下表单,我们将尽快与您联系</p>
  70. <form @submit.prevent="submitForm" class="contact-form">
  71. <div class="form-group">
  72. <label for="name">
  73. <i class="glyphicon glyphicon-user"></i>
  74. 联系人 <span class="required">*</span>
  75. </label>
  76. <input
  77. type="text"
  78. id="name"
  79. v-model="formData.name"
  80. placeholder="请输入您的姓名"
  81. required
  82. >
  83. </div>
  84. <div class="form-row">
  85. <div class="form-group">
  86. <label for="phone">
  87. <i class="glyphicon glyphicon-earphone"></i>
  88. 联系电话 <span class="required">*</span>
  89. </label>
  90. <input
  91. type="tel"
  92. id="phone"
  93. v-model="formData.phone"
  94. placeholder="请输入您的手机号"
  95. pattern="[0-9]{11}"
  96. required
  97. >
  98. </div>
  99. <div class="form-group">
  100. <label for="email">
  101. <i class="glyphicon glyphicon-envelope"></i>
  102. 邮箱 <span class="required">*</span>
  103. </label>
  104. <input
  105. type="email"
  106. id="email"
  107. v-model="formData.email"
  108. placeholder="请输入您的邮箱"
  109. required
  110. >
  111. </div>
  112. </div>
  113. <div class="form-group">
  114. <label for="company">
  115. <i class="glyphicon glyphicon-home"></i>
  116. 企业名称
  117. </label>
  118. <input
  119. type="text"
  120. id="company"
  121. v-model="formData.company"
  122. placeholder="请输入您的企业名称(选填)"
  123. >
  124. </div>
  125. <div class="form-group">
  126. <label for="message">
  127. <i class="glyphicon glyphicon-comment"></i>
  128. 留言内容
  129. </label>
  130. <textarea
  131. id="message"
  132. v-model="formData.message"
  133. placeholder="请详细描述您的需求...(选填)"
  134. rows="5"
  135. ></textarea>
  136. </div>
  137. <div class="form-agreement">
  138. <label>
  139. <input type="checkbox" v-model="formData.agreement" required>
  140. <span>我已阅读并同意 <a href="#">隐私政策</a> 和 <a href="#">服务条款</a></span>
  141. </label>
  142. </div>
  143. <button type="submit" class="btn-submit" :disabled="isSubmitting">
  144. <span v-if="!isSubmitting">
  145. <i class="glyphicon glyphicon-send"></i>
  146. 提交留言
  147. </span>
  148. <span v-else>
  149. <i class="glyphicon glyphicon-hourglass"></i>
  150. 提交中...
  151. </span>
  152. </button>
  153. </form>
  154. </div>
  155. </div>
  156. </div>
  157. <!-- 地图区域 -->
  158. <div class="map-section">
  159. <div class="container">
  160. <h2>公司位置</h2>
  161. <div class="map-container">
  162. <!-- 百度地图 -->
  163. <iframe
  164. width="100%"
  165. height="450"
  166. frameborder="0"
  167. scrolling="no"
  168. marginheight="0"
  169. src="https://j.map.baidu.com/68/irhJ"
  170. style="border:0;"
  171. allowfullscreen=""
  172. ></iframe>
  173. <p class="map-note">银海大楼 C 座(漕溪路辅路与漕东三路交叉口西 97 米)</p>
  174. </div>
  175. </div>
  176. </div>
  177. </div>
  178. </template>
  179. <script>
  180. import {WOW} from 'wowjs';
  181. export default {
  182. name: 'ContactUs',
  183. data() {
  184. return {
  185. formData: {
  186. name: '',
  187. phone: '',
  188. email: '',
  189. company: '',
  190. message: '',
  191. agreement: false
  192. },
  193. isSubmitting: false,
  194. // Formspree 配置
  195. // 1. 访问 https://formspree.io/ 免费注册
  196. // 2. 创建新表单,获取表单 ID
  197. // 3. 将 YOUR_FORMSPREE_ID 替换为您的实际表单 ID
  198. formspreeUrl: 'https://formspree.io/f/xqedwjbk'
  199. };
  200. },
  201. mounted() {
  202. var wow = new WOW();
  203. wow.init();
  204. },
  205. methods: {
  206. async submitForm() {
  207. console.log('开始提交表单...');
  208. // 验证表单
  209. if (!this.validateForm()) {
  210. console.log('表单验证失败');
  211. return;
  212. }
  213. console.log('表单验证通过,准备提交...');
  214. this.isSubmitting = true;
  215. try {
  216. // 准备表单数据
  217. const submitData = {
  218. name: this.formData.name,
  219. phone: this.formData.phone,
  220. email: this.formData.email,
  221. company: this.formData.company,
  222. message: this.formData.message,
  223. replyto: this.formData.email // Formspree 专用,用于回复
  224. };
  225. console.log('提交数据:', submitData);
  226. // 提交到 Formspree
  227. const response = await fetch(this.formspreeUrl, {
  228. method: 'POST',
  229. headers: {
  230. 'Content-Type': 'application/json',
  231. 'Accept': 'application/json'
  232. },
  233. body: JSON.stringify(submitData)
  234. });
  235. console.log('Formspree 响应:', response.status);
  236. if (response.ok) {
  237. const result = await response.json();
  238. console.log('提交成功!', result);
  239. // 显示成功提示
  240. this.showNotification('success', '提交成功!我们会尽快与您联系。');
  241. // 重置表单
  242. this.resetForm();
  243. } else {
  244. const error = await response.json();
  245. console.error('提交失败:', error);
  246. this.showNotification('error', error.errors ?
  247. error.errors.map(e => e.message).join(', ') :
  248. '提交失败,请稍后重试或直接拨打电话联系我们');
  249. }
  250. } catch (error) {
  251. console.error('网络错误:', error);
  252. this.showNotification('error', '网络错误,请检查网络连接后重试');
  253. } finally {
  254. this.isSubmitting = false;
  255. }
  256. },
  257. validateForm() {
  258. console.log('开始验证表单...');
  259. console.log('表单数据:', {
  260. name: this.formData.name,
  261. phone: this.formData.phone,
  262. email: this.formData.email,
  263. company: this.formData.company,
  264. message: this.formData.message,
  265. agreement: this.formData.agreement
  266. });
  267. // 姓名验证
  268. if (!this.formData.name || this.formData.name.trim().length < 2) {
  269. console.log('姓名验证失败');
  270. this.showNotification('error', '请输入有效的姓名(至少 2 个字符)');
  271. return false;
  272. }
  273. // 手机号验证
  274. const phoneRegex = /^1[3-9]\d{9}$/;
  275. if (!phoneRegex.test(this.formData.phone)) {
  276. console.log('手机号验证失败:', this.formData.phone);
  277. this.showNotification('error', '请输入有效的 11 位手机号码');
  278. return false;
  279. }
  280. // 邮箱验证
  281. const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  282. if (!emailRegex.test(this.formData.email)) {
  283. console.log('邮箱验证失败:', this.formData.email);
  284. this.showNotification('error', '请输入有效的邮箱地址');
  285. return false;
  286. }
  287. // 企业验证(选填,如果填写则至少 2 个字符)
  288. if (this.formData.company && this.formData.company.trim().length < 2) {
  289. console.log('企业验证失败');
  290. this.showNotification('error', '企业名称至少 2 个字符(或留空)');
  291. return false;
  292. }
  293. // 留言内容验证(选填,如果填写则至少 5 个字符)
  294. if (this.formData.message && this.formData.message.trim().length < 5) {
  295. console.log('留言内容验证失败:', this.formData.message);
  296. this.showNotification('error', '留言内容至少 5 个字符(或留空)');
  297. return false;
  298. }
  299. // 协议验证
  300. if (!this.formData.agreement) {
  301. console.log('协议验证失败');
  302. this.showNotification('error', '请同意隐私政策和服务条款');
  303. return false;
  304. }
  305. console.log('表单验证通过');
  306. return true;
  307. },
  308. showNotification(type, message) {
  309. // 创建提示元素
  310. const notification = document.createElement('div');
  311. notification.className = `notification notification-${type}`;
  312. notification.innerHTML = `
  313. <i class="glyphicon glyphicon-${type === 'success' ? 'ok' : 'remove'}"></i>
  314. <span>${message}</span>
  315. `;
  316. // 添加到页面
  317. document.body.appendChild(notification);
  318. // 动画显示
  319. setTimeout(() => {
  320. notification.classList.add('show');
  321. }, 10);
  322. // 3 秒后移除
  323. setTimeout(() => {
  324. notification.classList.remove('show');
  325. setTimeout(() => {
  326. document.body.removeChild(notification);
  327. }, 300);
  328. }, 3000);
  329. },
  330. resetForm() {
  331. this.formData = {
  332. name: '',
  333. phone: '',
  334. email: '',
  335. company: '',
  336. subject: '',
  337. message: '',
  338. agreement: false
  339. };
  340. }
  341. }
  342. };
  343. </script>
  344. <style scoped>
  345. /* Banner */
  346. .banner {
  347. color: #fff;
  348. height: 200px;
  349. display: flex;
  350. flex-direction: column;
  351. justify-content: center;
  352. align-items: center;
  353. background-image: url("../../assets/img/banner_4.jpg");
  354. background-repeat: no-repeat;
  355. background-size: cover;
  356. background-attachment: scroll;
  357. background-position: center center;
  358. }
  359. .banner h1 {
  360. font-size: 36px;
  361. font-weight: var(--font-weight-bold);
  362. margin: 0 0 10px;
  363. letter-spacing: 2px;
  364. }
  365. .banner p {
  366. font-size: 16px;
  367. color: rgba(255, 255, 255, 0.8);
  368. margin: 0;
  369. letter-spacing: 1px;
  370. }
  371. /* 联系网格 */
  372. .contact-grid {
  373. display: grid;
  374. grid-template-columns: 400px 1fr;
  375. gap: 60px;
  376. margin-top: 40px;
  377. }
  378. /* 左侧联系信息 */
  379. .contact-info {
  380. background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
  381. padding: 40px;
  382. border-radius: 12px;
  383. color: #fff;
  384. }
  385. .contact-info h2 {
  386. font-size: 24px;
  387. font-weight: 600;
  388. margin-bottom: 15px;
  389. }
  390. .info-description {
  391. font-size: 14px;
  392. color: rgba(255, 255, 255, 0.8);
  393. margin-bottom: 30px;
  394. line-height: 1.6;
  395. }
  396. .info-item {
  397. display: flex;
  398. gap: 15px;
  399. margin-bottom: 25px;
  400. }
  401. .info-icon {
  402. width: 40px;
  403. height: 40px;
  404. background: rgba(255, 255, 255, 0.2);
  405. border-radius: 50%;
  406. display: flex;
  407. align-items: center;
  408. justify-content: center;
  409. flex-shrink: 0;
  410. }
  411. .info-icon i {
  412. font-size: 18px;
  413. color: #fff;
  414. }
  415. .info-content h4 {
  416. font-size: 14px;
  417. font-weight: 600;
  418. margin-bottom: 5px;
  419. }
  420. .info-content p {
  421. font-size: 13px;
  422. color: rgba(255, 255, 255, 0.8);
  423. margin: 0;
  424. line-height: 1.4;
  425. }
  426. /* 社交媒体 */
  427. .social-links {
  428. margin-top: 40px;
  429. padding-top: 30px;
  430. border-top: 1px solid rgba(255, 255, 255, 0.2);
  431. }
  432. .social-links h4 {
  433. font-size: 14px;
  434. font-weight: 600;
  435. margin-bottom: 15px;
  436. }
  437. .social-icons {
  438. display: flex;
  439. gap: 10px;
  440. }
  441. .social-icon {
  442. width: 36px;
  443. height: 36px;
  444. background: rgba(255, 255, 255, 0.2);
  445. border-radius: 50%;
  446. display: flex;
  447. align-items: center;
  448. justify-content: center;
  449. color: #fff;
  450. text-decoration: none;
  451. transition: all 0.3s ease;
  452. }
  453. .social-icon:hover {
  454. background: rgba(255, 255, 255, 0.3);
  455. transform: scale(1.1);
  456. }
  457. .social-icon.wechat { background: #07C160; }
  458. .social-icon.weibo { background: #E6162D; }
  459. .social-icon.qq { background: #12B7F5; }
  460. /* 右侧表单 */
  461. .contact-form-wrapper {
  462. background: #fff;
  463. padding: 40px;
  464. border-radius: 12px;
  465. box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  466. }
  467. .contact-form-wrapper h2 {
  468. font-size: 24px;
  469. font-weight: 600;
  470. color: #333;
  471. margin-bottom: 10px;
  472. }
  473. .form-description {
  474. font-size: 14px;
  475. color: #666;
  476. margin-bottom: 30px;
  477. }
  478. .contact-form {
  479. max-width: 100%;
  480. }
  481. .form-group {
  482. margin-bottom: 20px;
  483. }
  484. .form-group label {
  485. display: flex;
  486. align-items: center;
  487. gap: 8px;
  488. font-size: 14px;
  489. font-weight: 500;
  490. color: #333;
  491. margin-bottom: 8px;
  492. }
  493. .form-group label i {
  494. color: #1e73be;
  495. font-size: 14px;
  496. }
  497. .form-group .required {
  498. color: #f44336;
  499. }
  500. .form-group input,
  501. .form-group select,
  502. .form-group textarea {
  503. width: 100%;
  504. padding: 12px 15px;
  505. border: 1px solid #e0e0e0;
  506. border-radius: 6px;
  507. font-size: 14px;
  508. color: #333;
  509. transition: all 0.3s ease;
  510. box-sizing: border-box;
  511. }
  512. .form-group input:focus,
  513. .form-group select:focus,
  514. .form-group textarea:focus {
  515. border-color: #1e73be;
  516. outline: none;
  517. box-shadow: 0 0 0 3px rgba(30, 115, 190, 0.1);
  518. }
  519. .form-group input::placeholder,
  520. .form-group textarea::placeholder {
  521. color: #999;
  522. }
  523. .form-group textarea {
  524. resize: vertical;
  525. min-height: 120px;
  526. }
  527. .form-row {
  528. display: grid;
  529. grid-template-columns: 1fr 1fr;
  530. gap: 20px;
  531. }
  532. .form-agreement {
  533. margin: 20px 0;
  534. }
  535. .form-agreement label {
  536. display: flex;
  537. align-items: flex-start;
  538. gap: 10px;
  539. font-size: 13px;
  540. color: #666;
  541. cursor: pointer;
  542. }
  543. .form-agreement input[type="checkbox"] {
  544. width: auto;
  545. margin-top: 2px;
  546. }
  547. .form-agreement a {
  548. color: #1e73be;
  549. text-decoration: none;
  550. }
  551. .form-agreement a:hover {
  552. text-decoration: underline;
  553. }
  554. .btn-submit {
  555. width: 100%;
  556. padding: 15px;
  557. background: linear-gradient(135deg, #1e73be 0%, #3b82f6 100%);
  558. color: #fff;
  559. border: none;
  560. border-radius: 6px;
  561. font-size: 16px;
  562. font-weight: 600;
  563. cursor: pointer;
  564. transition: all 0.3s ease;
  565. display: flex;
  566. align-items: center;
  567. justify-content: center;
  568. gap: 10px;
  569. }
  570. .btn-submit:hover:not(:disabled) {
  571. transform: translateY(-2px);
  572. box-shadow: 0 8px 20px rgba(30, 115, 190, 0.3);
  573. }
  574. .btn-submit:disabled {
  575. opacity: 0.6;
  576. cursor: not-allowed;
  577. }
  578. /* 地图区域 */
  579. .map-section {
  580. background: #f8f9fa;
  581. padding: 60px 0;
  582. margin-top: 60px;
  583. }
  584. .map-section h2 {
  585. font-size: 24px;
  586. font-weight: 600;
  587. color: #333;
  588. text-align: center;
  589. margin-bottom: 30px;
  590. }
  591. .map-container {
  592. max-width: 1200px;
  593. margin: 0 auto;
  594. border-radius: 12px;
  595. overflow: hidden;
  596. box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  597. }
  598. .map-note {
  599. text-align: center;
  600. padding: 15px;
  601. background: #f8f9fa;
  602. font-size: 14px;
  603. color: #666;
  604. margin: 0;
  605. }
  606. /* 通知提示 */
  607. .notification {
  608. position: fixed;
  609. top: 20px;
  610. right: 20px;
  611. padding: 15px 25px;
  612. border-radius: 6px;
  613. color: #fff;
  614. font-size: 14px;
  615. font-weight: 500;
  616. box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  617. z-index: 999999;
  618. display: flex;
  619. align-items: center;
  620. gap: 10px;
  621. transform: translateX(400px);
  622. transition: transform 0.3s ease;
  623. }
  624. .notification.show {
  625. transform: translateX(0);
  626. }
  627. .notification-success {
  628. background: #4CAF50;
  629. }
  630. .notification-error {
  631. background: #f44336;
  632. }
  633. /* 响应式 */
  634. @media screen and (max-width: 991px) {
  635. .contact-grid {
  636. grid-template-columns: 1fr;
  637. gap: 40px;
  638. }
  639. .contact-info {
  640. padding: 30px;
  641. }
  642. .form-row {
  643. grid-template-columns: 1fr;
  644. }
  645. }
  646. @media screen and (max-width: 767px) {
  647. .banner {
  648. height: 150px;
  649. }
  650. .banner h1 {
  651. font-size: 28px;
  652. }
  653. .contact-info,
  654. .contact-form-wrapper {
  655. padding: 25px;
  656. }
  657. .form-group input,
  658. .form-group select,
  659. .form-group textarea {
  660. font-size: 13px;
  661. padding: 10px 12px;
  662. }
  663. .btn-submit {
  664. font-size: 15px;
  665. padding: 12px;
  666. }
  667. }
  668. </style>