Commit 3b581a76df27456fce8e71c4752d4b21550fc586

Authored by boyang
1 parent cd5cc258

fix: 解决热销bug,prod2-41/42

components/Footer.vue
... ... @@ -17,11 +17,51 @@
17 17 </v-col>
18 18 <v-col cols="12" lg="3" sm="12" md="6">
19 19 <b>About</b>
20   - <p><router-link to="/about">About us</router-link></p>
  20 + <!-- <p>
  21 + <span
  22 + ><v-img
  23 + src="/public/logo.jpg"
  24 + style="width: auto; height: auto"
  25 + ></v-img
  26 + ></span>
  27 +
  28 + <router-link to="/about">About us</router-link>
  29 + </p> -->
  30 + <p style="display: flex; align-items: center; gap: 8px">
  31 + <router-link
  32 + to="/about"
  33 + style="display: flex; align-items: center; gap: 8px"
  34 + >
  35 + About us</router-link
  36 + >
  37 + </p>
21 38 <p>
22 39 <a
23 40 href="https://www.linkedin.com/company/canrd?originalSubdomain=cn"
24 41 rel="noopener noreferrer"
  42 + style="display: flex; align-items: center; gap: 8px"
  43 + >
  44 + <span
  45 + ><svg
  46 + t="1733206392822"
  47 + class="icon"
  48 + viewBox="0 0 1024 1024"
  49 + version="1.1"
  50 + xmlns="http://www.w3.org/2000/svg"
  51 + p-id="5464"
  52 + width="20"
  53 + height="20"
  54 + >
  55 + <path
  56 + 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"
  57 + fill="#007BB5"
  58 + p-id="5465"
  59 + ></path>
  60 + <path
  61 + 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"
  62 + fill="#FFFFFF"
  63 + p-id="5466"
  64 + ></path></svg></span
25 65 >LinkedIn</a
26 66 >
27 67 </p>
... ... @@ -29,25 +69,97 @@
29 69 <a
30 70 href="https://www.amazon.com/s?me=A3A2SQ086XUS66&marketplaceID=ATVPDKIKX0DER"
31 71 rel="noopener noreferrer"
  72 + style="display: flex; align-items: center; gap: 8px"
  73 + ><svg
  74 + t="1733207196625"
  75 + class="icon"
  76 + viewBox="0 0 1126 1024"
  77 + version="1.1"
  78 + xmlns="http://www.w3.org/2000/svg"
  79 + p-id="7890"
  80 + width="20"
  81 + height="20"
  82 + >
  83 + <path
  84 + 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"
  85 + fill="#FF9900"
  86 + p-id="7891"
  87 + ></path></svg
32 88 >Amazon</a
33 89 >
34 90 </p>
35 91 <p>
36 92 <a
37   - href="https://canrd.en.alibaba.com/company_profile.html?spm=a2700.galleryofferlist.normal_offer.d_companyName.262213a0fqshG2"
38   - rel="noopener noreferrer"
39   - >Alibaba</a
  93 + href="https://canrd.en.alibaba.com/company_profile.html?spm=a2700.galleryofferlist.normal_offer.d_companyName.262213a0fqshG2"
  94 + rel="noopener noreferrer"
  95 + style="display: flex; align-items: center; gap: 8px"
  96 + ><svg
  97 + t="1733207242907"
  98 + class="icon"
  99 + viewBox="0 0 1651 1024"
  100 + version="1.1"
  101 + xmlns="http://www.w3.org/2000/svg"
  102 + p-id="9032"
  103 + width="20"
  104 + height="20"
  105 + >
  106 + <path
  107 + 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"
  108 + fill="#FF6600"
  109 + p-id="9033"
  110 + ></path></svg
  111 + >Alibaba</a
40 112 >
41 113 </p>
42 114 <p>
43 115 <a
44 116 href="https://www.youtube.com/@Canrd_Tech"
45 117 rel="noopener noreferrer"
  118 + style="display: flex; align-items: center; gap: 8px"
  119 + >
  120 + <svg
  121 + t="1733207323150"
  122 + class="icon"
  123 + viewBox="0 0 1024 1024"
  124 + version="1.1"
  125 + xmlns="http://www.w3.org/2000/svg"
  126 + p-id="14163"
  127 + width="20"
  128 + height="20"
  129 + >
  130 + <path
  131 + 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"
  132 + fill="#DC2217"
  133 + p-id="14164"
  134 + ></path>
  135 + <path
  136 + d="M406.293333 644.821333l-0.064-287.722666 276.693334 144.362666-276.629334 143.36z"
  137 + fill="#FFFFFF"
  138 + p-id="14165"
  139 + ></path></svg
46 140 >Youtube</a
47 141 >
48 142 </p>
49 143 <p>
50   - <a href="https://x.com/canrdenerge?s=11" rel="noopener noreferrer"
  144 + <a
  145 + href="https://x.com/canrdenerge?s=11"
  146 + rel="noopener noreferrer"
  147 + style="display: flex; align-items: center; gap: 8px"
  148 + ><svg
  149 + t="1733207912677"
  150 + class="icon"
  151 + viewBox="0 0 1024 1024"
  152 + version="1.1"
  153 + xmlns="http://www.w3.org/2000/svg"
  154 + p-id="22952"
  155 + width="20"
  156 + height="20"
  157 + >
  158 + <path
  159 + 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"
  160 + fill="#55ACEE"
  161 + p-id="22953"
  162 + ></path></svg
51 163 >Twitter</a
52 164 >
53 165 </p>
... ... @@ -72,6 +184,7 @@
72 184 </template>
73 185  
74 186 <script setup lang="ts">
  187 +import { mdiYoutube } from "@mdi/js";
75 188 </script>
76 189  
77 190 <style>
... ...
components/HotProducts.vue 0 → 100644
  1 +<template>
  2 + <v-tabs
  3 + class="tabs"
  4 + v-model="tabRecom"
  5 + color="white"
  6 + bg-color="#eeeeee"
  7 + style="margin-top: 40px"
  8 + slider-color="blue-lighten-1"
  9 + selected-class="active"
  10 + v-if="recommendImages[0] !== null && !isMobile()"
  11 + >
  12 + <v-tab :value="1">Best Sellers</v-tab>
  13 + <!-- <v-tab :value="3">商品百科</v-tab> -->
  14 + </v-tabs>
  15 + <div id="image-container" v-if="recommendImages[0] !== null && !isMobile()">
  16 + <div class="recommend-left-box">
  17 + <v-img
  18 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/76c987e13a334be481a346c19c2284f3qy4tjnxps7.png"
  19 + alt="往左移"
  20 + class="recommend-img-left"
  21 + @click="toggleRowLeft"
  22 + />
  23 + </div>
  24 + <div class="image-row" id="row1">
  25 + <!-- <img
  26 + v-for="(imageObj, index) in recommendImages.slice(0, 5)"
  27 + :key="'row1-' + index"
  28 + :src="imageObj[0]?.url"
  29 + :alt="'Image ' + (index + 1)"
  30 + style="margin: 0 5px; width: 200px; height: 200px"
  31 + /> -->
  32 + <div
  33 + v-for="(imageObj, index) in recommendImages"
  34 + :key="'row1-' + index"
  35 + class="imageTotal"
  36 + >
  37 + <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank">
  38 + <img
  39 + :src="imageObj[0]?.url"
  40 + :alt="'Image ' + (index + 1)"
  41 + class="item-imgHot"
  42 + />
  43 + <span class="image-name">
  44 + {{ imageObj[0]?.name }}
  45 + </span>
  46 + </a>
  47 + <div v-else class="image-substitute"></div>
  48 + </div>
  49 + </div>
  50 + <div class="recommend-right-box">
  51 + <v-img
  52 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/b5daa0a8f2f140f5b406e984c730a453iznzlekysg.png"
  53 + alt="往右移"
  54 + class="recommend-img-right"
  55 + @click="toggleRowRight"
  56 + />
  57 + </div>
  58 + </div>
  59 + <div style="padding-left: 16px; padding-right: 16px">
  60 + <v-tabs
  61 + class="tabs2"
  62 + ref="tabs2"
  63 + v-model="tabRecom"
  64 + style="margin-top: 25px; margin-bottom: 20px; width: 100%"
  65 + color="white"
  66 + bg-color="#eeeeee"
  67 + slider-color="blue-lighten-1"
  68 + selected-class="active"
  69 + v-if="isMobile()"
  70 + >
  71 + <v-tab :value="1">Best Sellers</v-tab>
  72 + <!-- <v-tab :value="3">商品百科</v-tab> -->
  73 + </v-tabs>
  74 + <div class="tw-text-center" v-if="hotLoadingMobile && isMobile()">
  75 + <v-progress-circular
  76 + color="blue-lighten-2"
  77 + indeterminate
  78 + size="64"
  79 + class="tw-m-auto"
  80 + ></v-progress-circular>
  81 + </div>
  82 + <v-item-group multiple v-if="isMobile()">
  83 + <v-row v-if="!hotLoadingMobile">
  84 + <v-col
  85 + v-for="(item, i) in recommendImagesMobile"
  86 + :key="i"
  87 + cols="6"
  88 + lg="3"
  89 + md="4"
  90 + sm="6"
  91 + >
  92 + <div v-if="item !== null">
  93 + <v-card :elevation="4" class="mx-auto" :href="item[0].productUrl">
  94 + <v-img
  95 + :src="item[0].url"
  96 + :alt="item[0].name"
  97 + eager
  98 + class="d-block"
  99 + />
  100 + <v-card-text class="tw-text-left font-weight-medium title">
  101 + <h4 class="clamp-text">{{ item[0].name }}</h4>
  102 + </v-card-text>
  103 + </v-card>
  104 + </div>
  105 + </v-col>
  106 + </v-row>
  107 + </v-item-group>
  108 + <v-row v-if="isMobile()">
  109 + <v-col>
  110 + <v-pagination
  111 + :size="isMobile() ? 'small' : 'default'"
  112 + v-if="hotTotalMobile"
  113 + v-model="currentIndexMobile"
  114 + @update:modelValue="toggleRowMobile"
  115 + :length="hotLength"
  116 + rounded="0"
  117 + class="tw-float-right tw-mt-[32px]"
  118 + total-visible="5"
  119 + ></v-pagination></v-col
  120 + ></v-row>
  121 + </div>
  122 +</template>
  123 +
  124 +<script setup lang="ts">
  125 +import { computed, onMounted, reactive, ref } from "vue";
  126 +import { isMobile } from "../utils";
  127 +import { useRoute } from "vue-router";
  128 +
  129 +const route = useRoute(); // 获取路由信息
  130 +const maxPage = ref(1);
  131 +const maxPageMobile = ref(1);
  132 +const tabRecom = ref();
  133 +const recommendList = ref({});
  134 +const recommendImages = ref({});
  135 +const currentIndex = ref(1);
  136 +const hotLoading = ref(false);
  137 +const hotTotal = ref(10);
  138 +const isOrNotMobile = isMobile();
  139 +const recommendListMobile = ref({});
  140 +const recommendImagesMobile = ref({});
  141 +const currentIndexMobile = ref(1);
  142 +const hotLoadingMobile = ref(false);
  143 +const hotTotalMobile = ref(10);
  144 +const loadHotProducts = async () => {
  145 + hotLoading.value = true;
  146 + let { data: hotProducts } = await useAsyncData(
  147 + "hotProducts",
  148 + () =>
  149 + $fetch("/shop/product/hotProducts", {
  150 + method: "GET",
  151 + params: {
  152 + pageNo: currentIndex.value,
  153 + pageSize: 5,
  154 + },
  155 + }),
  156 + {
  157 + server: true, // 仅在服务器端获取数据
  158 + }
  159 + );
  160 + hotTotal.value = hotProducts.value.data.total;
  161 + recommendList.value = hotProducts.value.data.records;
  162 + maxPage.value = hotProducts.value.data.pages;
  163 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  164 + recommendImages.value = Array.from({ length: 5 }).map((_, index) => {
  165 + const item = recommendList.value[index];
  166 + if (!item) {
  167 + return null;
  168 + }
  169 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  170 + if (typeof item.productimageliststore === "string") {
  171 + try {
  172 + item.productimageliststore = JSON.parse(item.productimageliststore);
  173 + } catch (error) {
  174 + item.productimageliststore = []; // 解析失败时,设置为空数组
  175 + }
  176 + }
  177 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  178 + (productItem: ProductImage) => ({
  179 + ...productItem,
  180 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  181 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  182 + name: item.name,
  183 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  184 + })
  185 + ));
  186 + return ree;
  187 + });
  188 + hotLoading.value = false;
  189 +};
  190 +
  191 +const toggleRowLeft = () => {
  192 + if (currentIndex.value !== 1) {
  193 + currentIndex.value--;
  194 + } else if (currentIndex.value == 1) {
  195 + currentIndex.value = maxPage.value;
  196 + }
  197 + startTimer();
  198 +};
  199 +let intervalId: any;
  200 +const toggleRowRight = () => {
  201 + if (currentIndex.value < maxPage.value) {
  202 + currentIndex.value++;
  203 + } else if (currentIndex.value == maxPage.value) {
  204 + currentIndex.value = 1;
  205 + }
  206 + startTimer();
  207 +};
  208 +const startTimer = () => {
  209 + // 清除已有计时器,防止重复
  210 + clearInterval(intervalId);
  211 + intervalId = setInterval(() => {
  212 + toggleRowRight();
  213 + }, 5000); // 每6秒调用一次
  214 +};
  215 +
  216 +onMounted(() => {
  217 + startTimer();
  218 +});
  219 +
  220 +const toggleRowMobile = (value: number) => {
  221 + currentIndexMobile.value = value;
  222 +};
  223 +const { width } = useDisplay();
  224 +const firstIndex = ref(true);
  225 +// 监听屏幕宽度变化
  226 +// watch(width, async (newWidth) => {
  227 +// console.log(newWidth, "5656widthvalue1");
  228 +// if (newWidth > 600) {
  229 +// await loadHotProducts();
  230 +// } else {
  231 +// await loadHotProductsMobile();
  232 +// }
  233 +// });
  234 +
  235 +// // 监听路由变化
  236 +// watch(
  237 +// () => route.fullPath,
  238 +// async () => {
  239 +// console.log(width.value, "5656widthvalue2");
  240 +// if (width.value > 600) {
  241 +// await loadHotProducts();
  242 +// } else {
  243 +// await loadHotProductsMobile();
  244 +// }
  245 +// }
  246 +// );
  247 +watch(currentIndex, (newIndex) => {
  248 + loadHotProducts(); // Call loadHotProducts when currentIndex changes
  249 +});
  250 +
  251 +const loadHotProductsMobile = async () => {
  252 + hotLoadingMobile.value = true;
  253 + let { data: hotProductsMobile } = await useAsyncData(
  254 + "hotProducts",
  255 + () =>
  256 + $fetch("/shop/product/hotProducts", {
  257 + method: "GET",
  258 + params: {
  259 + pageNo: currentIndexMobile.value,
  260 + pageSize: 4,
  261 + },
  262 + }),
  263 + {
  264 + server: true, // 仅在服务器端获取数据
  265 + }
  266 + );
  267 + hotTotalMobile.value = hotProductsMobile.value.data.total;
  268 + recommendListMobile.value = hotProductsMobile.value.data.records;
  269 + maxPageMobile.value = hotProductsMobile.value.data.pages;
  270 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  271 + recommendImagesMobile.value = Array.from({ length: 4 }).map((_, index) => {
  272 + const item = recommendListMobile.value[index];
  273 + if (!item) {
  274 + return null;
  275 + }
  276 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  277 + if (typeof item.productimageliststore === "string") {
  278 + try {
  279 + item.productimageliststore = JSON.parse(item.productimageliststore);
  280 + } catch (error) {
  281 + item.productimageliststore = []; // 解析失败时,设置为空数组
  282 + }
  283 + }
  284 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  285 + (productItem: ProductImage) => ({
  286 + ...productItem,
  287 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  288 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  289 + name: item.name,
  290 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  291 + })
  292 + ));
  293 + return ree;
  294 + });
  295 + hotLoadingMobile.value = false;
  296 +};
  297 +watch(currentIndexMobile, (newIndex) => {
  298 + loadHotProductsMobile(); // Call loadHotProducts when currentIndex changes
  299 +});
  300 +watchEffect(async () => {
  301 + console.log("Current route:", route.fullPath, "Width:", width.value);
  302 +
  303 + if (firstIndex.value) {
  304 + if (width.value > 600) {
  305 + await loadHotProducts();
  306 + } else {
  307 + await loadHotProductsMobile();
  308 + }
  309 + }
  310 +});
  311 +// Initial load of hot products
  312 +const hotLength = computed(() =>
  313 + hotTotalMobile.value ? Math.ceil(hotTotalMobile.value / 4) : 0
  314 +);
  315 +</script>
  316 +
  317 +<style lang="scss" scoped>
  318 +@media screen and (min-width: 1537px) {
  319 + .tabs {
  320 + border-bottom: 2px solid #1f88e5;
  321 + margin: 10px auto 100px;
  322 + width: 93%;
  323 + }
  324 +}
  325 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  326 + .tabs {
  327 + border-bottom: 2px solid #1f88e5;
  328 + margin: 10px auto 20px;
  329 + width: 82%;
  330 + }
  331 +}
  332 +@media screen and (max-width: 1280px) {
  333 + .tabs {
  334 + border-bottom: 2px solid #1f88e5;
  335 + margin: 10px auto 0px;
  336 + width: 88%;
  337 + }
  338 +}
  339 +
  340 +.active {
  341 + background-color: #1086e8;
  342 +}
  343 +
  344 +/* #image-container {
  345 + display: flex;
  346 + align-items: center;
  347 + justify-content: center;
  348 + height: 320px;
  349 + margin: 10px auto 50px;
  350 + width: 80%;
  351 +} */
  352 +
  353 +@media screen and (min-width: 1537px) {
  354 + #image-container {
  355 + display: flex;
  356 + align-items: center;
  357 + justify-content: center;
  358 + height: 320px;
  359 + margin: 10px auto 50px;
  360 + width: 96%;
  361 + }
  362 +}
  363 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  364 + #image-container {
  365 + display: flex;
  366 + align-items: center;
  367 + justify-content: center;
  368 + height: 240px;
  369 + margin: 10px auto 0px;
  370 + width: 80%;
  371 + }
  372 +}
  373 +@media screen and (max-width: 1280px) {
  374 + #image-container {
  375 + display: flex;
  376 + align-items: center;
  377 + justify-content: center;
  378 + height: 260px;
  379 + margin: 10px auto 0px;
  380 + width: 90%;
  381 + }
  382 +}
  383 +.image-row {
  384 + display: flex;
  385 + height: 305px;
  386 +}
  387 +@media screen and (min-width: 1537px) {
  388 + .image-row {
  389 + display: flex;
  390 + height: 305px;
  391 + }
  392 +}
  393 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  394 + .image-row {
  395 + display: flex;
  396 + height: 245px;
  397 + }
  398 +}
  399 +@media screen and (max-width: 1280px) {
  400 + .image-row {
  401 + display: flex;
  402 + height: 220px;
  403 + }
  404 +}
  405 +@media screen and (min-width: 1537px) {
  406 + .imageTotal {
  407 + display: inline-block;
  408 + margin: 0 5px;
  409 + text-align: center;
  410 + width: 315px;
  411 + }
  412 +}
  413 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  414 + .imageTotal {
  415 + display: inline-block;
  416 + margin: 0 5px;
  417 + text-align: center;
  418 + width: 210px;
  419 + }
  420 +}
  421 +@media screen and (max-width: 1280px) {
  422 + .imageTotal {
  423 + display: inline-block;
  424 + margin: 0 5px;
  425 + text-align: center;
  426 + width: 185px;
  427 + }
  428 +}
  429 +@media screen and (min-width: 1537px) {
  430 + .image-row img {
  431 + width: 240px;
  432 + height: 240px;
  433 + }
  434 +}
  435 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  436 + .image-row img {
  437 + width: 180px;
  438 + height: 180px;
  439 + }
  440 +}
  441 +
  442 +@media screen and (min-width: 1537px) {
  443 + .image-row .image-substitute {
  444 + width: 200px;
  445 + height: 200px;
  446 + }
  447 +}
  448 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  449 + .image-row .image-substitute {
  450 + width: 200px;
  451 + height: 200px;
  452 + }
  453 +}
  454 +
  455 +@media screen and (max-width: 1280px) {
  456 + .image-row .image-substitute {
  457 + width: 185px;
  458 + height: 185px;
  459 + }
  460 +}
  461 +@media screen and (max-width: 1280px) {
  462 + .image-row img {
  463 + width: 160px;
  464 + height: 160px;
  465 + margin-left: 10px;
  466 + }
  467 +}
  468 +@media screen and (min-width: 1537px) {
  469 + .image-name {
  470 + display: -webkit-box; /* Enables multi-line text handling */
  471 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  472 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  473 + overflow: hidden; /* Hides the overflowed text */
  474 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  475 + margin-top: 5px;
  476 + font-size: 16px;
  477 + width: 180px;
  478 + color: #555;
  479 + text-align: center; /* Centers the text horizontally */
  480 + margin-left: 50px;
  481 + }
  482 +}
  483 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  484 + .image-name {
  485 + display: -webkit-box; /* Enables multi-line text handling */
  486 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  487 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  488 + overflow: hidden; /* Hides the overflowed text */
  489 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  490 + margin-top: 5px;
  491 + font-size: 16px;
  492 + width: 180px;
  493 + color: #555;
  494 + text-align: center; /* Centers the text horizontally */
  495 + margin-left: 10px;
  496 + }
  497 +}
  498 +@media screen and (max-width: 1280px) {
  499 + .image-name {
  500 + display: -webkit-box; /* Enables multi-line text handling */
  501 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  502 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  503 + overflow: hidden; /* Hides the overflowed text */
  504 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  505 + margin-top: 5px;
  506 + font-size: 16px;
  507 + width: 180px;
  508 + color: #555;
  509 + text-align: center; /* Centers the text horizontally */
  510 + margin-left: 5px;
  511 + }
  512 +}
  513 +button .recommendButton {
  514 + margin: 0 0px;
  515 + cursor: pointer;
  516 +}
  517 +
  518 +.recommend-left-box {
  519 +}
  520 +
  521 +.recommend-img-left {
  522 + width: 26px;
  523 + height: 27px;
  524 + margin-right: 40px;
  525 +}
  526 +
  527 +.recommend-img-left:hover {
  528 + cursor: pointer;
  529 +}
  530 +.recommend-right-box {
  531 +}
  532 +
  533 +.recommend-img-right {
  534 + width: 26px;
  535 + height: 27px;
  536 + margin-left: 40px;
  537 +}
  538 +
  539 +.recommend-img-right:hover {
  540 + cursor: pointer;
  541 +}
  542 +.image-grid {
  543 + padding: 16px;
  544 +}
  545 +
  546 +.v-card {
  547 + transition: all 0.3s ease-in-out;
  548 +}
  549 +.clamp-text {
  550 + display: -webkit-box; /* 使用弹性盒子 */
  551 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  552 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  553 + overflow: hidden; /* 隐藏多余内容 */
  554 + text-overflow: ellipsis; /* 添加省略号 */
  555 + white-space: normal; /* 允许换行 */
  556 + line-height: 1.5em; /* 设置每行的高度 */
  557 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  558 +}
  559 +</style>
