Przeglądaj źródła

移动端页面更新

shaogen1995 3 lat temu
rodzic
commit
979ddf7da6

BIN
webM/public/data/1.png


+ 42 - 1
webM/src/assets/base.css

@@ -70,4 +70,45 @@ body {
 
 /* 移动端横竖屏字体乎⼤乎⼩ */
 /* -webkit-text-size-adjust: none;  */
-/* 禁⽌⽂字⾃动调整⼤⼩(默认情况下旋转设备的时候⽂字⼤⼩会发⽣变化),此属性也不继承,⼀般加在body上规定整个body的⽂字都不会⾃动调整  */
+/* 禁⽌⽂字⾃动调整⼤⼩(默认情况下旋转设备的时候⽂字⼤⼩会发⽣变化),此属性也不继承,⼀般加在body上规定整个body的⽂字都不会⾃动调整  */
+.comTit{
+  width: 100%;
+  height: 80px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.comTit img{
+  width: 20px;
+  margin-top: 2px;
+}
+.comTit span{
+  display: inline-block;
+  font-family: 'SYST';
+  font-size: 18px;
+  color: #9F171C;
+  margin: 0 10px;
+}
+.comBs{
+  position: absolute;
+  bottom: 10px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 29px;
+  height: 29px;
+  background: url('../assets/img/slide.png');
+  background-size: 100% 100%;
+}
+.opcBase{
+  opacity: 0 !important;
+}
+.conShowLoad{
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}

BIN
webM/src/assets/img/btnDe.png


BIN
webM/src/assets/img/btn_record.png


BIN
webM/src/assets/img/cCj/1.png


BIN
webM/src/assets/img/comBs1.png


BIN
webM/src/assets/img/comBs2.png


BIN
webM/src/assets/img/copy.png


BIN
webM/src/assets/img/download.png


BIN
webM/src/assets/img/llBg.png


BIN
webM/src/assets/img/loading.gif


BIN
webM/src/assets/img/mainBg.png


BIN
webM/src/assets/img/meanHeng.png


BIN
webM/src/assets/img/meanShu.png


BIN
webM/src/assets/img/menu.png


BIN
webM/src/assets/img/playCard.png


Plik diff jest za duży
+ 13 - 0
webM/src/assets/swiper/swiper.css


Plik diff jest za duży
+ 14 - 0
webM/src/assets/swiper/swiper.js


+ 292 - 0
webM/src/components/five.vue

@@ -0,0 +1,292 @@
+<template>
+  <div class="five">
+    <div class="comTit">
+      <img src="../assets/img/comBs1.png" alt="" />
+      <span>{{ tit }}</span>
+      <img src="../assets/img/comBs2.png" alt="" />
+    </div>
+    <div class="main" :class="{ opcBase: conShowLoad }">
+      <div class="row" v-for="item in data" :key="item.id">
+        <img :src="baseURL + imgSrc(item)" alt="" />
+        <div class="txt">
+          <p :title="item.txt1"><span>编号:</span>{{ item.txt1 }}</p>
+          <p :title="item.txt2"><span>类型:</span>{{ item.txt2 }}</p>
+        </div>
+        <div class="txt">
+          <p :title="item.name"><span>名称:</span>{{ item.name }}</p>
+          <p :title="item.txt3"><span>年代:</span>{{ item.txt3 }}</p>
+        </div>
+        <!-- 详情按钮 -->
+        <div class="detailBtn" @click="lookDetail(item)"></div>
+      </div>
+    </div>
+    <!-- 点击详情出来的弹窗 -->
+    <div class="detailBox" v-if="detailShow">
+      <div class="detailMain">
+        <!-- 标题 -->
+        <h3 class="detailTit">环境信息</h3>
+        <!-- 文字信息 -->
+        <div class="detailRow">
+          <p>
+            <span>名称:</span><i>{{ detailData.name }}</i>
+          </p>
+          <p>
+            <span>编号:</span><i>{{ detailData.txt1 }}</i>
+          </p>
+          <p>
+            <span>类型:</span><i>{{ detailData.txt2 }}</i>
+          </p>
+          <p>
+            <span>年代:</span><i>{{ detailData.txt3 }}</i>
+          </p>
+          <p>
+            <span>简介:</span><i>{{ detailData.txt4 }}</i>
+          </p>
+        </div>
+        <!-- 轮播图 -->
+        <!-- 图片 -->
+        <div class="detailImg">
+          <div class="swiper-container detailImgSon">
+            <div class="swiper-wrapper detailImgSon">
+              <div
+                class="swiper-slide detailImgSon"
+                v-for="item in detailData.imgList"
+                :key="item.id"
+              >
+                <img
+                  class="detailImgSonImg"
+                  :src="baseURL + item.filePath"
+                  alt=""
+                />
+              </div>
+            </div>
+          </div>
+        </div>
+        <!-- 关闭按钮 -->
+        <div class="detailClose" @click="detailShow = false"></div>
+      </div>
+    </div>
+    <!-- 切换下一页 -->
+    <div class="comBs" @click="$emit('pageNext')"></div>
+    <!-- 数据加载中 -->
+    <div class="conShowLoad" v-show="conShowLoad">
+      <img src="../assets/img/loading.gif" alt="" />
+    </div>
+  </div>
+</template>
+
+<script>
+import Swiper from "@/assets/swiper/swiper.js";
+import axios from "@/utils/request";
+export default {
+  name: "five",
+  props: {
+    tit: {
+      type: String,
+    },
+    data: {
+      type: Array,
+      default: () => [],
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      conShowLoad: true,
+      baseURL: "",
+      detailData: {},
+      detailShow: false,
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {
+    detailShow(val) {
+      if (val) {
+        this.$nextTick(() => {
+          new Swiper(".five .swiper-container", {
+            slidesPerView: 1.2,
+            spaceBetween: 10,
+          });
+        });
+      }
+    },
+  },
+  //方法集合
+  methods: {
+    imgSrc(item) {
+      return item.imgList.find((v) => v.id === item.imgActive).filePath;
+    },
+    lookDetail(item) {
+      this.detailData = item;
+      this.detailShow = true;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL;
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.conShowLoad = false;
+      }, 1000);
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+@import "../assets/swiper/swiper.css";
+.five {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .main {
+    width: 100%;
+    height: calc(100% - 130px);
+    overflow-y: auto;
+    padding: 0 18px;
+    .row {
+      display: flex;
+      position: relative;
+      width: 100%;
+      height: 95px;
+      margin-bottom: 15px;
+      padding-bottom: 15px;
+      border-bottom: 1px solid #bfb094;
+      & > img {
+        width: 110px;
+        height: 80px;
+        object-fit: cover;
+        margin-right: 10px;
+      }
+      .txt {
+        font-size: 14px;
+        width: 100px;
+        color: #8a7351;
+        display: flex;
+        flex-direction: column;
+        margin-right: 8px;
+        p {
+          width: 100px;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          margin-bottom: 5px;
+          & > span {
+            font-weight: 700;
+            font-family: "SYST";
+          }
+        }
+      }
+      .detailBtn {
+        position: absolute;
+        bottom: 10px;
+        right: 8px;
+        width: 30px;
+        height: 30px;
+        background: url("../assets/img/btnDe.png");
+        background-size: 100% 100%;
+      }
+    }
+  }
+  /deep/.comBs {
+    display: none;
+  }
+  // 点击详情出来的弹窗
+  .detailBox {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    z-index: 999;
+    &::before {
+      content: "";
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
+      backdrop-filter: blur(20px);
+      z-index: -2;
+    }
+    .detailMain {
+      color: #fff;
+      border-radius: 5px;
+      position: absolute;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      left: 50%;
+      width: calc(100% - 24px);
+      height: calc(100% - 60px);
+      background-color: rgba(0, 0, 0, 0.8);
+      padding: 0 25px;
+
+      .detailClose {
+        position: absolute;
+        right: 16px;
+        top: -4px;
+        width: 35px;
+        height: 60px;
+        background: url("../assets/img/close.png");
+        background-size: 100% 100%;
+      }
+      .detailTit {
+        font-family: "SYST";
+        letter-spacing: 5px;
+        text-align: center;
+        font-size: 24px;
+        height: 60px;
+        line-height: 60px;
+      }
+      .detailRow {
+        height: calc(100% - 400px);
+        overflow-y: auto;
+        & > p {
+          margin: 5px 0;
+          display: flex;
+          span {
+            width: 50px;
+            height: 100%;
+            font-family: "SYST";
+          }
+          i {
+            flex: 1;
+            font-style: normal;
+          }
+        }
+      }
+      .detailImg {
+        margin-top: 20px;
+        width: 100%;
+        height: 300px;
+        .swiper-container {
+          width: 100%;
+          height: 100%;
+          .swiper-slide {
+            width: 100%;
+            height: 100%;
+            img {
+              width: 100%;
+              height: 100%;
+              object-fit: cover;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 100 - 0
webM/src/components/four.vue

@@ -0,0 +1,100 @@
+<template>
+  <div class="four">
+    <div class="comTit">
+      <img src="../assets/img/comBs1.png" alt="" />
+      <span>{{ tit }}</span>
+      <img src="../assets/img/comBs2.png" alt="" />
+    </div>
+    <div class="main" :class="{ opcBase: conShowLoad }">
+      <div class="row" v-for="item in data.videos" :key="item.id">
+        <div class="videoName">{{ item.name }}</div>
+        <video controls :src="baseURL + item.filePath"></video>
+      </div>
+    </div>
+    <!-- 数据加载中 -->
+    <div class="conShowLoad" v-show="conShowLoad">
+      <img src="../assets/img/loading.gif" alt="" />
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from "@/utils/request";
+export default {
+  name: "four",
+  props: {
+    tit: {
+      type: String,
+    },
+    data: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      conShowLoad: true,
+      baseURL: "",
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL;
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.conShowLoad = false;
+      }, 1000);
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.four {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .main {
+    width: 100%;
+    height: calc(100% - 130px);
+    overflow-y: auto;
+    padding: 0 20px;
+    .row {
+      width: 100%;
+      height: 210px;
+      position: relative;
+      background-color: rgba(0, 0, 0, 0.6);
+      margin-bottom: 15px;
+      video {
+        width: 100%;
+        height: 100%;
+      }
+      .videoName {
+        position: absolute;
+        top: 1px;
+        left: 5px;
+        color: #fff;
+        font-size: 14px;
+      }
+    }
+  }
+}
+</style>

+ 148 - 0
webM/src/components/one.vue

@@ -0,0 +1,148 @@
+<template>
+  <div class="one">
+    <div class="comTit">
+      <img src="../assets/img/comBs1.png" alt="" />
+      <span>{{ tit }}</span>
+      <img src="../assets/img/comBs2.png" alt="" />
+    </div>
+    <div
+      class="main"
+      v-html="data.content"
+      :class="{ opcBase: conShowLoad }"
+    ></div>
+    <div class="swBox" :class="{ opcBase: conShowLoad }">
+      <div class="swiper-container">
+        <div class="swiper-wrapper">
+          <!-- 图片 -->
+          <div class="swiper-slide" v-for="item in data.images" :key="item.id">
+            <img :src="baseURL + item.filePath" alt="" />
+          </div>
+          <div
+            class="swiper-slide swiperVideo"
+            v-for="item in data.videos"
+            :key="item.id"
+          >
+            <!-- 视频 -->
+            <div class="videoName">{{ item.name }}</div>
+            <video controls :src="baseURL + item.filePath"></video>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 切换下一页 -->
+    <div class="comBs" @click="$emit('pageNext')"></div>
+    <!-- 数据加载中 -->
+    <div class="conShowLoad" v-show="conShowLoad">
+      <img src="../assets/img/loading.gif" alt="" />
+    </div>
+  </div>
+</template>
+
+<script>
+import Swiper from "@/assets/swiper/swiper.js";
+import axios from "@/utils/request";
+export default {
+  name: "one",
+  props: {
+    tit: {
+      type: String,
+    },
+    data: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      conShowLoad: true,
+      baseURL: "",
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL;
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        new Swiper(".one .swiper-container", {
+          slidesPerView: 1.4,
+          spaceBetween: 10,
+        });
+        this.conShowLoad = false;
+      }, 1000);
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+@import "../assets/swiper/swiper.css";
+.one {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .main {
+    letter-spacing: 1px;
+    color: #8a7351;
+    line-height: 24px;
+    font-size: 14px;
+    padding: 0 12px 0 20px;
+    width: 100%;
+    height: calc(100% - 320px);
+    overflow-y: auto;
+    margin-bottom: 20px;
+  }
+  .swBox {
+    width: 100%;
+    height: 170px;
+    .swiper-container {
+      width: calc(100% - 40px);
+      margin: 0 auto;
+      height: 170px;
+    }
+    .swiper-slide {
+      width: 100%;
+      height: 100%;
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+      video {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .swiperVideo {
+      position: relative;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.6);
+      .videoName {
+        position: absolute;
+        top: 1px;
+        left: 5px;
+        color: #fff;
+        font-size: 14px;
+      }
+    }
+  }
+}
+</style>

+ 148 - 0
webM/src/components/one2.vue

@@ -0,0 +1,148 @@
+<template>
+  <div class="one2">
+    <div class="comTit">
+      <img src="../assets/img/comBs1.png" alt="" />
+      <span>{{ tit }}</span>
+      <img src="../assets/img/comBs2.png" alt="" />
+    </div>
+    <div
+      class="main"
+      v-html="data.content"
+      :class="{ opcBase: conShowLoad }"
+    ></div>
+    <div class="swBox" :class="{ opcBase: conShowLoad }">
+      <div class="swiper-container">
+        <div class="swiper-wrapper">
+          <!-- 图片 -->
+          <div class="swiper-slide" v-for="item in data.images" :key="item.id">
+            <img :src="baseURL + item.filePath" alt="" />
+          </div>
+          <div
+            class="swiper-slide swiperVideo"
+            v-for="item in data.videos"
+            :key="item.id"
+          >
+            <!-- 视频 -->
+            <div class="videoName">{{ item.name }}</div>
+            <video controls :src="baseURL + item.filePath"></video>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 切换下一页 -->
+    <div class="comBs" @click="$emit('pageNext')"></div>
+    <!-- 数据加载中 -->
+    <div class="conShowLoad" v-show="conShowLoad">
+      <img src="../assets/img/loading.gif" alt="" />
+    </div>
+  </div>
+</template>
+
+<script>
+import Swiper from "@/assets/swiper/swiper.js";
+import axios from "@/utils/request";
+export default {
+  name: "one2",
+  props: {
+    tit: {
+      type: String,
+    },
+    data: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      conShowLoad: true,
+      baseURL: "",
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL;
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        new Swiper(".one2 .swiper-container", {
+          slidesPerView: 2.4,
+          spaceBetween: 10,
+        });
+        this.conShowLoad = false;
+      }, 1000);
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+@import "../assets/swiper/swiper.css";
+.one2 {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .main {
+    letter-spacing: 1px;
+    color: #8a7351;
+    line-height: 24px;
+    font-size: 14px;
+    padding: 0 12px 0 20px;
+    width: 100%;
+    height: calc(100% - 320px);
+    overflow-y: auto;
+    margin-bottom: 20px;
+  }
+  .swBox {
+    width: 100%;
+    height: 170px;
+    .swiper-container {
+      width: calc(100% - 40px);
+      margin: 0 auto;
+      height: 170px;
+    }
+    .swiper-slide {
+      width: 100%;
+      height: 100%;
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+      video {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .swiperVideo {
+      position: relative;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.6);
+      .videoName {
+        position: absolute;
+        top: 1px;
+        left: 5px;
+        color: #fff;
+        font-size: 14px;
+      }
+    }
+  }
+}
+</style>

+ 149 - 0
webM/src/components/three.vue

@@ -0,0 +1,149 @@
+<template>
+  <div class="three">
+    <div class="comTit">
+      <img src="../assets/img/comBs1.png" alt="" />
+      <span>{{ tit }}</span>
+      <img src="../assets/img/comBs2.png" alt="" />
+    </div>
+    <div class="swBox" :class="{ opcBase: conShowLoad }">
+      <div class="swiper-container">
+        <div class="swiper-wrapper">
+          <!-- 图片 -->
+          <div class="swiper-slide" v-for="item in data.images" :key="item.id">
+            <img :src="baseURL + item.filePath" alt="" />
+          </div>
+          <div
+            class="swiper-slide swiperVideo"
+            v-for="item in data.videos"
+            :key="item.id"
+          >
+            <!-- 视频 -->
+            <div class="videoName">{{ item.name }}</div>
+            <video controls :src="baseURL + item.filePath"></video>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div
+      class="main"
+      v-html="data.content"
+      :class="{ opcBase: conShowLoad }"
+    ></div>
+    <!-- 切换下一页 -->
+    <div class="comBs" @click="$emit('pageNext')"></div>
+    <!-- 数据加载中 -->
+    <div class="conShowLoad" v-show="conShowLoad">
+      <img src="../assets/img/loading.gif" alt="" />
+    </div>
+  </div>
+</template>
+
+<script>
+import Swiper from "@/assets/swiper/swiper.js";
+import axios from "@/utils/request";
+export default {
+  name: "three",
+  props: {
+    tit: {
+      type: String,
+    },
+    data: {
+      type: Object,
+      default: () => {},
+    },
+    
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      conShowLoad: true,
+      baseURL: "",
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL;
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        new Swiper(".three .swiper-container", {
+          slidesPerView: 1.4,
+          spaceBetween: 10,
+        });
+        this.conShowLoad = false;
+      }, 1000);
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+@import "../assets/swiper/swiper.css";
+.three {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .main {
+    letter-spacing: 1px;
+    color: #8a7351;
+    line-height: 24px;
+    font-size: 14px;
+    padding: 0 12px 0 20px;
+    width: 100%;
+    height: calc(100% - 320px);
+    overflow-y: auto;
+    margin-top: 20px;
+  }
+  .swBox {
+    width: 100%;
+    height: 170px;
+    .swiper-container {
+      width: calc(100% - 40px);
+      margin: 0 auto;
+      height: 170px;
+    }
+    .swiper-slide {
+      width: 100%;
+      height: 100%;
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+      video {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .swiperVideo {
+      position: relative;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.6);
+      .videoName {
+        position: absolute;
+        top: 1px;
+        left: 5px;
+        color: #fff;
+        font-size: 14px;
+      }
+    }
+  }
+}
+</style>

+ 149 - 0
webM/src/components/three2.vue

@@ -0,0 +1,149 @@
+<template>
+  <div class="three2">
+    <div class="comTit">
+      <img src="../assets/img/comBs1.png" alt="" />
+      <span>{{ tit }}</span>
+      <img src="../assets/img/comBs2.png" alt="" />
+    </div>
+    <div class="swBox" :class="{ opcBase: conShowLoad }">
+      <div class="swiper-container">
+        <div class="swiper-wrapper">
+          <!-- 图片 -->
+          <div class="swiper-slide" v-for="item in data.images" :key="item.id">
+            <img :src="baseURL + item.filePath" alt="" />
+          </div>
+          <div
+            class="swiper-slide swiperVideo"
+            v-for="item in data.videos"
+            :key="item.id"
+          >
+            <!-- 视频 -->
+            <div class="videoName">{{ item.name }}</div>
+            <video controls :src="baseURL + item.filePath"></video>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div
+      class="main"
+      v-html="data.content"
+      :class="{ opcBase: conShowLoad }"
+    ></div>
+    <!-- 切换下一页 -->
+    <div class="comBs" @click="$emit('pageNext')"></div>
+    <!-- 数据加载中 -->
+    <div class="conShowLoad" v-show="conShowLoad">
+      <img src="../assets/img/loading.gif" alt="" />
+    </div>
+  </div>
+</template>
+
+<script>
+import Swiper from "@/assets/swiper/swiper.js";
+import axios from "@/utils/request";
+export default {
+  name: "three2",
+  props: {
+    tit: {
+      type: String,
+    },
+    data: {
+      type: Object,
+      default: () => {},
+    },
+    
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      conShowLoad: true,
+      baseURL: "",
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL;
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        new Swiper(".three2 .swiper-container", {
+          slidesPerView: 1.2,
+          spaceBetween: 10,
+        });
+        this.conShowLoad = false;
+      }, 1000);
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+@import "../assets/swiper/swiper.css";
+.three2 {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .main {
+    letter-spacing: 1px;
+    color: #8a7351;
+    line-height: 24px;
+    font-size: 14px;
+    padding: 0 12px 0 20px;
+    width: 100%;
+    height: calc(100% - 320px);
+    overflow-y: auto;
+    margin-top: 20px;
+  }
+  .swBox {
+    width: 100%;
+    height: 170px;
+    .swiper-container {
+      width: calc(100% - 40px);
+      margin: 0 auto;
+      height: 170px;
+    }
+    .swiper-slide {
+      width: 100%;
+      height: 100%;
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+      video {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .swiperVideo {
+      position: relative;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.6);
+      .videoName {
+        position: absolute;
+        top: 1px;
+        left: 5px;
+        color: #fff;
+        font-size: 14px;
+      }
+    }
+  }
+}
+</style>

+ 124 - 0
webM/src/components/tow.vue

@@ -0,0 +1,124 @@
+<template>
+  <div class="tow">
+    <div class="comTit">
+      <img src="../assets/img/comBs1.png" alt="" />
+      <span>{{ tit }}</span>
+      <img src="../assets/img/comBs2.png" alt="" />
+    </div>
+    <div class="main" :class="{ opcBase: conShowLoad }">
+      <div class="row" v-for="(item, index) in data" :key="item.id">
+        <div class="rowLeft">
+          <span>{{ index + 1 < 10 ? `0${index + 1}` : index + 1 }}</span>
+        </div>
+        <div class="rowRight">
+          <div class="sroolStop">{{ item.name }}</div>
+          <p class="sroolStop">{{ item.txt }}</p>
+        </div>
+      </div>
+    </div>
+    <!-- 切换下一页 -->
+    <div class="comBs" @click="$emit('pageNext')"></div>
+    <!-- 数据加载中 -->
+    <div class="conShowLoad" v-show="conShowLoad">
+      <img src="../assets/img/loading.gif" alt="" />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "tow",
+  props: {
+    tit: {
+      type: String,
+    },
+    data: {
+      type: Array,
+      default: () => [],
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      conShowLoad: true,
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      setTimeout(() => {
+        this.conShowLoad = false;
+      }, 1000);
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.tow {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .main {
+    width: 100%;
+    height: calc(100% - 130px);
+    overflow-y: auto;
+    .row {
+      display: flex;
+      padding: 20px 20px 0px 20px;
+      min-height: 110px;
+      .rowLeft {
+        position: relative;
+        opacity: 0.8;
+        color: #8a7351;
+        width: 60px;
+        padding-bottom: 20px;
+        border-bottom: 1px solid #bfb094;
+        font-weight: 700;
+        font-size: 50px;
+        & > span {
+          position: absolute;
+          width: 100%;
+          height: 100%;
+          top: 25px;
+          left: 0;
+          font-family: "SYST";
+        }
+      }
+      .rowRight {
+        color: #8a7351;
+        flex: 1;
+        padding-bottom: 20px;
+        border-bottom: 1px solid #bfb094;
+        padding-left: 20px;
+        & > div {
+          font-size: 24px;
+          font-family: "SYST";
+        }
+        & > p {
+          margin-top: 5px;
+          font-size: 16px;
+        }
+      }
+      &:nth-of-type(1) {
+        padding-top: 0;
+      }
+    }
+  }
+}
+</style>

+ 5 - 0
webM/src/router/index.js

@@ -14,6 +14,11 @@ const routes = [
     name: 'stair',
     component: () => import( '../views/stair/index.vue')
   },
+  {
+    path: '/info/:id',
+    name: 'info',
+    component: () => import( '../views/info/index.vue')
+  },
 ]
 
 const router = new VueRouter({

+ 1 - 2
webM/src/views/Home.vue

@@ -75,7 +75,7 @@ export default {
       ],
       // 数据最大值
       maxNum: 0,
-      searchShow:true
+      searchShow:false
     };
   },
   //监听属性 类似于data概念
@@ -240,7 +240,6 @@ export default {
         overflow-y: auto;
         padding-top: 15px;
         .row {
-          cursor: pointer;
           height: 40px;
           display: flex;
           .rowLeft {

+ 81 - 0
webM/src/views/info/component/son1.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="son1">
+    <One tit="建村历史" :data="data1" @pageNext="$emit('pageNext', 1)" />
+    <Tow tit="历史人物" :data="data2" @pageNext="$emit('pageNext', 2)" />
+    <Three tit="历史事件" :data="data3" @pageNext="$emit('pageNext', 3)" />
+    <One tit="族谱家训" :data="data4" @pageNext="$emit('pageNext', 4)" />
+    <Three2 tit="口述史" :data="data5" @pageNext="$emit('pageNext', 5)"/>
+    <Four tit="视频集" :data="data6" />
+  </div>
+</template>
+
+<script>
+import One from '@/components/one.vue'
+import Tow from '@/components/tow.vue'
+import Three from '@/components/three.vue'
+import Three2 from '@/components/three2.vue'
+import Four from '@/components/four.vue'
+import { getInfoApi } from "@/utils/api";
+export default {
+  name: "son1",
+  components: {One,Tow,Three,Three2,Four},
+  data() {
+    //这里存放数据
+    return {
+      data1: {},
+      data2: [],
+      data3: {},
+      data4: {},
+      data5: {},
+      data6: {},
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  async created() {
+    let res = await getInfoApi(Number(this.$route.params.id));
+    res.data.forEach((v) => {
+      // console.log(v);
+      if (v.menuId === 1001) {
+        this.data1 = v;
+        return;
+      } else if (v.menuId === 1002) {
+        this.data2 = JSON.parse(v.contentJson);
+        return;
+      } else if (v.menuId === 1003) {
+        this.data3 = v;
+        return;
+      } else if (v.menuId === 1004) {
+        this.data4 = v;
+        return;
+      } else if (v.menuId === 1005) {
+        this.data5 = v;
+        return;
+      } else if (v.menuId === 1006) {
+        this.data6 = v;
+        return;
+      }
+    });
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.son1 {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 89 - 0
webM/src/views/info/component/son2.vue

@@ -0,0 +1,89 @@
+<!--  -->
+<template>
+  <div class="Son2">
+    <One tit="村落选址" :data="data1" @pageNext="$emit('pageNext', 1)" />
+    <Three2 tit="村落格局" :data="data2" @pageNext="$emit('pageNext', 2)" />
+    <Three tit="建村智慧" :data="data3" @pageNext="$emit('pageNext', 3)" />
+    <One tit="自然环境" :data="data4" @pageNext="$emit('pageNext', 4)" />
+    <One2 tit="风景名胜" :data="data5" @pageNext="$emit('pageNext', 5)" />
+    <Three2 tit="文物古迹" :data="data6" @pageNext="$emit('pageNext', 6)" />
+    <Five tit="历史环境要素" :data="data7" @pageNext="$emit('pageNext', 7)" />
+  </div>
+</template>
+
+<script>
+import { getInfoApi } from "@/utils/api";
+import One from "@/components/one.vue";
+import One2 from "@/components/one2.vue";
+import Three from "@/components/three.vue";
+import Three2 from "@/components/three2.vue";
+import Four from "@/components/four.vue";
+import Five from "@/components/five.vue";
+export default {
+  name: "Son2",
+  components: { One, One2, Three, Three2, Four,Five },
+  props: {},
+  data() {
+    //这里存放数据
+    return {
+      data1: {},
+      data2: {},
+      data3: {},
+      data4: {},
+      data5: {},
+      data6: {},
+      data7: [],
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  async created() {
+    let res = await getInfoApi(Number(this.$route.params.id));
+    res.data.forEach((v) => {
+      // console.log(v);
+      if (v.menuId === 2001) {
+        this.data1 = v;
+        return;
+      } else if (v.menuId === 2002) {
+        this.data2 = v;
+        return;
+      } else if (v.menuId === 2003) {
+        this.data3 = v;
+        return;
+      } else if (v.menuId === 2004) {
+        this.data4 = v;
+        return;
+      } else if (v.menuId === 2005) {
+        this.data5 = v;
+        return;
+      } else if (v.menuId === 2006) {
+        this.data6 = v;
+        return;
+      } else if (v.menuId === 2007) {
+        this.data7 = JSON.parse(v.contentJson);
+        return;
+      }
+    });
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.Son2 {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 39 - 0
webM/src/views/info/component/son3.vue

@@ -0,0 +1,39 @@
+<template>
+  <div class="son3">son3</div>
+</template>
+
+<script>
+export default {
+  name: "son3",
+  components: {},
+  data() {
+    //这里存放数据
+    return {};
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.son3{
+  width: 100%;
+  height: 100%;
+  background-color: blue;
+  opacity: .3;
+}
+</style>

+ 289 - 0
webM/src/views/info/index.vue

@@ -0,0 +1,289 @@
+<template>
+  <div class="info">
+    <div class="top">
+      <!-- 返回箭头 -->
+      <div class="back" @click="$router.go(-1)">
+        <img src="@/assets/img/arrows.png" alt="" />
+      </div>
+      <!-- 右边菜单 -->
+      <div class="mean" @click="meanShow = true">
+        <img src="@/assets/img/menu.png" alt="" />
+      </div>
+      <!-- 循环生成的模块 -->
+      <div class="rowBox">
+        <div class="row" :style="`width:${90 * leftData.length}px`">
+          <div
+            @click="pageInd = index"
+            v-for="(item, index) in leftData"
+            :key="item.id"
+            :class="{ active: index === pageInd }"
+          >
+            {{ item.name }}
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 菜单栏 -->
+    <div class="meanBox" v-if="meanShow">
+      <div class="meanTop">
+        <img src="@/assets/img/cancel.png" alt="" @click="meanShow = false" />
+      </div>
+      <div class="meanCon">
+        <div class="meanConL"></div>
+        <div class="meanConR">
+          <div
+            class="meanRow"
+            @click="cutInfo(item.id, item.children)"
+            :class="{ active: topDataInd === item.id }"
+            v-for="item in topData"
+            :key="item.id"
+          >
+            {{ item.name }}
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 下面主要内容盒子 -->
+    <div class="mainBox">
+      <Son1 @pageNext="pageNext" v-if="topDataInd === '1000'" />
+      <Son2 @pageNext="pageNext" v-else-if="topDataInd === '2000'" />
+      <Son3 @pageNext="pageNext" v-else-if="topDataInd === '3000'" />
+    </div>
+  </div>
+</template>
+
+<script>
+import Son1 from "./component/son1.vue";
+import Son2 from "./component/son2.vue";
+import Son3 from "./component/son3.vue";
+import { getTreeMenuApi } from "@/utils/api";
+export default {
+  name: "info",
+  components: { Son1, Son2, Son3 },
+  data() {
+    //这里存放数据
+    return {
+      // 菜单数据
+      topData: [],
+      // 菜单的显示和隐藏
+      meanShow: false,
+      // 菜单高亮
+      topDataInd: "1000",
+      // 控制顶部数据高亮和翻页
+      pageInd: 0,
+      // 顶部数据
+      leftData: [],
+      // 页面盒子的高度
+      pageHei:0
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {
+    pageInd(val) {
+      // 控制顶部滑动
+      let dom = document.querySelector(".rowBox");
+      dom.scrollTo({ left: 82 * (val - 1), behavior: "smooth" });
+      // 控制页面滑动
+      let pageDom = document.querySelector('.mainBox')
+      pageDom.scrollTo({ top: this.pageHei * val, behavior: "smooth" });
+      // 切换的时候暂时视频
+      this.$nextTick(() => {
+        setTimeout(() => {
+          let dom = document.querySelectorAll("video");
+          dom.forEach((v) => {
+            v.pause();
+          });
+        }, 100);
+      });
+    },
+  },
+  //方法集合
+  methods: {
+    // 子组件传过来的下一页事件
+    pageNext(index) {
+      this.pageInd = index;
+    },
+    // 点击菜单栏里面切换模块
+    cutInfo(id, val) {
+      let dom = document.querySelector(".rowBox");
+      dom.scrollTo({ top: 0 });
+      this.topDataInd = id;
+      this.leftData = val;
+      this.pageInd = 0;
+      this.meanShow = false;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  async created() {
+    // 获取菜单树
+    let res = await getTreeMenuApi();
+    this.topData = res.data;
+    this.leftData = res.data[0].children;
+  }, //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    // 获取页面盒子的高度
+    let pageDom = document.querySelector('.mainBox')
+    this.pageHei=pageDom.offsetHeight
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.info {
+  width: 100vw;
+  height: 100vh;
+  padding-top: 46px;
+  // 主要内容盒子
+  .mainBox {
+    overflow: hidden;
+    width: 100%;
+    height: 100%;
+    background: url("../../assets/img/mainBg.png");
+    background-size: 100% 100%;
+  }
+  // 菜单栏
+  .meanBox {
+    z-index: 3;
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    .meanTop {
+      width: 100%;
+      height: 48px;
+      text-align: right;
+      background-color: #fffaf1;
+      background-image: url("../../assets/img/meanHeng.png");
+      background-size: 100% 100%;
+      & > img {
+        margin-top: 9px;
+        margin-right: 10px;
+        width: 29px;
+      }
+    }
+    .meanCon {
+      width: 100%;
+      height: calc(100% - 48px);
+      display: flex;
+      .meanConL {
+        position: relative;
+        width: 110px;
+        height: 100%;
+        background: url("../../assets/img/llBg.png");
+        background-size: 100% 100%;
+        // &::before {
+        //   content: "";
+        //   position: absolute;
+        //   left: 0;
+        //   top: 0;
+        //   width: 100%;
+        //   height: 100%;
+        //   background-color: rgba(191, 176, 148, .5);
+        //   backdrop-filter: blur(10px);
+        //   z-index: -2;
+        // }
+      }
+      .meanConR {
+        border-top: 1px solid #bfb094;
+        width: calc(100% - 110px);
+        height: 100%;
+        background-color: #fffaf1;
+        background-image: url("../../assets/img/meanShu.png");
+        background-size: 100% 100%;
+        .meanRow {
+          font-size: 18px;
+          color: #bfb094;
+          height: 60px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          border-bottom: 1px solid #bfb094;
+        }
+        .active {
+          pointer-events: none;
+          color: #9f171c;
+          border-left: 5px solid #9f171c;
+        }
+      }
+    }
+  }
+  // 顶部导航栏
+  .top {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 46px;
+    background-color: #d7c9b8;
+    padding-left: 45px;
+    padding-right: 45px;
+    .back {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 40px;
+      height: 46px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      & > img {
+        transform: rotate(90deg);
+        width: 29px;
+      }
+    }
+    .mean {
+      position: absolute;
+      top: 0;
+      right: 0;
+      width: 40px;
+      height: 46px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      & > img {
+        width: 29px;
+      }
+    }
+    .rowBox::-webkit-scrollbar {
+      /*滚动条整体样式*/
+      width: 0px; /*高宽分别对应横竖滚动条的尺寸*/
+      height: 0px;
+    }
+    .rowBox {
+      width: 100%;
+      height: 48px;
+      overflow-x: auto;
+      .row {
+        display: flex;
+        min-width: 100%;
+        justify-content: space-around;
+        height: 46px;
+        & > div {
+          padding: 0 3px;
+          height: 48px;
+          line-height: 46px;
+          color: #fff;
+          font-size: 14px;
+          margin: 0 10px;
+        }
+        .active {
+          position: relative;
+          color: #9f171c;
+          font-weight: 700;
+          pointer-events: none;
+          border-bottom: 2px solid #9f171c;
+        }
+      }
+    }
+  }
+}
+</style>

+ 146 - 0
webM/src/views/stair/component/card.vue

@@ -0,0 +1,146 @@
+<template>
+  <div class="card">
+    <div class="main">
+      <h3>观光打卡</h3>
+      <div class="swImg">
+        <div class="swiper-container">
+          <div class="swiper-wrapper">
+            <div class="swiper-slide" v-for="i in 5" :key="i">
+              <img src="@/assets/img/cCj/1.png" alt="" />
+              <!-- 底部文字 -->
+              <div class="swTxt">
+                <h4>开平碉楼</h4>
+                <p>2022.04.13</p>
+              </div>
+              <!-- 已打卡标记 -->
+              <div class="playCard" v-if="i===2"></div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="flloTit">参观景点VR场景,完成打卡签到!</div>
+      <!-- 关闭按钮 -->
+      <div class="close" @click="$emit('close')"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Swiper from "@/assets/swiper/swiper.js";
+export default {
+  name: "card",
+  components: {},
+  data() {
+    //这里存放数据
+    return {};
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.$nextTick(() => {
+      new Swiper(".card .swiper-container", {
+        slidesPerView: 1.4,
+        spaceBetween: 20,
+      });
+    });
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+@import "../../../assets/swiper/swiper.css";
+.card {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  backdrop-filter: blur(4px);
+  top: 0;
+  left: 0;
+  .main {
+    padding-top: 20px;
+    position: absolute;
+    width: calc(100% - 30px);
+    height: calc(100% - 110px);
+    left: 15px;
+    top: 30px;
+    background-color: rgba(0, 0, 0, 0.7);
+    .close {
+      position: absolute;
+      top: -4px;
+      right: 15px;
+      z-index: 10;
+      width: 40px;
+      height: 71px;
+      background: url("../../../assets/img/close.png");
+      background-size: 100% 100%;
+    }
+    & > h3 {
+      color: #fff;
+      font-family: "SYST";
+      font-size: 24px;
+      text-align: center;
+      margin-bottom: 40px;
+    }
+    .swImg {
+      width: 100%;
+      height: calc(100% - 150px);
+      .swiper-container {
+        width: calc(100% - 24px);
+        margin: 0 auto;
+        height: 100%;
+        .swiper-slide{
+          position: relative;
+          padding: 8px 12px;
+          background: url('../../../assets/img/btn_record.png');
+          background-size: 100% 100%;
+          img {
+            width: 100%;
+            height: calc(100% - 66px);
+            object-fit: cover;
+          }
+          .swTxt{
+            padding-top: 10px;
+            height: 50px;
+            color: #887B67;
+            font-size: 16px;
+            h4{
+              margin-bottom: 3px;
+              font-family: 'SYST';
+              font-size: 18px;
+            }
+          }
+          .playCard{
+            position: absolute;
+            bottom: 20px;
+            right: 15px;
+            width: 135px;
+            height: 90px;
+            background: url('../../../assets/img/playCard.png');
+            background-size: 100% 100%;
+          }
+        }
+      }
+    }
+    .flloTit {
+      height: 75px;
+      line-height: 75px;
+      text-align: center;
+      font-size: 16px;
+      color: #ffffff;
+    }
+  }
+}
+</style>

+ 138 - 0
webM/src/views/stair/component/share.vue

@@ -0,0 +1,138 @@
+<template>
+  <div class="share">
+    <div class="main">
+      <h3>分享</h3>
+      <div class="imgBox">
+        <img src="data/1.png" alt="" />
+      </div>
+      <!-- 底部功能按钮 -->
+      <div class="btn">
+        <div class="lianjie" title="复制链接" @click="copy">
+          <img src="@/assets/img/copy.png" alt="" />
+        </div>
+        <a href="data/1.png" download title="下载">
+          <img src="@/assets/img/download.png" alt="" />
+        </a>
+      </div>
+      <!-- 关闭按钮 -->
+      <div class="close" @click="$emit('close')"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "share",
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      copy() {
+        // 存储传递过来的数据
+        let OrderNumber = "9999999999";
+        // 创建一个input 元素
+        // createElement() 方法通过指定名称创建一个元素
+        let newInput = document.createElement("input");
+        // 讲存储的数据赋值给input的value值
+        newInput.value = OrderNumber;
+        // appendChild() 方法向节点添加最后一个子节点。
+        document.body.appendChild(newInput);
+        // 选中input元素中的文本
+        // select() 方法用于选择该元素中的文本。
+        newInput.select();
+        // 执行浏览器复制命令
+        //  execCommand方法是执行一个对当前文档,当前选择或者给出范围的命令
+        document.execCommand("Copy");
+        // 清空输入框
+        newInput.remove();
+        // 下面是element的弹窗 不需要的自行删除就好
+        alert("复制成功");
+      },
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.share {
+  color: #fff;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  backdrop-filter: blur(4px);
+  top: 0;
+  left: 0;
+  .main {
+    padding-top: 20px;
+    position: absolute;
+    width: calc(100% - 30px);
+    height: calc(100% - 110px);
+    left: 15px;
+    top: 30px;
+    background-color: rgba(0, 0, 0, 0.7);
+    .close {
+      position: absolute;
+      top: -4px;
+      right: 15px;
+      z-index: 10;
+      width: 40px;
+      height: 71px;
+      background: url("../../../assets/img/close.png");
+      background-size: 100% 100%;
+    }
+    & > h3 {
+      font-family: "SYST";
+      font-size: 24px;
+      text-align: center;
+      margin-bottom: 40px;
+    }
+    .imgBox {
+      padding: 0 22px;
+      width: 100%;
+      height: calc(100% - 150px);
+      & > img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+    }
+    .btn {
+      width: 100%;
+      height: 70px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      .lianjie {
+        width: 40px;
+        height: 40px;
+        margin-right: 50px;
+      }
+      a {
+        display: block;
+        width: 40px;
+        height: 40px;
+      }
+      img {
+        width: 40px;
+        height: 40px;
+      }
+    }
+  }
+}
+</style>

+ 8 - 3
webM/src/views/stair/index.vue

@@ -42,15 +42,21 @@
     </div>
     <!-- 简介组件 -->
     <StairIntro v-if="btnDataAc === 1" @close="btnDataAc = null" />
+    <!-- 打卡组件 -->
+    <StairCard v-if="btnDataAc === 2" @close="btnDataAc = null" />
+    <!-- 分享组件 -->
+    <StairShare v-if="btnDataAc === 3" @close="btnDataAc = null" />
   </div>
 </template>
 
 <script>
 import StairIntro from "./component/intro.vue";
+import StairCard from "./component/card.vue";
+import StairShare from "./component/share.vue";
 import { likeSaveApi, lookSaveApi, getCunNumApi } from "@/utils/api";
 export default {
   name: "stair",
-  components: { StairIntro },
+  components: { StairIntro, StairCard, StairShare },
   data() {
     //这里存放数据
     return {
@@ -156,11 +162,10 @@ export default {
     position: absolute;
     width: 100%;
     justify-content: space-around;
-    bottom: 20px;
+    bottom: 24px;
     left: 0px;
     .btnRow {
       position: relative;
-      cursor: pointer;
       text-align: center;
       width: 52px;
       height: 51px;