Commit e4098c053e3d9eab7f7f0d39f170404c173ea156

Authored by 曾国涛
2 parents a7b494e2 f11f3bbf
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/MobileProductDetail.vue
... ... @@ -226,22 +226,22 @@
226 226 <div v-if="info.physicalproperty" class="tw-mb-[24px]">
227 227 <div class="py-2 pl-2 text-h6">Physical Property</div>
228 228 <v-divider class="tw-mb-[12px]"></v-divider>
229   - <div v-html="info.physicalproperty"></div>
  229 + <div v-html="clearSpanStyle(info.physicalproperty)"></div>
230 230 </div>
231 231 <div v-if="info.storage" class="tw-mb-[24px]">
232 232 <div class="py-2 pl-2 text-h6">Storage</div>
233 233 <v-divider class="tw-mb-[12px]"></v-divider>
234   - <div v-html="info.storage"></div>
  234 + <div v-html="clearSpanStyle(info.storage)"></div>
235 235 </div>
236 236 <div v-if="info.introduction" class="tw-mb-[24px]">
237 237 <div class="py-2 pl-2 text-h6">Introduction</div>
238 238 <v-divider class="tw-mb-[12px]"></v-divider>
239   - <div v-html="info.introduction"></div>
  239 + <div v-html="clearSpanStyle(info.introduction)"></div>
240 240 </div>
241 241 <div v-if="info.description" class="tw-mb-[24px]">
242 242 <div class="py-2 pl-2 text-h6">Description</div>
243 243 <v-divider class="tw-mb-[12px]"></v-divider>
244   - <div v-html="info.description"></div>
  244 + <div v-html="clearSpanStyle(info.description)"></div>
245 245 </div>
246 246 </v-window-item>
247 247 <v-window-item key="2" :value="2">
... ... @@ -309,7 +309,7 @@
309 309 class="d-block"
310 310 />
311 311 <v-card-text class="tw-text-left font-weight-medium title">
312   - <h4>{{ item[0].name }}</h4>
  312 + <h4 class="clamp-text">{{ item[0].name }}</h4>
313 313 </v-card-text>
314 314 </v-card>
315 315 </div>
... ... @@ -370,7 +370,7 @@
370 370 class="d-block"
371 371 />
372 372 <v-card-text class="tw-text-left font-weight-medium title">
373   - <h4>{{ item[0].name }}</h4>
  373 + <h4 class="clamp-text">{{ item[0].name }}</h4>
374 374 </v-card-text>
375 375 </v-card>
376 376 </div>
... ... @@ -505,6 +505,30 @@ const hotTotal = ref(10);
505 505 const isOrNotMobile = isMobile();
506 506 const hoveredItem = ref(null);
507 507  
  508 +const clearSpanStyle = (htmlContent) => {
  509 + if (!htmlContent) return ""; // 检查是否为空
  510 + // 创建一个 DOM 解析器
  511 + const parser = new DOMParser();
  512 + const doc = parser.parseFromString(htmlContent, "text/html");
  513 +
  514 + // 清理 span 的 style 属性
  515 + const spans = doc.querySelectorAll("span");
  516 + spans.forEach((span) => {
  517 + span.removeAttribute("style"); // 清空 style 属性
  518 + });
  519 +
  520 + // 修改 img 的 style 属性,追加 width: 100%
  521 + const imgs = doc.querySelectorAll("img");
  522 + imgs.forEach((img) => {
  523 + const style = img.getAttribute("style") || ""; // 获取现有 style
  524 + if (!style.includes("width: 100%")) {
  525 + img.setAttribute("style", `${style} width: 100%;`.trim()); // 添加 width: 100%
  526 + }
  527 + });
  528 +
  529 + // 返回处理后的 HTML
  530 + return doc.body.innerHTML;
  531 +};