... ...
components/ProductDetail.vue
... ... @@ -501,7 +501,7 @@
501 501  
502 502 <script setup lang="ts">
503 503 import type { Product, ProductImage } from "~/type";
504   -import { onMounted, ref } from "vue";
  504 +import { defineProps, onMounted, ref } from "vue";
505 505 import { useDialogStore } from "~/stores/dialog";
506 506 import { useRouter, useRoute } from "vue-router";
507 507 import { useRouteQuery } from "@/stores/route_query";
... ... @@ -643,12 +643,15 @@ const clearSpanStyle = (htmlContent) =&gt; {
643 643 // 返回处理后的 HTML
644 644 return doc.body.innerHTML;
645 645 };
  646 +
  647 +let intervalId: any;
646 648 const toggleRowLeft = () => {
647 649 if (currentIndexHot.value !== 1) {
648 650 currentIndexHot.value--;
649 651 } else if (currentIndexHot.value == 1) {
650 652 currentIndexHot.value = maxPage.value;
651 653 }
  654 + startTimer();
652 655 };
653 656 const toggleRowRight = () => {
654 657 if (currentIndexHot.value < maxPage.value) {
... ... @@ -656,7 +659,20 @@ const toggleRowRight = () =&gt; {
656 659 } else if (currentIndexHot.value == maxPage.value) {
657 660 currentIndexHot.value = 1;
658 661 }
  662 + startTimer();
  663 +};
  664 +const startTimer = () => {
  665 + // 清除已有计时器,防止重复
  666 + clearInterval(intervalId);
  667 + intervalId = setInterval(() => {
  668 + toggleRowRight();
  669 + }, 5000); // 每6秒调用一次
659 670 };
  671 +
  672 +onMounted(() => {
  673 + startTimer();
  674 +});
  675 +
660 676 watch(currentIndexHot, (newIndex) => {
661 677 loadHotProducts(); // Call loadHotProducts when currentIndex changes
662 678 });
... ... @@ -665,7 +681,6 @@ watch(currentIndexHot, (newIndex) =&gt; {
665 681 await loadHotProducts(); // Load hot products the first time
666 682  
667 683 watchEffect(() => {
668   - console.log(info, "5656info");
669 684 currentUrl.value = "https://www.canrud.com/products/detail/" + info.id;
670 685 if (info?.productCrumbsVO?.category1 && productStore.keyword) {
671 686 items.value[1].title = info.productCrumbsVO.category1;
... ... @@ -798,21 +813,21 @@ const slide = ref(0);
798 813 @media screen and (min-width: 1537px) {
799 814 .tabs {
800 815 border-bottom: 2px solid #1f88e5;
801   - margin: 10px auto 20px;
  816 + margin: 0px auto 20px;
802 817 width: 100%;
803 818 }
804 819 }
805 820 @media screen and (max-width: 1536px) and (min-width: 1281px) {
806 821 .tabs {
807 822 border-bottom: 2px solid #1f88e5;
808   - margin: 10px auto 40px;
  823 + margin: 0px auto 40px;
809 824 width: 100%;
810 825 }
811 826 }
812 827 @media screen and (max-width: 1280px) {
813 828 .tabs {
814 829 border-bottom: 2px solid #1f88e5;
815   - margin: 10px auto 40px;
  830 + margin: 0px auto 40px;
816 831 width: 100%;
817 832 }
818 833 }
... ...
deploy/prod2.sh
1 1 #!/bin/bash
2 2 # 变量定义
3   -LAST_TAG="1.0.40"
4   -TAG="1.0.41"
  3 +LAST_TAG="1.0.41"
  4 +TAG="1.0.42"
5 5 TARGET_PATH="/root/web/canrud-outside-nuxt-front"
6 6 DOCKERFILE_PATH="/root/web/canrud-outside-nuxt-front/canrud-nuxt-front"
7 7 IMAGE_NAME="canrud-outside-front"
... ...
package.json
... ... @@ -19,6 +19,7 @@
19 19 "vuetify-nuxt-module": "^0.14.0"
20 20 },
21 21 "devDependencies": {
  22 + "@mdi/js": "^7.4.47",
22 23 "@nuxtjs/i18n": "^8.3.1",
23 24 "@tailwindcss/aspect-ratio": "^0.4.2",
24 25 "autoprefixer": "^10.4.19",
... ...
pages/about.vue
1 1 <template>
  2 + <HotProducts />
  3 +
  4 + <!-- <v-tabs
  5 + class="tabs"
  6 + v-model="tabRecom"
  7 + style="margin-top: 25px"
  8 + color="white"
  9 + bg-color="#eeeeee"
  10 + slider-color="blue-lighten-1"
  11 + selected-class="active"
  12 + v-if="recommendImages[0] !== null && !isMobile()"
  13 + >
  14 + <v-tab :value="1">Best Sellers</v-tab>
  15 + </v-tabs>
  16 + <div id="image-container" v-if="recommendImages[0] !== null && !isMobile()">
  17 + <div class="recommend-left-box">
  18 + <v-img
  19 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/76c987e13a334be481a346c19c2284f3qy4tjnxps7.png"
  20 + alt="往左移"
  21 + class="recommend-img-left"
  22 + @click="toggleRowLeft"
  23 + />
  24 + </div>
  25 + <div class="image-row" id="row1">
  26 + <div
  27 + v-for="(imageObj, index) in recommendImages"
  28 + :key="'row1-' + index"
  29 + class="imageTotal"
  30 + >
  31 + <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank">
  32 + <img
  33 + :src="imageObj[0]?.url"
  34 + :alt="'Image ' + (index + 1)"
  35 + class="item-imgHot"
  36 + />
  37 + <span class="image-name">
  38 + {{ imageObj[0]?.name }}
  39 + </span>
  40 + </a>
  41 + <div v-else style="width: 200px; height: 200px"></div>
  42 + </div>
  43 + </div>
  44 + <div class="recommend-right-box">
  45 + <v-img
  46 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/b5daa0a8f2f140f5b406e984c730a453iznzlekysg.png"
  47 + alt="往右移"
  48 + class="recommend-img-right"
  49 + @click="toggleRowRight"
  50 + />
  51 + </div>
  52 + </div>
  53 + <div style="padding-left: 16px; padding-right: 16px; margin-bottom: 30px">
  54 + <v-tabs
  55 + class="tabs2"
  56 + ref="tabs2"
  57 + v-model="tabRecom"
  58 + style="margin-top: 25px; margin-bottom: 20px"
  59 + color="white"
  60 + bg-color="#eeeeee"
  61 + slider-color="blue-lighten-1"
  62 + selected-class="active"
  63 + v-if="isMobile()"
  64 + >
  65 + <v-tab :value="1">Best Sellers</v-tab>
  66 + </v-tabs>
  67 + <div class="tw-text-center" v-if="hotLoading && isMobile()">
  68 + <v-progress-circular
  69 + color="blue-lighten-2"
  70 + indeterminate
  71 + size="64"
  72 + class="tw-m-auto"
  73 + ></v-progress-circular>
  74 + </div>
  75 + <v-item-group multiple v-if="isMobile()">
  76 + <v-row v-if="!hotLoading">
  77 + <v-col
  78 + v-for="(item, i) in recommendImages"
  79 + :key="i"
  80 + cols="6"
  81 + lg="3"
  82 + md="4"
  83 + sm="6"
  84 + >
  85 + <div v-if="item !== null">
  86 + <v-card :elevation="4" class="mx-auto" :href="item[0].productUrl">
  87 + <v-img
  88 + :src="item[0].url"
  89 + :alt="item[0].name"
  90 + eager
  91 + class="d-block"
  92 + />
  93 + <v-card-text class="tw-text-left font-weight-medium title">
  94 + <h4>{{ item[0].name }}</h4>
  95 + </v-card-text>
  96 + </v-card>
  97 + </div>
  98 + </v-col>
  99 + </v-row>
  100 + </v-item-group>
  101 + <v-row v-if="isMobile()">
  102 + <v-col>
  103 + <v-pagination
  104 + :size="isMobile() ? 'small' : 'default'"
  105 + v-if="hotTotal"
  106 + v-model="currentIndex"
  107 + @update:modelValue="toggleRowMobile"
  108 + :length="hotLength"
  109 + rounded="0"
  110 + class="tw-float-right tw-mt-[32px]"
  111 + total-visible="5"
  112 + ></v-pagination></v-col
  113 + ></v-row>
  114 + </div> -->
2 115 <v-container class="pa-0 pa-sm-4">
3   - <div class="my-8 my-sm-16 text-blue-darken-1 text-h4 tw-text-center" v-if="!isMobile()">
  116 + <div
  117 + class="my-8 my-sm-16 text-blue-darken-1 text-h4 tw-text-center"
  118 + v-if="!isMobile()"
  119 + >
4 120 <strong>Company Profile</strong>
5 121 </div>
6 122  
... ... @@ -9,7 +125,8 @@
9 125 <v-img src="/about_img/1.jpg" alt="canrud"></v-img>
10 126 <div
11 127 class="py-4 tw-bottom-0 tw-absolute tw-w-full text-h5 tw-text-center tw-bg-[rgba(30,136,229,0.8)] tw-text-white"
12   - v-if="isMobile()">
  128 + v-if="isMobile()"
  129 + >
13 130 <strong>Company Profile</strong>
14 131 </div>
15 132 </v-col>
... ... @@ -23,107 +140,195 @@
23 140 </p>
24 141 <p class="text-grey-darken-1">
25 142 <b>4.</b>
26   - (Customized/ equipment / testing / materials / new product development, etc.);
  143 + (Customized/ equipment / testing / materials / new product
  144 + development, etc.);
27 145 </p>
28 146 <p class="text-grey-darken-1">
29 147 <b>5.</b> In 2017, it was approved as a national high-tech enterprise;
30 148 </p>
31   - <p class="text-grey-darken-1"><b>6.</b> 120+ invention patents; 100 + authorized;</p>
32 149 <p class="text-grey-darken-1">
33   - <b>7.</b> The plant area is 6,000 m 2, with 70 employees (the core team is from Ningde
34   - ATL/ Foxconn).
  150 + <b>6.</b> 120+ invention patents; 100 + authorized;
  151 + </p>
  152 + <p class="text-grey-darken-1">
  153 + <b>7.</b> The plant area is 6,000 m 2, with 70 employees (the core
  154 + team is from Ningde ATL/ Foxconn).
35 155 </p>
36 156 </v-col>
37   - <v-col cols="12" class="tw-leading-6 tw-text-white tw-bg-[#1e88e5] px-10 pb-2" v-if="isMobile()">
  157 + <v-col
  158 + cols="12"
  159 + class="tw-leading-6 tw-text-white tw-bg-[#1e88e5] px-10 pb-2"
  160 + v-if="isMobile()"
  161 + >
38 162 <ul>
39   - <li class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc">
  163 + <li
  164 + class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc"
  165 + >
40 166 2015.2.11 was established in Songshan Lake High-tech Zone;
41 167 </li>
42   - <li class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc">
  168 + <li
  169 + class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc"
  170 + >
43 171 Registered capital of 1000W;
44 172 </li>
45   - <li class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc">
  173 + <li
  174 + class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc"
  175 + >
46 176 Main business of new energy technology development
47 177 </li>
48   - <li class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc">
49   - (Customized/ equipment / testing / materials / new product development, etc.);
  178 + <li
  179 + class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc"
  180 + >
  181 + (Customized/ equipment / testing / materials / new product
  182 + development, etc.);
50 183 </li>
51   - <li class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc">
  184 + <li
  185 + class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc"
  186 + >
52 187 In 2017, it was approved as a national high-tech enterprise;
53 188 </li>
54   - <li class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc">
  189 + <li
  190 + class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc"
  191 + >
55 192 120+ invention patents; 100 + authorized;
56 193 </li>
57   - <li class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc">
58   - The plant area is 6,000 m 2, with 70 employees (the core team is from Ningde ATL/
59   - Foxconn).
  194 + <li
  195 + class="mb-1 tw-border-white tw-border-0 tw-border-b-2 tw-border-solid tw-list-disc"
  196 + >
  197 + The plant area is 6,000 m 2, with 70 employees (the core team is
  198 + from Ningde ATL/ Foxconn).
60 199 </li>
61 200 </ul>
62 201 </v-col>
63 202 </v-row>
64   - <iframe width="100%" :height="isMobile() ? 200 : 550"
65   - src="https://www.youtube.com/embed/Wj6bOrbuwWA?si=Za2aq-Ej28xpIFt6" title="YouTube video player" frameborder="0"
  203 + <iframe
  204 + width="100%"
  205 + :height="isMobile() ? 200 : 550"
  206 + src="https://www.youtube.com/embed/Wj6bOrbuwWA?si=Za2aq-Ej28xpIFt6"
  207 + title="YouTube video player"
  208 + frameborder="0"
66 209 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
67   - referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
  210 + referrerpolicy="strict-origin-when-cross-origin"
  211 + allowfullscreen
  212 + ></iframe>
68 213 </v-container>
69 214  
70 215 <v-sheet class="py-8 bg-grey-lighten-5 py-sm-16">
71 216 <v-container>
72   - <div class="mb-8 text-blue-darken-1 tw-text-center text-h5 text-sm-h4 mb-sm-6">
  217 + <div
  218 + class="mb-8 text-blue-darken-1 tw-text-center text-h5 text-sm-h4 mb-sm-6"
  219 + >
73 220 <strong>Corporate Culture</strong>
74 221 </div>
75 222 <v-sheet border rounded v-if="!isMobile()">
76 223 <v-row>
77 224 <v-col>
78   - <div class="tw-my-[32px] tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300">
79   - <div class="mb-4 text-center tw-font-medium tw-text-[32px] tw-flex tw-items-center tw-justify-center">
80   - <img width="36" src="/about_img/2.png" class="mr-4" alt="canrud" />
  225 + <div
  226 + class="tw-my-[32px] tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300"
  227 + >
  228 + <div
  229 + class="mb-4 text-center tw-font-medium tw-text-[32px] tw-flex tw-items-center tw-justify-center"
  230 + >
  231 + <img
  232 + width="36"
  233 + src="/about_img/2.png"
  234 + class="mr-4"
  235 + alt="canrud"
  236 + />
81 237 Vision
82 238 </div>
83 239  
84 240 <v-card-text>
85   - the world's top one-stop serviceprovider in the field of new energy research
  241 + the world's top one-stop serviceprovider in the field of new
  242 + energy research
86 243 </v-card-text>
87 244 </div>
88 245 </v-col>
89 246 <v-col>
90   - <div class="tw-my-[32px] tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300">
91   - <div class="mb-4 text-center tw-font-medium tw-text-[36px] tw-flex tw-items-center tw-justify-center">
92   - <img width="30" src="/about_img/3.png" class="mr-4" alt="canrud" />Mission
  247 + <div
  248 + class="tw-my-[32px] tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300"
  249 + >
  250 + <div
  251 + class="mb-4 text-center tw-font-medium tw-text-[36px] tw-flex tw-items-center tw-justify-center"
  252 + >
  253 + <img
  254 + width="30"
  255 + src="/about_img/3.png"
  256 + class="mr-4"
  257 + alt="canrud"
  258 + />Mission
93 259 </div>
94   - <v-card-text>Build a "industry-university-research" high-speed channel </v-card-text>
  260 + <v-card-text
  261 + >Build a "industry-university-research" high-speed channel
  262 + </v-card-text>
95 263 </div>
96 264 </v-col>
97 265 <v-col>
98 266 <div class="tw-my-[32px]">
99   - <div class="mb-4 text-center tw-font-medium tw-text-[36px] tw-flex tw-items-center tw-justify-center">
100   - <img width="30" src="/about_img/4.png" class="mr-4" alt="canrud" />Values
  267 + <div
  268 + class="mb-4 text-center tw-font-medium tw-text-[36px] tw-flex tw-items-center tw-justify-center"
  269 + >
  270 + <img
  271 + width="30"
  272 + src="/about_img/4.png"
  273 + class="mr-4"
  274 + alt="canrud"
  275 + />Values
101 276 </div>
102   - <v-card-text>Burn yourself and contribute to the society Scientific</v-card-text>
  277 + <v-card-text
  278 + >Burn yourself and contribute to the society
  279 + Scientific</v-card-text
  280 + >
103 281 </div>
104 282 </v-col>
105 283 </v-row>
106 284 </v-sheet>
107 285 <div v-if="isMobile()">
108   - <v-sheet border rounded="lg" class="my-4 tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300">
  286 + <v-sheet
  287 + border
  288 + rounded="lg"
  289 + class="my-4 tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300"
  290 + >
109 291 <v-row
110   - class="py-2 ma-0 pr-2 tw-bg-[linear-gradient(rgba(215,237,254,0.88),rgba(215,237,254,0.36))] tw-rounded-[8px]">
111   - <v-col cols="3" class="text-center tw-flex tw-items-center tw-justify-center tw-box-border">
112   - <img width="48" src="/about_img/2.png" class="tw-m-auto" alt="canrud" />
  292 + class="py-2 ma-0 pr-2 tw-bg-[linear-gradient(rgba(215,237,254,0.88),rgba(215,237,254,0.36))] tw-rounded-[8px]"
  293 + >
  294 + <v-col
  295 + cols="3"
  296 + class="text-center tw-flex tw-items-center tw-justify-center tw-box-border"
  297 + >
  298 + <img
  299 + width="48"
  300 + src="/about_img/2.png"
  301 + class="tw-m-auto"
  302 + alt="canrud"
  303 + />
113 304 </v-col>
114 305 <v-col cols="9">
115 306 <div class="font-weight-bold tw-text-[32px] text-h5">Vision</div>
116 307 <div class="font-weight-bold text-body-1">
117   - the world's top one-stop serviceprovider in the field of new energy research
  308 + the world's top one-stop serviceprovider in the field of new
  309 + energy research
118 310 </div>
119 311 </v-col>
120 312 </v-row>
121 313 </v-sheet>
122   - <v-sheet border rounded="lg" class="my-4 tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300">
  314 + <v-sheet
  315 + border
  316 + rounded="lg"
  317 + class="my-4 tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300"
  318 + >
123 319 <v-row
124   - class="ma-0 py-2 pr-2 tw-bg-[linear-gradient(rgba(203,220,254,0.88),rgba(203,220,254,0.36))] tw-rounded-[8px]">
125   - <v-col cols="3" class="text-center tw-flex tw-items-center tw-justify-center tw-box-border">
126   - <img width="48" src="/about_img/3.png" class="tw-m-auto" alt="canrud" />
  320 + class="ma-0 py-2 pr-2 tw-bg-[linear-gradient(rgba(203,220,254,0.88),rgba(203,220,254,0.36))] tw-rounded-[8px]"
  321 + >
  322 + <v-col
  323 + cols="3"
  324 + class="text-center tw-flex tw-items-center tw-justify-center tw-box-border"
  325 + >
  326 + <img
  327 + width="48"
  328 + src="/about_img/3.png"
  329 + class="tw-m-auto"
  330 + alt="canrud"
  331 + />
127 332 </v-col>
128 333 <v-col cols="9 tw-h-[120px]">
129 334 <div class="font-weight-bold tw-text-[32px] text-h5">Mission</div>
... ... @@ -133,11 +338,24 @@
133 338 </v-col>
134 339 </v-row>
135 340 </v-sheet>
136   - <v-sheet border rounded="lg" class="my-4 tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300">
  341 + <v-sheet
  342 + border
  343 + rounded="lg"
  344 + class="my-4 tw-border-0 tw-border-solid tw-border-r-[1px] tw-border-e-blue-300"
  345 + >
137 346 <v-row
138   - class="py-2 ma-0 tw-bg-[linear-gradient(rgba(212,246,255,0.88),rgba(212,246,255,0.36))] tw-rounded-[8px]">
139   - <v-col cols="3" class="text-center tw-flex tw-items-center tw-justify-center tw-box-border">
140   - <img width="48" src="/about_img/4.png" class="tw-m-auto" alt="canrud" />
  347 + class="py-2 ma-0 tw-bg-[linear-gradient(rgba(212,246,255,0.88),rgba(212,246,255,0.36))] tw-rounded-[8px]"
  348 + >
  349 + <v-col
  350 + cols="3"
  351 + class="text-center tw-flex tw-items-center tw-justify-center tw-box-border"
  352 + >
  353 + <img
  354 + width="48"
  355 + src="/about_img/4.png"
  356 + class="tw-m-auto"
  357 + alt="canrud"
  358 + />
141 359 </v-col>
142 360 <v-col cols="9 tw-h-[120px]">
143 361 <div class="font-weight-bold tw-text-[32px] text-h5">Values</div>
... ... @@ -150,30 +368,46 @@
150 368 </div>
151 369 </v-container>
152 370 </v-sheet>
153   - <v-sheet class="py-8 py-sm-16" :style="isMobile()
154   - ? 'background: url(/mobile/about-bg.png) no-repeat; background-size: 100% 100%'
155   - : 'background: url(/about_img/bg.png) no-repeat; background-size: 100% 100%'
156   - ">
  371 + <v-sheet
  372 + class="py-8 py-sm-16"
  373 + :style="
  374 + isMobile()
  375 + ? 'background: url(/mobile/about-bg.png) no-repeat; background-size: 100% 100%'
  376 + : 'background: url(/about_img/bg.png) no-repeat; background-size: 100% 100%'
  377 + "
  378 + >
157 379 <v-container>
158   - <div class="mb-8 text-blue-darken-1 tw-text-center text-h5 text-sm-h4 mb-sm-6">
  380 + <div
  381 + class="mb-8 text-blue-darken-1 tw-text-center text-h5 text-sm-h4 mb-sm-6"
  382 + >
159 383 <strong>Milestone</strong>
160 384 </div>
161 385 <v-timeline :direction="isMobile() ? 'vertical' : 'horizontal'">
162 386 <v-timeline-item dot-color="indigo-lighten-1" size="16" fill-dot>
163 387 <template v-slot:opposite>
164   - <strong class="text-blue-darken-1 tw-text-[22px]">2015</strong></template>
  388 + <strong class="text-blue-darken-1 tw-text-[22px]"
  389 + >2015</strong
  390 + ></template
  391 + >
165 392 <p class="tw-text-[14px]">
166   - <strong>Canrd <br />
167   - established</strong>
  393 + <strong
  394 + >Canrd <br />
  395 + established</strong
  396 + >
168 397 </p>
169 398 </v-timeline-item>
170 399 <v-timeline-item dot-color="blue-darken-1" fill-dot size="32">
171 400 <template v-slot:opposite>
172   - <strong class="text-blue-darken-1 tw-text-[22px]">2017</strong></template>
  401 + <strong class="text-blue-darken-1 tw-text-[22px]"
  402 + >2017</strong
  403 + ></template
  404 + >
173 405 <div>
174 406 <p>
175   - <strong class="tw-text-[14px]">National high-tech <br />
176   - enterprise</strong>
  407 + <strong class="tw-text-[14px]"
  408 + >National high-tech <br />
  409 + enterprise</strong
  410 + >
177 411 </p>
178 412 </div>
179 413 </v-timeline-item>
... ... @@ -188,7 +422,9 @@
188 422 </v-timeline-item>
189 423 <v-timeline-item dot-color="blue-darken-1" fill-dot size="32">
190 424 <template v-slot:opposite>
191   - <strong class="text-blue-darken-1 tw-text-[22px]" fill-dot>2020</strong>
  425 + <strong class="text-blue-darken-1 tw-text-[22px]" fill-dot
  426 + >2020</strong
  427 + >
192 428 </template>
193 429  
194 430 <div class="tw-text-[14px]">
... ... @@ -206,7 +442,10 @@
206 442 </v-timeline-item>
207 443 <v-timeline-item dot-color="blue-darken-1" fill-dot size="32">
208 444 <template v-slot:opposite>
209   - <strong class="text-blue-darken-1 tw-text-[22px]">2022</strong></template>
  445 + <strong class="text-blue-darken-1 tw-text-[22px]"
  446 + >2022</strong
  447 + ></template
  448 + >
210 449  
211 450 <div class="tw-text-[14px]">
212 451 <p><strong>R&D center(Houjie)</strong></p>
... ... @@ -218,34 +457,50 @@
218 457 </v-sheet>
219 458 <v-sheet class="bg-grey-lighten-6 pt-8 pt-sm-16 tw-pb-[128px]">
220 459 <v-container>
221   - <div class="mb-8 text-blue-darken-1 tw-text-center text-h5 text-sm-h4 mb-sm-6">
  460 + <div
  461 + class="mb-8 text-blue-darken-1 tw-text-center text-h5 text-sm-h4 mb-sm-6"
  462 + >
222 463 <strong>R&D Ability</strong>
223 464 </div>
224   - <div class="text-body-1 font-weight-medium tw-mb-[24px] tw-max-w-[600px] tw-m-auto text-grey-darken-1">
225   - The combination of hardware and software creates strong research and development
226   - capabilities.
  465 + <div
  466 + class="text-body-1 font-weight-medium tw-mb-[24px] tw-max-w-[600px] tw-m-auto text-grey-darken-1"
  467 + >
  468 + The combination of hardware and software creates strong research and
  469 + development capabilities.
227 470 </div>
228   - <div class="text-body-1 font-weight-medium tw-mb-[64px] tw-max-w-[600px] tw-m-auto text-grey-darken-1">
229   - The invention patents cover new materials such as silicon carbon, graphene, lithium sulfur,
230   - sodium electricity and lithium metal, as well as gel process, pre-lithium process and
231   - flexible battery design."
  471 + <div
  472 + class="text-body-1 font-weight-medium tw-mb-[64px] tw-max-w-[600px] tw-m-auto text-grey-darken-1"
  473 + >
  474 + The invention patents cover new materials such as silicon carbon,
  475 + graphene, lithium sulfur, sodium electricity and lithium metal, as well
  476 + as gel process, pre-lithium process and flexible battery design."
232 477 </div>
233 478 <v-row>
234 479 <v-col cols="12" sm="4">
235 480 <v-card variant="outlined" color="blue-darken-1" v-if="!isMobile()">
236 481 <v-img src="/about_img/5.png" alt="canrud"></v-img>
237 482 <v-card-title class="text-grey-darken-4">Team</v-card-title>
238   - <v-card-text class="text-grey-darken-4">Core team members are all from ATL/Foxconn 12+working experience
  483 + <v-card-text class="text-grey-darken-4"
  484 + >Core team members are all from ATL/Foxconn 12+working experience
239 485 </v-card-text>
240 486 </v-card>
241 487 <v-sheet v-if="isMobile()" rounded="lg">
242 488 <v-row class="ma-0">
243 489 <v-col cols="5" sm="12" class="pa-0 tw-rounded-l-lg">
244   - <img src="/about_img/5.png" alt="canrud" class="tw-w-full tw-h-full tw-rounded-l-lg" />
  490 + <img
  491 + src="/about_img/5.png"
  492 + alt="canrud"
  493 + class="tw-w-full tw-h-full tw-rounded-l-lg"
  494 + />
245 495 </v-col>
246   - <v-col cols="7" class="pa-0 tw-bg-[#1e88e5] tw-rounded-r-lg text-white">
  496 + <v-col
  497 + cols="7"
  498 + class="pa-0 tw-bg-[#1e88e5] tw-rounded-r-lg text-white"
  499 + >
247 500 <v-card-title class="">Team</v-card-title>
248   - <v-card-text>Core team members are all from ATL/Foxconn 12+working experience
  501 + <v-card-text
  502 + >Core team members are all from ATL/Foxconn 12+working
  503 + experience
249 504 </v-card-text>
250 505 </v-col>
251 506 </v-row>
... ... @@ -256,21 +511,28 @@
256 511 <v-img src="/about_img/6.png" alt="canrud"></v-img>
257 512 <v-card-title class="text-grey-darken-4">Patents</v-card-title>
258 513 <v-card-text class="text-grey-darken-4">
259   - More than 120 invention patents, covering materials, design, process, equipment and so
260   - on
  514 + More than 120 invention patents, covering materials, design,
  515 + process, equipment and so on
261 516 </v-card-text>
262 517 </v-card>
263 518 <v-sheet v-if="isMobile()" rounded="lg">
264 519 <v-row class="ma-0">
265   - <v-col cols="7" class="pa-0 tw-bg-[#1e88e5] tw-rounded-l-lg text-white">
  520 + <v-col
  521 + cols="7"
  522 + class="pa-0 tw-bg-[#1e88e5] tw-rounded-l-lg text-white"
  523 + >
266 524 <v-card-title>Patents</v-card-title>
267 525 <v-card-text>
268   - More than 120 invention patents, covering materials, design, process, equipment
269   - and so on
  526 + More than 120 invention patents, covering materials, design,
  527 + process, equipment and so on
270 528 </v-card-text>
271 529 </v-col>
272 530 <v-col cols="5" sm="12" class="pa-0 tw-rounded-r-lg">
273   - <img src="/about_img/6.png" alt="canrud" class="tw-w-full tw-h-full tw-rounded-r-lg" />
  531 + <img
  532 + src="/about_img/6.png"
  533 + alt="canrud"
  534 + class="tw-w-full tw-h-full tw-rounded-r-lg"
  535 + />
274 536 </v-col>
275 537 </v-row>
276 538 </v-sheet>
... ... @@ -280,19 +542,29 @@
280 542 <v-img src="/about_img/7.png" alt="canrud"></v-img>
281 543 <v-card-title class="text-grey-darken-4">Hardware</v-card-title>
282 544 <v-card-text class="text-grey-darken-4">
283   - <row>Independent battery pilot line and equipment production line</row>
  545 + <row
  546 + >Independent battery pilot line and equipment production
  547 + line</row
  548 + >
284 549 </v-card-text>
285 550 </v-card>
286 551 <v-sheet v-if="isMobile()" rounded="lg">
287 552 <v-row class="ma-0">
288   - <v-col cols="7" class="pa-0 tw-bg-[#1e88e5] tw-rounded-l-lg text-white">
  553 + <v-col
  554 + cols="7"
  555 + class="pa-0 tw-bg-[#1e88e5] tw-rounded-l-lg text-white"
  556 + >
289 557 <v-card-title>Hardware</v-card-title>
290 558 <div class="px-4 text-body-1 text-bold">
291 559 Independent battery pilot line and equipment production line
292 560 </div>
293 561 </v-col>
294 562 <v-col cols="5" sm="12" class="pa-0 tw-rounded-r-lg">
295   - <img src="/about_img/7.png" alt="canrud" class="tw-w-full tw-h-full tw-rounded-r-lg" />
  563 + <img
  564 + src="/about_img/7.png"
  565 + alt="canrud"
  566 + class="tw-w-full tw-h-full tw-rounded-r-lg"
  567 + />
296 568 </v-col>
297 569 </v-row>
298 570 </v-sheet>
... ... @@ -303,27 +575,141 @@
303 575 </template>
304 576  
305 577 <script setup lang="ts">
306   -import MainTitle from '../components/MainTitle.vue'
307   -import { isMobile } from '../utils'
  578 +import MainTitle from "../components/MainTitle.vue";
  579 +import HotProducts from "../components/HotProducts.vue";
  580 +import { isMobile } from "../utils";
  581 +
  582 +const productStore = useProductListStore();
  583 +const categoryStore = useCategoryStore();
  584 +const loading = ref(false);
  585 +const hotLoading = ref(false);
  586 +const route = useRoute(); // 获取路由信息
  587 +const router = useRouter(); // 获取路由信息
  588 +const title = ref("");
  589 +const keywordTitle = ref("");
  590 +const maxPage = ref(1);
  591 +const tabRecom = ref();
  592 +const recommendList = ref();
  593 +const recommendImages = ref();
  594 +const currentIndex = ref(1);
  595 +const hotTotal = ref(10);
  596 +const isOrNotMobile = isMobile();
  597 +
  598 +// const loadHotProducts = async () => {
  599 +// const pageSize = ref(5);
  600 +// if (isOrNotMobile) {
  601 +// pageSize.value = 4;
  602 +// }
  603 +// hotLoading.value = true;
  604 +// let { data: hotProducts } = await useAsyncData(
  605 +// "hotProducts",
  606 +// () =>
  607 +// $fetch("/shop/product/hotProducts", {
  608 +// method: "GET",
  609 +// params: {
  610 +// pageNo: currentIndex.value,
  611 +// pageSize: pageSize.value,
  612 +// },
  613 +// }),
  614 +// {
  615 +// server: true, // 仅在服务器端获取数据
  616 +// }
  617 +// );
  618 +// hotTotal.value = hotProducts.value.data.total;
  619 +// recommendList.value = hotProducts.value.data.records;
  620 +// maxPage.value = hotProducts.value.data.pages;
  621 +// // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  622 +// recommendImages.value = Array.from({ length: pageSize.value }).map(
  623 +// (_, index) => {
  624 +// const item = recommendList.value[index];
  625 +// if (!item) {
  626 +// return null;
  627 +// }
  628 +// // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  629 +// if (typeof item.productimageliststore === "string") {
  630 +// try {
  631 +// item.productimageliststore = JSON.parse(item.productimageliststore);
  632 +// } catch (error) {
  633 +// item.productimageliststore = []; // 解析失败时,设置为空数组
  634 +// }
  635 +// }
  636 +// const ree = (item.productimageliststore = item?.productimageliststore.map(
  637 +// (productItem: ProductImage) => ({
  638 +// ...productItem,
  639 +// // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  640 +// url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  641 +// name: item.name,
  642 +// productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  643 +// })
  644 +// ));
  645 +// return ree;
  646 +// }
  647 +// );
  648 +// hotLoading.value = false;
  649 +// };
  650 +
  651 +// let intervalId: any;
  652 +// const toggleRowLeft = () => {
  653 +// if (currentIndex.value !== 1) {
  654 +// currentIndex.value--;
  655 +// } else if (currentIndex.value == 1) {
  656 +// currentIndex.value = maxPage.value;
  657 +// }
  658 +// startTimer();
  659 +// };
  660 +// const toggleRowRight = () => {
  661 +// if (currentIndex.value < maxPage.value) {
  662 +// currentIndex.value++;
  663 +// } else if (currentIndex.value == maxPage.value) {
  664 +// currentIndex.value = 1;
  665 +// }
  666 +// startTimer();
  667 +// };
  668 +// const startTimer = () => {
  669 +// // 清除已有计时器,防止重复
  670 +// clearInterval(intervalId);
  671 +// intervalId = setInterval(() => {
  672 +// toggleRowRight();
  673 +// }, 5000); // 每6秒调用一次
  674 +// };
  675 +
  676 +// onMounted(() => {
  677 +// startTimer();
  678 +// });
  679 +// const toggleRowMobile = (value: number) => {
  680 +// currentIndex.value = value;
  681 +// };
  682 +
  683 +// const hotLength = computed(() =>
  684 +// hotTotal.value ? Math.ceil(hotTotal.value / 4) : 0
  685 +// );
  686 +
  687 +// watch(currentIndex, (newIndex) => {
  688 +// loadHotProducts(); // Call loadHotProducts when currentIndex changes
  689 +// });
  690 +// // Initial load of hot products
  691 +// await loadHotProducts(); // Load hot products the first time
308 692  
309 693 useHead({
310   - title: 'About Us',
  694 + title: "About Us",
311 695 meta: [
312 696 {
313   - name: 'title',
314   - content: '科路得,canrd,canrud,New energy technology development,National high-tech enterprise,Battery pilot line,Lab Device',
315   - }, {
316   - name: 'keywords',
  697 + name: "title",
317 698 content:
318   - '科路得,canrd,canrud,New energy technology development,National high-tech enterprise,Battery pilot line,Lab Device',
319   - }, {
320   - name: 'description',
  699 + "科路得,canrd,canrud,New energy technology development,National high-tech enterprise,Battery pilot line,Lab Device",
  700 + },
  701 + {
  702 + name: "keywords",
321 703 content:
322   - '科路得,助您科研之路势在必得。Canrd aims to be the world‘s leading one-stop service provider in new energy research. With a dedication to excellence, we offer Material Reagents, Lab Devices, Customized Batteries, Testing, and Advanced Packaging for energy materials and storage systems. We master advanced technologies to provide high-quality solutions.',
  704 + "科路得,canrd,canrud,New energy technology development,National high-tech enterprise,Battery pilot line,Lab Device",
  705 + },
  706 + {
  707 + name: "description",
  708 + content:
  709 + "科路得,助您科研之路势在必得。Canrd aims to be the world‘s leading one-stop service provider in new energy research. With a dedication to excellence, we offer Material Reagents, Lab Devices, Customized Batteries, Testing, and Advanced Packaging for energy materials and storage systems. We master advanced technologies to provide high-quality solutions.",
323 710 },
324 711 ],
325   -})
326   -
  712 +});
327 713 </script>
328 714  
329 715 <style lang="scss" scoped>
... ... @@ -342,4 +728,200 @@ p {
342 728 cursor: default;
343 729 font-weight: bold;
344 730 }
  731 +
  732 +@media screen and (min-width: 1537px) {
  733 + .tabs {
  734 + border-bottom: 2px solid #1f88e5;
  735 + margin: 10px auto 20px;
  736 + width: 93%;
  737 + }
  738 +}
  739 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  740 + .tabs {
  741 + border-bottom: 2px solid #1f88e5;
  742 + margin: 10px auto 40px;
  743 + width: 78%;
  744 + }
  745 +}
  746 +@media screen and (max-width: 1280px) {
  747 + .tabs {
  748 + border-bottom: 2px solid #1f88e5;
  749 + margin: 10px auto 40px;
  750 + width: 92%;
  751 + }
  752 +}
  753 +/* .tabs {
  754 + border-bottom: 2px solid #1f88e5;
  755 +} */
  756 +
  757 +.active {
  758 + background-color: #1086e8;
  759 +}
  760 +
  761 +@media screen and (min-width: 1537px) {
  762 + #image-container {
  763 + display: flex;
  764 + align-items: center;
  765 + justify-content: center;
  766 + height: 320px;
  767 + margin: 10px auto 50px;
  768 + width: 80%;
  769 + }
  770 +}
  771 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  772 + #image-container {
  773 + display: flex;
  774 + align-items: center;
  775 + justify-content: center;
  776 + height: 260px;
  777 + margin: 10px auto 0px;
  778 + width: 80%;
  779 + padding: 0;
  780 + }
  781 +}
  782 +@media screen and (max-width: 1280px) {
  783 + #image-container {
  784 + display: flex;
  785 + align-items: center;
  786 + justify-content: center;
  787 + height: 260px;
  788 + margin: 10px auto 0px;
  789 + width: 80%;
  790 + padding: 0;
  791 + }
  792 +}
  793 +.image-row {
  794 + display: flex;
  795 + height: 245px;
  796 +}
  797 +@media screen and (min-width: 1537px) {
  798 + .imageTotal {
  799 + display: inline-block;
  800 + margin: 0 5px;
  801 + text-align: center;
  802 + width: 300px;
  803 + }
  804 +}
  805 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  806 + .imageTotal {
  807 + display: inline-block;
  808 + margin: 0 5px;
  809 + text-align: center;
  810 + width: 200px;
  811 + }
  812 +}
  813 +@media screen and (max-width: 1280px) {
  814 + .imageTotal {
  815 + display: inline-block;
  816 + margin: 0 5px;
  817 + text-align: center;
  818 + width: 200px;
  819 + }
  820 +}
  821 +@media screen and (min-width: 1537px) {
  822 + .image-row img {
  823 + width: 240px;
  824 + height: 240px;
  825 + }
  826 +}
  827 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  828 + .image-row img {
  829 + width: 140px;
  830 + height: 140px;
  831 + }
  832 +}
  833 +@media screen and (max-width: 1280px) {
  834 + .image-row img {
  835 + width: 120px;
  836 + height: 120px;
  837 + }
  838 +}
  839 +@media screen and (min-width: 1537px) {
  840 + .image-name {
  841 + display: -webkit-box; /* Enables multi-line text handling */
  842 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  843 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  844 + overflow: hidden; /* Hides the overflowed text */
  845 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  846 + margin-top: 5px;
  847 + font-size: 16px;
  848 + width: 180px;
  849 + color: #555;
  850 + text-align: center; /* Centers the text horizontally */
  851 + margin-left: 50px;
  852 + }
  853 +}
  854 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  855 + .image-name {
  856 + display: -webkit-box; /* Enables multi-line text handling */
  857 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  858 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  859 + overflow: hidden; /* Hides the overflowed text */
  860 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  861 + margin-top: 5px;
  862 + font-size: 16px;
  863 + width: 180px;
  864 + color: #555;
  865 + text-align: center; /* Centers the text horizontally */
  866 + margin-left: 10px;
  867 + }
  868 +}
  869 +@media screen and (max-width: 1280px) {
  870 + .image-name {
  871 + display: -webkit-box; /* Enables multi-line text handling */
  872 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  873 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  874 + overflow: hidden; /* Hides the overflowed text */
  875 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  876 + margin-top: 5px;
  877 + font-size: 16px;
  878 + width: 180px;
  879 + color: #555;
  880 + text-align: center; /* Centers the text horizontally */
  881 + margin-left: 10px;
  882 + }
  883 +}
  884 +
  885 +button .recommendButton {
  886 + margin: 0 0px;
  887 + cursor: pointer;
  888 +}
  889 +
  890 +.recommend-left-box {
  891 +}
  892 +
  893 +@media screen and (max-width: 1280px) {
  894 + .recommend-img-left {
  895 + width: 26px;
  896 + height: 27px;
  897 + margin-bottom: 60px;
  898 + }
  899 +}
  900 +.recommend-img-left {
  901 + width: 26px;
  902 + height: 27px;
  903 + margin-right: 30px;
  904 + margin-bottom: 60px;
  905 +}
  906 +
  907 +.recommend-img-left:hover {
  908 + cursor: pointer;
  909 +}
  910 +.recommend-right-box {
  911 +}
  912 +
  913 +.recommend-img-right {
  914 + width: 26px;
  915 + height: 27px;
  916 + margin-left: 30px;
  917 + margin-bottom: 60px;
  918 +}
  919 +
  920 +.recommend-img-right:hover {
  921 + cursor: pointer;
  922 +}
  923 +
  924 +.v-card {
  925 + transition: all 0.3s ease-in-out;
  926 +}
