Переглянути джерело

Merge branch 'dev' of http://1.94.207.143:3000/xyy/xyy-m into dev

suwenjiang 2 місяців тому
батько
коміт
c467147066
33 змінених файлів з 402 додано та 216 видалено
  1. 27 4
      src/assets/iconfont/demo_index.html
  2. 8 4
      src/assets/iconfont/iconfont.css
  3. 0 0
      src/assets/iconfont/iconfont.js
  4. 7 0
      src/assets/iconfont/iconfont.json
  5. 2 0
      src/assets/iconfont/iconfont.svg
  6. BIN
      src/assets/iconfont/iconfont.ttf
  7. BIN
      src/assets/iconfont/iconfont.woff
  8. BIN
      src/assets/iconfont/iconfont.woff2
  9. BIN
      src/assets/img/home/home_hot_projects_bg.png
  10. BIN
      src/assets/img/home/home_menu_car.png
  11. BIN
      src/assets/img/home/home_menu_house.png
  12. BIN
      src/assets/img/home/home_menu_note.png
  13. BIN
      src/assets/img/home/home_menu_visa.png
  14. BIN
      src/assets/img/home/home_plane.png
  15. BIN
      src/assets/img/kefu_qrcode.png
  16. 31 30
      src/components/Footer/index.vue
  17. 2 6
      src/components/Home/Banner.vue
  18. 31 26
      src/components/Home/HotCountry/index.vue
  19. 66 12
      src/components/Home/HotTravelProjects/Item.vue
  20. 32 26
      src/components/Home/HotTravelProjects/index.vue
  21. 10 4
      src/components/Home/Menu/index.vue
  22. 33 0
      src/components/Home/SectionHeader/index.vue
  23. 2 7
      src/components/Home/TravelMenu/Item.vue
  24. 3 1
      src/components/Home/TravelMenu/index.vue
  25. 20 19
      src/components/Home/TravelNotes/Item.vue
  26. 96 0
      src/components/Home/TravelNotes/index.client.vue
  27. 0 56
      src/components/Home/TravelNotes/index.vue
  28. 3 0
      src/components/TravelProjectDetail/BookInfo.vue
  29. 8 2
      src/pages/house/components/filters.vue
  30. 10 9
      src/pages/index.vue
  31. 4 0
      src/pages/t/[id].client.vue
  32. 3 6
      src/pages/yj/[id].vue
  33. 4 4
      src/utils/request.js

+ 27 - 4
src/assets/iconfont/demo_index.html

@@ -55,6 +55,12 @@
           <ul class="icon_lists dib-box">
           
             <li class="dib">
+              <span class="icon iconfont">&#xe7ec;</span>
+                <div class="name">left</div>
+                <div class="code-name">&amp;#xe7ec;</div>
+              </li>
+          
+            <li class="dib">
               <span class="icon iconfont">&#xe7eb;</span>
                 <div class="name">right</div>
                 <div class="code-name">&amp;#xe7eb;</div>
@@ -192,10 +198,10 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1734919733283') format('woff2'),
-       url('iconfont.woff?t=1734919733283') format('woff'),
-       url('iconfont.ttf?t=1734919733283') format('truetype'),
-       url('iconfont.svg?t=1734919733283#iconfont') format('svg');
+  src: url('iconfont.woff2?t=1735367455324') format('woff2'),
+       url('iconfont.woff?t=1735367455324') format('woff'),
+       url('iconfont.ttf?t=1735367455324') format('truetype'),
+       url('iconfont.svg?t=1735367455324#iconfont') format('svg');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -222,6 +228,15 @@
         <ul class="icon_lists dib-box">
           
           <li class="dib">
+            <span class="icon iconfont icon-left"></span>
+            <div class="name">
+              left
+            </div>
+            <div class="code-name">.icon-left
+            </div>
+          </li>
+          
+          <li class="dib">
             <span class="icon iconfont icon-right"></span>
             <div class="name">
               right
@@ -430,6 +445,14 @@
           
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-left"></use>
+                </svg>
+                <div class="name">left</div>
+                <div class="code-name">#icon-left</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-right"></use>
                 </svg>
                 <div class="name">right</div>

+ 8 - 4
src/assets/iconfont/iconfont.css