508 532 const navigateToUrl = (url) => {
509 533 window.open(url); // 在新标签页中打开链接
510 534 };
... ... @@ -810,4 +834,14 @@ const hotLength = computed(() =&gt;
810 834 .v-card {
811 835 transition: all 0.3s ease-in-out;
812 836 }
  837 +.clamp-text {
  838 + display: -webkit-box; /* 使用弹性盒子 */
  839 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  840 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  841 + overflow: hidden; /* 隐藏多余内容 */
  842 + text-overflow: ellipsis; /* 添加省略号 */
  843 + white-space: normal; /* 允许换行 */
  844 + line-height: 1.5em; /* 设置每行的高度 */
  845 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  846 +}
813 847 </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.43"
  4 +TAG="1.0.44"
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,567 @@
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 + <h3 class="text-h5 tw-mb-5 tw-mt-5">Other Platforms</h3>
  38 + <div class="tw-mb-5">
  39 + <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block"
  40 + >LinkedIn:</label
  41 + >
  42 + <span>https://www.linkedin.com/company/canrd?originalSubdomain=cn</span>
  43 + </div>
  44 + <div class="tw-mb-5">
  45 + <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block"
  46 + >Amazon:</label
  47 + >
  48 + <span
  49 + >https://www.amazon.com/s?me=A3A2SQ086XUS66&marketplaceID=ATVPDKIKX0DER</span
  50 + >
  51 + </div>
  52 + <div class="tw-mb-5">
  53 + <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block"
  54 + >Alibaba:</label
  55 + >
  56 + <span
  57 + >https://canrd.en.alibaba.com/company_profile.html?spm=a2700.galleryofferlist.normal_offer.d_companyName.262213a0fqshG2</span
  58 + >
  59 + </div>
  60 + <div class="tw-mb-5">
  61 + <label class="text-subtitle-1 tw-mr-4 tw-w-20 tw-inline-block"
  62 + >Youtube:</label
  63 + >
  64 + <span>https://www.youtube.com/@Canrd_Tech</span>
  65 + </div>
  66 + <div style="margin-bottom: 10px">
  67 + <v-tabs
  68 + class="tabs2"
  69 + ref="tabs2"
  70 + v-model="tabRecom"
  71 + style="margin-top: 25px; margin-bottom: 20px"
  72 + color="white"
  73 + bg-color="#eeeeee"
  74 + slider-color="blue-lighten-1"
  75 + selected-class="active"
  76 + v-if="isMobile()"
  77 + >
  78 + <v-tab :value="1">Best Sellers</v-tab>
  79 + <!-- <v-tab :value="3">商品百科</v-tab> -->
  80 + </v-tabs>
  81 + <div class="tw-text-center" v-if="hotLoadingMobile && isMobile()">
  82 + <v-progress-circular
  83 + color="blue-lighten-2"
  84 + indeterminate
  85 + size="64"
  86 + class="tw-m-auto"
  87 + ></v-progress-circular>
  88 + </div>
  89 + <v-item-group multiple v-if="isMobile()">
  90 + <v-row v-if="!hotLoadingMobile">
  91 + <v-col
  92 + v-for="(item, i) in recommendImagesMobile"
  93 + :key="i"
  94 + cols="6"
  95 + lg="3"
  96 + md="4"
  97 + sm="6"
  98 + >
  99 + <div v-if="item !== null">
  100 + <v-card :elevation="4" class="mx-auto" :href="item[0].productUrl">
  101 + <!-- 设置 eager 属性,确保图片直接加载 -->
  102 + <v-img
  103 + :src="item[0].url"
  104 + :alt="item[0].name"
  105 + eager
  106 + class="d-block"
  107 + />
  108 + <v-card-text class="tw-text-left font-weight-medium title">
  109 + <h4 class="clamp-text">{{ item[0].name }}</h4>
  110 + </v-card-text>
  111 + </v-card>
  112 + </div>
  113 + </v-col>
  114 + </v-row>
  115 + <!-- <div
  116 + v-if="!hotTotal"
  117 + class="text-medium-emphasis text-body-1 tw-text-center tw-m-[64px]"
  118 + >
  119 + no data
  120 + </div> -->
  121 + </v-item-group>
  122 + <v-row v-if="isMobile()">
  123 + <v-col>
  124 + <v-pagination
  125 + :size="isMobile() ? 'small' : 'default'"
  126 + v-if="hotTotalMobile"
  127 + v-model="currentIndexMobile"
  128 + @update:modelValue="toggleRowMobile"
  129 + :length="hotLength"
  130 + rounded="0"
  131 + class="tw-float-right tw-mt-[32px]"
  132 + total-visible="5"
  133 + ></v-pagination></v-col
  134 + ></v-row>
  135 + </div>
29 136 </v-card>
  137 + <v-tabs
  138 + class="tabs"
  139 + v-model="tabRecom"
  140 + style="margin-top: 25px"
  141 + color="white"
  142 + bg-color="#eeeeee"
  143 + slider-color="blue-lighten-1"
  144 + selected-class="active"
  145 + v-if="recommendImages[0] !== null && !isMobile()"
  146 + >
  147 + <v-tab :value="1">Best Sellers</v-tab>
  148 + <!-- <v-tab :value="3">商品百科</v-tab> -->
  149 + </v-tabs>
  150 + <div id="image-container" v-if="recommendImages[0] !== null && !isMobile()">
  151 + <div class="recommend-left-box">
  152 + <v-img
  153 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/76c987e13a334be481a346c19c2284f3qy4tjnxps7.png"
  154 + alt="往左移"
  155 + class="recommend-img-left"
  156 + @click="toggleRowLeft"
  157 + />
  158 + </div>
  159 + <div class="image-row" id="row1">
  160 + <!-- <img
  161 + v-for="(imageObj, index) in recommendImages.slice(0, 5)"
  162 + :key="'row1-' + index"
  163 + :src="imageObj[0]?.url"
  164 + :alt="'Image ' + (index + 1)"
  165 + style="margin: 0 5px; width: 200px; height: 200px"
  166 + /> -->
  167 + <div
  168 + v-for="(imageObj, index) in recommendImages"
  169 + :key="'row1-' + index"
  170 + class="imageTotal"
  171 + >
  172 + <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank">
  173 + <img
  174 + :src="imageObj[0]?.url"
  175 + :alt="'Image ' + (index + 1)"
  176 + class="item-imgHot"
  177 + />
  178 + <span class="image-name">
  179 + {{ imageObj[0]?.name }}
  180 + </span>
  181 + </a>
  182 + <div v-else style="width: 200px; height: 200px"></div>
  183 + </div>
  184 + </div>
  185 + <div class="recommend-right-box">
  186 + <v-img
  187 + src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/b5daa0a8f2f140f5b406e984c730a453iznzlekysg.png"
  188 + alt="往右移"
  189 + class="recommend-img-right"
  190 + @click="toggleRowRight"
  191 + />
  192 + </div>
  193 + </div>
30 194 </template>
31 195  
32 196 <script setup lang="ts">
  197 +const productStore = useProductListStore();
  198 +const categoryStore = useCategoryStore();
  199 +const loading = ref(false);
  200 +const hotLoading = ref(false);
  201 +const route = useRoute(); // 获取路由信息
  202 +const router = useRouter(); // 获取路由信息
  203 +const title = ref("");
  204 +const keywordTitle = ref("");
  205 +const maxPage = ref(1);
  206 +const maxPageMobile = ref(1);
  207 +const tabRecom = ref();
  208 +const recommendList = ref({});
  209 +const recommendImages = ref({});
  210 +const currentIndex = ref(1);
  211 +const hotTotal = ref(10);
  212 +const isOrNotMobile = isMobile();
  213 +const recommendListMobile = ref({});
  214 +const recommendImagesMobile = ref({});
  215 +const currentIndexMobile = ref(1);
  216 +const hotLoadingMobile = ref(false);
  217 +const hotTotalMobile = ref(10);
  218 +const loadHotProducts = async () => {
  219 + hotLoading.value = true;
  220 + let { data: hotProducts } = await useAsyncData(
  221 + "hotProducts",
  222 + () =>
  223 + $fetch("/shop/product/hotProducts", {
  224 + method: "GET",
  225 + params: {
  226 + pageNo: currentIndex.value,
  227 + pageSize: 5,
  228 + },
  229 + }),
  230 + {
  231 + server: true, // 仅在服务器端获取数据
  232 + }
  233 + );
  234 + hotTotal.value = hotProducts.value.data.total;
  235 + recommendList.value = hotProducts.value.data.records;
  236 + maxPage.value = hotProducts.value.data.pages;
  237 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  238 + recommendImages.value = Array.from({ length: 5 }).map((_, index) => {
  239 + const item = recommendList.value[index];
  240 + if (!item) {
  241 + return null;
  242 + }
  243 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  244 + if (typeof item.productimageliststore === "string") {
  245 + try {
  246 + item.productimageliststore = JSON.parse(item.productimageliststore);
  247 + } catch (error) {
  248 + item.productimageliststore = []; // 解析失败时,设置为空数组
  249 + }
  250 + }
  251 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  252 + (productItem: ProductImage) => ({
  253 + ...productItem,
  254 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  255 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  256 + name: item.name,
  257 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  258 + })
  259 + ));
  260 + return ree;
  261 + });
  262 + hotLoading.value = false;
  263 +};
  264 +
  265 +const toggleRowLeft = () => {
  266 + if (currentIndex.value !== 1) {
  267 + currentIndex.value--;
  268 + } else if (currentIndex.value == 1) {
  269 + currentIndex.value = maxPage.value;
  270 + }
  271 + startTimer();
  272 +};
  273 +let intervalId: any;
  274 +const toggleRowRight = () => {
  275 + if (currentIndex.value < maxPage.value) {
  276 + currentIndex.value++;
  277 + } else if (currentIndex.value == maxPage.value) {
  278 + currentIndex.value = 1;
  279 + }
  280 + startTimer();
  281 +};
  282 +const startTimer = () => {
  283 + // 清除已有计时器,防止重复
  284 + clearInterval(intervalId);
  285 + intervalId = setInterval(() => {
  286 + toggleRowRight();
  287 + }, 5000); // 每6秒调用一次
  288 +};
  289 +
  290 +onMounted(() => {
  291 + startTimer();
  292 +});
  293 +
  294 +const toggleRowMobile = (value: number) => {
  295 + currentIndexMobile.value = value;
  296 +};
  297 +const { width } = useDisplay();
  298 +const firstIndex = ref(true);
  299 +
  300 +watch(currentIndex, (newIndex) => {
  301 + loadHotProducts(); // Call loadHotProducts when currentIndex changes
  302 +});
  303 +
  304 +const loadHotProductsMobile = async () => {
  305 + hotLoadingMobile.value = true;
  306 + let { data: hotProductsMobile } = await useAsyncData(
  307 + "hotProducts",
  308 + () =>
  309 + $fetch("/shop/product/hotProducts", {
  310 + method: "GET",
  311 + params: {
  312 + pageNo: currentIndexMobile.value,
  313 + pageSize: 4,
  314 + },
  315 + }),
  316 + {
  317 + server: true, // 仅在服务器端获取数据
  318 + }
  319 + );
  320 + hotTotalMobile.value = hotProductsMobile.value.data.total;
  321 + recommendListMobile.value = hotProductsMobile.value.data.records;
  322 + maxPageMobile.value = hotProductsMobile.value.data.pages;
  323 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  324 + recommendImagesMobile.value = Array.from({ length: 4 }).map((_, index) => {
  325 + const item = recommendListMobile.value[index];
  326 + if (!item) {
  327 + return null;
  328 + }
  329 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  330 + if (typeof item.productimageliststore === "string") {
  331 + try {
  332 + item.productimageliststore = JSON.parse(item.productimageliststore);
  333 + } catch (error) {
  334 + item.productimageliststore = []; // 解析失败时,设置为空数组
  335 + }
  336 + }
  337 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  338 + (productItem: ProductImage) => ({
  339 + ...productItem,
  340 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  341 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  342 + name: item.name,
  343 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  344 + })
  345 + ));
  346 + return ree;
  347 + });
  348 + hotLoadingMobile.value = false;
  349 +};
  350 +watch(currentIndexMobile, (newIndex) => {
  351 + loadHotProductsMobile(); // Call loadHotProducts when currentIndex changes
  352 +});
  353 +// Initial load of hot products
  354 +watchEffect(async () => {
  355 + console.log("Current route:", route.fullPath, "Width:", width.value);
  356 +
  357 + if (firstIndex.value) {
  358 + if (width.value > 600) {
  359 + await loadHotProducts();
  360 + } else {
  361 + await loadHotProductsMobile();
  362 + }
  363 + }
  364 +});