345 927 </style>
... ...
pages/contact.vue
1 1 <template>
2   - <div class="tw-text-center tw-text-4xl tw-mb-[32px] tw-mt-[30px]">Contact Us</div>
  2 + <div class="tw-text-center tw-text-4xl tw-mb-[32px] tw-mt-[30px]">
  3 + Contact Us
  4 + </div>
3 5 <v-card class="pa-10 tw-max-w-[800px] tw-m-auto">
4 6 <h3 class="text-h5 tw-mb-5">Official Web</h3>
5 7 <div class="tw-mb-10">
... ... @@ -12,27 +14,538 @@
12 14 <span>3632191327</span>
13 15 </div> -->
14 16 <div>
15   - <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block">Phone</label>
  17 + <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block"
  18 + >Phone</label
  19 + >
16 20 <span>+86 19867737979</span>
17 21 </div>
18 22 <div>
19   - <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block">Email</label>
  23 + <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block"
  24 + >Email</label
  25 + >
20 26 <span>contact@canrd.com</span>
21 27 </div>
22 28 <div class="tw-mb-1">
23   - <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block">Wechat</label>
  29 + <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block"
  30 + >Wechat</label
  31 + >
24 32 <span>contactcanrd</span>
25 33 </div>
26 34 <div class="tw-w-[300px]">
27 35 <v-img src="/wechat.jpg" alt="canrud-wechat"></v-img>
28 36 </div>
  37 + <div style="margin-bottom: 10px">
  38 + <v-tabs
  39 + class="tabs2"
  40 + ref="tabs2"
  41 + v-model="tabRecom"
  42 + style="margin-top: 25px; margin-bottom: 20px"
  43 + color="white"
  44 + bg-color="#eeeeee"
  45 + slider-color="blue-lighten-1"
  46 + selected-class="active"
  47 + v-if="isMobile()"
  48 + >
  49 + <v-tab :value="1">Best Sellers</v-tab>
  50 + <!-- <v-tab :value="3">商品百科</v-tab> -->
  51 + </v-tabs>
  52 + <div class="tw-text-center" v-if="hotLoadingMobile && isMobile()">
  53 + <v-progress-circular
  54 + color="blue-lighten-2"
  55 + indeterminate
  56 + size="64"
  57 + class="tw-m-auto"
  58 + ></v-progress-circular>
  59 + </div>
  60 + <v-item-group multiple v-if="isMobile()">
  61 + <v-row v-if="!hotLoadingMobile">
  62 + <v-col
  63 + v-for="(item, i) in recommendImagesMobile"
  64 + :key="i"
  65 + cols="6"
  66 + lg="3"
  67 + md="4"
  68 + sm="6"
  69 + >
  70 + <div v-if="item !== null">
  71 + <v-card :elevation="4" class="mx-auto" :href="item[0].productUrl">
  72 + <!-- 设置 eager 属性,确保图片直接加载 -->
  73 + <v-img
  74 + :src="item[0].url"
  75 + :alt="item[0].name"
  76 + eager
  77 + class="d-block"
  78 + />
  79 + <v-card-text class="tw-text-left font-weight-medium title">
  80 + <h4 class="clamp-text">{{ item[0].name }}</h4>
  81 + </v-card-text>
  82 + </v-card>
  83 + </div>
  84 + </v-col>
  85 + </v-row>
  86 + <!-- <div
  87 + v-if="!hotTotal"
  88 + class="text-medium-emphasis text-body-1 tw-text-center tw-m-[64px]"
  89 + >
  90 + no data
  91 + </div> -->
  92 + </v-item-group>
  93 + <v-row v-if="isMobile()">
  94 + <v-col>
  95 + <v-pagination
  96 + :size="isMobile() ? 'small' : 'default'"
  97 + v-if="hotTotalMobile"
  98 + v-model="currentIndexMobile"
  99 + @update:modelValue="toggleRowMobile"
  100 + :length="hotLength"
  101 + rounded="0"
  102 + class="tw-float-right tw-mt-[32px]"
  103 + total-visible="5"
  104 + ></v-pagination></v-col
  105 + ></v-row>
  106 + </div>
