소스 검색

Merge branch 'master' of http://face3d.4dage.com:7005/shaogen1995/YFYC-H5 into master

shaogen1995 2 년 전
부모
커밋
c3a30189dc

BIN
src/assets/img/service/【古建筑】.png


BIN
src/assets/img/service/【快速浏览】.png


BIN
src/assets/img/service/【西洋建筑】.png


BIN
src/assets/img/service/一日游.png


src/libs/ua-parser.min.js → src/assets/libs/ua-parser.min.js


+ 73 - 0
src/components/TabbarSmall.vue

@@ -0,0 +1,73 @@
+<template>
+  <div class="tabbar-small">
+    <ul>
+      <li
+        v-for="(item, index) in tabList"
+        :key="item"
+        :class="{
+          active: index === activeTabIdx,
+        }"
+        @click="activeTabIdx = index"
+      >
+        {{item}}
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    tabList: {
+      type: Array,
+      require: true,
+    },
+  },
+  data() {
+    return {
+      activeTabIdx: 0,
+    }
+  },
+  watch: {
+    activeTabIdx: {
+      handler(vNew) {
+        this.$emit('change', vNew)
+      },
+      immediate: true,
+    }
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.tabbar-small {
+  margin-top: 3.1vw;
+  margin-bottom: 3.6vw;
+  > ul {
+    display: flex;
+    align-items: center;
+    > li {
+      margin-right: 12vw;
+      position: relative;
+      font-size: 3.2vw;
+      font-weight: 600;
+      color: #333333;
+      &.active {
+        font-weight: bold;
+        &::after {
+          content: '';
+          display: absolute;
+          top: calc(100% + 0.9vw);
+          position: absolute;
+          left: 50%;
+          transform: translateX(-50%);
+          width: 10.1vw;
+          height: 1.3vw;
+          background: linear-gradient(0deg, #FF615C 0%, #FF9877 100%);
+          border-radius: 0.7vw;
+        }
+      }
+    }
+  }
+}
+</style>

+ 1 - 1
src/main.js

@@ -2,7 +2,7 @@ import Vue from 'vue'
 import App from './App.vue'
 import router from './router'
 import store from './store'
-// import UAParser from "@/libs/ua-parser.min.js"
+// import UAParser from "@/assets/libs/ua-parser.min.js"
 import clickOutside from "@/directives/v-click-outside.js"
 import 'viewerjs/dist/viewer.css'
 import Viewer from 'v-viewer'

+ 12 - 12
src/utils/index.js

@@ -7,12 +7,12 @@
  * isRememberLastCall:是否在一组中最后一次调用后等delay时长再执行fn
  * 
  * 如果isRememberLastCall为false,意味着fn不会被延迟执行,所以fnDebounced执行时,要么在内部调用fn,同步返回fn返回值;要么内部决定本次不调用fn,同步返回null。
- * 如果isRememberLastCall为true,意味着fn可能被延迟执行,所以fnDebounced会返回一个Promise,在fn被调用时用其返回值resolve该Promise,或者在fn的延时调用计划被取消时用null reject该Promise。
+ * 如果isRememberLastCall为true,意味着fn可能被延迟执行,所以fnDebounced会返回一个Promise,在fn被调用时用其返回值resolve该Promise,或者在fn的延时调用计划被取消时用'canceled'resolve该Promise。(不宜reject,否则又没有人去catch,会导致浏览器报错。)
  */
 export function debounce(fn, delay = 250, isImmediateCall = false, isRememberLastCall = true) {
   console.assert(isImmediateCall || isRememberLastCall, 'isImmediateCall 和 isRememberLastCall 至少应有一个是true,否则没有意义!')
   let timer = null
-  let retPromiseLastTimeRejector = null
+  let retPromiseLastTimeResolver = null
   // 上次调用的时刻
   let lastCallTime = 0
 
@@ -32,15 +32,15 @@ export function debounce(fn, delay = 250, isImmediateCall = false, isRememberLas
         clearTimeout(timer)
         timer = null
       }
-      if (retPromiseLastTimeRejector) {
-        retPromiseLastTimeRejector(null)
-        retPromiseLastTimeRejector = null
+      if (retPromiseLastTimeResolver) {
+        retPromiseLastTimeResolver('canceled')
+        retPromiseLastTimeResolver = null
       }
       const ret = new Promise((resolve, reject) => {
-        retPromiseLastTimeRejector = reject
+        retPromiseLastTimeResolver = resolve
         timer = setTimeout(() => {
           timer = null
-          retPromiseLastTimeRejector = null
+          retPromiseLastTimeResolver = null
           resolve(fn.apply(this, args))
         }, delay)
       })
@@ -59,16 +59,16 @@ export function debounce(fn, delay = 250, isImmediateCall = false, isRememberLas
           clearTimeout(timer)
           timer = null
         }
-        if (retPromiseLastTimeRejector) {
-          retPromiseLastTimeRejector(null)
-          retPromiseLastTimeRejector = null
+        if (retPromiseLastTimeResolver) {
+          retPromiseLastTimeResolver('canceled')
+          retPromiseLastTimeResolver = null
         }
         const ret = new Promise((resolve, reject) => {
-          retPromiseLastTimeRejector = reject
+          retPromiseLastTimeResolver = resolve
           timer = setTimeout(() => {
             lastCallTime = 0
             timer = null
-            retPromiseLastTimeRejector = null
+            retPromiseLastTimeResolver = null
             resolve(fn.apply(this, args))
           }, delay)
         })

+ 214 - 17
src/views/Serve/index.vue

@@ -50,36 +50,98 @@
       <h3>推荐路线</h3>
       <router-link class="more" to="/">更多  》</router-link>
       <div class="grid-wrap">
+        <div class="left-wrap card">
+          <img src="@/assets/img/service/一日游.png" alt="" draggable="false">
+          <h4>一日游</h4>
+        </div>
+        <div class="right-wrap">
+          <div class="card">
+            <img src="@/assets/img/service/【快速浏览】.png" alt="" draggable="false">
+            <h4>【快速浏览】</h4>
+          </div>
+          <div class="card">
+            <img src="@/assets/img/service/【西洋建筑】.png" alt="" draggable="false">
+            <h4>【西洋建筑】</h4>
+          </div>
+          <div class="card">
+            <img src="@/assets/img/service/【古建筑】.png" alt="" draggable="false">
+            <h4>【古建筑】</h4>
+          </div>
+        </div>
       </div>
     </div>
 
     <div class="travel-plague">
       <h3>出游防疫</h3>
       <router-link class="more" to="/">更多  》</router-link>
-      <!-- todo tab -->
-      <div class="swiper">
-        <!-- todo -->
+      <TabbarSmall :tabList="['景区开放', '出行政策']" @change="onTravelPlageTabbarChange"></TabbarSmall>
+      <div class="open-status" v-show="travelPlagueActiveIdx === 0">
+        <div class="swiper-container">
+          <div class="swiper-wrapper">
+            <div class="swiper-slide">
+              <img src="@/assets/img/service/【古建筑】.png" alt="">
+              <div class="title-wrap">
+                <h4>芜湖方特旅游区</h4>
+              </div>
+            </div>
+            <div class="swiper-slide">
+              <img src="@/assets/img/service/【快速浏览】.png" alt="">
+              <div class="title-wrap">
+                <h4>芜湖方特旅游区</h4>
+              </div>
+            </div>
+            <div class="swiper-slide">
+              <img src="@/assets/img/service/【西洋建筑】.png" alt="">
+              <div class="title-wrap">
+                <h4>芜湖方特旅游区</h4>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="open-status" v-show="travelPlagueActiveIdx === 1">
+        <div class="swiper-container">
+          <div class="swiper-wrapper">
+            <div class="swiper-slide">
+              <img src="@/assets/img/service/【古建筑】.png" alt="">
+              <div class="title-wrap">
+                <h4>电话1</h4>
+              </div>
+            </div>
+            <div class="swiper-slide">
+              <img src="@/assets/img/service/【快速浏览】.png" alt="">
+              <div class="title-wrap">
+                <h4>电话2</h4>
+              </div>
+            </div>
+            <div class="swiper-slide">
+              <img src="@/assets/img/service/【西洋建筑】.png" alt="">
+              <div class="title-wrap">
+                <h4>电话3</h4>
+              </div>
+            </div>
+          </div>
+        </div>
       </div>
-      <!-- todo 服务电话 -->
     </div>
 
     <div class="help-center">
       <h3>帮助中心</h3>
       <router-link class="more" to="/">更多  》</router-link>
-      <!-- todo tab -->
-      <ul class="questions">
-        <li v-for="n in 10" :key="n">
+      <TabbarSmall :tabList="['常见问题', '服务电话']" @change="onHelpCenterTabbarChange"></TabbarSmall>
+      <ul class="questions" v-show="helpCenterActiveIdx === 0">
+        <div v-for="n in 10" :key="n">
           <h4>芜湖全员核酸检测点最新安排出炉</h4>
           <span class="name">佚名用户</span>
           <span class="time">2022-10-10</span>
-        </li>
+        </div>
       </ul>
-      <ul class="phones">
-        <li v-for="n in 10" :key="n">
-          <h4>芜湖全员核酸检测点最新安排出炉</h4>
+      <ul class="phones" v-show="helpCenterActiveIdx === 1">
+        <div v-for="n in 10" :key="n">
+          <h4>电话电话电话</h4>
           <span class="name">佚名用户</span>
           <span class="time">2022-10-10</span>
-        </li>
+        </div>
       </ul>
     </div>
 
@@ -91,14 +153,19 @@
 
 <script>
 import BackTop from "@/components/BackTop.vue";
+import TabbarSmall from "@/components/TabbarSmall.vue";
+import Swiper from "../../assets/libs/swiper.js";
 
 export default {
 components: {
-  BackTop
+  BackTop,
+  TabbarSmall,
 },
 data() {
   return {
     searchKeyword: '',
+    travelPlagueActiveIdx: '',
+    helpCenterActiveIdx: '',
   };
 },
 computed: {},
@@ -106,13 +173,25 @@ watch: {},
 methods: {
   onClickSearch() {
 
+  },
+  onTravelPlageTabbarChange(idx) {
+    this.travelPlagueActiveIdx = idx
+    this.$nextTick(() => {
+      new Swiper(".swiper-container", {
+        slidesPerView: 1.4,
+        spaceBetween: 15,
+        centeredSlides: true,
+      })
+    })
+  },
+  onHelpCenterTabbarChange(idx) {
+    this.helpCenterActiveIdx = idx
   }
 },
 created() {
 
 },
 mounted() {
-
 },
 beforeCreate() {}, //生命周期 - 创建之前
 beforeMount() {}, //生命周期 - 挂载之前
@@ -125,9 +204,10 @@ activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
 </script>
 
 <style lang='less' scoped>
+@import "~@/assets/libs/swiper.css";
 .service {
   background-color: #f0f0f0;
-  height: calc(100% - 40px);
+  height: calc(100% - 80px);
   overflow: auto;
   .banner {
     height: 31.9vw;
@@ -233,6 +313,65 @@ activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
       font-size: 2.7vw;
       color: #333333;
     }
+    .grid-wrap {
+      margin-top: 3.1rem;
+      .left-wrap {
+        display: inline-block;
+        position: relative;
+        width: 41.9vw;
+        height: 56.8vw;
+        border-radius: 1.3vw;
+        margin-right: 2vw;
+        > img {
+          position: absolute;
+          left: 0;
+          top: 0;
+          width: 100%;
+          height: 100%;
+        }
+        > h4 {
+          position: absolute;
+          left: 3.9vw;
+          top: 3.1vw;
+          font-size: 6.4vw;
+          letter-spacing: 0.3em;
+          font-weight: bold;
+          color: #FFFFFF;
+          text-shadow: 0px 4px 4px #3A180F;
+          writing-mode: vertical-rl;
+        }
+      }
+      .right-wrap {
+        display: inline-block;
+        > .card {
+          position: relative;
+          width: 47.5vw;
+          height: 18.4vw;
+          margin-bottom: 0.8vw;
+          &:last-of-type {
+            margin-bottom: initial;
+          }
+          > img {
+            position: absolute;
+            right: 0;
+            top: 0;
+            width: 100%;
+            height: 100%;
+          }
+          > h4 {
+            position: absolute;
+            right: 1.1vw;
+            height: 100%;
+            font-size: 2.7vw;
+            font-weight: 500;
+            color: #FEFEFE;
+            writing-mode: vertical-rl;
+            text-align: center;
+            letter-spacing: 0.12em;
+          }
+        }
+      }
+    }
   }
 
   > .travel-plague {
@@ -254,12 +393,41 @@ activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
       font-size: 2.7vw;
       color: #333333;
     }
+    .open-status {
+      margin-top: 6vw;
+      .swiper-slide {
+        width: 75.5vw;
+        height: 31.2vw;
+        > img {
+          position: absolute;
+          left: 0;
+          top: 0;
+          width: 100%;
+          height: 100%;
+        }
+        > .title-wrap {
+          position: absolute;
+          left: 0;
+          bottom: 0;
+          width: 100%;
+          height: 8.5vw;
+          background-color: rgba(15, 5, 9, 0.54);
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          > h4 {
+            font-size: 3.2vw;
+            font-weight: 600;
+            color: #FFFFFF;
+          }
+        }
+      }
+    }
   }
 
   > .help-center {
     border-radius: 1.1vw;
     margin: 0 0.7vw 4vw 0.7vw;
-    overflow: hidden;
     position: relative;
     padding: 1.9vw 3.5vw 4.5vw;
     background: #fff;
@@ -275,11 +443,40 @@ activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
       font-size: 2.7vw;
       color: #333333;
     }
+    > ul {
+      margin-top: 6vw;
+      height: 42vw;
+      overflow: auto;
+      > div {
+        border-bottom: 1px solid #E5E5E5;
+        margin-bottom: 7.1vw;
+        &:last-of-type {
+          border-bottom: initial;
+          margin-bottom: initial;
+        }
+        > h4 {
+          font-size: 3.2vw;
+          font-weight: bold;
+          color: #000000;
+          overflow: hidden;
+          white-space: pre;
+          text-overflow: ellipsis;
+          margin-bottom: 3.9vw;
+        }
+        > span {
+          display: inline-block;
+          margin-right: 2em;
+          margin-bottom: 1.5vw;
+          font-size: 3.2vw;
+          color: #DCDCDC;
+        }
+      }
+    }
   }
   
   > .back-top {
     position: fixed;
-    bottom: calc(1.7vw + 40px);
+    bottom: calc(1.7vw + 80px);
     right: 1.7vw;
     width: 9.3vw;
     height: 9.3vw;