33 365 useHead({
34   - title: 'Contact',
  366 + title: "Contact",
  367 +});
  368 +const hotLength = computed(() =>
  369 + hotTotalMobile.value ? Math.ceil(hotTotalMobile.value / 4) : 0
  370 +);
  371 +</script>
  372 +
  373 +<style lang="scss" scoped>
  374 +@media screen and (min-width: 1537px) {
  375 + .tabs {
  376 + border-bottom: 2px solid #1f88e5;
  377 + margin: 10px auto 20px;
  378 + width: 93%;
  379 + }
  380 +}
  381 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  382 + .tabs {
  383 + border-bottom: 2px solid #1f88e5;
  384 + margin: 10px auto 40px;
  385 + width: 78%;
  386 + }
  387 +}
  388 +@media screen and (max-width: 1280px) {
  389 + .tabs {
  390 + border-bottom: 2px solid #1f88e5;
  391 + margin: 10px auto 40px;
  392 + width: 92%;
  393 + }
  394 +}
  395 +/* .tabs {
  396 + border-bottom: 2px solid #1f88e5;
  397 +} */
  398 +
  399 +.active {
  400 + background-color: #1086e8;
  401 +}
  402 +
  403 +@media screen and (min-width: 1537px) {
  404 + #image-container {
  405 + display: flex;
  406 + align-items: center;
  407 + justify-content: center;
  408 + height: 320px;
  409 + margin: 10px auto 50px;
  410 + width: 80%;
  411 + }
  412 +}
  413 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  414 + #image-container {
  415 + display: flex;
  416 + align-items: center;
  417 + justify-content: center;
  418 + height: 260px;
  419 + margin: 10px auto 0px;
  420 + width: 80%;
  421 + padding: 0;
  422 + }
  423 +}
  424 +@media screen and (max-width: 1280px) {
  425 + #image-container {
  426 + display: flex;
  427 + align-items: center;
  428 + justify-content: center;
  429 + height: 260px;
  430 + margin: 10px auto 0px;
  431 + width: 80%;
  432 + padding: 0;
  433 + }
  434 +}
  435 +.image-row {
  436 + display: flex;
  437 + height: 245px;
  438 +}
  439 +@media screen and (min-width: 1537px) {
  440 + .imageTotal {
  441 + display: inline-block;
  442 + margin: 0 5px;
  443 + text-align: center;
  444 + width: 320px;
  445 + }
  446 +}
  447 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  448 + .imageTotal {
  449 + display: inline-block;
  450 + margin: 0 5px;
  451 + text-align: center;
  452 + width: 200px;
  453 + }
  454 +}
  455 +@media screen and (max-width: 1280px) {
  456 + .imageTotal {
  457 + display: inline-block;
  458 + margin: 0 5px;
  459 + text-align: center;
  460 + width: 200px;
  461 + }
  462 +}
  463 +@media screen and (min-width: 1537px) {
  464 + .image-row img {
  465 + width: 240px;
  466 + height: 240px;
  467 + }
  468 +}
  469 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  470 + .image-row img {
  471 + width: 140px;
  472 + height: 140px;
  473 + }
  474 +}
  475 +
  476 +@media screen and (max-width: 1280px) {
  477 + .image-row img {
  478 + width: 140px;
  479 + height: 140px;
  480 + }
  481 +}
  482 +@media screen and (min-width: 1537px) {
  483 + .image-name {
  484 + display: -webkit-box; /* Enables multi-line text handling */
  485 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  486 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  487 + overflow: hidden; /* Hides the overflowed text */
  488 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  489 + margin-top: 5px;
  490 + font-size: 16px;
  491 + width: 180px;
  492 + color: #555;
  493 + text-align: center; /* Centers the text horizontally */
  494 + margin-left: 50px;
  495 + }
  496 +}
  497 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  498 + .image-name {
  499 + display: -webkit-box; /* Enables multi-line text handling */
  500 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  501 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  502 + overflow: hidden; /* Hides the overflowed text */
  503 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  504 + margin-top: 5px;
  505 + font-size: 16px;
  506 + width: 180px;
  507 + color: #555;
  508 + text-align: center; /* Centers the text horizontally */
  509 + margin-left: 10px;
  510 + }
  511 +}
  512 +@media screen and (max-width: 1280px) {
  513 + .image-name {
  514 + display: -webkit-box; /* Enables multi-line text handling */
  515 + -webkit-box-orient: vertical; /* Defines the vertical orientation of the box */
  516 + -webkit-line-clamp: 3; /* Limits the text to 3 lines */
  517 + overflow: hidden; /* Hides the overflowed text */
  518 + text-overflow: ellipsis; /* Adds an ellipsis when the text overflows */
  519 + margin-top: 5px;
  520 + font-size: 16px;
  521 + width: 180px;
  522 + color: #555;
  523 + text-align: center; /* Centers the text horizontally */
  524 + margin-left: 10px;
  525 + }
  526 +}
  527 +
  528 +button .recommendButton {
  529 + margin: 0 0px;
  530 + cursor: pointer;
  531 +}
  532 +
  533 +.recommend-left-box {
  534 +}
  535 +
  536 +// @media screen and (max-width: 1280px) {
  537 +// .recommend-img-left {
  538 +// width: 26px;
  539 +// height: 27px;
  540 +// margin-bottom: 60px;
  541 +// }
  542 +// }
  543 +.recommend-img-left {
  544 + width: 26px;
  545 + height: 27px;
  546 + margin-right: 30px;
  547 + margin-bottom: 60px;
  548 +}
  549 +
  550 +.recommend-img-left:hover {
  551 + cursor: pointer;
  552 +}
  553 +.recommend-right-box {
  554 +}
  555 +
  556 +.recommend-img-right {
  557 + width: 26px;
  558 + height: 27px;
  559 + margin-left: 30px;
  560 + margin-bottom: 60px;
  561 +}