29 107 </v-card>
  108 + <v-tabs
  109 + class="tabs"
  110 + v-model="tabRecom"
  111 + style="margin-top: 25px"
  112 + color="white"
  113 + bg-color="#eeeeee"
  114 + slider-color="blue-lighten-1"
  115 + selected-class="active"
  116 + v-if="recommendImages[0] !== null && !isMobile()"
  117 + >
  118 + <v-tab :value="1">Best Sellers</v-tab>
  119 + <!-- <v-tab :value="3">商品百科</v-tab> -->
  120 + </v-tabs>
  121 + <div id="image-container" v-if="recommendImages[0] !== null && !isMobile()">
  122 + <div class="recommend-left-box">
  123 + <v-img
  124 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/76c987e13a334be481a346c19c2284f3qy4tjnxps7.png"
  125 + alt="往左移"
  126 + class="recommend-img-left"
  127 + @click="toggleRowLeft"
  128 + />
  129 + </div>
  130 + <div class="image-row" id="row1">
  131 + <!-- <img
  132 + v-for="(imageObj, index) in recommendImages.slice(0, 5)"
  133 + :key="'row1-' + index"
  134 + :src="imageObj[0]?.url"
  135 + :alt="'Image ' + (index + 1)"
  136 + style="margin: 0 5px; width: 200px; height: 200px"
  137 + /> -->
  138 + <div
  139 + v-for="(imageObj, index) in recommendImages"
  140 + :key="'row1-' + index"
  141 + class="imageTotal"
  142 + >
  143 + <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank">
  144 + <img
  145 + :src="imageObj[0]?.url"
  146 + :alt="'Image ' + (index + 1)"
  147 + class="item-imgHot"
  148 + />
  149 + <span class="image-name">
  150 + {{ imageObj[0]?.name }}
  151 + </span>
  152 + </a>
  153 + <div v-else style="width: 200px; height: 200px"></div>
  154 + </div>
  155 + </div>
  156 + <div class="recommend-right-box">
  157 + <v-img
  158 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/b5daa0a8f2f140f5b406e984c730a453iznzlekysg.png"
  159 + alt="往右移"
  160 + class="recommend-img-right"
  161 + @click="toggleRowRight"
  162 + />
  163 + </div>
  164 + </div>
30 165 </template>
31 166  
32 167 <script setup lang="ts">
  168 +const productStore = useProductListStore();
  169 +const categoryStore = useCategoryStore();
  170 +const loading = ref(false);
  171 +const hotLoading = ref(false);
  172 +const route = useRoute(); // 获取路由信息
  173 +const router = useRouter(); // 获取路由信息
  174 +const title = ref("");
  175 +const keywordTitle = ref("");
  176 +const maxPage = ref(1);
  177 +const maxPageMobile = ref(1);
  178 +const tabRecom = ref();
  179 +const recommendList = ref({});
  180 +const recommendImages = ref({});
  181 +const currentIndex = ref(1);
  182 +const hotTotal = ref(10);
  183 +const isOrNotMobile = isMobile();
  184 +const recommendListMobile = ref({});
  185 +const recommendImagesMobile = ref({});
  186 +const currentIndexMobile = ref(1);
  187 +const hotLoadingMobile = ref(false);
  188 +const hotTotalMobile = ref(10);
  189 +const loadHotProducts = async () => {
  190 + hotLoading.value = true;
  191 + let { data: hotProducts } = await useAsyncData(
  192 + "hotProducts",
  193 + () =>
  194 + $fetch("/shop/product/hotProducts", {
  195 + method: "GET",
  196 + params: {
  197 + pageNo: currentIndex.value,
  198 + pageSize: 5,
  199 + },
  200 + }),
  201 + {
  202 + server: true, // 仅在服务器端获取数据
  203 + }
  204 + );
  205 + hotTotal.value = hotProducts.value.data.total;
  206 + recommendList.value = hotProducts.value.data.records;
  207 + maxPage.value = hotProducts.value.data.pages;
  208 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  209 + recommendImages.value = Array.from({ length: 5 }).map((_, index) => {
  210 + const item = recommendList.value[index];
  211 + if (!item) {
  212 + return null;
  213 + }
  214 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  215 + if (typeof item.productimageliststore === "string") {
  216 + try {
  217 + item.productimageliststore = JSON.parse(item.productimageliststore);
  218 + } catch (error) {
  219 + item.productimageliststore = []; // 解析失败时,设置为空数组
  220 + }
  221 + }
  222 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  223 + (productItem: ProductImage) => ({
  224 + ...productItem,
  225 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  226 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  227 + name: item.name,
  228 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  229 + })
  230 + ));
  231 + return ree;
  232 + });
  233 + hotLoading.value = false;
  234 +};
  235 +
  236 +const toggleRowLeft = () => {
  237 + if (currentIndex.value !== 1) {
  238 + currentIndex.value--;
  239 + } else if (currentIndex.value == 1) {
  240 + currentIndex.value = maxPage.value;
  241 + }
  242 + startTimer();
  243 +};
  244 +let intervalId: any;
  245 +const toggleRowRight = () => {
  246 + if (currentIndex.value < maxPage.value) {
  247 + currentIndex.value++;
  248 + } else if (currentIndex.value == maxPage.value) {
  249 + currentIndex.value = 1;
  250 + }
  251 + startTimer();
  252 +};
  253 +const startTimer = () => {
  254 + // 清除已有计时器,防止重复
  255 + clearInterval(intervalId);
  256 + intervalId = setInterval(() => {
  257 + toggleRowRight();
  258 + }, 5000); // 每6秒调用一次
  259 +};
  260 +
  261 +onMounted(() => {
  262 + startTimer();
  263 +});
  264 +
  265 +const toggleRowMobile = (value: number) => {
  266 + currentIndexMobile.value = value;
  267 +};
  268 +const { width } = useDisplay();
  269 +const firstIndex = ref(true);
  270 +
  271 +watch(currentIndex, (newIndex) => {
  272 + loadHotProducts(); // Call loadHotProducts when currentIndex changes
  273 +});
  274 +
  275 +const loadHotProductsMobile = async () => {
  276 + hotLoadingMobile.value = true;
  277 + let { data: hotProductsMobile } = await useAsyncData(
  278 + "hotProducts",
  279 + () =>
  280 + $fetch("/shop/product/hotProducts", {
  281 + method: "GET",
  282 + params: {
  283 + pageNo: currentIndexMobile.value,
  284 + pageSize: 4,
  285 + },
  286 + }),
  287 + {
  288 + server: true, // 仅在服务器端获取数据
  289 + }
  290 + );
  291 + hotTotalMobile.value = hotProductsMobile.value.data.total;
  292 + recommendListMobile.value = hotProductsMobile.value.data.records;
  293 + maxPageMobile.value = hotProductsMobile.value.data.pages;
  294 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  295 + recommendImagesMobile.value = Array.from({ length: 4 }).map((_, index) => {
  296 + const item = recommendListMobile.value[index];
  297 + if (!item) {
  298 + return null;
  299 + }
  300 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  301 + if (typeof item.productimageliststore === "string") {
  302 + try {
  303 + item.productimageliststore = JSON.parse(item.productimageliststore);
  304 + } catch (error) {
  305 + item.productimageliststore = []; // 解析失败时,设置为空数组
  306 + }
  307 + }
  308 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  309 + (productItem: ProductImage) => ({
  310 + ...productItem,
  311 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  312 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  313 + name: item.name,
  314 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  315 + })
  316 + ));
  317 + return ree;
  318 + });
  319 + hotLoadingMobile.value = false;
  320 +};
  321 +watch(currentIndexMobile, (newIndex) => {
  322 + loadHotProductsMobile(); // Call loadHotProducts when currentIndex changes
  323 +});
  324 +// Initial load of hot products
  325 +watchEffect(async () => {
  326 + console.log("Current route:", route.fullPath, "Width:", width.value);
  327 +
  328 + if (firstIndex.value) {
  329 + if (width.value > 600) {
  330 + await loadHotProducts();
  331 + } else {
  332 + await loadHotProductsMobile();
  333 + }
  334 + }
  335 +});
33 336 useHead({
34   - title: 'Contact',
  337 + title: "Contact",
  338 +});
  339 +const hotLength = computed(() =>
  340 + hotTotalMobile.value ? Math.ceil(hotTotalMobile.value / 4) : 0
  341 +);
  342 +</script>
  343 +
  344 +<style lang="scss" scoped>
  345 +@media screen and (min-width: 1537px) {
  346 + .tabs {
  347 + border-bottom: 2px solid #1f88e5;
  348 + margin: 10px auto 20px;
  349 + width: 93%;
  350 + }
  351 +}
  352 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  353 + .tabs {
  354 + border-bottom: 2px solid #1f88e5;
  355 + margin: 10px auto 40px;
  356 + width: 78%;
  357 + }
  358 +}
  359 +@media screen and (max-width: 1280px) {
  360 + .tabs {
  361 + border-bottom: 2px solid #1f88e5;
  362 + margin: 10px auto 40px;
  363 + width: 92%;
  364 + }
  365 +}
  366 +/* .tabs {
  367 + border-bottom: 2px solid #1f88e5;
  368 +} */
  369 +
  370 +.active {
  371 + background-color: #1086e8;
  372 +}
  373 +
  374 +@media screen and (min-width: 1537px) {
  375 + #image-container {
  376 + display: flex;
  377 + align-items: center;
  378 + justify-content: center;
  379 + height: 320px;
  380 + margin: 10px auto 50px;
  381 + width: 80%;
  382 + }
  383 +}
  384 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  385 + #image-container {
  386 + display: flex;
  387 + align-items: center;
  388 + justify-content: center;
  389 + height: 260px;
  390 + margin: 10px auto 0px;
  391 + width: 80%;
  392 + padding: 0;
  393 + }
  394 +}
  395 +@media screen and (max-width: 1280px) {
  396 + #image-container {
  397 + display: flex;
  398 + align-items: center;
  399 + justify-content: center;
  400 + height: 260px;
  401 + margin: 10px auto 0px;
  402 + width: 80%;
  403 + padding: 0;
  404 + }
  405 +}
  406 +.image-row {
  407 + display: flex;
  408 + height: 245px;
  409 +}
  410 +@media screen and (min-width: 1537px) {
  411 + .imageTotal {
  412 + display: inline-block;
  413 + margin: 0 5px;
  414 + text-align: center;
  415 + width: 320px;
  416 + }
  417 +}
  418 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  419 + .imageTotal {
  420 + display: inline-block;
  421 + margin: 0 5px;
  422 + text-align: center;
  423 + width: 200px;
  424 + }
  425 +}
  426 +@media screen and (max-width: 1280px) {
  427 + .imageTotal {
  428 + display: inline-block;
  429 + margin: 0 5px;
  430 + text-align: center;
  431 + width: 200px;
  432 + }
  433 +}
  434 +@media screen and (min-width: 1537px) {
  435 + .image-row img {
  436 + width: 240px;
  437 + height: 240px;
  438 + }
  439 +}
  440 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  441 + .image-row img {
  442 + width: 140px;
  443 + height: 140px;
  444 + }
  445 +}
  446 +
  447 +@media screen and (max-width: 1280px) {
  448 + .image-row img {
  449 + width: 140px;
  450 + height: 140px;
  451 + }
  452 +}
  453 +@media screen and (min-width: 1537px) {
  454 + .image-name {
  455 + display: -webkit-box; /* Enables multi-line text handling */
  456 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  457 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  458 + overflow: hidden; /* Hides the overflowed text */
  459 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  460 + margin-top: 5px;
  461 + font-size: 16px;
  462 + width: 180px;
  463 + color: #555;
  464 + text-align: center; /* Centers the text horizontally */
  465 + margin-left: 50px;
  466 + }
  467 +}
  468 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  469 + .image-name {
  470 + display: -webkit-box; /* Enables multi-line text handling */
  471 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  472 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  473 + overflow: hidden; /* Hides the overflowed text */
  474 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  475 + margin-top: 5px;
  476 + font-size: 16px;
  477 + width: 180px;
  478 + color: #555;
  479 + text-align: center; /* Centers the text horizontally */
  480 + margin-left: 10px;
  481 + }
  482 +}
  483 +@media screen and (max-width: 1280px) {
  484 + .image-name {
  485 + display: -webkit-box; /* Enables multi-line text handling */
  486 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  487 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  488 + overflow: hidden; /* Hides the overflowed text */
  489 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  490 + margin-top: 5px;
  491 + font-size: 16px;
  492 + width: 180px;
  493 + color: #555;
  494 + text-align: center; /* Centers the text horizontally */
  495 + margin-left: 10px;
  496 + }
  497 +}
  498 +
  499 +button .recommendButton {
  500 + margin: 0 0px;
  501 + cursor: pointer;
  502 +}
  503 +
  504 +.recommend-left-box {
  505 +}
  506 +
  507 +// @media screen and (max-width: 1280px) {
  508 +// .recommend-img-left {
  509 +// width: 26px;
  510 +// height: 27px;
  511 +// margin-bottom: 60px;
  512 +// }
  513 +// }
  514 +.recommend-img-left {
  515 + width: 26px;
  516 + height: 27px;
  517 + margin-right: 30px;
  518 + margin-bottom: 60px;
  519 +}
  520 +
  521 +.recommend-img-left:hover {
  522 + cursor: pointer;
  523 +}
  524 +.recommend-right-box {
  525 +}
  526 +
  527 +.recommend-img-right {
  528 + width: 26px;
  529 + height: 27px;
  530 + margin-left: 30px;
  531 + margin-bottom: 60px;
  532 +}
35 533  
36   -})</script>
  534 +.recommend-img-right:hover {
  535 + cursor: pointer;
  536 +}
37 537  
38   -<style lang="less" scoped></style>
  538 +.v-card {
  539 + transition: all 0.3s ease-in-out;
  540 +}
  541 +.clamp-text {
  542 + display: -webkit-box; /* 使用弹性盒子 */
  543 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  544 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  545 + overflow: hidden; /* 隐藏多余内容 */
  546 + text-overflow: ellipsis; /* 添加省略号 */
  547 + white-space: normal; /* 允许换行 */
  548 + line-height: 1.5em; /* 设置每行的高度 */
  549 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  550 +}
  551 +</style>
... ...
pages/index.vue
... ... @@ -31,7 +31,8 @@
31 31 </v-carousel-item>
32 32 </v-carousel>
33 33 </v-rows>
34   - <v-tabs
  34 + <HotProducts />
  35 + <!-- <v-tabs
35 36 class="tabs"
36 37 v-model="tabRecom"
37 38 color="white"
... ... @@ -42,8 +43,8 @@
42 43 v-if="recommendImages[0] !== null && !isMobile()"
43 44 >
44 45 <v-tab :value="1">Best Sellers</v-tab>
45   - <!-- <v-tab :value="3">商品百科</v-tab> -->
46 46 </v-tabs>
  47 +
47 48 <div id="image-container" v-if="recommendImages[0] !== null && !isMobile()">
48 49 <div class="recommend-left-box">
49 50 <v-img
... ... @@ -54,13 +55,6 @@
54 55 />
55 56 </div>
56 57 <div class="image-row" id="row1">
57   - <!-- <img
58   - v-for="(imageObj, index) in recommendImages.slice(0, 5)"
59   - :key="'row1-' + index"
60   - :src="imageObj[0]?.url"
61   - :alt="'Image ' + (index + 1)"
62   - style="margin: 0 5px; width: 200px; height: 200px"
63   - /> -->
64 58 <div
65 59 v-for="(imageObj, index) in recommendImages"
66 60 :key="'row1-' + index"
... ... @@ -76,7 +70,7 @@
76 70 {{ imageObj[0]?.name }}
77 71 </span>
78 72 </a>
79   - <div v-else style="width: 200px; height: 200px"></div>
  73 + <div v-else class="image-substitute"></div>
80 74 </div>
81 75 </div>
82 76 <div class="recommend-right-box">
... ... @@ -101,9 +95,8 @@
101 95 v-if="isMobile()"
102 96 >
103 97 <v-tab :value="1">Best Sellers</v-tab>
104   - <!-- <v-tab :value="3">商品百科</v-tab> -->
105 98 </v-tabs>
106   - <div class="tw-text-center" v-if="hotLoading && isMobile()">
  99 + <div class="tw-text-center" v-if="hotLoadingMobile && isMobile()">
