<template> <div class="tw-text-center tw-text-4xl tw-mb-[32px] tw-mt-[30px]"> Contact Us </div> <v-card class="pa-10 tw-max-w-[800px] tw-m-auto"> <h3 class="text-h5 tw-mb-5">Official Web</h3> <div class="tw-mb-10"> <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block">URL</label> <span>http://www.canrud.com</span> </div> <h3 class="text-h5 tw-mb-5">Technical Center</h3> <!-- <div> <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block">QQ</label> <span>3632191327</span> </div> --> <div> <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block" >Phone</label > <span>+86 19867737979</span> </div> <div> <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block" >Email</label > <span>contact@canrd.com</span> </div> <div class="tw-mb-1"> <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block" >Wechat</label > <span>contactcanrd</span> </div> <div class="tw-w-[300px]"> <v-img src="/wechat.jpg" alt="canrud-wechat"></v-img> </div> <div style="display: flex; gap: 16px; align-items: center"> <span class="text-h5 tw-mb-5 tw-mt-5">Other Platforms</span> <span class="tw-mt-2"> <a href="https://www.linkedin.com/company/canrd?originalSubdomain=cn" rel="noopener noreferrer" style="display: flex; align-items: center; gap: 8px" > <span ><svg t="1733206392822" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5464" width="20" height="20" > <path d="M948.245333 0H75.52C33.877333 0 0.021333 33.066667 0.021333 73.813333v876.288C0 990.890667 33.877333 1024 75.52 1024h872.704c41.749333 0 75.733333-33.109333 75.733333-73.898667V73.834667C1024 33.045333 989.994667 0 948.266667 0z" fill="#007BB5" p-id="5465" ></path> <path d="M151.744 383.893333h152.021333V872.533333H151.744V383.893333z m76.053333-242.922666a88.106667 88.106667 0 1 1-0.128 176.170666 88.106667 88.106667 0 0 1 0.128-176.170666M399.04 383.893333h145.578667v66.794667h2.090666c20.266667-38.4 69.802667-78.933333 143.701334-78.933333 153.770667 0 182.186667 101.184 182.186666 232.810666V872.533333h-151.850666v-237.653333c0-56.661333-0.981333-129.557333-78.933334-129.557333-79.018667 0-91.093333 61.76-91.093333 125.525333v241.706667h-151.68V383.872z" fill="#FFFFFF" p-id="5466" ></path></svg></span >LinkedIn</a > </span> <span class="tw-mt-2"> <a href="https://www.amazon.com/s?me=A3A2SQ086XUS66&marketplaceID=ATVPDKIKX0DER" rel="noopener noreferrer" style="display: flex; align-items: center; gap: 8px" > <svg class="icon" viewBox="0 0 1126 1024" width="20" height="20" aria-hidden="true" > <path d="M2.008553 794.830142c3.382073-5.461063 8.7738-5.813248 16.349072-1.021335q256.233047 148.673652 557.663492 148.72648 200.998387 0 396.851576-74.949297l14.798359-6.589155c6.483499-2.818578 10.993664-4.686257 13.777024-6.096097 10.606261-4.122762 18.322407-2.149427 24.665032 6.096097 5.637156 8.173986 4.228417 15.785577-5.637156 22.550824-12.015 8.914674-28.187979 19.273305-47.249974 30.724809q-87.681873 52.376462-196.611486 81.07621c-71.879788 19.061995-143.054106 28.645819-212.149434 28.645819q-159.614488 0-302.316409-55.777245A840.520599 840.520599 0 0 1 7.046995 810.829231c-4.686257-3.488829-7.043693-7.043693-7.043693-10.323413a9.795136 9.795136 0 0 1 2.075688-5.745012z m308.411405-292.13277q0-70.822133 34.918008-121.063475c23.255193-33.367295 54.96612-58.736697 95.839351-75.860575 37.384401-15.750358 82.484948-27.02577 136.817135-33.825135 18.322407-2.149427 48.518939-4.827131 90.201094-8.173986v-17.37591c0-43.692909-4.932786-73.188374-14.09399-88.087986-14.197444-20.190086-36.649216-30.548717-67.651371-30.548718h-8.562489c-22.550824 2.149427-42.105877 9.196422-58.525386 21.598825-16.454727 12.684151-27.02577 29.597819-31.710926 51.478391-2.818578 14.09399-9.685078 21.845354-20.436616 23.959562l-118.389073-14.798359c-11.666117-2.818578-17.476063-8.456834-17.476063-18.322406a28.0372 28.0372 0 0 1 1.021336-7.043693q17.389117-90.907664 85.514836-135.302742C463.72704 20.401397 516.544833 3.522947 577.149209 0h25.369401c77.516943 0 138.931344 20.401397 182.658371 60.604376 6.342626 7.043693 12.684151 14.09399 19.026776 22.550824 5.637156 7.751364 10.535824 14.763141 13.283965 21.140984a90.185686 90.185686 0 0 1 9.161204 26.77814c2.818578 11.944563 4.932786 19.731145 6.342625 23.959563 1.409839 4.897568 2.924233 14.09399 3.559266 28.892349 0.45784 14.692704 0.950899 23.149538 0.950899 25.973618v248.049156a153.121084 153.121084 0 0 0 7.751364 48.659813c4.932786 14.692704 9.865573 25.369402 14.798359 31.675708l23.959562 31.675709c4.228417 6.377844 6.377844 12.015 6.377844 16.912567 0 5.637156-2.818578 10.606261-8.456834 14.763141-56.375959 49.328964-87.385818 76.107104-92.209647 80.335521q-11.627597 9.513388-29.597818 2.114208a284.646645 284.646645 0 0 1-24.700251-23.290411l-14.549629-16.312753c-2.818578-3.487729-7.786583-9.865573-14.904014-19.731146l-14.096191-20.436615c-38.053552 41.612818-75.297079 67.651371-112.751918 78.221313-23.222176 7.043693-51.337517 10.675597-85.973777 10.675597-52.150844 0.001101-95.843752-16.102543-129.664485-48.587175-33.825135-32.416396-50.736602-78.221313-50.736602-138.12242z m176.312444-20.58079c0 26.602048 6.589155 47.919125 19.978775 64.092104 13.38962 15.958367 31.710927 24.065218 54.258449 24.065218a65.995002 65.995002 0 0 0 9.161203-0.950899 54.539096 54.539096 0 0 1 7.786583-1.091772c28.85713-7.504835 50.736602-25.973618 66.915084-55.359026a147.597288 147.597288 0 0 0 16.912568-42.739809 183.627979 183.627979 0 0 0 6.342625-37.595712c0.704369-9.161203 0.704369-25.369402 0.70437-47.214755v-25.361698c-39.463391 0-69.730361 2.818578-90.201094 8.456834-59.898906 16.912568-90.201094 54.96612-90.201094 114.161757z m430.435684 330.116985a34.135498 34.135498 0 0 1 6.201752-7.997893c17.018223-11.416286 33.543387-19.273305 49.328964-23.501722 25.827242-6.23697 51.196643-10.429068 75.719701-11.275412a62.565604 62.565604 0 0 1 19.273305 1.409839c30.548717 2.818578 49.328964 7.892238 55.071775 15.503829 2.959452 4.228417 4.228417 10.711916 4.228417 18.322407v7.043693c0 23.959562-6.589155 52.147542-19.480213 84.563938-13.072654 32.416396-31.18265 58.631041-54.296969 78.926783-3.417292 2.818578-6.589155 4.228417-9.266859 4.228417a10.956245 10.956245 0 0 1-4.228417-0.563496c-4.228417-2.07899-5.038442-5.637156-2.99467-11.275412 25.362798-59.190134 37.875259-100.659878 37.875258-124.022927 0-7.043693-1.409839-12.684151-4.087543-16.17298-6.80817-7.788784-25.830543-12.081034-57.507352-12.081034q-17.123878 0-40.87213 2.149427c-17.058944 2.114209-32.874237 4.228417-46.968226 6.342625-4.228417 0-6.941339-0.669151-8.456834-2.07899-1.409839-1.409839-1.691587-2.219864-0.950899-3.631904a7.546657 7.546657 0 0 1 0.950899-2.959452z" fill="#FF9900" ></path> </svg> Amazon </a> </span> <span class="tw-mt-2"> <a href="https://canrd.en.alibaba.com/company_profile.html?spm=a2700.galleryofferlist.normal_offer.d_companyName.262213a0fqshG2" rel="noopener noreferrer" style="display: flex; align-items: center; gap: 8px" > <svg t="1733207242907" class="icon" viewBox="0 0 1651 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9032" width="20" height="20" > <path d="M972.403613 749.997419c-59.986581 4.195097-54.172903-27.912258-18.531097-74.520774 81.259355-108.378839 231.787355-255.636645 238.558968-363.22271 9.348129-139.660387-131.138065-182.899613-275.819355-182.899612-100.64929 2.576516-204.833032 30.488774-275.819355 55.824516-244.504774 86.280258-397.708387 221.745548-494.988387 374.189419-100.64929 150.627097-69.367742 295.473548 148.050581 299.668645 164.203355-6.771613 275.026581-52.422194 386.64258-109.997419 0.792774 0-310.503226 88.856774-425.653677 23.717161-12.750452-6.804645-25.335742-16.152774-28.738065-42.28129 0-53.380129 88.097032-109.171613 139.726452-126.942968v-91.43329c104.018581 36.434581 226.733419 26.293677 331.742968-51.62942 3.402323 9.381161 6.771613 21.140645 5.945806 33.891097h17.771355c4.195097-36.467613-20.314839-71.944258-60.977548-74.520774 11.792516 9.348129 20.314839 16.945548 24.509935 23.717161l-1.585548 1.618581-0.825807 0.792774c-135.300129 94.835613-266.603355 50.803613-279.188645 48.227097l75.313549-73.728-21.140646-53.380129c149.867355-52.422194 273.408-90.640516 478.901678-126.909936l-45.980903-37.128258 23.717161-14.336c121.756903 33.858065 203.875097 59.193806 199.68 123.540645-1.618581 10.96671-5.945806 23.717161-12.750452 37.260388-36.302452 71.944258-142.897548 187.920516-186.136774 237.898322-27.879226 33.06529-55.824516 63.554065-75.313548 94.042839-21.933419 31.281548-33.032258 60.151742-33.858065 86.280258 4.195097 212.595613 631.279484-99.823484 754.820129-182.106839-180.157935 77.09729-375.642839 150.82529-588.07329 164.368516z m137.083871-488.547096c4.558452 8.390194 6.639484 18.696258 6.639484 30.819096a75.379613 75.379613 0 0 0-6.606452-30.819096z" fill="#FF6600" p-id="9033" ></path> </svg> Alibaba </a> </span> <span class="tw-mt-2"> <a href="https://www.youtube.com/@Canrd_Tech" rel="noopener noreferrer" style="display: flex; align-items: center; gap: 8px" > <svg t="1733207323150" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14163" width="20" height="20" > <path d="M1013.76 307.264s-9.984-70.570667-40.704-101.632c-38.933333-40.789333-82.56-41.002667-102.592-43.392C727.168 151.893333 512.213333 151.893333 512.213333 151.893333h-0.426666s-214.954667 0-358.250667 10.346667c-20.010667 2.389333-63.658667 2.602667-102.613333 43.392C20.245333 236.693333 10.24 307.264 10.24 307.264S0 390.122667 0 473.002667v77.674666c0 82.858667 10.24 165.738667 10.24 165.738667s9.984 70.570667 40.704 101.632c38.933333 40.789333 90.112 39.509333 112.896 43.776 81.92 7.850667 348.16 10.282667 348.16 10.282667s215.168-0.32 358.464-10.666667c20.010667-2.410667 63.658667-2.602667 102.613333-43.392 30.698667-31.061333 40.704-101.632 40.704-101.632S1024 633.536 1024 550.677333v-77.674666c0-82.88-10.24-165.738667-10.24-165.738667z" fill="#DC2217" p-id="14164" ></path> <path d="M406.293333 644.821333l-0.064-287.722666 276.693334 144.362666-276.629334 143.36z" fill="#FFFFFF" p-id="14165" ></path> </svg> Youtube </a> </span> <span class="tw-mt-2"> <a href="https://x.com/canrdenerge?s=11" rel="noopener noreferrer" class="link-container" style="display: flex; align-items: center; gap: 8px" > <svg class="icon" t="1733207912677" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="20" height="20" > <path d="M1024 186.368a410.325333 410.325333 0 0 1-120.618667 33.877333 214.954667 214.954667 0 0 0 92.373334-119.125333 413.781333 413.781333 0 0 1-133.504 52.181333A207.189333 207.189333 0 0 0 708.949333 85.333333c-115.968 0-210.005333 96.426667-210.005333 215.424 0 16.896 1.792 33.28 5.376 49.066667-174.592-9.002667-329.386667-94.72-433.066667-225.152a219.306667 219.306667 0 0 0-28.416 108.373333c0 74.709333 37.12 140.672 93.44 179.328a206.250667 206.250667 0 0 1-95.146666-26.88v2.645334c0 104.405333 72.405333 191.488 168.533333 211.2a200.32 200.32 0 0 1-55.296 7.594666c-13.525333 0-26.752-1.28-39.552-3.84 26.709333 85.589333 104.277333 147.882667 196.224 149.546667A414.805333 414.805333 0 0 1 0 841.941333 584.96 584.96 0 0 0 322.048 938.666667c386.474667 0 597.76-328.192 597.76-612.906667 0-9.386667-0.213333-18.730667-0.554667-27.904 41.045333-30.378667 76.672-68.266667 104.746667-111.488" fill="#55ACEE" ></path> </svg> Twitter </a> </span> </div> <div class="text-h5 tw-mb-5 tw-mt-5">Send an email to me</div> <form> <v-row> <v-col cols="8" md="6"> <v-text-field v-model="state.firstName" :error-messages="v$.firstName.$errors.map((e) => e.$message)" label="FirstName" required @blur="v$.firstName.$touch" @input="v$.firstName.$touch" ></v-text-field> </v-col> <v-col cols="8" md="6"> <v-text-field v-model="state.lastName" :error-messages="v$.lastName.$errors.map((e) => e.$message)" label="LastName" required @blur="v$.lastName.$touch" @input="v$.lastName.$touch" ></v-text-field> </v-col> </v-row> <v-text-field v-model="state.email" :error-messages="v$.email.$errors.map((e) => e.$message)" label="E-mail" required @blur="v$.email.$touch" @input="v$.email.$touch" ></v-text-field> <v-text-field v-model="state.text" :error-messages="v$.text.$errors.map((e) => e.$message)" label="message" required @blur="v$.text.$touch" @input="v$.text.$touch" ></v-text-field> <div class="recaptcha-container" style="margin-bottom: 20px"> <!-- reCAPTCHA v2 Checkbox --> <div id="recaptcha" class="g-recaptcha"></div> <!-- 验证成功后显示的消息 --> <!-- <div v-if="verified" class="success-message">验证通过!</div> --> </div> <!-- <v-btn class="me-4" @click="v$.$validate"> submit </v-btn> --> <v-btn class="me-4" @click="handleSubmit"> submit </v-btn> <v-btn @click="clear"> clear </v-btn> </form> <v-snackbar v-model="snackbar" :timeout="3000" top :style="{ top: '300px', position: 'fixed' }" color="success" > Sent successfully! </v-snackbar> <v-snackbar v-model="snackbarFailed" :timeout="3000" top :style="{ top: '100px', position: 'fixed' }" color="error" > Failed to send! </v-snackbar> <div style="margin-bottom: 10px"> <v-tabs class="tabs2" ref="tabs2" v-model="tabRecom" style="margin-top: 25px; margin-bottom: 20px" color="white" bg-color="#eeeeee" slider-color="blue-lighten-1" selected-class="active" v-if="isMobile()" > <v-tab :value="1">Best Sellers</v-tab> <!-- <v-tab :value="3">商品百科</v-tab> --> </v-tabs> <div class="tw-text-center" v-if="hotLoadingMobile && isMobile()"> <v-progress-circular color="blue-lighten-2" indeterminate size="64" class="tw-m-auto" ></v-progress-circular> </div> <v-item-group multiple v-if="isMobile()"> <v-row v-if="!hotLoadingMobile"> <v-col v-for="(item, i) in recommendImagesMobile" :key="i" cols="6" lg="3" md="4" sm="6" > <div v-if="item !== null"> <v-card :elevation="4" class="mx-auto" :href="item[0].productUrl"> <!-- 设置 eager 属性,确保图片直接加载 --> <v-img :src="item[0].url" :alt="item[0].name" eager class="d-block" /> <v-card-text class="tw-text-left font-weight-medium title"> <h4 class="clamp-text">{{ item[0].name }}</h4> </v-card-text> </v-card> </div> </v-col> </v-row> <!-- <div v-if="!hotTotal" class="text-medium-emphasis text-body-1 tw-text-center tw-m-[64px]" > no data </div> --> </v-item-group> <v-row v-if="isMobile()"> <v-col> <v-pagination :size="isMobile() ? 'small' : 'default'" v-if="hotTotalMobile" v-model="currentIndexMobile" @update:modelValue="toggleRowMobile" :length="hotLength" rounded="0" class="tw-float-right tw-mt-[32px]" total-visible="5" ></v-pagination></v-col ></v-row> </div> </v-card> <v-tabs class="tabs" v-model="tabRecom" style="margin-top: 25px" color="white" bg-color="#eeeeee" slider-color="blue-lighten-1" selected-class="active" v-if="recommendImages[0] !== null && !isMobile()" > <v-tab :value="1">Best Sellers</v-tab> <!-- <v-tab :value="3">商品百科</v-tab> --> </v-tabs> <div id="image-container" v-if="recommendImages[0] !== null && !isMobile()"> <div class="recommend-left-box"> <v-img src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/76c987e13a334be481a346c19c2284f3qy4tjnxps7.png" alt="往左移" class="recommend-img-left" @click="toggleRowLeft" /> </div> <div class="image-row" id="row1"> <!-- <img v-for="(imageObj, index) in recommendImages.slice(0, 5)" :key="'row1-' + index" :src="imageObj[0]?.url" :alt="'Image ' + (index + 1)" style="margin: 0 5px; width: 200px; height: 200px" /> --> <div v-for="(imageObj, index) in recommendImages" :key="'row1-' + index" class="imageTotal" > <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank"> <img :src="imageObj[0]?.url" :alt="'Image ' + (index + 1)" class="item-imgHot" /> <span class="image-name"> {{ imageObj[0]?.name }} </span> </a> <div v-else style="width: 200px; height: 200px"></div> </div> </div> <div class="recommend-right-box"> <v-img src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/b5daa0a8f2f140f5b406e984c730a453iznzlekysg.png" alt="往右移" class="recommend-img-right" @click="toggleRowRight" /> </div> </div> </template> <script setup lang="ts"> import { ref, reactive } from "vue"; import { useVuelidate } from "@vuelidate/core"; import { email, required, maxLength } from "@vuelidate/validators"; const productStore = useProductListStore(); const categoryStore = useCategoryStore(); const loading = ref(false); const hotLoading = ref(false); const route = useRoute(); // 获取路由信息 const router = useRouter(); // 获取路由信息 const title = ref(""); const keywordTitle = ref(""); const maxPage = ref(1); const maxPageMobile = ref(1); const tabRecom = ref(); const recommendList = ref({}); const recommendImages = ref({}); const currentIndex = ref(1); const hotTotal = ref(10); const isOrNotMobile = isMobile(); const recommendListMobile = ref({}); const recommendImagesMobile = ref({}); const currentIndexMobile = ref(1); const hotLoadingMobile = ref(false); const hotTotalMobile = ref(10); const verified = ref(false); // 验证状态 const snackbar = ref(false); const snackbarFailed = ref(false); const initialState = { firstName: "", lastName: "", email: "", text: "", }; const state = reactive({ ...initialState, }); const handleSubmit = async () => { if (verified.value) { let { data } = await useAsyncData( "sendEmail", () => $fetch("/email/send", { method: "POST", body: { firstName: state.firstName, lastName: state.lastName, email: state.email, message: state.text, subject: "", }, }), { server: true, // 仅在服务器端获取数据 } ); if (data.value.message == "成功") { snackbar.value = true; } else { snackbarFailed.value = true; } } else { snackbarFailed.value = true; } }; const rules = { name: { required }, firstName: { required }, lastName: { required }, email: { required, email }, text: { required, maxLength: maxLength(20) }, }; const v$ = useVuelidate(rules, state); function clear() { v$.value.$reset(); for (const [key, value] of Object.entries(initialState)) { state[key] = value; } } onMounted(() => { // 动态加载 reCAPTCHA 脚本并初始化 loadRecaptchaScript(() => { // 确保 grecaptcha 已经准备好 if (window.grecaptcha) { // 强制等待一段时间,确保 #recaptcha 元素已经渲染 setTimeout(() => { // 确保 #recaptcha 元素已经存在并且可用 const recaptchaElement = document.getElementById("recaptcha"); if (recaptchaElement) { try { window.grecaptcha.render("recaptcha", { sitekey: "6Lcgd6kqAAAAAAm0mLcuLcjv3zz55hB6wu5gkZMe", // 替换为你的 Site Key callback: onRecaptchaSuccess, "error-callback": onRecaptchaError, }); } catch (error) {} } else { } }, 1000); // 延时 1 秒,确保 DOM 渲染完成 } else { } }); }); // 验证成功回调 const onRecaptchaSuccess = (token) => { verified.value = true; // 设置为已验证 }; // 验证失败回调 const onRecaptchaError = () => { verified.value = false; // 设置为未验证 }; // 动态加载 reCAPTCHA 脚本 const loadRecaptchaScript = (callback) => { if (document.getElementById("recaptcha-api")) { callback(); // 如果脚本已加载,直接回调 return; } const script = document.createElement("script"); script.id = "recaptcha-api"; script.src = "https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=en"; script.async = true; script.defer = true; // 脚本加载完成后的回调 script.onload = () => { // 修改开始 callback(); }; // 修改结束 // 脚本加载失败时的回调 script.onerror = () => {}; document.head.appendChild(script); }; const loadHotProducts = async () => { hotLoading.value = true; let { data: hotProducts } = await useAsyncData( "hotProducts", () => $fetch("/shop/product/hotProducts", { method: "GET", params: { pageNo: currentIndex.value, pageSize: 5, }, }), { server: true, // 仅在服务器端获取数据 } ); hotTotal.value = hotProducts.value.data.total; recommendList.value = hotProducts.value.data.records; maxPage.value = hotProducts.value.data.pages; // recommendImages.value = recommendList.value.slice(0, 10).map((item) => { recommendImages.value = Array.from({ length: 5 }).map((_, index) => { const item = recommendList.value[index]; if (!item) { return null; } // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析 if (typeof item.productimageliststore === "string") { try { item.productimageliststore = JSON.parse(item.productimageliststore); } catch (error) { item.productimageliststore = []; // 解析失败时,设置为空数组 } } const ree = (item.productimageliststore = item?.productimageliststore.map( (productItem: ProductImage) => ({ ...productItem, // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`, url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`, name: item.name, productUrl: `https://www.canrud.com/products/detail/${item.id}`, }) )); return ree; }); hotLoading.value = false; }; const toggleRowLeft = () => { if (currentIndex.value !== 1) { currentIndex.value--; } else if (currentIndex.value == 1) { currentIndex.value = maxPage.value; } startTimer(); }; let intervalId: any; const toggleRowRight = () => { if (currentIndex.value < maxPage.value) { currentIndex.value++; } else if (currentIndex.value == maxPage.value) { currentIndex.value = 1; } startTimer(); }; const startTimer = () => { // 清除已有计时器,防止重复 clearInterval(intervalId); intervalId = setInterval(() => { toggleRowRight(); }, 5000); // 每6秒调用一次 }; onMounted(() => { startTimer(); }); const toggleRowMobile = (value: number) => { currentIndexMobile.value = value; }; const { width } = useDisplay(); const firstIndex = ref(true); watch(currentIndex, (newIndex) => { loadHotProducts(); // Call loadHotProducts when currentIndex changes }); const loadHotProductsMobile = async () => { hotLoadingMobile.value = true; let { data: hotProductsMobile } = await useAsyncData( "hotProducts", () => $fetch("/shop/product/hotProducts", { method: "GET", params: { pageNo: currentIndexMobile.value, pageSize: 4, }, }), { server: true, // 仅在服务器端获取数据 } ); hotTotalMobile.value = hotProductsMobile.value.data.total; recommendListMobile.value = hotProductsMobile.value.data.records; maxPageMobile.value = hotProductsMobile.value.data.pages; // recommendImages.value = recommendList.value.slice(0, 10).map((item) => { recommendImagesMobile.value = Array.from({ length: 4 }).map((_, index) => { const item = recommendListMobile.value[index]; if (!item) { return null; } // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析 if (typeof item.productimageliststore === "string") { try { item.productimageliststore = JSON.parse(item.productimageliststore); } catch (error) { item.productimageliststore = []; // 解析失败时,设置为空数组 } } const ree = (item.productimageliststore = item?.productimageliststore.map( (productItem: ProductImage) => ({ ...productItem, // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`, url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`, name: item.name, productUrl: `https://www.canrud.com/products/detail/${item.id}`, }) )); return ree; }); hotLoadingMobile.value = false; }; watch(currentIndexMobile, (newIndex) => { loadHotProductsMobile(); // Call loadHotProducts when currentIndex changes }); // Initial load of hot products watchEffect(async () => { console.log("Current route:", route.fullPath, "Width:", width.value); if (firstIndex.value) { if (width.value > 600) { await loadHotProducts(); } else { await loadHotProductsMobile(); } } }); useHead({ title: "Contact", }); const hotLength = computed(() => hotTotalMobile.value ? Math.ceil(hotTotalMobile.value / 4) : 0 ); </script> <style lang="scss" scoped> @media screen and (min-width: 1537px) { .tabs { border-bottom: 2px solid #1f88e5; margin: 10px auto 20px; width: 93%; } } @media screen and (max-width: 1536px) and (min-width: 1281px) { .tabs { border-bottom: 2px solid #1f88e5; margin: 10px auto 40px; width: 78%; } } @media screen and (max-width: 1280px) { .tabs { border-bottom: 2px solid #1f88e5; margin: 10px auto 40px; width: 92%; } } /* .tabs { border-bottom: 2px solid #1f88e5; } */ .active { background-color: #1086e8; } @media screen and (min-width: 1537px) { #image-container { display: flex; align-items: center; justify-content: center; height: 320px; margin: 10px auto 50px; width: 80%; } } @media screen and (max-width: 1536px) and (min-width: 1281px) { #image-container { display: flex; align-items: center; justify-content: center; height: 260px; margin: 10px auto 0px; width: 80%; padding: 0; } } @media screen and (max-width: 1280px) { #image-container { display: flex; align-items: center; justify-content: center; height: 260px; margin: 10px auto 0px; width: 80%; padding: 0; } } .image-row { display: flex; height: 245px; } @media screen and (min-width: 1537px) { .imageTotal { display: inline-block; margin: 0 5px; text-align: center; width: 320px; } } @media screen and (max-width: 1536px) and (min-width: 1281px) { .imageTotal { display: inline-block; margin: 0 5px; text-align: center; width: 200px; } } @media screen and (max-width: 1280px) { .imageTotal { display: inline-block; margin: 0 5px; text-align: center; width: 200px; } } @media screen and (min-width: 1537px) { .image-row img { width: 240px; height: 240px; } } @media screen and (max-width: 1536px) and (min-width: 1281px) { .image-row img { width: 140px; height: 140px; } } @media screen and (max-width: 1280px) { .image-row img { width: 140px; height: 140px; } } @media screen and (min-width: 1537px) { .image-name { display: -webkit-box; /* Enables multi-line text handling */ -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */ -webkit-line-clamp: 3; /* Limits the text to 3 lines */ overflow: hidden; /* Hides the overflowed text */ text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */ margin-top: 5px; font-size: 16px; width: 180px; color: #555; text-align: center; /* Centers the text horizontally */ margin-left: 50px; } } @media screen and (max-width: 1536px) and (min-width: 1281px) { .image-name { display: -webkit-box; /* Enables multi-line text handling */ -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */ -webkit-line-clamp: 3; /* Limits the text to 3 lines */ overflow: hidden; /* Hides the overflowed text */ text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */ margin-top: 5px; font-size: 16px; width: 180px; color: #555; text-align: center; /* Centers the text horizontally */ margin-left: 10px; } } @media screen and (max-width: 1280px) { .image-name { display: -webkit-box; /* Enables multi-line text handling */ -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */ -webkit-line-clamp: 3; /* Limits the text to 3 lines */ overflow: hidden; /* Hides the overflowed text */ text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */ margin-top: 5px; font-size: 16px; width: 180px; color: #555; text-align: center; /* Centers the text horizontally */ margin-left: 10px; } } button .recommendButton { margin: 0 0px; cursor: pointer; } .recommend-left-box { } // @media screen and (max-width: 1280px) { // .recommend-img-left { // width: 26px; // height: 27px; // margin-bottom: 60px; // } // } .recommend-img-left { width: 26px; height: 27px; margin-right: 30px; margin-bottom: 60px; } .recommend-img-left:hover { cursor: pointer; } .recommend-right-box { } .recommend-img-right { width: 26px; height: 27px; margin-left: 30px; margin-bottom: 60px; } .recommend-img-right:hover { cursor: pointer; } .v-card { transition: all 0.3s ease-in-out; } .clamp-text { display: -webkit-box; /* 使用弹性盒子 */ -webkit-box-orient: vertical; /* 设置为垂直方向 */ -webkit-line-clamp: 3; /* 限制最多显示3行 */ overflow: hidden; /* 隐藏多余内容 */ text-overflow: ellipsis; /* 添加省略号 */ white-space: normal; /* 允许换行 */ line-height: 1.5em; /* 设置每行的高度 */ min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */ } span a { color: black; } </style>