35 562  
36   -})</script>
  563 +.recommend-img-right:hover {
  564 + cursor: pointer;
  565 +}
37 566  
38   -<style lang="less" scoped></style>
  567 +.v-card {
  568 + transition: all 0.3s ease-in-out;
  569 +}
  570 +.clamp-text {
  571 + display: -webkit-box; /* 使用弹性盒子 */
  572 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  573 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  574 + overflow: hidden; /* 隐藏多余内容 */
  575 + text-overflow: ellipsis; /* 添加省略号 */
  576 + white-space: normal; /* 允许换行 */
  577 + line-height: 1.5em; /* 设置每行的高度 */
  578 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  579 +}
  580 +</style>
... ...
pages/index.vue
... ... @@ -31,126 +31,8 @@
31 31 </v-carousel-item>
32 32 </v-carousel>
33 33 </v-rows>
34   - <v-tabs
35   - class="tabs"
36   - v-model="tabRecom"
37   - color="white"
38   - bg-color="#eeeeee"
39   - style="margin-top: 40px"
40   - slider-color="blue-lighten-1"
41   - selected-class="active"
42   - v-if="recommendImages[0] !== null && !isMobile()"
43   - >
44   - <v-tab :value="1">Best Sellers</v-tab>
45   - <!-- <v-tab :value="3">商品百科</v-tab> -->
46   - </v-tabs>
47   - <div id="image-container" v-if="recommendImages[0] !== null && !isMobile()">
48   - <div class="recommend-left-box">
49   - <v-img
50   - src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/76c987e13a334be481a346c19c2284f3qy4tjnxps7.png"
51   - alt="往左移"
52   - class="recommend-img-left"
53   - @click="toggleRowLeft"
54   - />
55   - </div>
56   - <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   - <div
65   - v-for="(imageObj, index) in recommendImages"
66   - :key="'row1-' + index"
67   - class="imageTotal"
68   - >
69   - <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank">
70   - <img
71   - :src="imageObj[0]?.url"
72   - :alt="'Image ' + (index + 1)"
73   - class="item-imgHot"
74   - />
75   - <span class="image-name">
76   - {{ imageObj[0]?.name }}
77   - </span>
78   - </a>
79   - <div v-else style="width: 200px; height: 200px"></div>
80   - </div>
81   - </div>
82   - <div class="recommend-right-box">
83   - <v-img
84   - src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/b5daa0a8f2f140f5b406e984c730a453iznzlekysg.png"
85   - alt="往右移"
86   - class="recommend-img-right"
87   - @click="toggleRowRight"
88   - />
89   - </div>
90   - </div>
91   - <div style="padding-left: 16px; padding-right: 16px">
92   - <v-tabs
93   - class="tabs2"
94   - ref="tabs2"
95   - v-model="tabRecom"
96   - style="margin-top: 25px; margin-bottom: 20px; width: 100%"
97   - color="white"
98   - bg-color="#eeeeee"
99   - slider-color="blue-lighten-1"
100   - selected-class="active"
101   - v-if="isMobile()"
102   - >
103   - <v-tab :value="1">Best Sellers</v-tab>
104   - <!-- <v-tab :value="3">商品百科</v-tab> -->
105   - </v-tabs>
106   - <div class="tw-text-center" v-if="hotLoading && isMobile()">
107   - <v-progress-circular
108   - color="blue-lighten-2"
109   - indeterminate
110   - size="64"
111   - class="tw-m-auto"
112   - ></v-progress-circular>
113   - </div>
114   - <v-item-group multiple v-if="isMobile()">
115   - <v-row v-if="!hotLoading">
116   - <v-col
117   - v-for="(item, i) in recommendImages"
118   - :key="i"
119   - cols="6"
120   - lg="3"
121   - md="4"
122   - sm="6"
123   - >
124   - <div v-if="item !== null">
125   - <v-card :elevation="4" class="mx-auto" :href="item[0].productUrl">
126   - <v-img
127   - :src="item[0].url"
128   - :alt="item[0].name"
129   - eager
130   - class="d-block"
131   - />
132   - <v-card-text class="tw-text-left font-weight-medium title">
133   - <h4>{{ item[0].name }}</h4>
134   - </v-card-text>
135   - </v-card>
136   - </div>
137   - </v-col>
138   - </v-row>
139   - </v-item-group>
140   - <v-row v-if="isMobile()">
141   - <v-col>
142   - <v-pagination
143   - :size="isMobile() ? 'small' : 'default'"
144   - v-if="hotTotal"
145   - v-model="currentIndex"
146   - @update:modelValue="toggleRowMobile"
147   - :length="hotLength"
148   - rounded="0"
149   - class="tw-float-right tw-mt-[32px]"
150   - total-visible="5"
151   - ></v-pagination></v-col
152   - ></v-row>
153   - </div>
  34 + <HotProducts />
  35 +