107 100 <v-progress-circular
108 101 color="blue-lighten-2"
109 102 indeterminate
... ... @@ -112,9 +105,9 @@
112 105 ></v-progress-circular>
113 106 </div>
114 107 <v-item-group multiple v-if="isMobile()">
115   - <v-row v-if="!hotLoading">
  108 + <v-row v-if="!hotLoadingMobile">
116 109 <v-col
117   - v-for="(item, i) in recommendImages"
  110 + v-for="(item, i) in recommendImagesMobile"
118 111 :key="i"
119 112 cols="6"
120 113 lg="3"
... ... @@ -130,7 +123,7 @@
130 123 class="d-block"
131 124 />
132 125 <v-card-text class="tw-text-left font-weight-medium title">
133   - <h4>{{ item[0].name }}</h4>
  126 + <h4 class="clamp-text">{{ item[0].name }}</h4>
134 127 </v-card-text>
135 128 </v-card>
136 129 </div>
... ... @@ -141,8 +134,8 @@
141 134 <v-col>
142 135 <v-pagination
143 136 :size="isMobile() ? 'small' : 'default'"
144   - v-if="hotTotal"
145   - v-model="currentIndex"
  137 + v-if="hotTotalMobile"
  138 + v-model="currentIndexMobile"
146 139 @update:modelValue="toggleRowMobile"
147 140 :length="hotLength"
148 141 rounded="0"
... ... @@ -150,7 +143,7 @@
150 143 total-visible="5"
151 144 ></v-pagination></v-col
152 145 ></v-row>
153   - </div>
  146 + </div> -->
154 147 <!-- 能源材料 -->
155 148 <div class="tw-py-8 py-sm-16">
156 149 <v-container>
... ... @@ -208,162 +201,168 @@
208 201 />
209 202 </v-container>
210 203 </div>
211   - <div style="padding-left: 16px; padding-right: 16px; padding-bottom: 30px">
212   - <v-tabs
213   - class="tabs2"
214   - ref="tabs2"
215   - v-model="tabRecom"
216   - style="margin-top: 25px; margin-bottom: 20px; width: 100%"
217   - color="white"
218   - bg-color="#eeeeee"
219   - slider-color="blue-lighten-1"
220   - selected-class="active"
221   - v-if="isMobile()"
222   - >
223   - <v-tab :value="1">Best Sellers</v-tab>
224   - <!-- <v-tab :value="3">商品百科</v-tab> -->
225   - </v-tabs>
226   - <div class="tw-text-center" v-if="hotLoading && isMobile()">
227   - <v-progress-circular
228   - color="blue-lighten-2"
229   - indeterminate
230   - size="64"
231   - class="tw-m-auto"
232   - ></v-progress-circular>
233   - </div>
234   - <v-item-group multiple v-if="isMobile()">
235   - <v-row v-if="!hotLoading">
236   - <v-col
237   - v-for="(item, i) in recommendImages"
238   - :key="i"
239   - cols="6"
240   - lg="3"
241   - md="4"
242   - sm="6"
243   - >
244   - <div v-if="item !== null">
245   - <v-card :elevation="4" class="mx-auto" :href="item[0].productUrl">
246   - <v-img
247   - :src="item[0].url"
248   - :alt="item[0].name"
249   - eager
250   - class="d-block"
251   - />
252   - <v-card-text class="tw-text-left font-weight-medium title">
253   - <h4>{{ item[0].name }}</h4>
254   - </v-card-text>
255   - </v-card>
256   - </div>
257   - </v-col>
258   - </v-row>
259   - </v-item-group>
260   - <v-row v-if="isMobile()">
261   - <v-col>
262   - <v-pagination
263   - :size="isMobile() ? 'small' : 'default'"
264   - v-if="hotTotal"
265   - v-model="currentIndex"
266   - @update:modelValue="toggleRowMobile"
267   - :length="hotLength"
268   - rounded="0"
269   - class="tw-float-right tw-mt-[32px]"
270   - total-visible="5"
271   - ></v-pagination></v-col
272   - ></v-row>
273   - </div>
274 204 </template>
275 205  
276 206 <script setup lang="ts">
277 207 import MainTitleList from "../components/MainTitleList.vue";
278 208 import MainTitleListOdd from "../components/MainTitleListOdd.vue";
  209 +import HotProducts from "../components/HotProducts.vue";
279 210 import { useCategoryStore } from "../stores/category";
280 211 import { computed, onMounted, reactive, ref } from "vue";
281 212 import { isMobile } from "../utils";
282 213  
283 214 const maxPage = ref(1);
  215 +const maxPageMobile = ref(1);
284 216 const tabRecom = ref();
285   -const recommendList = ref();
286   -const recommendImages = ref();
  217 +const recommendList = ref({});
  218 +const recommendImages = ref({});
287 219 const currentIndex = ref(1);
288 220 const hotLoading = ref(false);
289 221 const hotTotal = ref(10);
290 222 const isOrNotMobile = isMobile();
291   -const loadHotProducts = async () => {
292   - const pageSize = ref(5);
293   - if (isOrNotMobile) {
294   - pageSize.value = 4;
295   - }
296   - hotLoading.value = true;
297   - let { data: hotProducts } = await useAsyncData(
298   - "hotProducts",
299   - () =>
300   - $fetch("/shop/product/hotProducts", {
301   - method: "GET",
302   - params: {
303   - pageNo: currentIndex.value,
304   - pageSize: pageSize.value,
305   - },
306   - }),
307   - {
308   - server: true, // 仅在服务器端获取数据
309   - }
310   - );
311   - hotTotal.value = hotProducts.value.data.total;
312   - recommendList.value = hotProducts.value.data.records;
313   - maxPage.value = hotProducts.value.data.pages;
314   - // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
315   - recommendImages.value = Array.from({ length: pageSize.value }).map(
316   - (_, index) => {
317   - const item = recommendList.value[index];
318   - if (!item) {
319   - return null;
320   - }
321   - // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
322   - if (typeof item.productimageliststore === "string") {
323   - try {
324   - item.productimageliststore = JSON.parse(item.productimageliststore);
325   - } catch (error) {
326   - item.productimageliststore = []; // 解析失败时,设置为空数组
327   - }
328   - }
329   - const ree = (item.productimageliststore = item?.productimageliststore.map(
330   - (productItem: ProductImage) => ({
331   - ...productItem,
332   - // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
333   - url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
334   - name: item.name,
335   - productUrl: `https://www.canrud.com/products/detail/${item.id}`,
336   - })
337   - ));
338   - return ree;
339   - }
340   - );
341   - hotLoading.value = false;
342   -};
  223 +const recommendListMobile = ref({});
  224 +const recommendImagesMobile = ref({});
  225 +const currentIndexMobile = ref(1);
  226 +const hotLoadingMobile = ref(false);
  227 +const hotTotalMobile = ref(10);
  228 +// const loadHotProducts = async () => {
  229 +// hotLoading.value = true;
  230 +// const pageSize = 5;
  231 +// let { data: hotProducts } = await useAsyncData(
  232 +// "hotProducts",
  233 +// () =>
  234 +// $fetch("/shop/product/hotProducts", {
  235 +// method: "GET",
  236 +// params: {
  237 +// pageNo: currentIndex.value,
  238 +// pageSize: pageSize,
  239 +// },
  240 +// }),
  241 +// {
  242 +// server: true, // 仅在服务器端获取数据
  243 +// }
  244 +// );
  245 +// hotTotal.value = hotProducts.value.data.total;
  246 +// recommendList.value = hotProducts.value.data.records;
  247 +// maxPage.value = hotProducts.value.data.pages;
  248 +// // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  249 +// recommendImages.value = Array.from({ length: 5 }).map((_, index) => {
  250 +// const item = recommendList.value[index];
  251 +// if (!item) {
  252 +// return null;
  253 +// }
  254 +// // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  255 +// if (typeof item.productimageliststore === "string") {
  256 +// try {
  257 +// item.productimageliststore = JSON.parse(item.productimageliststore);
  258 +// } catch (error) {
  259 +// item.productimageliststore = []; // 解析失败时,设置为空数组
  260 +// }
  261 +// }
  262 +// const ree = (item.productimageliststore = item?.productimageliststore.map(
  263 +// (productItem: ProductImage) => ({
  264 +// ...productItem,
  265 +// // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  266 +// url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  267 +// name: item.name,
  268 +// productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  269 +// })
  270 +// ));
  271 +// return ree;
  272 +// });
  273 +// hotLoading.value = false;
  274 +// };
343 275  
344   -const toggleRowLeft = () => {
345   - if (currentIndex.value !== 1) {
346   - currentIndex.value--;
347   - } else if (currentIndex.value == 1) {
348   - currentIndex.value = maxPage.value;
349   - }
350   -};
351   -const toggleRowRight = () => {
352   - if (currentIndex.value < maxPage.value) {
353   - currentIndex.value++;
354   - } else if (currentIndex.value == maxPage.value) {
355   - currentIndex.value = 1;
356   - }
357   -};
358   -const toggleRowMobile = (value: number) => {
359   - currentIndex.value = value;
360   -};
  276 +// const toggleRowLeft = () => {
  277 +// if (currentIndex.value !== 1) {
  278 +// currentIndex.value--;
  279 +// } else if (currentIndex.value == 1) {
  280 +// currentIndex.value = maxPage.value;
  281 +// }
  282 +// startTimer();
  283 +// };
  284 +// let intervalId: any;
  285 +// const toggleRowRight = () => {
  286 +// if (currentIndex.value < maxPage.value) {
  287 +// currentIndex.value++;
  288 +// } else if (currentIndex.value == maxPage.value) {
  289 +// currentIndex.value = 1;
  290 +// }
  291 +// startTimer();
  292 +// };
  293 +// const startTimer = () => {
  294 +// // 清除已有计时器,防止重复
  295 +// clearInterval(intervalId);
  296 +// intervalId = setInterval(() => {
  297 +// toggleRowRight();
  298 +// }, 5000); // 每6秒调用一次
  299 +// };
361 300  
362   -watch(currentIndex, (newIndex) => {
363   - loadHotProducts(); // Call loadHotProducts when currentIndex changes
364   -});
365   -// Initial load of hot products
366   -await loadHotProducts(); // Load hot products the first time
  301 +// onMounted(() => {
  302 +// startTimer();
  303 +// });
  304 +
  305 +// const toggleRowMobile = (value: number) => {
  306 +// currentIndexMobile.value = value;
  307 +// };
  308 +
  309 +// watch(currentIndex, (newIndex) => {
  310 +// loadHotProducts(); // Call loadHotProducts when currentIndex changes
  311 +// });
  312 +// // Initial load of hot products
  313 +// await loadHotProducts(); // Load hot products the first time
  314 +
  315 +// const loadHotProductsMobile = async () => {
  316 +// hotLoadingMobile.value = true;
  317 +// let { data: hotProductsMobile } = await useAsyncData(
  318 +// "hotProducts",
  319 +// () =>
  320 +// $fetch("/shop/product/hotProducts", {
  321 +// method: "GET",
  322 +// params: {
  323 +// pageNo: currentIndexMobile.value,
  324 +// pageSize: 4,
  325 +// },
  326 +// }),
  327 +// {
  328 +// server: true, // 仅在服务器端获取数据
  329 +// }
  330 +// );
  331 +// hotTotalMobile.value = hotProductsMobile.value.data.total;
  332 +// recommendListMobile.value = hotProductsMobile.value.data.records;
  333 +// maxPageMobile.value = hotProductsMobile.value.data.pages;
  334 +// // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  335 +// recommendImagesMobile.value = Array.from({ length: 4 }).map((_, index) => {
  336 +// const item = recommendListMobile.value[index];
  337 +// if (!item) {
  338 +// return null;
  339 +// }
  340 +// // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  341 +// if (typeof item.productimageliststore === "string") {
  342 +// try {
  343 +// item.productimageliststore = JSON.parse(item.productimageliststore);
  344 +// } catch (error) {
  345 +// item.productimageliststore = []; // 解析失败时,设置为空数组
  346 +// }
  347 +// }
  348 +// const ree = (item.productimageliststore = item?.productimageliststore.map(
  349 +// (productItem: ProductImage) => ({
  350 +// ...productItem,
  351 +// // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  352 +// url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  353 +// name: item.name,
  354 +// productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  355 +// })
  356 +// ));
  357 +// return ree;
  358 +// });
  359 +// hotLoadingMobile.value = false;
  360 +// };
  361 +// watch(currentIndexMobile, (newIndex) => {
  362 +// loadHotProductsMobile(); // Call loadHotProducts when currentIndex changes
  363 +// });
  364 +// // Initial load of hot products
  365 +// await loadHotProductsMobile(); // Load hot products the first time