@@ -1,9 +1,9 @@
 @font-face {
   font-family: "iconfont"; /* Project id 4723464 */
-  src: url('iconfont.woff2?t=1734919733283') format('woff2'),
-       url('iconfont.woff?t=1734919733283') format('woff'),
-       url('iconfont.ttf?t=1734919733283') format('truetype'),
-       url('iconfont.svg?t=1734919733283#iconfont') format('svg');
+  src: url('iconfont.woff2?t=1735367455324') format('woff2'),
+       url('iconfont.woff?t=1735367455324') format('woff'),
+       url('iconfont.ttf?t=1735367455324') format('truetype'),
+       url('iconfont.svg?t=1735367455324#iconfont') format('svg');
 }
 
 .iconfont {
@@ -14,6 +14,10 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-left:before {
+  content: "\e7ec";
+}
+
 .icon-right:before {
   content: "\e7eb";
 }

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
src/assets/iconfont/iconfont.js


+ 7 - 0
src/assets/iconfont/iconfont.json

@@ -6,6 +6,13 @@
   "description": "",
   "glyphs": [
     {
+      "icon_id": "4767012",
+      "name": "left",
+      "font_class": "left",
+      "unicode": "e7ec",
+      "unicode_decimal": 59372
+    },
+    {
       "icon_id": "4767011",
       "name": "right",
       "font_class": "right",

+ 2 - 0
src/assets/iconfont/iconfont.svg

@@ -14,6 +14,8 @@
     />
       <missing-glyph />
       
+      <glyph glyph-name="left" unicode="&#59372;" d="M724 677.7V755c0 6.7-7.7 10.4-12.9 6.3L260.3 409.2c-16.4-12.8-16.4-37.5 0-50.3l450.8-352.1c5.3-4.1 12.9-0.4 12.9 6.3v77.3c0 4.9-2.3 9.6-6.1 12.6l-360 281 360 281.1c3.8 3 6.1 7.7 6.1 12.6z"  horiz-adv-x="1024" />
+      
       <glyph glyph-name="right" unicode="&#59371;" d="M765.7 409.2L314.9 761.3c-5.3 4.1-12.9 0.4-12.9-6.3v-77.3c0-4.9 2.3-9.6 6.1-12.6l360-281.1-360-281.1c-3.9-3-6.1-7.7-6.1-12.6V13c0-6.7 7.7-10.4 12.9-6.3l450.8 352.1c16.4 12.8 16.4 37.6 0 50.4z"  horiz-adv-x="1024" />
       
       <glyph glyph-name="menu" unicode="&#59380;" d="M904 736H120c-4.4 0-8-3.6-8-8v-64c0-4.4 3.6-8 8-8h784c4.4 0 8 3.6 8 8v64c0 4.4-3.6 8-8 8zM904 112H120c-4.4 0-8-3.6-8-8v-64c0-4.4 3.6-8 8-8h784c4.4 0 8 3.6 8 8v64c0 4.4-3.6 8-8 8zM904 424H120c-4.4 0-8-3.6-8-8v-64c0-4.4 3.6-8 8-8h784c4.4 0 8 3.6 8 8v64c0 4.4-3.6 8-8 8z"  horiz-adv-x="1024" />

BIN
src/assets/iconfont/iconfont.ttf


BIN
src/assets/iconfont/iconfont.woff


BIN
src/assets/iconfont/iconfont.woff2


BIN
src/assets/img/home/home_hot_projects_bg.png


BIN
src/assets/img/home/home_menu_car.png


BIN
src/assets/img/home/home_menu_house.png


BIN
src/assets/img/home/home_menu_note.png


BIN
src/assets/img/home/home_menu_visa.png


BIN
src/assets/img/home/home_plane.png


BIN
src/assets/img/kefu_qrcode.png


+ 31 - 30
src/components/Footer/index.vue

@@ -1,13 +1,11 @@
 <template>
-  <div class="bg-[#FFFBF7] px-15 pb-30">
-    <div class="py-15">
-      <div class="flex items-center space-x-10">
-        <div class="w-3 h-17 bg-primary"></div>
-        <span class="text-black-3 text-xl font-semibold"
-          >我们足迹踏过的地区</span
-        >
-      </div>
-      <div class="flex flex-wrap gap-10 mt-10">
+  <div
+    class="bg-[#FFFBF7] py-20 px-20 pb-30 flex flex-col items-center text-black-6 text-sm"
+  >
+    <div class="pb-15 flex flex-col items-center">
+      <div class="text-black-3 text-xl font-semibold">我们足迹踏过的地区</div>
+      <div class="w-24 h-3 my-5 bg-primary"></div>
+      <div class="flex flex-wrap gap-20 mt-10">
         <NuxtLink
           :to="`/travel-projects?area=${item.parentId}&country=${item.id}`"
           v-for="item in hotCountryData"
@@ -18,11 +16,9 @@
       </div>
     </div>
     <van-divider />
-    <div class="py-15">
-      <div class="flex items-center space-x-10">
-        <div class="w-3 h-17 bg-primary"></div>
-        <span class="text-black-3 text-xl font-semibold">逍遥游旅游网</span>
-      </div>
+    <div class="py-15 flex flex-col items-center">
+      <div class="text-black-3 text-xl font-semibold">逍遥游旅游网</div>
+      <div class="w-24 h-3 my-5 bg-primary"></div>
       <div
         class="text-sm text-black-6 flex flex-col items-center mt-10 leading-[26px]"
       >
@@ -31,29 +27,34 @@
       </div>
     </div>
     <van-divider />
-    <div class="py-15">
-      <div class="flex items-center space-x-10">
-        <div class="w-3 h-17 bg-primary"></div>
-        <span class="text-black-3 text-xl font-semibold">关于我们</span>
-      </div>
-      <div class="flex items-center text-sm text-black-6 mt-10 space-x-20">
+    <div class="py-15 flex flex-col items-center">
+      <div class="text-black-3 text-xl font-semibold">关于我们</div>
+      <div class="w-24 h-3 my-5 bg-primary"></div>
+      <div class="flex items-center text-sm text-black-6 mt-10 space-x-30">
         <div>隐私政策</div>
         <div>用户协议</div>
       </div>
     </div>
+    <div class="bg-[#E0E8F6] opacity-30 h-1 w-full mt-10"></div>
     <van-divider />
-    <div class="flex items-center py-15 text-black-6 text-sm">
-      <img
-        src="~/assets/img/home/contract_travel_qrcode.png"
-        class="h-70 w-70 object-contain"
-        alt=""
-      />
-      <div class="flex flex-col items-center ml-40">
-        <span class="text-black-6 text-xl">扫一扫</span>
-        <span class="mt-5 text-sm">旅游顾问(扫码添加)</span>
+    <div class="flex items-center py-15 text-black-6 space-x-30">
+      <div class="flex flex-col items-center space-y-10">
+        <img
+          src="~/assets/img/home/contract_travel_qrcode.png"
+          class="h-70 w-70 object-contain"
+          alt=""
+        />
+        <span>旅游顾问(扫码添加)</span>
+      </div>
+      <div class="flex flex-col items-center space-y-10">
+        <img
+          src="~/assets/img/kefu_qrcode.png"
+          class="h-70 w-70 object-contain"
+        />
+        <span>公司客服(扫码添加)</span>
       </div>
     </div>
-    <div class="text-black-6 text-sm">
+    <div class="text-black-9 text-sm mt-15">
       <span>©2024 xiaoyaotravel.com All Rights Reserved</span>
       <NuxtLink to="https://beian.miit.gov.cn/" target="_blank"
         >鲁ICP备2024119076号-1</NuxtLink

+ 2 - 6
src/components/Home/Banner.vue

@@ -1,12 +1,8 @@
 <template>
-  <van-swipe
-    :autoplay="3000"
-    :show-indicators="false"
-    class="rounded-xl overflow-hidden"
-  >
+  <van-swipe :autoplay="3000" :show-indicators="false" class="">
     <van-swipe-item v-for="item in bannerList" :key="item.id">
       <img
-        class="object-cover w-full aspect-[1053/612] rounded-xl"
+        class="object-cover w-full aspect-[375/161]"
         :src="item.imgUrlsAfterConvert[0]"
       />
     </van-swipe-item>

+ 31 - 26
src/components/Home/HotCountry/index.vue

@@ -1,30 +1,29 @@
 <template>
-  <div class="flex justify-center">
-    <div class="w-wrap">
-      <div class="flex flex-col items-center space-y-5">
-        <div class="font-bold text-black-3 text-xl">热门目的地</div>
-        <div class="h-4 w-38 rounded-full bg-primary"></div>
-      </div>
-      <div class="grid grid-cols-2 gap-10 mt-20">
-        <NuxtLink
-          v-for="item in hotCountryData"
-          :to="`/travel-notes?area=${item.parentId}&country=${item.id}`"
-          class="relative cursor-pointer overflow-hidden rounded-lg transition-all"
+  <div class="px-20">
+    <HomeSectionHeader
+      title="热门目的地"
+      subTitle="Popular destinations"
+      :show-more="false"
+    />
+    <div class="flex overflow-scroll scrollbar space-x-15">
+      <NuxtLink
+        :to="`/travel-notes?area=${item.parentId}&country=${item.id}`"
+        v-for="item in hotCountryData"
+        :key="item"
+        class="relative"
+      >
+        <van-image
+          :src="formatImgSrc(item.hotPictureUrlsAfterConvert)"
+          fit="cover"
+          class="w-135 h-180 object-cover"
+          radius="10px"
+        />
+        <div
+          class="text-white text-xl font-semibold absolute left-0 bottom-12 right-0 px-10 flex items-center justify-center"
         >
-          <van-image
-            :src="formatImgSrc(item.hotPictureUrlsAfterConvert)"
-            fit="cover"
-            class="w-full aspect-[224/215] object-cover"
-            alt=""
-            srcset=""
-          />
-          <div
-            class="absolute bottom-0 left-0 right-0 flex h-37 items-center bg-gradient-to-b from-transparent to-[#020202] pl-10"
-          >
-            <span class="text-l text-white"> {{ item.menuName }}</span>
-          </div>
-        </NuxtLink>
-      </div>
+          <div class="truncate">{{ item.menuName }}</div>
+        </div>
+      </NuxtLink>
     </div>
   </div>
 </template>
@@ -34,4 +33,10 @@ const { data } = await useMyFetch(`website/basic/directoryList?isHotspot=1`);
 const hotCountryData = computed(() => (data.value?.dataList ?? []).slice(0, 4));
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.scrollbar::-webkit-scrollbar {
+  width: 0px;
+  height: 0px;
+  background-color: #ccc;
+}
+</style>

+ 66 - 12
src/components/Home/HotTravelProjects/Item.vue

@@ -2,30 +2,84 @@
   <NuxtLink
     :to="`/t/${itemData.id}`"
     target="_blank"
-    class="flex cursor-pointer flex-col"
+    class="flex shrink-0 w-240 box-border flex-col relative"
   >
-    <van-image
-      :src="formatImgSrc(itemData.homeHotPicturesAfterConvert)"
-      class="aspect-[226/254] object-cover"
-      radius="10px"
-      fit="cover"
-    />
-    <span class="mt-5 truncate text-xl font-bold text-black-3">
-      {{ itemData.shortTitle }}
+    <van-swipe
+      ref="swiperRef"
+      :autoplay="300000"
+      :show-indicators="false"
+      :loop="true"
+      :touchable="false"
+      class="overflow-hidden rounded-xl"
+    >
+      <van-swipe-item
+        v-for="item in itemData.fileUrlList"
+        :key="item.id"
+        class="border-[#ffffff4d] border-[2px] overflow-hidden rounded-xl"
+      >
+        <img class="object-cover w-240 h-180" :src="item" />
+      </van-swipe-item>
+    </van-swipe>
+    <div
+      @click.prevent="handleLeftClick"
+      class="w-26 h-26 z-50 bg-[#00000066] flex shadow-sm items-center justify-center absolute left-10 top-80 rounded-full"
+    >
+      <span class="iconfont icon-left text-white"></span>
+    </div>
+    <div
+      @click.prevent="handleRightClick"
+      class="w-26 h-26 z-50 bg-[#00000066] flex shadow-sm items-center justify-center absolute right-10 top-80 rounded-full"
+    >
+      <span class="iconfont icon-right text-white"></span>
+    </div>
+    <span class="mt-15 text-white line-clamp-2 text-xl font-bold">
+      {{ itemData.projectTitle }}
     </span>
-    <span class="mt-5 truncate text-base text-black-6">{{
-      itemData.shortDescription
+    <span class="mt-12 line-clamp-2 leading-[26px] text-[#FFEBB9] text-base">{{
+      itemData.remarks
     }}</span>
+    <div class="flex items-center mt-15 space-x-10 text-base text-white">
+      <span> [{{ itemData.startPlace }}出发] </span>
+      <span>[{{ itemData.countTimes }}]</span>
+    </div>
+    <div class="flex items-center flex-wrap gap-10 mt-15">
+      <div
+        v-for="label in projectLabels"
+        :key="label"
+        class="h-20 border-[#999999] bg-[#0000004d] text-sm text-[#FFEBB9] border flex items-center justify-center rounded-full px-6"
+      >
+        {{ label }}
+      </div>
+    </div>
   </NuxtLink>
 </template>
 
 <script setup>
-defineProps({
+const props = defineProps({
   itemData: {
     type: Object,
     default: () => {},
   },
 });
+
+const projectLabels = computed(() => {
+  return props.itemData.projectLabel.split("&").filter((item) => Boolean(item));
+});
+
+const swiperRef = ref(null);
+
+function handleLeftClick() {
+  if (swiperRef.value) {
+    swiperRef.value.prev();
+  }
+}
+
+function handleRightClick() {
+  console.log(swiperRef.value);
+  if (swiperRef.value) {
+    swiperRef.value.next();
+  }
+}
 </script>
 
 <style lang="scss" scoped></style>

+ 32 - 26
src/components/Home/HotTravelProjects/index.vue

@@ -1,34 +1,34 @@
 <template>
-  <div class="w-full">
-    <div class="relative mx-auto w-wrap">
-      <div class="flex items-center justify-between">
-        <div class="flex items-center space-x-5">
-          <img src="~/assets/img/home/home_plane.png" class="h-25 w-25" />
-          <div>
-            <div class="text-sm font-bold text-black-3">热门项目</div>
-            <div class="h-2 w-50 bg-primary"></div>
-            <div class="text-sm text-primary">Popular projectss</div>
-          </div>
-        </div>
-        <div class="flex items-center space-x-10">
-          <NuxtLink
-            to="/travel-projects"
-            class="flex h-30 px-15 cursor-pointer items-center justify-center space-x-5 rounded-full bg-primary"
-          >
-            <span class="text-sm font-bold text-white">了解更多</span>
-            <span
-              class="iconfont icon-arrow_right text-white"
-              style="font-size: 14px"
-            ></span>
-          </NuxtLink>
-        </div>
+  <div class="px-20">
+    <HomeSectionHeader
+      title="热门项目"
+      subTitle="Popular projects"
+      more-to-url="/travel-projects"
+    />
+    <div
+      class="w-full bg-[url('~/assets/img/home/home_hot_projects_bg.png')] bg-no-repeat bg-bottom bg-cover pb-30 rounded-xl overflow-hidden"
+    >
+      <div class="text-white pl-50 pt-20">
+        <div class="text-base">梦想旅行,触手可及</div>
+        <div class="text-sm mt-3">Dream travel, within reach</div>
       </div>
-      <div class="mt-15 grid grid-cols-2 gap-x-10 gap-y-20">
+      <div class="flex overflow-scroll mt-20 scrollbar">
         <HomeHotTravelProjectsItem
           v-for="item in travelProjectList"
           :key="item"
           :item-data="item"
+          class="ml-15"
         />
+        <NuxtLink
+          to="/travel-projects"
+          class="border w-240 mx-15 shrink-0 border-[#DFE0E4] rounded-xl bg-[#0B5C4D99] flex flex-col items-center justify-center text-xl text-white"
+        >
+          <span
+            class="iconfont icon-arrow_right"
+            style="font-size: 20px"
+          ></span>
+          <span>了解更多</span>
+        </NuxtLink>
       </div>
     </div>
   </div>
@@ -36,9 +36,15 @@
 
 <script setup>
 const { data } = await useMyFetch(
-  `website/tourism/project/list?isHotspot=1&pageNum=1&pageSize=4`
+  `website/tourism/project/list?isHotspot=1&pageNum=1&pageSize=10`
 );
 const travelProjectList = computed(() => data.value?.dataList ?? []);
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.scrollbar::-webkit-scrollbar {
+  width: 0px;
+  height: 0px;
+  background-color: #ccc;
+}
+</style>

+ 10 - 4
src/components/Home/Menu/index.vue

@@ -1,13 +1,13 @@
 <template>
-  <div class="flex items-center justify-around">
+  <div class="flex items-center justify-around bg-white">
     <NuxtLink
       :to="`/${item.to}`"
       v-for="item in menuData"
       :key="item.title"
-      class="flex items-center space-x-5"
+      class="flex flex-col items-center space-y-5"
     >
-      <img :src="item.icon" class="w-20 h-20" alt="" srcset="" />
-      <span class="text-sm text-black-6">{{ item.title }}</span>
+      <img :src="item.icon" class="w-24 h-24" alt="" srcset="" />
+      <span class="text-base text-black-3">{{ item.title }}</span>
     </NuxtLink>
   </div>
 </template>
@@ -16,6 +16,7 @@
 import home_menu_car from "~/assets/img/home/home_menu_car.png";
 import home_menu_house from "~/assets/img/home/home_menu_house.png";
 import home_menu_visa from "~/assets/img/home/home_menu_visa.png";
+import home_menu_note from "~/assets/img/home/home_menu_note.png";
 
 const menuData = [
   {
@@ -33,6 +34,11 @@ const menuData = [
     to: "house",
     icon: home_menu_visa,
   },
+  {
+    title: "写游记",
+    to: "note-create",
+    icon: home_menu_note,
+  },
 ];
 </script>
 

+ 33 - 0
src/components/Home/SectionHeader/index.vue

@@ -0,0 +1,33 @@
+<template>
+  <div class="flex items-end justify-between py-15">
+    <div class="flex items-end space-x-8">
+      <span class="text-black-3 text-2xl font-semibold">{{ title }}</span>
+      <div class="flex flex-col">
+        <img :src="plane" class="w-20" />
+        <span class="text-[#707070] text-sm">{{ subTitle }}</span>
+      </div>
+    </div>
+    <NuxtLink v-if="showMore" :to="moreToUrl" class="text-base text-[#acadb6]"
+      >了解更多</NuxtLink
+    >
+  </div>
+</template>
+
+<script setup>
+import plane from "~/assets/img/home/home_plane.png";
+
+defineProps({
+  title: String,
+  subTitle: String,
+  showMore: {
+    type: Boolean,
+    default: true,
+  },
+  moreToUrl: {
+    type: String,
+    default: "",
+  },
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 2 - 7
src/components/Home/TravelMenu/Item.vue

@@ -1,17 +1,12 @@
 <template>
   <NuxtLink
     :to="itemData.to"
-    class="flex cursor-pointer items-center justify-between rounded-xl border bg-white p-10 px-10 transition-all"
+    class="flex cursor-pointer border-r h-36 border-[#ededed] items-center space-x-10 justify-center p-10 px-10"
   >
     <div>
-      <div class="text-base font-bold text-black-3">
+      <div class="text-xl font-bold text-black-3">
         {{ itemData.title }}
       </div>
-      <!-- <div class="text-sm text-black-6">{{ itemData.subTitle }}</div>
-      <div
-        class="mt-5 h-2 w-18"
-        :style="{ backgroundColor: itemData.color }"
-      ></div> -->
     </div>
     <img :src="itemData.icon" class="h-20 w-20 object-contain" alt="" />
   </NuxtLink>

+ 3 - 1
src/components/Home/TravelMenu/index.vue

@@ -1,5 +1,7 @@
 <template>
-  <div class="grid grid-cols-3 gap-10">
+  <div
+    class="grid grid-cols-3 gap-y-15 py-15 bg-white shadow-[0px_4px_4px_0px_rgba(0,0,0,0.05);]"
+  >
     <HomeTravelMenuItem
       v-for="item in menuData"
       :key="item.title"

+ 20 - 19
src/components/Home/TravelNotes/Item.vue

@@ -1,30 +1,31 @@
 <template>
   <NuxtLink
     :to="`/yj/${itemData.id}`"
-    target="_blank"
-    class="relative cursor-pointer rounded-xl bg-white p-8"
+    class="relative block box-border rounded-xl pb-15 shrink-0 overflow-hidden bg-white border border-[#DFE0E4]"
   >
-    <div
-      class="absolute top-0 left-20 z-10 flex h-25 w-25 items-center justify-center rounded-md bg-[#ffffff80]"
-    >
-      <img
-        src="@/assets/img/home/home_travel_note_leaf.png"
-        class="h-20 w-20 object-cover"
-      />
-    </div>
     <van-image
       :src="formatImgSrc(itemData.homeHotPicturesAfterConvert)"
-      radius="10px"
+      width="100%"
       fit="cover"
-      class="w-full aspect-[230/172] object-cover"
-    />
-    <div class="text-base font-bold flex items-center text-primary mt-5">
-      <img
+      class="w-full object-cover aspect-[267/150] relative"
+    >
+      <div
         v-if="itemData.isOriginal === 1"
-        src="~/assets/img/home/original_label.png"
-        class="inline-block h-20 object-cover"
-      />
-      <span class="truncate">{{ itemData.projectTitle }}</span>
+        class="absolute top-0 right-0 h-28 w-60 bg-[#ffffff80] rounded-bl-xl flex items-center justify-center"
+      >
+        <img
+          src="~/assets/img/home/original_label.png"
+          class="inline-block h-20 object-cover"
+        />
+      </div>
+    </van-image>
+    <div class="px-10">
+      <div class="truncate w-full mt-8 font-semibold text-black text-base">
+        {{ itemData.projectTitle }}
+      </div>
+      <div class="truncate w-full mt-8 text-black-3 text-sm">
+        {{ itemData.remarks }}
+      </div>
     </div>
   </NuxtLink>
 </template>

+ 96 - 0
src/components/Home/TravelNotes/index.client.vue

@@ -0,0 +1,96 @@
+<template>
+  <div class="px-20 relative">
+    <HomeSectionHeader
+      title="旅行游记"
+      subTitle="Hot items"
+      more-to-url="/travel-notes"
+    />
+    <swiper-container ref="containerRef" class="swiper">
+      <swiper-slide v-for="(item, index) in travelNotesList" :key="item.id">
+        <HomeTravelNotesItem :itemData="item" />
+      </swiper-slide>
+      <swiper-slide>
+        <NuxtLink
+          to="/travel-notes"
+          class="border aspect-[267/230] border-[#DFE0E4] rounded-xl bg-[#FAFAFA] flex flex-col items-center justify-center text-xl text-black-3"
+        >
+          <span
+            class="iconfont icon-arrow_right"
+            style="font-size: 24px"
+          ></span>
+          <span>了解更多</span>
+        </NuxtLink>
+      </swiper-slide>
+    </swiper-container>
+    <div
+      @click="handleLeftClick"
+      class="w-30 h-30 bg-white flex shadow-sm items-center justify-center absolute left-10 top-140 z-50 rounded-full"
+    >
+      <span class="iconfont icon-left text-[#b0b0b0]"></span>
+    </div>
+    <div
+      @click="handleRightClick"
+      class="w-30 h-30 bg-white flex shadow-sm items-center justify-center absolute right-10 top-140 z-50 rounded-full"
+    >
+      <span class="iconfont icon-right text-[#b0b0b0]"></span>
+    </div>
+    <!-- <div class="relative">
+      <div class="flex w-full overflow-scroll space-x-20 scrollbar">
+        <HomeTravelNotesItem
+          v-for="item in travelNotesList"
+          :key="item.id"
+          :itemData="item"
+        />
+      </div>
+      <div
+        @click="handleLeftClick"
+        class="w-30 h-30 bg-white flex shadow-sm items-center justify-center absolute -left-10 top-1/2 -translate-y-1/2 rounded-full"
+      >
+        <span class="iconfont icon-left text-[#b0b0b0]"></span>
+      </div>
+      <div
+        @click="handleRightClick"
+        class="w-30 h-30 bg-white flex shadow-sm items-center justify-center absolute -right-10 top-1/2 -translate-y-1/2 rounded-full"
+      >
+        <span class="iconfont icon-right text-[#b0b0b0]"></span>
+      </div>
+    </div> -->
+  </div>
+</template>
+
+<script setup>
+const { data } = await useMyFetch(
+  `website/tourism/projectTravelNotes/homeList?pageNum=1&pageSize=10`
+);
+const travelNotesList = computed(() => data.value?.dataList ?? []);
+
+const containerRef = ref(null);
+const swiper = useSwiper(containerRef, {
+  effect: "creative",
+  autoplay: {
+    delay: 5000,
+  },
+  freeMode: {
+    enabled: true,
+  },
+  // freeMode: true,
+  slidesPerView: 1.2,
+  spaceBetween: 17,
+});
+
+function handleLeftClick() {
+  swiper.prev();
+}
+
+function handleRightClick() {
+  swiper.next();
+}
+</script>
+
+<style lang="scss" scoped>
+.scrollbar::-webkit-scrollbar {
+  width: 0px;
+  height: 0px;
+  background-color: #ccc;
+}
+</style>

+ 0 - 56
src/components/Home/TravelNotes/index.vue

@@ -1,56 +0,0 @@
-<template>
-  <div
-    class="bg-[url('~/assets/img/home/home_travel_notes_bg.png')] bg-cover bg-center bg-no-repeat px-15 pt-15"
-  >
-    <div class="relative mx-auto w-wrap">
-      <div class="flex items-center justify-between">
-        <div class="flex items-center space-x-5">
-          <img src="~/assets/img/home/home_plane.png" class="h-25 w-25" />
-          <div>
-            <div class="text-sm font-bold text-black-3">旅行游记</div>
-            <div class="h-2 w-50 bg-primary"></div>
-            <div class="text-sm text-primary">Hot items</div>
-          </div>
-        </div>
-        <div class="flex items-center space-x-10">
-          <NuxtLink
-            to="/note-create-start"
-            class="flex h-30 px-15 cursor-pointer items-center justify-center space-x-5 rounded-full bg-primary"
-          >
-            <span class="text-sm font-bold text-white">写游记</span>
-            <span
-              class="iconfont icon-edit-square text-white"
-              style="font-size: 14px"
-            ></span>
-          </NuxtLink>
-          <NuxtLink
-            to="/travel-notes"
-            class="flex h-30 px-15 cursor-pointer items-center justify-center space-x-5 rounded-full bg-primary"
-          >
-            <span class="text-sm font-bold text-white">了解更多</span>
-            <span
-              class="iconfont icon-arrow_right text-white"
-              style="font-size: 14px"
-            ></span>
-          </NuxtLink>
-        </div>
-      </div>
-      <div class="mt-20 grid grid-cols-2 gap-x-10 gap-y-12">
-        <HomeTravelNotesItem
-          v-for="item in travelNotesList"
-          :key="item"
-          :item-data="item"
-        />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-const { data } = await useMyFetch(
-  `website/tourism/projectTravelNotes/homeList?pageNum=1&pageSize=6`
-);
-const travelNotesList = computed(() => data.value?.dataList ?? []);
-</script>
-
-<style lang="scss" scoped></style>

+ 3 - 0
src/components/TravelProjectDetail/BookInfo.vue

@@ -50,12 +50,14 @@
           <van-field
             v-model="customerName"
             label="联系人"
+            required
             maxlength="50"
             placeholder="请输入联系人"
           />
           <van-field
             v-model="customerMobile"
             label="联系电话"
+            required
             type="tel"
             maxlength="20"
             placeholder="请输入联系电话"
@@ -70,6 +72,7 @@
           <van-field
             v-model="customerWechat"
             label="微信"
+            required
             maxlength="50"
             placeholder="请输入微信"
           />

+ 8 - 2
src/pages/house/components/filters.vue

@@ -8,7 +8,7 @@
             <van-dropdown-item v-if="props.listType!='rentHouse'" @change="doEmit()" :title="price_select == 0 ? '价格' : priceList[price_select].text"
                 v-model="price_select" :options="priceList" />
             <van-dropdown-item title="户型">
-                <div class="text-[#333] text-[12px] p-15">
+                <div class="text-[#333] text-[12px] p-15 pl-25">
                     <div class="text-[14px] text-[#444]">厅室</div>
                     <div class="flex items-center justify-between mt-10">
                         <div @click="officeTypeId = item.itemId, doEmit()" class="bg-[#e4e4e4] px-8 py-4 rounded"
@@ -38,7 +38,7 @@
                 </div>
             </van-dropdown-item>
             <van-dropdown-item title="更多">
-                <div class="text-[#333] text-[12px] p-15">
+                <div class="text-[#333] text-[12px] p-15 pl-25">
                     <div class="text-[14px] text-[#444]">楼层</div>
                     <div v-if="props.listType == 'newHouse' || props.listType=='oldHouse'" class="flex items-center mt-10">
                         <div @click="floor_select = item.itemId, doEmit()" class="bg-[#e4e4e4] mr-20 px-8 py-4 rounded"
@@ -510,4 +510,10 @@ function doEmit() {
 ::v-deep .van-picker__confirm {
     color: #fd9a00;
 }
+::v-deep .van-dropdown-item__option--active{
+    color: #fd9a00;
+}
+::v-deep .van-dropdown-item__icon::before{
+    color: #fd9a00;
+}
 </style>

+ 10 - 9
src/pages/index.vue

@@ -1,14 +1,15 @@
 <template>
-  <div class="bg-[#F1F1F1] mt-10">
-    <div class="px-15 bg-white pb-15">
+  <div>
+    <div class="bg-white pb-50">
       <HomeBanner />
-      <HomeTravelMenu class="mt-10" />
-      <HomeMenu class="mt-10" />
-    </div>
-    <HomeTravelNotes />
-    <div class="bg-white mt-20 px-15 pt-15 pb-30">
-      <HomeHotTravelProjects />
-      <HomeHotCountry class="mt-30" />
+      <HomeTravelMenu />
+      <HomeMenu class="mt-15" />
+      <div class="text-2xl font-semibold text-black-6 pl-20 pt-20">
+        探索世界热门景点
+      </div>
+      <HomeTravelNotes />
+      <HomeHotTravelProjects class="mt-10" />
+      <HomeHotCountry class="mt-10" />
     </div>
     <Footer />
   </div>

+ 4 - 0
src/pages/t/[id].client.vue

@@ -117,6 +117,10 @@ function handleSubmitInfo() {
     return;
   }
 
+  if (!bookInfo.customerWechat) {
+    showToast("请输入微信号");
+    return;
+  }
   submitLoading.value = true;
   request("/website/tourism/myOrder/add", {
     method: "post",

+ 3 - 6
src/pages/yj/[id].vue

@@ -253,7 +253,8 @@
         </div>
       </div>
     </div>
-    <div v-else class=" text-[#999] mt-100">
+    
+    <div v-if="['error'].includes(status)">
       <div class="text-center">
         不好意思,找不到这篇游记了~
       </div>
@@ -361,11 +362,7 @@ function textareaFocus() {
 // 获取评论列表
 const commentList = ref([])
 async function getComments() {
-  showLoadingToast({
-    forbidClick: true,
-    duration: 0,
-  })
-  const { data } = await request("/website/comment/tourTravelNotesComment/list?travelNoteId=" + id.value).finally(()=>closeToast())
+  const { data } = await request("/website/comment/tourTravelNotesComment/list?travelNoteId=" + id.value)
   if (!Array.isArray(data) || !data.length) return commentList.value = []
   commentList.value = data
 }

+ 4 - 4
src/utils/request.js

@@ -70,10 +70,10 @@ const handleServerError = async (code, msg) => {
   if (code === "UNAUTHORIZED_LOGIN") {
     const authStore = useAuthStore();
     authStore.cleanToken();
-    // await navigateTo({
-    //   path: '/login',
-    //   replace: true
-    // })
+    await navigateTo({
+      path: "/login",
+      replace: true,
+    });
     return;
   }
   if (msg) {

Деякі файли не було показано, через те що забагато файлів було змінено