154 36 <!-- 能源材料 -->
155 37 <div class="tw-py-8 py-sm-16">
156 38 <v-container>
... ... @@ -208,163 +90,16 @@
208 90 />
209 91 </v-container>
210 92 </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 93 </template>
275 94  
276 95 <script setup lang="ts">
277 96 import MainTitleList from "../components/MainTitleList.vue";
278 97 import MainTitleListOdd from "../components/MainTitleListOdd.vue";
  98 +import HotProducts from "../components/HotProducts.vue";
279 99 import { useCategoryStore } from "../stores/category";
280 100 import { computed, onMounted, reactive, ref } from "vue";
281 101 import { isMobile } from "../utils";
282 102  
283   -const maxPage = ref(1);
284   -const tabRecom = ref();
285   -const recommendList = ref();
286   -const recommendImages = ref();
287   -const currentIndex = ref(1);
288   -const hotLoading = ref(false);
289   -const hotTotal = ref(10);
290   -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   -};
343   -
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   -};
361   -
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
367   -
368 103 onMounted(() => {
369 104 console.log(
370 105 "%c [ onMounted ]-10",
... ... @@ -496,9 +231,9 @@ const packs = [
496 231 href: "/pack",
497 232 },
498 233 ];
499   -const hotLength = computed(() =>
500   - hotTotal.value ? Math.ceil(hotTotal.value / 4) : 0
501   -);
  234 +// const hotLength = computed(() =>
  235 +// hotTotal.value ? Math.ceil(hotTotal.value / 4) : 0
  236 +// );
502 237 </script>
503 238 <style scoped>
504 239 @media screen and (min-width: 1537px) {
... ... @@ -512,14 +247,14 @@ const hotLength = computed(() =&gt;
512 247 .tabs {
513 248 border-bottom: 2px solid #1f88e5;
514 249 margin: 10px auto 20px;
515   - width: 80%;
  250 + width: 85%;
516 251 }
517 252 }
518 253 @media screen and (max-width: 1280px) {
519 254 .tabs {
520 255 border-bottom: 2px solid #1f88e5;
521 256 margin: 10px auto 0px;
522   - width: 85%;
  257 + width: 88%;
523 258 }
524 259 }
525 260  
... ... @@ -527,15 +262,6 @@ const hotLength = computed(() =&gt;
527 262 background-color: #1086e8;
528 263 }
529 264  
530   -/* #image-container {
531   - display: flex;
532   - align-items: center;
533   - justify-content: center;
534   - height: 320px;
535   - margin: 10px auto 50px;
536   - width: 80%;
537   -} */
538   -
539 265 @media screen and (min-width: 1537px) {
540 266 #image-container {
541 267 display: flex;
... ... @@ -612,8 +338,28 @@ const hotLength = computed(() =&gt;
612 338 }
613 339 @media screen and (max-width: 1536px) and (min-width: 1281px) {
614 340 .image-row img {
615   - width: 140px;
616   - height: 140px;
  341 + width: 180px;
  342 + height: 180px;
  343 + }
  344 +}
  345 +
  346 +@media screen and (min-width: 1537px) {
  347 + .image-row .image-substitute {
  348 + width: 200px;
  349 + height: 200px;
  350 + }
  351 +}
  352 +@media screen and (max-width: 1536px) and (min-width: 1281px) {
  353 + .image-row .image-substitute {
  354 + width: 200px;
  355 + height: 200px;
  356 + }
  357 +}
  358 +
  359 +@media screen and (max-width: 1280px) {
  360 + .image-row .image-substitute {
  361 + width: 185px;
  362 + height: 185px;
617 363 }
618 364 }
619 365 @media screen and (max-width: 1280px) {
... ... @@ -704,4 +450,14 @@ button .recommendButton {
704 450 .v-card {
705 451 transition: all 0.3s ease-in-out;
706 452 }
  453 +.clamp-text {
  454 + display: -webkit-box; /* 使用弹性盒子 */
  455 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  456 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  457 + overflow: hidden; /* 隐藏多余内容 */
  458 + text-overflow: ellipsis; /* 添加省略号 */
  459 + white-space: normal; /* 允许换行 */
  460 + line-height: 1.5em; /* 设置每行的高度 */
  461 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  462 +}
707 463 </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"
... ... @@ -218,18 +222,20 @@ const title = ref(&quot;&quot;);
218 222 const keywordTitle = ref("");
219 223 const maxPage = ref(1);
220 224 const tabRecom = ref();
221   -const recommendList = ref();
222   -const recommendImages = ref();
  225 +const recommendList = ref({});
  226 +const recommendImages = ref({});
223 227 const currentIndex = ref(1);
224 228 const hotTotal = ref(10);
225   -const isOrNotMobile = isMobile();
  229 +const isOrNotMobile = ref(isMobile());
  230 +const maxPageMobile = ref(1);
  231 +const recommendListMobile = ref({});
  232 +const recommendImagesMobile = ref({});
  233 +const currentIndexMobile = ref(1);
  234 +const hotLoadingMobile = ref(false);
  235 +const hotTotalMobile = ref(10);
226 236  
227 237 const loadHotProducts = async () => {
228   - const pageSize = ref(5);
229   - if (isOrNotMobile) {
230   - pageSize.value = 4;
231   - }
232   - hotLoading.value = true;
  238 + const pageSize = 5;
233 239 let { data: hotProducts } = await useAsyncData(
234 240 "hotProducts",
235 241 () =>
... ... @@ -237,7 +243,7 @@ const loadHotProducts = async () =&gt; {
237 243 method: "GET",
238 244 params: {
239 245 pageNo: currentIndex.value,
240   - pageSize: pageSize.value,
  246 + pageSize: pageSize,
241 247 },
242 248 }),
243 249 {
... ... @@ -248,33 +254,30 @@ const loadHotProducts = async () =&gt; {
248 254 recommendList.value = hotProducts.value.data.records;
249 255 maxPage.value = hotProducts.value.data.pages;
250 256 // 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   - }
  257 + recommendImages.value = Array.from({ length: 5 }).map((_, index) => {
  258 + const item = recommendList.value[index];
  259 + if (!item) {
  260 + return null;
  261 + }
  262 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  263 + if (typeof item.productimageliststore === "string") {
  264 + try {
  265 + item.productimageliststore = JSON.parse(item.productimageliststore);
  266 + } catch (error) {
  267 + item.productimageliststore = []; // 解析失败时,设置为空数组
264 268 }
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 269 }
276   - );
277   - hotLoading.value = false;
  270 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  271 + (productItem: ProductImage) => ({
  272 + ...productItem,
  273 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  274 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  275 + name: item.name,
  276 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  277 + })
  278 + ));
  279 + return ree;
  280 + });
278 281 };
279 282  
280 283 const toggleRowLeft = () => {
... ... @@ -283,24 +286,125 @@ const toggleRowLeft = () =&gt; {
283 286 } else if (currentIndex.value == 1) {
284 287 currentIndex.value = maxPage.value;
285 288 }
  289 + startTimer();
286 290 };
  291 +let intervalId: any;
287 292 const toggleRowRight = () => {
288 293 if (currentIndex.value < maxPage.value) {
289 294 currentIndex.value++;
290 295 } else if (currentIndex.value == maxPage.value) {
291 296 currentIndex.value = 1;
292 297 }
  298 + startTimer();
293 299 };
  300 +const startTimer = () => {
  301 + // 清除已有计时器,防止重复
  302 + clearInterval(intervalId);
  303 + intervalId = setInterval(() => {
  304 + toggleRowRight();
  305 + }, 5000); // 每6秒调用一次
  306 +};
  307 +
  308 +onMounted(() => {
  309 + startTimer();
  310 +});
  311 +
294 312 const toggleRowMobile = (value: number) => {
295   - currentIndex.value = value;
  313 + currentIndexMobile.value = value;
296 314 };
  315 +const { width } = useDisplay();
  316 +const firstHotIndex = ref(true);
  317 +
  318 +// // 监听屏幕宽度变化
  319 +// watch(width, async (newWidth) => {
  320 +// console.log(newWidth, "5656widthvalue");
  321 +// if (firstHotIndex.value) {
  322 +// if (newWidth > 600) {
  323 +// await loadHotProducts();
  324 +// } else {
  325 +// await loadHotProductsMobile();
  326 +// }
  327 +// }
  328 +// });
  329 +
  330 +// // 监听路由变化
  331 +// watch(
  332 +// () => route.fullPath,
  333 +// async () => {
  334 +// if (firstHotIndex.value) {
  335 +// if (width.value > 600) {
  336 +// await loadHotProducts();
  337 +// } else {
  338 +// await loadHotProductsMobile();
  339 +// }
  340 +// }
  341 +// }
  342 +// );
297 343  
298 344 watch(currentIndex, (newIndex) => {
299 345 loadHotProducts(); // Call loadHotProducts when currentIndex changes
300 346 });
301   -// Initial load of hot products
302   -await loadHotProducts(); // Load hot products the first time
303 347  
  348 +const loadHotProductsMobile = async () => {
  349 + hotLoadingMobile.value = true;
  350 + let { data: hotProductsMobile } = await useAsyncData(
  351 + "hotProducts",
  352 + () =>
  353 + $fetch("/shop/product/hotProducts", {
  354 + method: "GET",
  355 + params: {
  356 + pageNo: currentIndexMobile.value,
  357 + pageSize: 4,
  358 + },
  359 + }),
  360 + {
  361 + server: true, // 仅在服务器端获取数据
  362 + }
  363 + );
  364 + hotTotalMobile.value = hotProductsMobile.value.data.total;
  365 + recommendListMobile.value = hotProductsMobile.value.data.records;
  366 + maxPageMobile.value = hotProductsMobile.value.data.pages;
  367 + // recommendImages.value = recommendList.value.slice(0, 10).map((item) => {
  368 + recommendImagesMobile.value = Array.from({ length: 4 }).map((_, index) => {
  369 + const item = recommendListMobile.value[index];
  370 + if (!item) {
  371 + return null;
  372 + }
  373 + // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析
  374 + if (typeof item.productimageliststore === "string") {
  375 + try {
  376 + item.productimageliststore = JSON.parse(item.productimageliststore);
  377 + } catch (error) {
  378 + item.productimageliststore = []; // 解析失败时,设置为空数组
  379 + }
  380 + }
  381 + const ree = (item.productimageliststore = item?.productimageliststore.map(
  382 + (productItem: ProductImage) => ({
  383 + ...productItem,
  384 + // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`,
  385 + url: `https://www.canrud.com/api/show/image?fileKey=${productItem.fileKey}&psize=p256`,
  386 + name: item.name,
  387 + productUrl: `https://www.canrud.com/products/detail/${item.id}`,
  388 + })
  389 + ));
  390 + return ree;
  391 + });
  392 + hotLoadingMobile.value = false;
  393 +};
  394 +watch(currentIndexMobile, (newIndex) => {
  395 + loadHotProductsMobile(); // Call loadHotProducts when currentIndex changes
  396 +});
  397 +watchEffect(async () => {
  398 + console.log("Current route:", route.fullPath, "Width:", width.value);
  399 +
  400 + if (firstHotIndex.value) {
  401 + if (width.value > 600) {
  402 + await loadHotProducts();
  403 + } else {
  404 + await loadHotProductsMobile();
  405 + }
  406 + }
  407 +});
304 408 watchEffect(() => {
305 409 // 遍历数组
306 410 if (router.currentRoute.value.query.categories) {
... ... @@ -441,52 +545,13 @@ watchEffect(async () =&gt; {
441 545 isWindowAssigned.value = true;
442 546 }
443 547 loadProducts();
444   - // console.log(categoryStore.selectedSubCategory, "5656index-categoryStore");
445 548 });
446   -// onMounted(() => {
447   -// // window.selectedSubCategory = categoryStore.selectedSubCategory;
448   -// // window.selectedFuncCategory = categoryStore.selectedFuncCategory;
449   -// if (route.query.function) {
450   -// const functionName = route.query.function.trim();
451   -// const funcCategoryList = computed(() => {
452   -// if (categoryStore.selectedCategory) {
453   -// const tmp = categoryStore.list.filter(
454   -// (item) => item.categoryDisplayName === categoryStore.selectedCategory
455   -// );
456   -// return tmp?.[0]?.productFunctions || [];
457   -// }
458   -// return [];
459   -// });
460   -// const foundFuncCategory = funcCategoryList.value.find(
461   -// (func) => func.name === functionName
462   -// );
463   -
464   -// if (foundFuncCategory) {
465   -// const funcCategoryId = foundFuncCategory.id;
466   -// if (typeof localStorage !== "undefined") {
467   -// localStorage.setItem("selectedFuncCategory2", funcCategoryId);
468   -// localStorage.setItem("selectedFuncCategory3", "1");
469   -// }
470   -// // 你可以在这里使用找到的 funcCategoryId
471   -// }
472   -// // // 6. 查找对应的功能分类 ID
473   -// // const foundFuncCategory = funcCategories.find(
474   -// // (func) => func.name === functionName
475   -// // );
476   -
477   -// // if (foundFuncCategory) {
478   -// // const funcCategoryId = foundFuncCategory.id;
479   -// // // 使用找到的 funcCategoryId
480   -// // categoryStore.updateFuncCategory(funcCategoryId);
481   -// // }
482   -// }
483   -// });
484 549  
485 550 const length = computed(() =>
486 551 productStore.total ? Math.ceil(productStore.total / productStore.pageSize) : 0
487 552 );
488 553 const hotLength = computed(() =>
489   - hotTotal.value ? Math.ceil(hotTotal.value / 4) : 0
  554 + hotTotalMobile.value ? Math.ceil(hotTotalMobile.value / 4) : 0
490 555 );
491 556 </script>
492 557  
... ... @@ -695,4 +760,35 @@ button .recommendButton {
695 760 .v-card {
696 761 transition: all 0.3s ease-in-out;
697 762 }
  763 +
  764 +.v-card-text {
  765 + max-width: 100%; /* 确保文字宽度受限 */
  766 +}
  767 +.item-name {
  768 + display: -webkit-box !important;
  769 + -webkit-box-orient: vertical !important;
  770 + -webkit-line-clamp: 3 !important;
  771 + overflow: hidden !important;
  772 + text-overflow: ellipsis !important;
  773 + white-space: normal !important;
  774 + text-align: left;
  775 + line-height: 1.5em;
  776 + min-height: calc(3 * 1.5em); /* 强制未满三行时高度一致 */
  777 +}
  778 +
  779 +#product-card .v-responsive.v-img {
  780 + width: 274px !important; /* 设置宽度 */
  781 + height: 274px !important; /* 设置高度 */
  782 +}
  783 +
  784 +.clamp-text {
  785 + display: -webkit-box; /* 使用弹性盒子 */
  786 + -webkit-box-orient: vertical; /* 设置为垂直方向 */
  787 + -webkit-line-clamp: 3; /* 限制最多显示3行 */
  788 + overflow: hidden; /* 隐藏多余内容 */
  789 + text-overflow: ellipsis; /* 添加省略号 */
  790 + white-space: normal; /* 允许换行 */
  791 + line-height: 1.5em; /* 设置每行的高度 */
  792 + min-height: calc(3 * 1.5em); /* 确保最小高度为3行 */
  793 +}
698 794 </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 +};
... ...