367 366  
368 367 onMounted(() => {
369 368 console.log(
... ... @@ -496,9 +495,9 @@ const packs = [
496 495 href: "/pack",
497 496 },
498 497 ];
499   -const hotLength = computed(() =>
500   - hotTotal.value ? Math.ceil(hotTotal.value / 4) : 0
501   -);
  498 +// const hotLength = computed(() =>
  499 +// hotTotal.value ? Math.ceil(hotTotal.value / 4) : 0
  500 +// );
502 501 </script>
503 502 <style scoped>
504 503 @media screen and (min-width: 1537px) {
... ... @@ -512,14 +511,14 @@ const hotLength = computed(() =&gt;
512 511 .tabs {
513 512 border-bottom: 2px solid #1f88e5;
514 513 margin: 10px auto 20px;
515   - width: 80%;
  514 + width: 85%;
516 515 }
517 516 }
518 517 @media screen and (max-width: 1280px) {
519 518 .tabs {
520 519 border-bottom: 2px solid #1f88e5;
521 520 margin: 10px auto 0px;
522   - width: 85%;
  521 + width: 88%;
523 522 }
524 523 }
525 524  
... ... @@ -612,8 +611,28 @@ const hotLength = computed(() =&gt;
612 611 }
613 612 @media screen and (max-width: 1536px) and (min-width: 1281px) {
614 613 .image-row img {
615   - width: 140px;
616   - height: 140px;
  614 + width: 180px;
  615 + height: 180px;
  616 + }
  617 +}
  618 +
  619 +@media screen and (min-width: 1537px) {
  620 + .image-row .image-substitute {
  621 + width: 200px;
  622 + height: 200px;
  623 + }
  624 +}
  625 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  626 + .image-row .image-substitute {
  627 + width: 200px;
  628 + height: 200px;
  629 + }
  630 +}
  631 +
  632 +@media screen and (max-width: 1280px) {
  633 + .image-row .image-substitute {
  634 + width: 185px;
  635 + height: 185px;
617 636 }
618 637 }
619 638 @media screen and (max-width: 1280px) {
... ... @@ -704,4 +723,14 @@ button .recommendButton {
704 723 .v-card {
705 724 transition: all 0.3s ease-in-out;
706 725 }
  726 +.clamp-text {
  727 + display: -webkit-box; /* 使用弹性盒子 */
  728 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  729 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  730 + overflow: hidden; /* 隐藏多余内容 */
  731 + text-overflow: ellipsis; /* 添加省略号 */
  732 + white-space: normal; /* 允许换行 */
  733 + line-height: 1.5em; /* 设置每行的高度 */
  734 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  735 +}
707 736 </style>
... ...
pages/products/index.vue
... ... @@ -80,6 +80,7 @@
80 80 >
81 81 <v-hover v-slot="{ isHovering, props }" open-delay="200">
82 82 <v-card
  83 + id="product-card"
83 84 :elevation="isHovering ? 16 : 2"
84 85 :class="{ 'on-hover': isHovering }"
85 86 class="mx-auto"
... ... @@ -97,11 +98,14 @@
97 98 </div>
98 99 </v-expand-transition> -->
99 100 </v-img>
100   - <v-card-text class="tw-text-left font-weight-medium title">
  101 + <v-card-text
  102 + class="tw-text-left font-weight-medium title"
  103 + style="height: auto"
  104 + >
101 105 <h3 style="color: red" v-if="item.price">
102 106 ${{ item.price }}
103 107 </h3>
104   - <h4>{{ item.name }}</h4>
  108 + <h4 class="item-name">{{ item.name }}</h4>
105 109 </v-card-text>
106 110 </v-card>
107 111 </v-hover>
... ... @@ -117,16 +121,16 @@
117 121 <v-row>
118 122 <v-col>
119 123 <v-pagination
120   - :size="isMobile() ? 'small' : 'default'"
121   - v-if="productStore.total"
122   - v-model="productStore.pageNo"
123   - @update:modelValue="productStore.updatePageNo"
124   - :length="length"
125   - rounded="0"
126   - class="tw-float-right tw-mt-[32px]"
127   - total-visible="5"
  124 + :size="isMobile() ? 'small' : 'default'"
  125 + v-if="productStore.total"
  126 + v-model="productStore.pageNo"
  127 + @update:modelValue="productStore.updatePageNo"
  128 + :length="length"
  129 + rounded="0"
  130 + class="tw-float-right tw-mt-[32px]"
  131 + total-visible="5"
128 132 ></v-pagination></v-col
129   - ></v-row>
  133 + ></v-row>
130 134 <v-tabs
131 135 class="tabs2"
132 136 ref="tabs2"
... ... @@ -141,7 +145,7 @@
141 145 <v-tab :value="1">Best Sellers</v-tab>
142 146 <!-- <v-tab :value="3">商品百科</v-tab> -->
143 147 </v-tabs>
144   - <div class="tw-text-center" v-if="hotLoading && isMobile()">
  148 + <div class="tw-text-center" v-if="hotLoadingMobile && isMobile()">
145 149 <v-progress-circular
146 150 color="blue-lighten-2"
147 151 indeterminate
... ... @@ -150,9 +154,9 @@
150 154 ></v-progress-circular>
151 155 </div>
152 156 <v-item-group multiple v-if="isMobile()">
153   - <v-row v-if="!hotLoading">
  157 + <v-row v-if="!hotLoadingMobile">
154 158 <v-col
155   - v-for="(item, i) in recommendImages"
  159 + v-for="(item, i) in recommendImagesMobile"
156 160 :key="i"
157 161 cols="6"
158 162 lg="3"
... ... @@ -169,7 +173,7 @@
169 173 class="d-block"
170 174 />
171 175 <v-card-text class="tw-text-left font-weight-medium title">
172   - <h4>{{ item[0].name }}</h4>
  176 + <h4 class="clamp-text">{{ item[0].name }}</h4>
173 177 </v-card-text>
174 178 </v-card>
175 179 </div>
... ... @@ -186,8 +190,8 @@
186 190 <v-col>
187 191 <v-pagination
188 192 :size="isMobile() ? 'small' : 'default'"
189   - v-if="hotTotal"
190   - v-model="currentIndex"
  193 + v-if="hotTotalMobile"
  194 + v-model="currentIndexMobile"
191 195 @update:modelValue="toggleRowMobile"
192 196 :length="hotLength"
193 197 rounded="0"
... ... @@ -206,6 +210,7 @@ import { useProductListStore } from &quot;~/stores/product_list&quot;;
206 210 import { useCategoryStore } from "~/stores/category";
207 211 import CategoryList from "~/components/CategoryList.vue";
208 212 import MobileCategoryList from "~/components/MobileCategoryList.vue";
  213 +import HotProducts from "../components/HotProducts.vue";
209 214 import { watchEffect, computed, ref } from "vue";
210 215  
211 216 const productStore = useProductListStore();
... ... @@ -218,18 +223,20 @@ const title = ref(&quot;&quot;);
218 223 const keywordTitle = ref("");
219 224 const maxPage = ref(1);
220 225 const tabRecom = ref();
221   -const recommendList = ref();
222   -const recommendImages = ref();
  226 +const recommendList = ref({});
  227 +const recommendImages = ref({});
223 228 const currentIndex = ref(1);
224 229 const hotTotal = ref(10);
225   -const isOrNotMobile = isMobile();
  230 +const isOrNotMobile = ref(isMobile());
  231 +const maxPageMobile = ref(1);
  232 +const recommendListMobile = ref({});
  233 +const recommendImagesMobile = ref({});
  234 +const currentIndexMobile = ref(1);
  235 +const hotLoadingMobile = ref(false);
  236 +const hotTotalMobile = ref(10);
226 237  
227 238 const loadHotProducts = async () => {
228   - const pageSize = ref(5);
229   - if (isOrNotMobile) {
230   - pageSize.value = 4;
231   - }
232   - hotLoading.value = true;
  239 + const pageSize = 5;
233 240 let { data: hotProducts } = await useAsyncData(
234 241 "hotProducts",
235 242 () =>
... ... @@ -237,7 +244,7 @@ const loadHotProducts = async () =&gt; {
237 244 method: "GET",
238 245 params: {
239 246 pageNo: currentIndex.value,
240   - pageSize: pageSize.value,
  247 + pageSize: pageSize,
241 248 },
242 249 }),
243 250 {
... ... @@ -248,33 +255,30 @@ const loadHotProducts = async () =&gt; {
248 255 recommendList.value = hotProducts.value.data.records;
249 256 maxPage.value = hotProducts.value.data.pages;
250 257 // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
251   - recommendImages.value = Array.from({ length: pageSize.value }).map(
252   - (_, index) => {
253   - const item = recommendList.value[index];
254   - if (!item) {
255   - return null;
256   - }
257   - // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
258   - if (typeof item.productimageliststore === "string") {
259   - try {
260   - item.productimageliststore = JSON.parse(item.productimageliststore);
261   - } catch (error) {
262   - item.productimageliststore = []; // 解析失败时,设置为空数组
263   - }
  258 + recommendImages.value = Array.from({ length: 5 }).map((_, index) => {
  259 + const item = recommendList.value[index];
  260 + if (!item) {
  261 + return null;
  262 + }
  263 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  264 + if (typeof item.productimageliststore === "string") {
  265 + try {
  266 + item.productimageliststore = JSON.parse(item.productimageliststore);
  267 + } catch (error) {
  268 + item.productimageliststore = []; // 解析失败时,设置为空数组
264 269 }
265   - const ree = (item.productimageliststore = item?.productimageliststore.map(
266   - (productItem: ProductImage) => ({
267   - ...productItem,
268   - // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
269   - url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
270   - name: item.name,
271   - productUrl: `https://www.canrud.com/products/detail/${item.id}`,
272   - })
273   - ));
274   - return ree;
275 270 }
276   - );
277   - hotLoading.value = false;
  271 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  272 + (productItem: ProductImage) => ({
  273 + ...productItem,
  274 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  275 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  276 + name: item.name,
  277 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  278 + })
  279 + ));
  280 + return ree;
  281 + });
278 282 };
279 283  
280 284 const toggleRowLeft = () => {
... ... @@ -283,24 +287,125 @@ const toggleRowLeft = () =&gt; {
283 287 } else if (currentIndex.value == 1) {
284 288 currentIndex.value = maxPage.value;
285 289 }
  290 + startTimer();
286 291 };
  292 +let intervalId: any;
287 293 const toggleRowRight = () => {
288 294 if (currentIndex.value < maxPage.value) {
289 295 currentIndex.value++;
290 296 } else if (currentIndex.value == maxPage.value) {
291 297 currentIndex.value = 1;
292 298 }
  299 + startTimer();
293 300 };
  301 +const startTimer = () => {
  302 + // 清除已有计时器,防止重复
  303 + clearInterval(intervalId);
  304 + intervalId = setInterval(() => {
  305 + toggleRowRight();
  306 + }, 5000); // 每6秒调用一次
  307 +};
  308 +
  309 +onMounted(() => {
  310 + startTimer();
  311 +});
  312 +
294 313 const toggleRowMobile = (value: number) => {
295   - currentIndex.value = value;
  314 + currentIndexMobile.value = value;
296 315 };
  316 +const { width } = useDisplay();
  317 +const firstHotIndex = ref(true);
  318 +
  319 +// // 监听屏幕宽度变化
  320 +// watch(width, async (newWidth) => {
  321 +// console.log(newWidth, "5656widthvalue");
  322 +// if (firstHotIndex.value) {
  323 +// if (newWidth > 600) {
  324 +// await loadHotProducts();
  325 +// } else {
  326 +// await loadHotProductsMobile();
  327 +// }
  328 +// }
  329 +// });
  330 +
  331 +// // 监听路由变化
  332 +// watch(
  333 +// () => route.fullPath,
  334 +// async () => {
  335 +// if (firstHotIndex.value) {
  336 +// if (width.value > 600) {
  337 +// await loadHotProducts();
  338 +// } else {
  339 +// await loadHotProductsMobile();
  340 +// }
  341 +// }
  342 +// }
  343 +// );
297 344  
298 345 watch(currentIndex, (newIndex) => {
299 346 loadHotProducts(); // Call loadHotProducts when currentIndex changes
300 347 });
301   -// Initial load of hot products
302   -await loadHotProducts(); // Load hot products the first time
303 348  
  349 +const loadHotProductsMobile = async () => {
  350 + hotLoadingMobile.value = true;
  351 + let { data: hotProductsMobile } = await useAsyncData(
  352 + "hotProducts",
  353 + () =>
  354 + $fetch("/shop/product/hotProducts", {
  355 + method: "GET",
  356 + params: {
  357 + pageNo: currentIndexMobile.value,
  358 + pageSize: 4,
  359 + },
  360 + }),
  361 + {
  362 + server: true, // 仅在服务器端获取数据
  363 + }
  364 + );
  365 + hotTotalMobile.value = hotProductsMobile.value.data.total;
  366 + recommendListMobile.value = hotProductsMobile.value.data.records;
  367 + maxPageMobile.value = hotProductsMobile.value.data.pages;
  368 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  369 + recommendImagesMobile.value = Array.from({ length: 4 }).map((_, index) => {
  370 + const item = recommendListMobile.value[index];
  371 + if (!item) {
  372 + return null;
  373 + }
  374 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  375 + if (typeof item.productimageliststore === "string") {
  376 + try {
  377 + item.productimageliststore = JSON.parse(item.productimageliststore);
  378 + } catch (error) {
  379 + item.productimageliststore = []; // 解析失败时,设置为空数组
  380 + }
  381 + }
  382 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  383 + (productItem: ProductImage) => ({
  384 + ...productItem,
  385 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  386 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  387 + name: item.name,
  388 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  389 + })
  390 + ));
  391 + return ree;
  392 + });
  393 + hotLoadingMobile.value = false;
  394 +};
  395 +watch(currentIndexMobile, (newIndex) => {
  396 + loadHotProductsMobile(); // Call loadHotProducts when currentIndex changes
  397 +});
  398 +watchEffect(async () => {
  399 + console.log("Current route:", route.fullPath, "Width:", width.value);
  400 +
  401 + if (firstHotIndex.value) {
  402 + if (width.value > 600) {
  403 + await loadHotProducts();
  404 + } else {
  405 + await loadHotProductsMobile();
  406 + }
  407 + }
  408 +});
304 409 watchEffect(() => {
305 410 // 遍历数组
306 411 if (router.currentRoute.value.query.categories) {
... ... @@ -486,7 +591,7 @@ const length = computed(() =&gt;
486 591 productStore.total ? Math.ceil(productStore.total / productStore.pageSize) : 0
487 592 );
488 593 const hotLength = computed(() =>
489   - hotTotal.value ? Math.ceil(hotTotal.value / 4) : 0
  594 + hotTotalMobile.value ? Math.ceil(hotTotalMobile.value / 4) : 0
490 595 );
491 596 </script>
492 597  
... ... @@ -695,4 +800,35 @@ button .recommendButton {
695 800 .v-card {
696 801 transition: all 0.3s ease-in-out;
697 802 }
  803 +
  804 +.v-card-text {
  805 + max-width: 100%; /* 确保文字宽度受限 */
  806 +}
  807 +.item-name {
  808 + display: -webkit-box !important;
  809 + -webkit-box-orient: vertical !important;
  810 + -webkit-line-clamp: 3 !important;
  811 + overflow: hidden !important;
  812 + text-overflow: ellipsis !important;
  813 + white-space: normal !important;
  814 + text-align: left;
  815 + line-height: 1.5em;
  816 + min-height: calc(3 * 1.5em); /* 强制未满三行时高度一致 */
  817 +}
  818 +
  819 +#product-card .v-responsive.v-img {
  820 + width: 274px !important; /* 设置宽度 */
  821 + height: 274px !important; /* 设置高度 */
  822 +}
  823 +
  824 +.clamp-text {
  825 + display: -webkit-box; /* 使用弹性盒子 */
  826 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  827 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  828 + overflow: hidden; /* 隐藏多余内容 */
  829 + text-overflow: ellipsis; /* 添加省略号 */
  830 + white-space: normal; /* 允许换行 */
  831 + line-height: 1.5em; /* 设置每行的高度 */
  832 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  833 +}
698 834 </style>
... ...
pnpm-lock.yaml
... ... @@ -30,6 +30,9 @@ importers:
30 30 specifier: ^0.14.0
31 31 version: 0.14.0(rollup@4.17.2)(vite@5.2.11(@types/node@20.12.11)(sass@1.77.1)(terser@5.31.0))(vue-i18n@9.13.1(vue@3.4.27))(vue@3.4.27)
32 32 devDependencies:
  33 + '@mdi/js':
  34 + specifier: ^7.4.47
  35 + version: 7.4.47
33 36 '@nuxtjs/i18n':
34 37 specifier: ^8.3.1
35 38 version: 8.3.1(rollup@4.17.2)(vue@3.4.27)
... ... @@ -60,7 +63,7 @@ packages:
60 63 engines: {node: '>=6.0.0'}
61 64  
62 65 '@antfu/install-pkg@0.1.1':
63   - resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==}
  66 + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==, tarball: https://registry.npmmirror.com/@antfu/install-pkg/-/install-pkg-0.1.1.tgz}
64 67  
65 68 '@antfu/utils@0.7.8':
66 69 resolution: {integrity: sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==}
... ... @@ -263,7 +266,7 @@ packages:
263 266 '@babel/core': ^7.0.0-0
264 267  
265 268 '@babel/plugin-transform-modules-commonjs@7.24.1':
266   - resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==}
  269 + resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==, tarball: https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz}
267 270 engines: {node: '>=6.9.0'}
268 271 peerDependencies:
269 272 '@babel/core': ^7.0.0-0
... ... @@ -275,7 +278,7 @@ packages:
275 278 '@babel/core': ^7.0.0-0
276 279  
277 280 '@babel/preset-typescript@7.24.1':
278   - resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==}
  281 + resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==, tarball: https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz}
279 282 engines: {node: '>=6.9.0'}
280 283 peerDependencies:
281 284 '@babel/core': ^7.0.0-0
... ... @@ -317,139 +320,139 @@ packages:
317 320 engines: {node: '>=16.13'}
318 321  
319 322 '@esbuild/aix-ppc64@0.20.2':
320   - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
  323 + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==, tarball: https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz}
321 324 engines: {node: '>=12'}
322 325 cpu: [ppc64]
323 326 os: [aix]
324 327  
325 328 '@esbuild/android-arm64@0.20.2':
326   - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==}
  329 + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz}
327 330 engines: {node: '>=12'}
328 331 cpu: [arm64]
329 332 os: [android]
330 333  
331 334 '@esbuild/android-arm@0.20.2':
332   - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==}
  335 + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz}
333 336 engines: {node: '>=12'}
334 337 cpu: [arm]
335 338 os: [android]
336 339  
337 340 '@esbuild/android-x64@0.20.2':
338   - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==}
  341 + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz}
339 342 engines: {node: '>=12'}
340 343 cpu: [x64]
341 344 os: [android]
342 345  
343 346 '@esbuild/darwin-arm64@0.20.2':
344   - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==}
  347 + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz}
345 348 engines: {node: '>=12'}
346 349 cpu: [arm64]
347 350 os: [darwin]
348 351  
349 352 '@esbuild/darwin-x64@0.20.2':
350   - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==}
  353 + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz}
351 354 engines: {node: '>=12'}
352 355 cpu: [x64]
353 356 os: [darwin]
354 357  
355 358 '@esbuild/freebsd-arm64@0.20.2':
356   - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==}
  359 + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz}
357 360 engines: {node: '>=12'}
358 361 cpu: [arm64]
359 362 os: [freebsd]
360 363  
361 364 '@esbuild/freebsd-x64@0.20.2':
362   - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==}
  365 + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz}
363 366 engines: {node: '>=12'}
364 367 cpu: [x64]
365 368 os: [freebsd]
366 369  
367 370 '@esbuild/linux-arm64@0.20.2':
368   - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==}
  371 + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz}
369 372 engines: {node: '>=12'}
370 373 cpu: [arm64]
371 374 os: [linux]
372 375  
373 376 '@esbuild/linux-arm@0.20.2':
374   - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==}
  377 + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz}
375 378 engines: {node: '>=12'}
376 379 cpu: [arm]
377 380 os: [linux]
378 381  
379 382 '@esbuild/linux-ia32@0.20.2':
380   - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==}
  383 + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz}
381 384 engines: {node: '>=12'}
382 385 cpu: [ia32]
383 386 os: [linux]
384 387  
385 388 '@esbuild/linux-loong64@0.20.2':
386   - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==}
  389 + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz}
387 390 engines: {node: '>=12'}
388 391 cpu: [loong64]
389 392 os: [linux]
390 393  
391 394 '@esbuild/linux-mips64el@0.20.2':
392   - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==}
  395 + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz}
393 396 engines: {node: '>=12'}
394 397 cpu: [mips64el]
395 398 os: [linux]
396 399  
397 400 '@esbuild/linux-ppc64@0.20.2':
398   - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==}
  401 + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz}
399 402 engines: {node: '>=12'}
400 403 cpu: [ppc64]
401 404 os: [linux]
402 405  
403 406 '@esbuild/linux-riscv64@0.20.2':
404   - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==}
  407 + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz}
405 408 engines: {node: '>=12'}
406 409 cpu: [riscv64]
407 410 os: [linux]
408 411  
409 412 '@esbuild/linux-s390x@0.20.2':
410   - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==}
  413 + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz}
411 414 engines: {node: '>=12'}
412 415 cpu: [s390x]
413 416 os: [linux]
414 417  
415 418 '@esbuild/linux-x64@0.20.2':
416   - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==}
  419 + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz}
417 420 engines: {node: '>=12'}
418 421 cpu: [x64]
419 422 os: [linux]
420 423  
421 424 '@esbuild/netbsd-x64@0.20.2':
422   - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==}
  425 + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz}
423 426 engines: {node: '>=12'}
424 427 cpu: [x64]
425 428 os: [netbsd]
426 429  
427 430 '@esbuild/openbsd-x64@0.20.2':
428   - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==}
  431 + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz}
429 432 engines: {node: '>=12'}
430 433 cpu: [x64]
431 434 os: [openbsd]
432 435  
433 436 '@esbuild/sunos-x64@0.20.2':
434   - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==}
  437 + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz}
435 438 engines: {node: '>=12'}
436 439 cpu: [x64]
437 440 os: [sunos]
438 441  
439 442 '@esbuild/win32-arm64@0.20.2':
440   - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==}
  443 + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz}
441 444 engines: {node: '>=12'}
442 445 cpu: [arm64]
443 446 os: [win32]
444 447  
445 448 '@esbuild/win32-ia32@0.20.2':
446   - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==}
  449 + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz}
447 450 engines: {node: '>=12'}
448 451 cpu: [ia32]
449 452 os: [win32]
450 453  
451 454 '@esbuild/win32-x64@0.20.2':
452   - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==}
  455 + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz}
453 456 engines: {node: '>=12'}
454 457 cpu: [x64]
455 458 os: [win32]
... ... @@ -459,19 +462,19 @@ packages:
459 462 engines: {node: '>=14'}
460 463  
461 464 '@floating-ui/core@1.6.1':
462   - resolution: {integrity: sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==}
  465 + resolution: {integrity: sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==, tarball: https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.1.tgz}
463 466  
464 467 '@floating-ui/dom@1.1.1':
465   - resolution: {integrity: sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw==}
  468 + resolution: {integrity: sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw==, tarball: https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.1.1.tgz}
466 469  
467 470 '@floating-ui/utils@0.2.2':
468   - resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==}
  471 + resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==, tarball: https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.2.tgz}
469 472  
470 473 '@iconify/types@2.0.0':
471   - resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
  474 + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==, tarball: https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz}
472 475  
473 476 '@iconify/utils@2.1.23':
474   - resolution: {integrity: sha512-YGNbHKM5tyDvdWZ92y2mIkrfvm5Fvhe6WJSkWu7vvOFhMtYDP0casZpoRz0XEHZCrYsR4stdGT3cZ52yp5qZdQ==}
  477 + resolution: {integrity: sha512-YGNbHKM5tyDvdWZ92y2mIkrfvm5Fvhe6WJSkWu7vvOFhMtYDP0casZpoRz0XEHZCrYsR4stdGT3cZ52yp5qZdQ==, tarball: https://registry.npmmirror.com/@iconify/utils/-/utils-2.1.23.tgz}
475 478  
476 479 '@intlify/bundle-utils@7.5.1':
477 480 resolution: {integrity: sha512-UovJl10oBIlmYEcWw+VIHdKY5Uv5sdPG0b/b6bOYxGLln3UwB75+2dlc0F3Fsa0RhoznQ5Rp589/BZpABpE4Xw==}
... ... @@ -565,6 +568,9 @@ packages:
565 568 resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
566 569 hasBin: true
567 570  
  571 + '@mdi/js@7.4.47':
  572 + resolution: {integrity: sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==, tarball: https://registry.npmmirror.com/@mdi/js/-/js-7.4.47.tgz}
  573 +
568 574 '@miyaneee/rollup-plugin-json5@1.2.0':
569 575 resolution: {integrity: sha512-JjTIaXZp9WzhUHpElrqPnl1AzBi/rvRs065F71+aTmlqvTMVkdbjZ8vfFl4nRlgJy+TPBw69ZK4pwFdmOAt4aA==}
570 576 peerDependencies:
... ... @@ -769,59 +775,59 @@ packages:
769 775 engines: {node: '>=14'}
770 776  
771 777 '@parcel/watcher-android-arm64@2.4.1':
772   - resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==}
  778 + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==, tarball: https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz}
773 779 engines: {node: '>= 10.0.0'}
774 780 cpu: [arm64]
775 781 os: [android]
776 782  
777 783 '@parcel/watcher-darwin-arm64@2.4.1':
778   - resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==}
  784 + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz}
779 785 engines: {node: '>= 10.0.0'}
780 786 cpu: [arm64]
781 787 os: [darwin]
782 788  
783 789 '@parcel/watcher-darwin-x64@2.4.1':
784   - resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==}
  790 + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==, tarball: https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz}
785 791 engines: {node: '>= 10.0.0'}
786 792 cpu: [x64]
787 793 os: [darwin]
788 794  
789 795 '@parcel/watcher-freebsd-x64@2.4.1':
790   - resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==}
  796 + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==, tarball: https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz}
791 797 engines: {node: '>= 10.0.0'}
792 798 cpu: [x64]
793 799 os: [freebsd]
794 800  
795 801 '@parcel/watcher-linux-arm-glibc@2.4.1':
796   - resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==}
  802 + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz}
797 803 engines: {node: '>= 10.0.0'}
798 804 cpu: [arm]
799 805 os: [linux]
800 806 libc: [glibc]
801 807  
802 808 '@parcel/watcher-linux-arm64-glibc@2.4.1':
803   - resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==}
  809 + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz}
804 810 engines: {node: '>= 10.0.0'}
805 811 cpu: [arm64]
806 812 os: [linux]
807 813 libc: [glibc]
808 814  
809 815 '@parcel/watcher-linux-arm64-musl@2.4.1':
810   - resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==}
  816 + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz}
811 817 engines: {node: '>= 10.0.0'}
812 818 cpu: [arm64]
813 819 os: [linux]
814 820 libc: [musl]
815 821  
816 822 '@parcel/watcher-linux-x64-glibc@2.4.1':
817   - resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==}
  823 + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz}
818 824 engines: {node: '>= 10.0.0'}
819 825 cpu: [x64]
820 826 os: [linux]
821 827 libc: [glibc]
822 828  
823 829 '@parcel/watcher-linux-x64-musl@2.4.1':
824   - resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==}
  830 + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==, tarball: https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz}
825 831 engines: {node: '>= 10.0.0'}
826 832 cpu: [x64]
827 833 os: [linux]
... ... @@ -834,19 +840,19 @@ packages:
834 840 - napi-wasm
835 841  
836 842 '@parcel/watcher-win32-arm64@2.4.1':
837   - resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==}
  843 + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz}
838 844 engines: {node: '>= 10.0.0'}
839 845 cpu: [arm64]
840 846 os: [win32]
841 847  
842 848 '@parcel/watcher-win32-ia32@2.4.1':
843   - resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==}
  849 + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz}
844 850 engines: {node: '>= 10.0.0'}
845 851 cpu: [ia32]
846 852 os: [win32]
847 853  
848 854 '@parcel/watcher-win32-x64@2.4.1':
849   - resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==}
  855 + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==, tarball: https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz}
850 856 engines: {node: '>= 10.0.0'}
851 857 cpu: [x64]
852 858 os: [win32]
... ... @@ -859,7 +865,7 @@ packages:
859 865 resolution: {integrity: sha512-6wT6TqY81n+7/x3Yhf0yfaJVKkZU42AGqOR0T3+UvChcaOJhSma7OWPN64v+ptYlznat+fS1VTwNAcbi2lzHnw==}
860 866  
861 867 '@pkgjs/parseargs@0.11.0':
862   - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
  868 + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, tarball: https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz}
863 869 engines: {node: '>=14'}
864 870  
865 871 '@polka/url@1.0.0-next.25':
... ... @@ -960,91 +966,91 @@ packages:
960 966 optional: true
961 967  
962 968 '@rollup/rollup-android-arm-eabi@4.17.2':
963   - resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==}
  969 + resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz}
964 970 cpu: [arm]
965 971 os: [android]
966 972  
967 973 '@rollup/rollup-android-arm64@4.17.2':
968   - resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==}
  974 + resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz}
969 975 cpu: [arm64]
970 976 os: [android]
971 977  
972 978 '@rollup/rollup-darwin-arm64@4.17.2':
973   - resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==}
  979 + resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz}
974 980 cpu: [arm64]
975 981 os: [darwin]
976 982  
977 983 '@rollup/rollup-darwin-x64@4.17.2':
978   - resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==}
  984 + resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz}
979 985 cpu: [x64]
980 986 os: [darwin]
981 987  
982 988 '@rollup/rollup-linux-arm-gnueabihf@4.17.2':
983   - resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==}
  989 + resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz}
984 990 cpu: [arm]
985 991 os: [linux]
986 992 libc: [glibc]
987 993  
988 994 '@rollup/rollup-linux-arm-musleabihf@4.17.2':
989   - resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==}
  995 + resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz}
990 996 cpu: [arm]
991 997 os: [linux]
992 998 libc: [musl]
993 999  
994 1000 '@rollup/rollup-linux-arm64-gnu@4.17.2':
995   - resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==}
  1001 + resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz}
996 1002 cpu: [arm64]
997 1003 os: [linux]
998 1004 libc: [glibc]
999 1005  
1000 1006 '@rollup/rollup-linux-arm64-musl@4.17.2':
1001   - resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==}
  1007 + resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz}
1002 1008 cpu: [arm64]
1003 1009 os: [linux]
1004 1010 libc: [musl]
1005 1011  
1006 1012 '@rollup/rollup-linux-powerpc64le-gnu@4.17.2':
1007   - resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==}
  1013 + resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz}
1008 1014 cpu: [ppc64]
1009 1015 os: [linux]
1010 1016 libc: [glibc]
1011 1017  
1012 1018 '@rollup/rollup-linux-riscv64-gnu@4.17.2':
1013   - resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==}
  1019 + resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz}
1014 1020 cpu: [riscv64]
1015 1021 os: [linux]
1016 1022 libc: [glibc]
1017 1023  
1018 1024 '@rollup/rollup-linux-s390x-gnu@4.17.2':
1019   - resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==}
  1025 + resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz}
1020 1026 cpu: [s390x]
1021 1027 os: [linux]
1022 1028 libc: [glibc]
1023 1029  
1024 1030 '@rollup/rollup-linux-x64-gnu@4.17.2':
1025   - resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==}
  1031 + resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz}
1026 1032 cpu: [x64]
1027 1033 os: [linux]
1028 1034 libc: [glibc]
1029 1035  
1030 1036 '@rollup/rollup-linux-x64-musl@4.17.2':
1031   - resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==}
  1037 + resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz}
1032 1038 cpu: [x64]
1033 1039 os: [linux]
1034 1040 libc: [musl]
1035 1041  
1036 1042 '@rollup/rollup-win32-arm64-msvc@4.17.2':
1037   - resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==}
  1043 + resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz}
1038 1044 cpu: [arm64]
1039 1045 os: [win32]
1040 1046  
1041 1047 '@rollup/rollup-win32-ia32-msvc@4.17.2':
1042   - resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==}
  1048 + resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz}
1043 1049 cpu: [ia32]
1044 1050 os: [win32]
1045 1051  
1046 1052 '@rollup/rollup-win32-x64-msvc@4.17.2':
1047   - resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==}
  1053 + resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz}
1048 1054 cpu: [x64]
1049 1055 os: [win32]
1050 1056  
... ... @@ -1132,7 +1138,7 @@ packages:
1132 1138 vue: '>=2.7 || >=3'
1133 1139  
1134 1140 '@unocss/astro@0.60.2':
1135   - resolution: {integrity: sha512-H8kJHj8aCQXksr0o7OpHqNkzm0RmpOm+qCt8vRcJJVFrdzQyaIQ/vyq3BUTV0Ex6OSzPirTe8fOaWoZdKtKf2Q==}
  1141 + resolution: {integrity: sha512-H8kJHj8aCQXksr0o7OpHqNkzm0RmpOm+qCt8vRcJJVFrdzQyaIQ/vyq3BUTV0Ex6OSzPirTe8fOaWoZdKtKf2Q==, tarball: https://registry.npmmirror.com/@unocss/astro/-/astro-0.60.2.tgz}
1136 1142 peerDependencies:
1137 1143 vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
1138 1144 peerDependenciesMeta:
... ... @@ -1140,80 +1146,80 @@ packages:
1140 1146 optional: true
1141 1147  
1142 1148 '@unocss/cli@0.60.2':
1143   - resolution: {integrity: sha512-zX7eM95UI6LpKRfHTr8T2gSlFFXemPUswBxR5H4vPVlLeeCOhJWfc04vGdtSwoix5qFdnhQWIwzXGXAaB+kwoA==}
  1149 + resolution: {integrity: sha512-zX7eM95UI6LpKRfHTr8T2gSlFFXemPUswBxR5H4vPVlLeeCOhJWfc04vGdtSwoix5qFdnhQWIwzXGXAaB+kwoA==, tarball: https://registry.npmmirror.com/@unocss/cli/-/cli-0.60.2.tgz}
1144 1150 engines: {node: '>=14'}
1145 1151 hasBin: true
1146 1152  
1147 1153 '@unocss/config@0.60.2':
1148   - resolution: {integrity: sha512-EEgivE1xEnamAsYMcmjUmLJjOa9dBdV2zygT/blSFyX6rMfA4OuRlZ8hgfeWrHImZGiTXUU0jV2EaRmK9jEImQ==}
  1154 + resolution: {integrity: sha512-EEgivE1xEnamAsYMcmjUmLJjOa9dBdV2zygT/blSFyX6rMfA4OuRlZ8hgfeWrHImZGiTXUU0jV2EaRmK9jEImQ==, tarball: https://registry.npmmirror.com/@unocss/config/-/config-0.60.2.tgz}
1149 1155 engines: {node: '>=14'}
1150 1156  
1151 1157 '@unocss/core@0.60.2':
1152   - resolution: {integrity: sha512-9i+eAJAqvy9bv0vrQxUU7VtR+wO6Vfk6dqrPHKRV/vlbwRT18v/C++dQ2L6PLM1CKxgNTeld0iTlpo8J3xZlxQ==}
  1158 + resolution: {integrity: sha512-9i+eAJAqvy9bv0vrQxUU7VtR+wO6Vfk6dqrPHKRV/vlbwRT18v/C++dQ2L6PLM1CKxgNTeld0iTlpo8J3xZlxQ==, tarball: https://registry.npmmirror.com/@unocss/core/-/core-0.60.2.tgz}
1153 1159  
1154 1160 '@unocss/extractor-arbitrary-variants@0.60.2':
1155   - resolution: {integrity: sha512-uO4ZPUcaYvyWshXnqzFnSWeh+Du6xVYwaz3oBKq4n7Ryw2Grc0IhiZe6n9MC8w6nkbopdo6ngr5LnFGp86horQ==}
  1161 + resolution: {integrity: sha512-uO4ZPUcaYvyWshXnqzFnSWeh+Du6xVYwaz3oBKq4n7Ryw2Grc0IhiZe6n9MC8w6nkbopdo6ngr5LnFGp86horQ==, tarball: https://registry.npmmirror.com/@unocss/extractor-arbitrary-variants/-/extractor-arbitrary-variants-0.60.2.tgz}
1156 1162  
1157 1163 '@unocss/inspector@0.60.2':
1158   - resolution: {integrity: sha512-tc+TtTA7yNCS10oT7MfI2rEv1KErwLgEDRvBLCM1vsXmjzsGxkhqnT3vT5pqRkENYh/QhmIfpz1899GvH8WBMQ==}
  1164 + resolution: {integrity: sha512-tc+TtTA7yNCS10oT7MfI2rEv1KErwLgEDRvBLCM1vsXmjzsGxkhqnT3vT5pqRkENYh/QhmIfpz1899GvH8WBMQ==, tarball: https://registry.npmmirror.com/@unocss/inspector/-/inspector-0.60.2.tgz}
1159 1165  
1160 1166 '@unocss/postcss@0.60.2':
1161   - resolution: {integrity: sha512-fGXzhx5bh1iYxQ0wThmUsu+KMxCTqZsQQZ/a2kbTNzmOIslX1/cCWaQ62BWsfER7rOnZVG6DzGR+3CzVcDzuXg==}
  1167 + resolution: {integrity: sha512-fGXzhx5bh1iYxQ0wThmUsu+KMxCTqZsQQZ/a2kbTNzmOIslX1/cCWaQ62BWsfER7rOnZVG6DzGR+3CzVcDzuXg==, tarball: https://registry.npmmirror.com/@unocss/postcss/-/postcss-0.60.2.tgz}
1162 1168 engines: {node: '>=14'}
1163 1169 peerDependencies:
1164 1170 postcss: ^8.4.21
1165 1171  
1166 1172 '@unocss/preset-attributify@0.60.2':
1167   - resolution: {integrity: sha512-PQDObhVtopL/eEceAHX/pBmPQhm50l4yhTu/pMH31hL13DuRYODngWe00jjgmMRTwIAFpMpDVKk2GjxeD05+cQ==}
  1173 + resolution: {integrity: sha512-PQDObhVtopL/eEceAHX/pBmPQhm50l4yhTu/pMH31hL13DuRYODngWe00jjgmMRTwIAFpMpDVKk2GjxeD05+cQ==, tarball: https://registry.npmmirror.com/@unocss/preset-attributify/-/preset-attributify-0.60.2.tgz}
1168 1174  
1169 1175 '@unocss/preset-icons@0.60.2':
1170   - resolution: {integrity: sha512-knE4CKn4tgjvyZQSZTuC5FIO2/jcP1AWBvpWyJTax5kcKAIrL8IU4b7PhiPwPrQpe0LBTtyQKWCXqWXp7DhDwA==}
  1176 + resolution: {integrity: sha512-knE4CKn4tgjvyZQSZTuC5FIO2/jcP1AWBvpWyJTax5kcKAIrL8IU4b7PhiPwPrQpe0LBTtyQKWCXqWXp7DhDwA==, tarball: https://registry.npmmirror.com/@unocss/preset-icons/-/preset-icons-0.60.2.tgz}
1171 1177  
1172 1178 '@unocss/preset-mini@0.60.2':
1173   - resolution: {integrity: sha512-Vp5UWzD9FgxeYNhyJIXjMt8HyL7joGJWzmFa2zR8ZAYZ+WIIIJWtxa+9/H8gJgnGTWa2H9oyj9h3IqOYT/lmSg==}
  1179 + resolution: {integrity: sha512-Vp5UWzD9FgxeYNhyJIXjMt8HyL7joGJWzmFa2zR8ZAYZ+WIIIJWtxa+9/H8gJgnGTWa2H9oyj9h3IqOYT/lmSg==, tarball: https://registry.npmmirror.com/@unocss/preset-mini/-/preset-mini-0.60.2.tgz}
1174 1180  
1175 1181 '@unocss/preset-tagify@0.60.2':
1176   - resolution: {integrity: sha512-M730DpoPJ8/uG7aKme9EYrzspr0WfKp7z3CTpb2hb4YHuiCXmiTjdxo5xa9vK3ZGQTZlUkG0rz3TLw8tRKqRDg==}
  1182 + resolution: {integrity: sha512-M730DpoPJ8/uG7aKme9EYrzspr0WfKp7z3CTpb2hb4YHuiCXmiTjdxo5xa9vK3ZGQTZlUkG0rz3TLw8tRKqRDg==, tarball: https://registry.npmmirror.com/@unocss/preset-tagify/-/preset-tagify-0.60.2.tgz}
1177 1183  
1178 1184 '@unocss/preset-typography@0.60.2':
1179   - resolution: {integrity: sha512-QKJi1LbC/f8RwwSwV6yQCXu/8wlBcrNyKiUSe7o9I2NYP+mzINlp64pXEP43UtUQo6x8Dil/TuzpRqMFPG/pMA==}
  1185 + resolution: {integrity: sha512-QKJi1LbC/f8RwwSwV6yQCXu/8wlBcrNyKiUSe7o9I2NYP+mzINlp64pXEP43UtUQo6x8Dil/TuzpRqMFPG/pMA==, tarball: https://registry.npmmirror.com/@unocss/preset-typography/-/preset-typography-0.60.2.tgz}
1180 1186  
1181 1187 '@unocss/preset-uno@0.60.2':
1182   - resolution: {integrity: sha512-ggOCehuBm6depGV+79heBlcYlwgcfbIMLnxbywZPIrLwPB/4YaTArBcG4giKILyu4p2PcodAZvfv4uYXrLaE5Q==}
  1188 + resolution: {integrity: sha512-ggOCehuBm6depGV+79heBlcYlwgcfbIMLnxbywZPIrLwPB/4YaTArBcG4giKILyu4p2PcodAZvfv4uYXrLaE5Q==, tarball: https://registry.npmmirror.com/@unocss/preset-uno/-/preset-uno-0.60.2.tgz}
1183 1189  
1184 1190 '@unocss/preset-web-fonts@0.60.2':
1185   - resolution: {integrity: sha512-1lHZVOR6JHkPOvFBQeqZLoAwDk9spUxrX2WfLSVL+sCuBLLeo8voa/LnCxPxKiQwKZGEEoh+qM2MKsLnRd+P6w==}
  1191 + resolution: {integrity: sha512-1lHZVOR6JHkPOvFBQeqZLoAwDk9spUxrX2WfLSVL+sCuBLLeo8voa/LnCxPxKiQwKZGEEoh+qM2MKsLnRd+P6w==, tarball: https://registry.npmmirror.com/@unocss/preset-web-fonts/-/preset-web-fonts-0.60.2.tgz}
1186 1192  
1187 1193 '@unocss/preset-wind@0.60.2':
1188   - resolution: {integrity: sha512-9Ml2Wyn7LAcKfqHMJmflT/jdz5eLZtm3SEZKH5Lfk5MOyeVm6NDXjXK140u3zaP5tGKqtO6akJZGtYktWJ6+WQ==}
  1194 + resolution: {integrity: sha512-9Ml2Wyn7LAcKfqHMJmflT/jdz5eLZtm3SEZKH5Lfk5MOyeVm6NDXjXK140u3zaP5tGKqtO6akJZGtYktWJ6+WQ==, tarball: https://registry.npmmirror.com/@unocss/preset-wind/-/preset-wind-0.60.2.tgz}
1189 1195  
1190 1196 '@unocss/reset@0.60.2':
1191   - resolution: {integrity: sha512-kM0DYAcbmzpAyHefa/W+cifBTScWeZGsNpKagMQ6vci6OlTUiDB1GcmhQZ6dC0Ks59GtPmRbzZLaK1MgG6ayrA==}
  1197 + resolution: {integrity: sha512-kM0DYAcbmzpAyHefa/W+cifBTScWeZGsNpKagMQ6vci6OlTUiDB1GcmhQZ6dC0Ks59GtPmRbzZLaK1MgG6ayrA==, tarball: https://registry.npmmirror.com/@unocss/reset/-/reset-0.60.2.tgz}
1192 1198  
1193 1199 '@unocss/rule-utils@0.60.2':
1194   - resolution: {integrity: sha512-pg3XbU0s0TmmRk0UkSV6wTlca+Zz5xe9V+Mk8a5QqVp0oJ2jNWHO9AfzF4NcvTzM2zV2a/WbpjSBgoK8iAz3zg==}
  1200 + resolution: {integrity: sha512-pg3XbU0s0TmmRk0UkSV6wTlca+Zz5xe9V+Mk8a5QqVp0oJ2jNWHO9AfzF4NcvTzM2zV2a/WbpjSBgoK8iAz3zg==, tarball: https://registry.npmmirror.com/@unocss/rule-utils/-/rule-utils-0.60.2.tgz}
1195 1201 engines: {node: '>=14'}
1196 1202  
1197 1203 '@unocss/scope@0.60.2':
1198   - resolution: {integrity: sha512-pdwNZzQBb6rllgCwirPPrydDZH2XL0DI8/W7iM1RKYiNeDYjoDAWdVD46CrRmxadiHesrhdIwDL6rQz7Q7bl0w==}
  1204 + resolution: {integrity: sha512-pdwNZzQBb6rllgCwirPPrydDZH2XL0DI8/W7iM1RKYiNeDYjoDAWdVD46CrRmxadiHesrhdIwDL6rQz7Q7bl0w==, tarball: https://registry.npmmirror.com/@unocss/scope/-/scope-0.60.2.tgz}
1199 1205  
1200 1206 '@unocss/transformer-attributify-jsx-babel@0.60.2':
1201   - resolution: {integrity: sha512-mb66b39qsjyH7+XqC/0ciLdPatVKH5CfMDxUMvzczuFTQ/+V3VAN/Mm6Ru+oxMgbf7qPTALSnLgu6RUhEldTzA==}
  1207 + resolution: {integrity: sha512-mb66b39qsjyH7+XqC/0ciLdPatVKH5CfMDxUMvzczuFTQ/+V3VAN/Mm6Ru+oxMgbf7qPTALSnLgu6RUhEldTzA==, tarball: https://registry.npmmirror.com/@unocss/transformer-attributify-jsx-babel/-/transformer-attributify-jsx-babel-0.60.2.tgz}
1202 1208  
1203 1209 '@unocss/transformer-attributify-jsx@0.60.2':
1204   - resolution: {integrity: sha512-GZbtuZLz3COMhEqdc33zmn8cKupAzVeLcAV66EL+zj7hfZIvrIEs5RFajtzlkQa7RC5YOOjZfHxMccGBEP1RMQ==}
  1210 + resolution: {integrity: sha512-GZbtuZLz3COMhEqdc33zmn8cKupAzVeLcAV66EL+zj7hfZIvrIEs5RFajtzlkQa7RC5YOOjZfHxMccGBEP1RMQ==, tarball: https://registry.npmmirror.com/@unocss/transformer-attributify-jsx/-/transformer-attributify-jsx-0.60.2.tgz}
1205 1211  
1206 1212 '@unocss/transformer-compile-class@0.60.2':
1207   - resolution: {integrity: sha512-dZfkGsqd7mdyRRCG8om5lTxQ4CjaaDka8gPbVawbDkK4U53G2vnN3daVlE7UflUXS32hOPj16RfOcb8cH+pypw==}
  1213 + resolution: {integrity: sha512-dZfkGsqd7mdyRRCG8om5lTxQ4CjaaDka8gPbVawbDkK4U53G2vnN3daVlE7UflUXS32hOPj16RfOcb8cH+pypw==, tarball: https://registry.npmmirror.com/@unocss/transformer-compile-class/-/transformer-compile-class-0.60.2.tgz}
1208 1214  
1209 1215 '@unocss/transformer-directives@0.60.2':
1210   - resolution: {integrity: sha512-p4ZtXoz1mZ125WfANFAD6pXwQJdA4lfff5abZfoDiTPLvtvYQFmwGCeBXUnEKAnBnTwwiBD2zsIwGfumWAsqrA==}
  1216 + resolution: {integrity: sha512-p4ZtXoz1mZ125WfANFAD6pXwQJdA4lfff5abZfoDiTPLvtvYQFmwGCeBXUnEKAnBnTwwiBD2zsIwGfumWAsqrA==, tarball: https://registry.npmmirror.com/@unocss/transformer-directives/-/transformer-directives-0.60.2.tgz}
1211 1217  
1212 1218 '@unocss/transformer-variant-group@0.60.2':
1213   - resolution: {integrity: sha512-2eE2MZhFhNj+3fxO9VE1yC8LddUn9vetNZKrgGlegrBH/jOL9Pn/vygBmMAg1XFLEgC3DtvwdzCKMVttV30Ivw==}
  1219 + resolution: {integrity: sha512-2eE2MZhFhNj+3fxO9VE1yC8LddUn9vetNZKrgGlegrBH/jOL9Pn/vygBmMAg1XFLEgC3DtvwdzCKMVttV30Ivw==, tarball: https://registry.npmmirror.com/@unocss/transformer-variant-group/-/transformer-variant-group-0.60.2.tgz}
1214 1220  
1215 1221 '@unocss/vite@0.60.2':
1216   - resolution: {integrity: sha512-+gBjyT5z/aZgPIZxpUbiXyOt1diY9YQfIJStOhBG0MP6daMdDX78SnDuUq/zKMk9EJuZ3FxhbZF5dYSD4bhJmw==}
  1222 + resolution: {integrity: sha512-+gBjyT5z/aZgPIZxpUbiXyOt1diY9YQfIJStOhBG0MP6daMdDX78SnDuUq/zKMk9EJuZ3FxhbZF5dYSD4bhJmw==, tarball: https://registry.npmmirror.com/@unocss/vite/-/vite-0.60.2.tgz}
1217 1223 peerDependencies:
1218 1224 vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0
1219 1225  
... ... @@ -1507,7 +1513,7 @@ packages:
1507 1513 resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
1508 1514  
1509 1515 bare-events@2.2.2:
1510   - resolution: {integrity: sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==}
  1516 + resolution: {integrity: sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==, tarball: https://registry.npmmirror.com/bare-events/-/bare-events-2.2.2.tgz}
1511 1517  
1512 1518 base64-js@1.5.1:
1513 1519 resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
... ... @@ -1670,7 +1676,7 @@ packages:
1670 1676 resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
1671 1677  
1672 1678 colorette@2.0.20:
1673   - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
  1679 + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, tarball: https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz}
1674 1680  
1675 1681 commander@2.20.3:
1676 1682 resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
... ... @@ -1936,7 +1942,7 @@ packages:
1936 1942 resolution: {integrity: sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ==}
1937 1943  
1938 1944 emoji-regex@8.0.0:
1939   - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
  1945 + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, tarball: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz}
1940 1946  
1941 1947 emoji-regex@9.2.2:
1942 1948 resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
... ... @@ -1946,7 +1952,7 @@ packages:
1946 1952 engines: {node: '>= 0.8'}
1947 1953  
1948 1954 encoding@0.1.13:
1949   - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
  1955 + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==, tarball: https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz}
1950 1956  
1951 1957 enhanced-resolve@5.16.1:
1952 1958 resolution: {integrity: sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==}
... ... @@ -2035,7 +2041,7 @@ packages:
2035 2041 engines: {node: '>=0.8.x'}
2036 2042  
2037 2043 execa@5.1.1:
2038   - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
  2044 + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, tarball: https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz}
2039 2045 engines: {node: '>=10'}
2040 2046  
2041 2047 execa@7.2.0:
... ... @@ -2070,14 +2076,14 @@ packages:
2070 2076 engines: {node: '>=8'}
2071 2077  
2072 2078 find-up@5.0.0:
2073   - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
  2079 + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, tarball: https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz}
2074 2080 engines: {node: '>=10'}
2075 2081  
2076 2082 flatted@3.3.1:
2077 2083 resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
2078 2084  
2079 2085 floating-vue@5.2.2:
2080   - resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==}
  2086 + resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==, tarball: https://registry.npmmirror.com/floating-vue/-/floating-vue-5.2.2.tgz}
2081 2087 peerDependencies:
2082 2088 '@nuxt/kit': ^3.2.0
2083 2089 vue: ^3.2.0
... ... @@ -2115,7 +2121,7 @@ packages:
2115 2121 resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
2116 2122  
2117 2123 fsevents@2.3.3:
2118   - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
  2124 + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz}
2119 2125 engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
2120 2126 os: [darwin]
2121 2127  
... ... @@ -2199,7 +2205,7 @@ packages:
2199 2205 resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
2200 2206  
2201 2207 gzip-size@6.0.0:
2202   - resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
  2208 + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==, tarball: https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz}
2203 2209 engines: {node: '>=10'}
2204 2210  
2205 2211 gzip-size@7.0.0:
... ... @@ -2265,7 +2271,7 @@ packages:
2265 2271 resolution: {integrity: sha512-hqLDO+rfststuyEUTWObQK6zHEEmZ/kaIP2/zclGGZn6X8h/ESTWg+WKecQ/e5k4nPswjzZD+q2VqZIbr15CoQ==}
2266 2272  
2267 2273 human-signals@2.1.0:
2268   - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
  2274 + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, tarball: https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz}
2269 2275 engines: {node: '>=10.17.0'}
2270 2276  
2271 2277 human-signals@4.3.1:
... ... @@ -2359,7 +2365,7 @@ packages:
2359 2365 engines: {node: '>=0.10.0'}
2360 2366  
2361 2367 is-fullwidth-code-point@3.0.0:
2362   - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
  2368 + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, tarball: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz}
2363 2369 engines: {node: '>=8'}
2364 2370  
2365 2371 is-glob@4.0.3:
... ... @@ -2539,7 +2545,7 @@ packages:
2539 2545 engines: {node: '>=14'}
2540 2546  
2541 2547 locate-path@6.0.0:
2542   - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
  2548 + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, tarball: https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz}
2543 2549 engines: {node: '>=10'}
2544 2550  
2545 2551 lodash-es@4.17.21:
... ... @@ -2624,7 +2630,7 @@ packages:
2624 2630 hasBin: true
2625 2631  
2626 2632 mimic-fn@2.1.0:
2627   - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
  2633 + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz}
2628 2634 engines: {node: '>=6'}
2629 2635  
2630 2636 mimic-fn@4.0.0:
... ... @@ -2892,7 +2898,7 @@ packages:
2892 2898 resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
2893 2899  
2894 2900 onetime@5.1.2:
2895   - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
  2901 + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, tarball: https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz}
2896 2902 engines: {node: '>=6'}
2897 2903  
2898 2904 onetime@6.0.0:
... ... @@ -2915,11 +2921,11 @@ packages:
2915 2921 resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==}
2916 2922  
2917 2923 p-limit@3.1.0:
2918   - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
  2924 + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, tarball: https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz}
2919 2925 engines: {node: '>=10'}
2920 2926  
2921 2927 p-locate@5.0.0:
2922   - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
  2928 + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, tarball: https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz}
2923 2929 engines: {node: '>=10'}
2924 2930  
2925 2931 p-map@4.0.0:
... ... @@ -2946,7 +2952,7 @@ packages:
2946 2952 engines: {node: '>= 0.8'}
2947 2953  
2948 2954 path-exists@4.0.0:
2949   - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
  2955 + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, tarball: https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz}
2950 2956 engines: {node: '>=8'}
2951 2957  
2952 2958 path-is-absolute@1.0.1:
... ... @@ -3480,7 +3486,7 @@ packages:
3480 3486 resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
3481 3487  
3482 3488 source-map@0.6.1:
3483   - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
  3489 + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz}
3484 3490 engines: {node: '>=0.10.0'}
3485 3491  
3486 3492 source-map@0.7.4:
... ... @@ -3533,7 +3539,7 @@ packages:
3533 3539 resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==}
3534 3540  
3535 3541 string-width@4.2.3:
3536   - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
  3542 + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, tarball: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz}
3537 3543 engines: {node: '>=8'}
3538 3544  
3539 3545 string-width@5.1.2:
... ... @@ -3555,7 +3561,7 @@ packages:
3555 3561 engines: {node: '>=12'}
3556 3562  
3557 3563 strip-final-newline@2.0.0:
3558   - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
  3564 + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, tarball: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz}
3559 3565 engines: {node: '>=6'}
3560 3566  
3561 3567 strip-final-newline@3.0.0:
... ... @@ -3733,7 +3739,7 @@ packages:
3733 3739 engines: {node: '>= 10.0.0'}
3734 3740  
3735 3741 unocss@0.60.2:
3736   - resolution: {integrity: sha512-Cj1IXS+VZuiZtQxHn/ffAAN422gUusUEgF1RS83WyNB0kMsJyIxb9KK9N425QAvQvsKpL5GrZs5KoNtU3zGMog==}
  3742 + resolution: {integrity: sha512-Cj1IXS+VZuiZtQxHn/ffAAN422gUusUEgF1RS83WyNB0kMsJyIxb9KK9N425QAvQvsKpL5GrZs5KoNtU3zGMog==, tarball: https://registry.npmmirror.com/unocss/-/unocss-0.60.2.tgz}
3737 3743 engines: {node: '>=14'}
3738 3744 peerDependencies:
3739 3745 '@unocss/webpack': 0.60.2
... ... @@ -4075,7 +4081,7 @@ packages:
4075 4081 resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
4076 4082  
4077 4083 wrap-ansi@7.0.0:
4078   - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
  4084 + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz}
4079 4085 engines: {node: '>=10'}
4080 4086  
4081 4087 wrap-ansi@8.1.0:
... ... @@ -4125,7 +4131,7 @@ packages:
4125 4131 engines: {node: '>=12'}
4126 4132  
4127 4133 yocto-queue@0.1.0:
4128   - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
  4134 + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, tarball: https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz}
4129 4135 engines: {node: '>=10'}
4130 4136  
4131 4137 zhead@2.2.4:
... ... @@ -4306,15 +4312,6 @@ snapshots:
4306 4312 '@babel/helper-split-export-declaration': 7.24.5
4307 4313 '@babel/helper-validator-identifier': 7.24.5
4308 4314  
4309   - '@babel/helper-module-transforms@7.24.5(@babel/core@7.26.0)':
4310   - dependencies:
4311   - '@babel/core': 7.26.0
4312   - '@babel/helper-environment-visitor': 7.22.20
4313   - '@babel/helper-module-imports': 7.24.3
4314   - '@babel/helper-simple-access': 7.24.5
4315   - '@babel/helper-split-export-declaration': 7.24.5
4316   - '@babel/helper-validator-identifier': 7.24.5
4317   -
4318 4315 '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)':
4319 4316 dependencies:
4320 4317 '@babel/core': 7.26.0
... ... @@ -4441,9 +4438,11 @@ snapshots:
4441 4438 '@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.26.0)':
4442 4439 dependencies:
4443 4440 '@babel/core': 7.26.0
4444   - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.26.0)
  4441 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0)
4445 4442 '@babel/helper-plugin-utils': 7.24.5
4446 4443 '@babel/helper-simple-access': 7.24.5
  4444 + transitivePeerDependencies:
  4445 + - supports-color
4447 4446  
4448 4447 '@babel/plugin-transform-typescript@7.24.5(@babel/core@7.24.5)':
4449 4448 dependencies:
... ... @@ -4465,10 +4464,12 @@ snapshots:
4465 4464 dependencies:
4466 4465 '@babel/core': 7.26.0
4467 4466 '@babel/helper-plugin-utils': 7.24.5
4468   - '@babel/helper-validator-option': 7.23.5
  4467 + '@babel/helper-validator-option': 7.25.9
4469 4468 '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.26.0)
4470 4469 '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.26.0)
4471 4470 '@babel/plugin-transform-typescript': 7.24.5(@babel/core@7.26.0)
  4471 + transitivePeerDependencies:
  4472 + - supports-color
4472 4473  
4473 4474 '@babel/standalone@7.24.5': {}
4474 4475  
... ... @@ -4618,8 +4619,8 @@ snapshots:
4618 4619 '@iconify/types': 2.0.0
4619 4620 debug: 4.3.4
4620 4621 kolorist: 1.8.0
4621   - local-pkg: 0.5.0
4622   - mlly: 1.7.1
  4622 + local-pkg: 0.5.1
  4623 + mlly: 1.7.3
4623 4624 transitivePeerDependencies:
4624 4625 - supports-color
4625 4626  
... ... @@ -4740,6 +4741,8 @@ snapshots:
4740 4741 - encoding
4741 4742 - supports-color
4742 4743  
  4744 + '@mdi/js@7.4.47': {}
  4745 +
4743 4746 '@miyaneee/rollup-plugin-json5@1.2.0(rollup@4.17.2)':
4744 4747 dependencies:
4745 4748 '@rollup/pluginutils': 5.1.0(rollup@4.17.2)
... ... @@ -5546,7 +5549,7 @@ snapshots:
5546 5549 '@unocss/cli@0.60.2(rollup@4.17.2)':
5547 5550 dependencies:
5548 5551 '@ampproject/remapping': 2.3.0
5549   - '@rollup/pluginutils': 5.1.0(rollup@4.17.2)
  5552 + '@rollup/pluginutils': 5.1.3(rollup@4.17.2)
5550 5553 '@unocss/config': 0.60.2
5551 5554 '@unocss/core': 0.60.2
5552 5555 '@unocss/preset-uno': 0.60.2
... ... @@ -5555,7 +5558,7 @@ snapshots:
5555 5558 colorette: 2.0.20
5556 5559 consola: 3.2.3
5557 5560 fast-glob: 3.3.2
5558   - magic-string: 0.30.10
  5561 + magic-string: 0.30.13
5559 5562 pathe: 1.1.2
5560 5563 perfect-debounce: 1.0.0
5561 5564 transitivePeerDependencies:
... ... @@ -5586,7 +5589,7 @@ snapshots:
5586 5589 '@unocss/rule-utils': 0.60.2
5587 5590 css-tree: 2.3.1
5588 5591 fast-glob: 3.3.2
5589   - magic-string: 0.30.10
  5592 + magic-string: 0.30.13
5590 5593 postcss: 8.4.38
5591 5594  
5592 5595 '@unocss/preset-attributify@0.60.2':
... ... @@ -5639,7 +5642,7 @@ snapshots:
5639 5642 '@unocss/rule-utils@0.60.2':
5640 5643 dependencies:
5641 5644 '@unocss/core': 0.60.2
5642   - magic-string: 0.30.10
  5645 + magic-string: 0.30.13
5643 5646  
5644 5647 '@unocss/scope@0.60.2': {}
5645 5648  
... ... @@ -5673,7 +5676,7 @@ snapshots:
5673 5676 '@unocss/vite@0.60.2(rollup@4.17.2)(vite@5.2.11(@types/node@20.12.11)(sass@1.77.1)(terser@5.31.0))':
5674 5677 dependencies:
5675 5678 '@ampproject/remapping': 2.3.0
5676   - '@rollup/pluginutils': 5.1.0(rollup@4.17.2)
  5679 + '@rollup/pluginutils': 5.1.3(rollup@4.17.2)
5677 5680 '@unocss/config': 0.60.2
5678 5681 '@unocss/core': 0.60.2
5679 5682 '@unocss/inspector': 0.60.2
... ... @@ -5681,7 +5684,7 @@ snapshots:
5681 5684 '@unocss/transformer-directives': 0.60.2
5682 5685 chokidar: 3.6.0
5683 5686 fast-glob: 3.3.2
5684   - magic-string: 0.30.10
  5687 + magic-string: 0.30.13
5685 5688 vite: 5.2.11(@types/node@20.12.11)(sass@1.77.1)(terser@5.31.0)
5686 5689 transitivePeerDependencies:
5687 5690 - rollup
... ...
public/logo.svg 0 → 100644
  1 +<?xml version="1.0" standalone="no"?>
  2 +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
  3 + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
  4 +<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
  5 + width="1024.000000pt" height="1024.000000pt" viewBox="0 0 1024.000000 1024.000000"
  6 + preserveAspectRatio="xMidYMid meet">
  7 +
  8 +<g transform="translate(0.000000,1024.000000) scale(0.100000,-0.100000)"
  9 +fill="#000000" stroke="none">
  10 +<path d="M4993 8899 c-26 -265 -80 -388 -417 -947 -95 -158 -224 -368 -288
  11 +-467 -150 -233 -231 -375 -289 -505 -174 -391 -186 -703 -38 -990 139 -268
  12 +483 -545 911 -734 l57 -25 -70 86 c-131 164 -224 341 -275 524 -35 128 -44
  13 +334 -20 462 39 203 101 324 334 645 323 447 445 648 511 847 93 281 55 559
  14 +-116 847 -54 90 -179 261 -244 332 l-44 48 -12 -123z"/>
  15 +<path d="M5587 7583 c-10 -305 -59 -413 -471 -1028 -218 -325 -267 -413 -293
  16 +-519 -29 -122 5 -240 119 -414 l54 -83 18 82 c55 257 191 528 368 732 307 354
  17 +455 838 354 1152 -25 77 -85 183 -124 218 -19 17 -19 15 -25 -140z"/>
  18 +<path d="M6040 7202 c0 -69 -29 -257 -56 -360 -67 -258 -149 -430 -293 -615
  19 +-133 -170 -212 -289 -276 -417 -98 -197 -132 -357 -98 -460 3 -9 14 6 31 40
  20 +27 58 96 131 322 340 258 240 420 480 495 735 33 112 45 308 25 418 -17 94
  21 +-52 195 -96 276 -48 88 -54 93 -54 43z"/>
  22 +<path d="M3189 6402 c-79 -41 -114 -102 -114 -196 0 -50 7 -84 21 -116 37 -81
  23 +512 -574 694 -722 417 -336 851 -494 1305 -475 478 20 937 198 1380 536 128
  24 +97 367 335 428 426 84 125 98 260 40 368 -65 119 -242 162 -374 91 -88 -48
  25 +-127 -99 -394 -509 -170 -261 -302 -414 -460 -531 -209 -155 -433 -227 -705
  26 +-227 -341 0 -621 119 -893 382 -60 59 -139 142 -174 186 -91 112 -234 330
  27 +-349 530 -141 246 -145 252 -206 270 -79 23 -137 19 -199 -13z"/>
  28 +<path d="M6989 5681 c-109 -43 -215 -116 -529 -371 -494 -399 -860 -564 -1337
  29 +-600 -315 -24 -613 37 -904 186 -215 110 -399 247 -689 514 -293 270 -342 295
  30 +-437 224 -61 -46 -64 -135 -6 -226 38 -62 177 -202 288 -291 360 -291 799
  31 +-476 1275 -539 138 -18 477 -15 635 6 573 76 1192 320 1659 654 191 137 269
  32 +261 236 380 -21 79 -92 102 -191 63z"/>
  33 +<path d="M3374 4906 c-108 -49 -29 -247 146 -366 332 -225 997 -364 1587 -330
  34 +386 22 760 88 1078 191 330 106 455 202 455 346 0 61 -30 98 -88 108 -78 13
  35 +-150 -13 -346 -127 -296 -171 -497 -244 -816 -293 -142 -22 -552 -31 -702 -16
  36 +-361 38 -607 128 -913 336 -88 59 -184 119 -212 132 -66 30 -147 39 -189 19z"/>
  37 +<path d="M2548 3310 c-220 -37 -388 -198 -445 -426 -22 -88 -24 -323 -4 -404
  38 +49 -197 177 -345 354 -408 61 -22 90 -26 187 -26 211 -1 352 70 444 223 34 56
  39 +85 186 76 194 -3 2 -60 19 -128 39 -108 32 -124 34 -137 21 -8 -8 -15 -20 -15
  40 +-26 0 -24 -48 -113 -76 -141 -123 -123 -338 -68 -406 104 -19 48 -22 75 -23
  41 +215 0 185 13 241 74 308 109 121 312 115 393 -12 16 -25 32 -58 35 -73 3 -16
  42 +8 -28 11 -28 17 0 247 42 255 47 15 9 1 67 -34 140 -92 193 -316 294 -561 253z"/>
  43 +<path d="M3720 3278 c-6 -13 -113 -286 -239 -608 -168 -427 -227 -588 -219
  44 +-597 7 -9 48 -13 143 -13 l133 0 48 133 49 132 229 0 228 0 52 -133 51 -133
  45 +140 3 c131 3 140 4 143 23 2 15 -291 756 -475 1203 -4 9 -41 12 -139 12 -130
  46 +0 -135 -1 -144 -22z m212 -533 l66 -175 -134 0 c-74 0 -134 3 -134 6 0 15 125
  47 +344 131 344 3 0 35 -79 71 -175z"/>
  48 +<path d="M4635 3288 c-3 -7 -4 -285 -3 -618 l3 -605 116 -3 c89 -2 119 1 127
  49 +11 8 10 13 121 14 363 l3 349 221 -360 221 -360 122 -3 c82 -2 128 1 137 9 19
  50 +16 21 1198 2 1217 -16 16 -220 16 -236 0 -9 -9 -12 -105 -12 -372 0 -303 -2
  51 +-358 -13 -346 -8 8 -112 176 -231 373 l-218 357 -124 0 c-91 0 -126 -3 -129
  52 +-12z"/>
  53 +<path d="M5883 3289 c-20 -20 -19 -1202 1 -1218 9 -8 55 -11 137 -9 l124 3 3
  54 +248 2 247 53 0 c125 0 141 -15 337 -306 l131 -194 148 0 c129 0 150 2 155 16
  55 +12 32 -224 393 -308 472 -31 29 -50 54 -43 57 82 25 118 45 168 95 72 71 94
  56 +131 94 250 -1 71 -5 95 -28 145 -45 97 -110 153 -210 182 -72 21 -745 32 -764
  57 +12z m653 -245 c68 -33 88 -137 37 -194 -38 -42 -79 -49 -265 -50 l-158 0 0
  58 +130 0 130 176 0 c142 0 183 -3 210 -16z"/>
  59 +<path d="M7133 3289 c-10 -10 -13 -146 -13 -610 0 -511 2 -598 15 -609 11 -9
  60 +88 -11 312 -7 326 5 351 8 463 68 77 41 130 101 180 203 48 99 70 204 70 334
  61 +0 317 -121 533 -339 604 -60 19 -93 22 -371 25 -240 4 -308 2 -317 -8z m565
  62 +-244 c109 -33 159 -113 171 -274 15 -205 -17 -363 -86 -420 -49 -40 -101 -51
  63 +-252 -51 l-131 0 0 380 0 380 123 0 c82 0 141 -5 175 -15z"/>
  64 +</g>
  65 +</svg>
... ...
utils/index.ts
1   -import { useDisplay } from 'vuetify'
2   -import { MOBILE_WIDTH } from '../constant/index'
  1 +import { useDisplay } from "vuetify";
  2 +import { MOBILE_WIDTH } from "../constant/index";
3 3  
4 4 export const isMobile = () => {
5   - const { width } = useDisplay()
6   - return width.value <= MOBILE_WIDTH
7   -}
  5 + const { width } = useDisplay();
  6 + return width.value <= MOBILE_WIDTH;
  7 +};
8 8  
9   -export const isEqual = (value:any, other:any) => {
  9 +export const isEqual = (value: any, other: any) => {
10 10 // 获取两个比较值的类型
11 11 const type = Object.prototype.toString.call(value);
12 12  
... ... @@ -14,10 +14,12 @@ export const isEqual = (value:any, other:any) =&gt; {
14 14 if (type !== Object.prototype.toString.call(other)) return false;
15 15  
16 16 // 根据不同的数据类型进行比较
17   - if (type === '[object Object]' || type === '[object Array]') {
  17 + if (type === "[object Object]" || type === "[object Array]") {
18 18 // 比较数组或对象的长度
19   - const valueLen = type === '[object Object]' ? Object.keys(value).length : value.length;
20   - const otherLen = type === '[object Object]' ? Object.keys(other).length : other.length;
  19 + const valueLen =
  20 + type === "[object Object]" ? Object.keys(value).length : value.length;
  21 + const otherLen =
  22 + type === "[object Object]" ? Object.keys(other).length : other.length;
21 23 if (valueLen !== otherLen) return false;
22 24  
23 25 // 递归比较数组或对象中的每个元素
... ... @@ -33,4 +35,4 @@ export const isEqual = (value:any, other:any) =&gt; {
33 35 // 基本数据类型直接比较
34 36 return value === other;
35 37 }
36   -}
37 38 \ No newline at end of file
  39 +};
... ...