Browse Source

画刊增加预览

natasha 2 months ago
parent
commit
ce283ad272

+ 3 - 0
src/icons/svg/arrow-left-s-line.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M6.31592 7.00041L9.2033 9.88773L8.37835 10.7127L4.66602 7.00041L8.37835 3.28809L9.2033 4.11304L6.31592 7.00041Z" fill="currentColor"/>
+</svg>

+ 3 - 0
src/icons/svg/arrow-right-s-line.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M8.26624 7.00236L5.37891 4.11499L6.20386 3.29004L9.9162 7.00236L6.20386 10.7146L5.37891 9.88968L8.26624 7.00236Z" fill="currentColor"/>
+</svg>

+ 3 - 0
src/icons/svg/video-line.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3 3.9934C3 3.44476 3.44495 3 3.9934 3H20.0066C20.5552 3 21 3.44495 21 3.9934V20.0066C21 20.5552 20.5551 21 20.0066 21H3.9934C3.44476 21 3 20.5551 3 20.0066V3.9934ZM5 5V19H19V5H5ZM10.6219 8.41459L15.5008 11.6672C15.6846 11.7897 15.7343 12.0381 15.6117 12.2219C15.5824 12.2658 15.5447 12.3035 15.5008 12.3328L10.6219 15.5854C10.4381 15.708 10.1897 15.6583 10.0672 15.4745C10.0234 15.4088 10 15.3316 10 15.2526V8.74741C10 8.52649 10.1791 8.34741 10.4 8.34741C10.479 8.34741 10.5562 8.37078 10.6219 8.41459Z" fill="currentColor"/>
+</svg>

+ 44 - 5
src/views/content_manage/pictorial_manage/CreatePictorial.vue

@@ -268,6 +268,13 @@
                   @click="savePageInfo(picIndex)"
                   >保存</el-button
                 >
+                <el-button
+                  type="primary"
+                  size="small"
+                  :loading="loading"
+                  @click="savePageInfo(picIndex, '', '', 'preview')"
+                  >预览</el-button
+                >
               </div>
             </div>
             <div class="picArticle-pic">
@@ -609,6 +616,21 @@
         >
       </span>
     </el-dialog>
+    <el-dialog
+      :visible.sync="previewArticle"
+      :show-close="false"
+      :close-on-click-modal="false"
+      width="100%"
+      top="0"
+      class="login-dialog"
+      v-if="previewArticle"
+    >
+      <magazineDetail
+        @closePreviewArticle="closePreviewArticle"
+        :iss_no="newspaperForm.iss_no"
+        :dataInfo="dataInfo"
+      ></magazineDetail>
+    </el-dialog>
   </div>
 </template>
 
@@ -622,10 +644,18 @@ import Upload from "../../../components/Upload.vue";
 import { getLogin } from "@/api/ajax";
 import { mapState } from "vuex";
 import draggable from "vuedraggable";
+import magazineDetail from "./magazineDetail.vue";
 
 export default {
   //import引入的组件需要注入到对象中才能使用
-  components: { Header, NavMenu, Breadcrumb, Upload, draggable },
+  components: {
+    Header,
+    NavMenu,
+    Breadcrumb,
+    Upload,
+    draggable,
+    magazineDetail,
+  },
   props: {},
   data() {
     const validateIssNo = (rule, value, callback) => {
@@ -809,6 +839,8 @@ export default {
       editSentencesTimeData: [], // 校对句子时间字幕数据
       editSentenceTimeData: [], // 校对单条句子时间字幕数据
       editSentenceTimeFlag: false,
+      previewArticle: false, // 预览画刊
+      dataInfo: null,
     };
   },
   //计算属性 类似于data概念
@@ -1127,7 +1159,7 @@ export default {
         .catch(() => {});
     },
     // 获取画刊内容
-    getPicArticleInfo() {
+    getPicArticleInfo(types) {
       this.loading = true;
       let MethodName =
         "/PaperServer/Manager/PicArticleManager/FindPicArticleBeanById";
@@ -1195,12 +1227,19 @@ export default {
                 this.picActiveVideo = [];
               }
             }
+            if (types && types === "preview") {
+              this.dataInfo = res.data;
+              this.previewArticle = true;
+            }
           }
         })
         .catch(() => {
           this.loading = false;
         });
     },
+    closePreviewArticle() {
+      this.previewArticle = false;
+    },
     // 删除热区
     deletehotspots(index) {
       this.pages[this.picActiveId].hotspots.splice(index, 1);
@@ -1246,7 +1285,7 @@ export default {
         });
     },
     // 保存图片信息
-    savePageInfo(index, type, list) {
+    savePageInfo(index, type, list, types) {
       if (index || index === 0) {
         this.picIndex = index;
         this.picActiveId = this.pageIds[index];
@@ -1283,7 +1322,7 @@ export default {
       getLogin(MethodName, data)
         .then((res) => {
           if (res.status === 1) {
-            this.getPicArticleInfo();
+            this.getPicArticleInfo(types);
           }
         })
         .catch(() => {});
@@ -1687,7 +1726,7 @@ export default {
         padding: 0 16px 0 24px;
       }
       .el-input {
-        width: 280px;
+        width: 200px;
       }
     }
   }

+ 446 - 0
src/views/content_manage/pictorial_manage/components/MagazineSentence.vue

@@ -0,0 +1,446 @@
+<template>
+  <div
+    class="sentence-box"
+    :style="{ background: themeList[sentenceTheme].bg }"
+  >
+    <div class="sentence-top">
+      <a
+        class="play-btn"
+        @click="handlePlay"
+        :style="{ background: themeList[sentenceTheme].playBtnBg }"
+      >
+        <svg-icon v-if="isPlay" icon-class="pause"></svg-icon>
+        <svg-icon v-else icon-class="play"></svg-icon>
+      </a>
+      <div
+        class="sentence-right"
+        :style="{ color: themeList[sentenceTheme].rightBtnColor }"
+      >
+        <a class="btn" @click="handlePage('-')"
+          ><svg-icon icon-class="arrow-left-s-line"></svg-icon
+        ></a>
+        <span>{{ sentenceActive + 1 + "/" + data.length }}</span>
+        <a class="btn" @click="handlePage('+')"
+          ><svg-icon icon-class="arrow-right-s-line"></svg-icon
+        ></a>
+        <i class="el-icon-close" @click="closeWord"></i>
+      </div>
+    </div>
+    <div
+      class="content-inner"
+      :style="{ background: themeList[sentenceTheme].contentBg }"
+    >
+      <template v-for="(itemC, indexC) in data[sentenceActive].tokens">
+        <div
+          :key="indexC"
+          :class="[
+            'content-item',
+            (activeWordIndex === null &&
+              currentTime * 1000 <= data[sentenceActive].e &&
+              currentTime * 1000 >= data[sentenceActive].tokens[indexC].s) ||
+            activeWordIndex === indexC
+              ? 'active'
+              : '',
+          ]"
+          :style="{
+            color:
+              (activeWordIndex === null &&
+                currentTime * 1000 <= data[sentenceActive].e &&
+                currentTime * 1000 >= data[sentenceActive].tokens[indexC].s) ||
+              activeWordIndex === indexC
+                ? themeList[sentenceTheme].sentenceActiveColor
+                : themeList[sentenceTheme].sentenceColor,
+            fontSize: fontSize + 'px',
+            lineHeight: fontSize + 8 + 'px',
+            marginRight: itemC.a === '' ? '0' : '',
+          }"
+          @click="palyWord(indexC)"
+        >
+          {{ itemC.w }}
+        </div>
+      </template>
+    </div>
+    <div class="sentence-bottom">
+      <div
+        class="fontsize-box"
+        :style="{ background: themeList[sentenceTheme].bottomBg }"
+      >
+        <span
+          :style="{
+            background:
+              fontSize === 32
+                ? themeList[sentenceTheme].bottomBarActiveBtnBg
+                : '',
+            color:
+              fontSize === 32 ? themeList[sentenceTheme].bottomBarActive : '',
+          }"
+          @click="handleChangeBgColor(32, 'fontSize')"
+          >小</span
+        >
+        <div
+          class="border"
+          :style="{
+            background:
+              fontSize === 48 ? themeList[sentenceTheme].bottomBarBorder : '',
+          }"
+        ></div>
+        <span
+          :style="{
+            background:
+              fontSize === 40
+                ? themeList[sentenceTheme].bottomBarActiveBtnBg
+                : '',
+            color:
+              fontSize === 40 ? themeList[sentenceTheme].bottomBarActive : '',
+          }"
+          @click="handleChangeBgColor(40, 'fontSize')"
+          >中</span
+        >
+        <div
+          class="border"
+          :style="{
+            background:
+              fontSize === 32 ? themeList[sentenceTheme].bottomBarBorder : '',
+          }"
+        ></div>
+        <span
+          :style="{
+            background:
+              fontSize === 48
+                ? themeList[sentenceTheme].bottomBarActiveBtnBg
+                : '',
+            color:
+              fontSize === 48 ? themeList[sentenceTheme].bottomBarActive : '',
+          }"
+          @click="handleChangeBgColor(48, 'fontSize')"
+          >大</span
+        >
+      </div>
+      <ul
+        class="article-color"
+        :style="{ background: themeList[sentenceTheme].bottomBg }"
+      >
+        <li
+          :class="['color-item', sentenceTheme === indexC ? 'active' : '']"
+          v-for="(itemC, indexC) in themeList"
+          :key="indexC"
+          @click="handleChangeBgColor(indexC, 'theme')"
+          :style="{
+            borderColor: sentenceTheme === indexC ? itemC.boxBorder : '',
+          }"
+        >
+          <a
+            :style="{
+              background: itemC.themeBg,
+              borderColor:
+                sentenceTheme === indexC ? itemC.themeActiveBorder : '',
+            }"
+          ></a>
+        </li>
+      </ul>
+    </div>
+  </div>
+</template>
+
+<script>
+//这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+//例如:import 《组件名称》from ‘《组件路径》';
+
+export default {
+  //import引入的组件需要注入到对象中才能使用
+  components: {},
+  props: ["fontSize", "sentenceTheme", "data", "activeIndex", "mp3Url"],
+  data() {
+    //这里存放数据
+    return {
+      isPlay: false, // 音频是否在播放
+      sentenceActive: this.activeIndex,
+      themeList: [
+        {
+          type: "white",
+          bg: "#E5E6EB",
+          playBtnBg: "#175DFF", // 播放按钮背景色
+          rightBtnColor: "rgba(0, 0, 0, 0.96)", // 右侧按钮颜色
+          contentBg: "#F7F8FA",
+          sentenceColor: "rgba(0, 0, 0, 0.96)",
+          sentenceActiveColor: "#175DFF",
+          bottomBg: "#F2F3F5",
+          bottomBarActiveBtnBg: "#FFFFFF",
+          bottomBarColor: "#4E5969",
+          bottomBarActive: "#165DFF",
+          bottomBarBorder: "#E5E6EB",
+          themeBg: "#FFFFFF",
+          themeActiveBorder: "#E5E6EB",
+          boxBorder: "#3459D2", // 选中时高亮的外圈边框
+        },
+        {
+          type: "darkGreen",
+          bg: "#C2C9C6",
+          playBtnBg: "#236E55", // 播放按钮背景色
+          rightBtnColor: "rgba(0, 0, 0, 0.96)", // 右侧按钮颜色
+          contentBg: "#DFE4E2",
+          sentenceColor: "rgba(0, 0, 0, 0.96)",
+          sentenceActiveColor: "#236E55",
+          bottomBg: "#DFE4E2",
+          bottomBarActiveBtnBg: "#FFFFFF",
+          bottomBarColor: "#4E5969",
+          bottomBarActive: "#236E55",
+          bottomBarBorder: "#C2C9C6",
+          themeBg: "#5BB99A",
+          themeActiveBorder: "#5BB99A",
+          boxBorder: "#fff", // 选中时高亮的外圈边框
+        },
+        {
+          type: "darkBlue",
+          bg: "#1C2129",
+          playBtnBg: "#5373E7", // 播放按钮背景色
+          rightBtnColor: "#fff", // 右侧按钮颜色
+          contentBg: "#2F3742",
+          sentenceColor: "#C1C5CD",
+          sentenceActiveColor: "#5373E7",
+          bottomBg: "#2F3742",
+          bottomBarActiveBtnBg: "#1C2129",
+          bottomBarColor: "#929CA8",
+          bottomBarActive: "#5373E7",
+          bottomBarBorder: "#1C2129",
+          themeBg: "#1F2C5C",
+          themeActiveBorder: "#1F2C5C",
+          boxBorder: "#fff", // 选中时高亮的外圈边框
+        },
+        {
+          type: "armyGreen",
+          bg: "#2A2F2C",
+          playBtnBg: "#30A47D", // 播放按钮背景色
+          rightBtnColor: "#fff", // 右侧按钮颜色
+          contentBg: "#393F3C",
+          sentenceColor: "#C1C5CD",
+          sentenceActiveColor: "#30A47D",
+          bottomBg: "#393F3C",
+          bottomBarActiveBtnBg: "#2A2F2C",
+          bottomBarColor: "#C1C5CD",
+          bottomBarActive: "#30A47D",
+          bottomBarBorder: "#2A2F2C",
+          themeBg: "#13392E",
+          themeActiveBorder: "#13392E",
+          boxBorder: "#fff", // 选中时高亮的外圈边框
+        },
+      ],
+      currentTime: 0,
+      audio: new Audio(),
+      ed: null,
+      activeWordIndex: null,
+    };
+  },
+  //计算属性 类似于data概念
+  computed: {},
+  //监控data中数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 播放、暂停
+    handlePlay() {
+      let _this = this;
+      _this.activeWordIndex = null;
+      _this.isPlay = !_this.isPlay;
+      if (!_this.isPlay) {
+        _this.audio.pause();
+        return;
+      }
+      _this.audio.pause();
+      _this.audio.load();
+      _this.audio.src = _this.mp3Url;
+      if (_this.currentTime <= _this.data[_this.sentenceActive].s / 1000) {
+        _this.audio.currentTime = _this.data[_this.sentenceActive].s / 1000;
+      } else {
+        _this.audio.currentTime = _this.currentTime;
+      }
+      _this.ed = _this.data[_this.sentenceActive].e / 1000;
+      _this.audio.loop = false;
+      _this.audio.play();
+    },
+    palyWord(index) {
+      let _this = this;
+      _this.activeWordIndex = index;
+      _this.audio.pause();
+      _this.audio.load();
+      _this.audio.src = _this.mp3Url;
+      _this.audio.currentTime =
+        _this.data[_this.sentenceActive].tokens[index].s / 1000;
+      _this.ed = _this.data[_this.sentenceActive].tokens[index].e / 1000;
+      _this.audio.loop = false;
+      _this.audio.play();
+    },
+    // 关闭
+    closeWord() {
+      this.$emit("closeWord");
+    },
+    handlePage(type) {
+      if (type === "-") {
+        if (this.sentenceActive > 0) {
+          this.audio.pause();
+          this.isPlay = false;
+          this.currentTime = 0;
+          this.sentenceActive--;
+        } else {
+          this.$message.warning("已经是第一句");
+        }
+      } else {
+        if (this.sentenceActive < this.data.length - 1) {
+          this.audio.pause();
+          this.isPlay = false;
+          this.currentTime = 0;
+          this.sentenceActive++;
+        } else {
+          this.$message.warning("已经是最后一句");
+        }
+      }
+    },
+    // 切换主题颜色
+    handleChangeBgColor(index, type) {
+      if (type === "fontSize") {
+        this.$emit("changeTheme", "", index);
+      } else {
+        this.$emit("changeTheme", index);
+      }
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    let _this = this;
+    _this.audio.addEventListener("timeupdate", function () {
+      _this.currentTime = _this.audio.currentTime;
+      const currentTime = _this.audio.currentTime;
+      if (_this.ed && currentTime >= _this.ed) {
+        _this.audio.pause();
+        _this.isPlay = false;
+        _this.currentTime = 0;
+        _this.activeWordIndex = null;
+      }
+    });
+  },
+  //生命周期-创建之前
+  beforeCreated() {},
+  //生命周期-挂载之前
+  beforeMount() {},
+  //生命周期-更新之前
+  beforUpdate() {},
+  //生命周期-更新之后
+  updated() {},
+  //生命周期-销毁之前
+  beforeDestory() {},
+  //生命周期-销毁完成
+  destoryed() {},
+  //如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+<style lang="scss" scoped>
+/* @import url(); 引入css类 */
+.sentence-box {
+  padding: 16px;
+  .sentence-top {
+    display: flex;
+    justify-content: space-between;
+    .play-btn {
+      width: 40px;
+      height: 40px;
+      border-radius: 20px;
+      padding: 8px;
+      background: #175dff;
+      color: rgba(255, 255, 255, 0.96);
+    }
+    .sentence-right {
+      color: rgba(0, 0, 0, 0.96);
+      font-weight: 700;
+      font-size: 12px;
+      line-height: 20px;
+      display: flex;
+      align-items: center;
+      .btn {
+        width: 40px;
+        height: 40px;
+        padding: 8px;
+      }
+      span {
+        min-width: 40px;
+        text-align: center;
+      }
+      .el-icon-close {
+        cursor: pointer;
+        font-size: 16px;
+        font-weight: 700;
+      }
+    }
+    .svg-icon {
+      font-size: 24px;
+    }
+  }
+  .content-inner {
+    padding: 40px 45px;
+    border-radius: 8px;
+    margin: 16px 0;
+    display: flex;
+    flex-flow: wrap;
+    .content-item {
+      margin: 0 6px 0 0;
+      font-size: 32px;
+      line-height: 40px;
+      cursor: pointer;
+      &.active {
+        font-weight: 700;
+      }
+    }
+  }
+  .sentence-bottom {
+    display: flex;
+    .fontsize-box {
+      display: flex;
+      padding: 3px;
+      border-radius: 20px;
+      align-items: center;
+      span {
+        font-weight: 400;
+        font-size: 14px;
+        line-height: 22px;
+        width: 38px;
+        padding: 2px 12px;
+        border-radius: 20px;
+        cursor: pointer;
+        &.active {
+          font-weight: 500;
+        }
+      }
+      .border {
+        width: 1px;
+        height: 14px;
+      }
+    }
+    .article-color {
+      list-style: none;
+      display: flex;
+      width: 132px;
+      height: 32px;
+      justify-content: space-between;
+      align-items: center;
+      border-radius: 40px;
+      margin: 0 0 0 12px;
+      padding: 4px;
+      .color-item {
+        padding: 2px;
+        border: 2px solid transparent;
+        border-radius: 50%;
+        a {
+          width: 16px;
+          height: 16px;
+          border-radius: 50%;
+          display: block;
+          border: 1px solid transparent;
+          padding: 0;
+        }
+      }
+    }
+  }
+}
+</style>

+ 87 - 0
src/views/content_manage/pictorial_manage/components/MagazineVideo.vue

@@ -0,0 +1,87 @@
+<template>
+  <div style="position: relative">
+    <i class="el-icon-close" @click="closeWord"></i>
+    <div class="video" id="video-box"></div>
+  </div>
+</template>
+
+<script>
+//这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+//例如:import 《组件名称》from ‘《组件路径》';
+import Player from "xgplayer";
+import "xgplayer/dist/index.min.css";
+
+export default {
+  //import引入的组件需要注入到对象中才能使用
+  components: {},
+  props: ["url"],
+  data() {
+    //这里存放数据
+    return {
+      player: null,
+    };
+  },
+  //计算属性 类似于data概念
+  computed: {},
+  //监控data中数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 关闭
+    closeWord() {
+      this.player.destroy();
+      this.player = null;
+      this.$emit("closeWord");
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    this.player = new Player({
+      id: "video-box",
+      url: this.url,
+      height: "100%",
+      width: "100%",
+      cssFullscreen: false,
+      commonStyle: {
+        progressColor: "rgba(255, 255, 255, 0.7)",
+        playedColor: "#0081F1",
+        volumeColor: "#0081F1",
+        sliderBtnStyle: {},
+      },
+      poster: "", // 封面图
+    });
+  },
+  //生命周期-创建之前
+  beforeCreated() {},
+  //生命周期-挂载之前
+  beforeMount() {},
+  //生命周期-更新之前
+  beforUpdate() {},
+  //生命周期-更新之后
+  updated() {},
+  //生命周期-销毁之前
+  beforeDestory() {},
+  //生命周期-销毁完成
+  destoryed() {},
+  //如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+<style lang="scss" scoped>
+/* @import url(); 引入css类 */
+.video {
+  height: 450px !important;
+}
+.el-icon-close {
+  font-size: 16px;
+  padding: 8px;
+  cursor: pointer;
+  position: absolute;
+  right: 0;
+  top: 0;
+  z-index: 1;
+  color: #fff;
+}
+</style>

+ 464 - 0
src/views/content_manage/pictorial_manage/magazineDetail.vue

@@ -0,0 +1,464 @@
+<template>
+  <div class="magazine-detail">
+    <div class="navBar">
+      <div class="navBar-left">
+        <a class="goback" @click="closePreviewArticle"
+          ><i class="el-icon-arrow-left"></i> 第 {{ iss_no }} 期</a
+        >
+        <div class="border"></div>
+        <p class="article-title">{{ iss_name }}</p>
+      </div>
+    </div>
+    <div class="magazine-inner">
+      <div class="btn-box">
+        <el-button round class="btn-left" @click="handlePage('-')"
+          ><svg-icon icon-class="arrow-left-s-line"></svg-icon>上一页</el-button
+        >
+        <el-button
+          v-if="
+            magazineList[activePage] &&
+            magazineList[activePage].video &&
+            magazineList[activePage].video.id
+          "
+          round
+          class="explain-video"
+          @click="handleVideo"
+          ><svg-icon icon-class="video-line"></svg-icon>讲解视频</el-button
+        >
+        <el-button round class="btn-right" @click="handlePage('+')"
+          >下一页<svg-icon icon-class="arrow-right-s-line"></svg-icon
+        ></el-button>
+      </div>
+
+      <div class="audio-box">
+        <div
+          class="aduioLine-content aduioLine-box"
+          v-if="
+            magazineList[activePage] &&
+            magazineList[activePage].sound &&
+            magazineList[activePage].sound.id
+          "
+        >
+          <AudioLine
+            audioId="artMagazineAudio"
+            :mp3="magazineList[activePage].sound.url"
+            :getCurTime="getCurTime"
+            ref="audioLine"
+            :mp3Source="'mp3'"
+            type="audioLine"
+            :ed="ed"
+            :showEd="showEd"
+            @emptyEd="emptyEd"
+          />
+          <!-- <svg-icon icon-class="icon-wrapper" class="wrapper" @click="fullScreen"></svg-icon> -->
+        </div>
+      </div>
+      <div class="magazine-box">
+        <a class="btn-left" @click="handlePage('-')"
+          ><svg-icon icon-class="arrow-left-s-line"></svg-icon
+        ></a>
+        <a class="btn-right" @click="handlePage('+')"
+          ><svg-icon icon-class="arrow-right-s-line"></svg-icon
+        ></a>
+        <template v-for="(item, index) in magazineList">
+          <div
+            :key="index"
+            class="magazine"
+            :class="['magazine' + index]"
+            :style="{
+              top: 24 + (index - activePage) * 16 + 'px',
+              marginLeft: -554 + (index - activePage) * 16 + 'px',
+              zIndex: magazineList.length - index,
+              height: 783 - (index - activePage) * 16 + 'px',
+            }"
+            v-show="index >= activePage && index <= activePage + 3"
+          >
+            <div
+              class="img-box"
+              :style="{
+                background:
+                  'url(' + item.img.url + ') center / contain no-repeat',
+              }"
+            >
+              <div
+                v-for="(itemP, indexP) in item.hotspots"
+                :key="indexP"
+                :class="[
+                  'position-item',
+                  mageazineDetailIndex === indexP ? 'active' : '',
+                ]"
+                :style="{
+                  width: itemP.width,
+                  height: itemP.height,
+                  left: itemP.x,
+                  top: itemP.y,
+                }"
+                @click="handleChangePosition(indexP)"
+              ></div>
+            </div>
+          </div>
+        </template>
+      </div>
+    </div>
+    <el-dialog
+      :visible.sync="magazineVideoShow"
+      :show-close="false"
+      :close-on-click-modal="false"
+      width="800px"
+      class="login-dialog"
+      v-if="magazineVideoShow"
+      :append-to-body="true"
+    >
+      <magazine-video
+        :url="magazineList[activePage].video.url"
+        @closeWord="closeWord"
+      ></magazine-video>
+    </el-dialog>
+    <el-dialog
+      :visible.sync="mageazineDetailShow"
+      :show-close="false"
+      :close-on-click-modal="false"
+      width="1200px"
+      class="login-dialog magazine-detail-dialog"
+      :modal="false"
+      v-if="mageazineDetailShow"
+      :append-to-body="true"
+    >
+      <magazine-sentence
+        :fontSize="fontSize"
+        :sentenceTheme="sentenceTheme"
+        :data="magazineList[activePage].hotspots"
+        :activeIndex="mageazineDetailIndex"
+        @closeWord="closeMagazineSentence"
+        @changeTheme="changeTheme"
+        :mp3Url="
+          magazineList[activePage].sound && magazineList[activePage].sound.url
+            ? magazineList[activePage].sound.url
+            : ''
+        "
+      ></magazine-sentence>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+//这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+//例如:import 《组件名称》from ‘《组件路径》';
+import MagazineVideo from "./components/MagazineVideo.vue";
+import MagazineSentence from "./components/MagazineSentence.vue";
+import AudioLine from "@/components/AudioLine.vue";
+import { getLogin } from "@/api/ajax";
+export default {
+  //import引入的组件需要注入到对象中才能使用
+  components: { MagazineVideo, MagazineSentence, AudioLine },
+  props: ["iss_no", "dataInfo"],
+  data() {
+    //这里存放数据
+    return {
+      magazineList: [],
+      activePage: 0, // 当前显示第几页
+      magazineVideoShow: false, // 讲解视频是否显示
+      mageazineDetailIndex: null, // 当前画刊高亮第几个
+      mageazineDetailShow: false,
+      fontSize: 32,
+      sentenceTheme: 0,
+      ed: undefined,
+      showEd: false, //是否看ed的值
+      curTime: 0, //单位s
+      picObj: {}, // 存放图片地址
+      soundObj: {}, //存放音频地址
+      videoObj: {}, //存放视频地址
+      pageIds: [],
+    };
+  },
+  //计算属性 类似于data概念
+  computed: {},
+  //监控data中数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 翻页
+    handlePage(type) {
+      if (type === "-") {
+        if (this.activePage > 0) {
+          this.activePage--;
+          this.mageazineDetailIndex = null;
+        } else {
+          this.$message.warning("已经是第一张");
+        }
+      } else {
+        if (this.activePage < this.magazineList.length - 1) {
+          this.activePage++;
+          this.mageazineDetailIndex = null;
+        } else {
+          this.$message.warning("已经是最后一张");
+        }
+      }
+    },
+    // 讲解视频
+    handleVideo() {
+      this.magazineVideoShow = true;
+    },
+    // 关闭视频
+    closeWord() {
+      this.magazineVideoShow = false;
+    },
+    // 切换画刊里面的卡片
+    handleChangePosition(index) {
+      if (this.$refs.audioLine.audio.playing) {
+        this.$refs.audioLine.PlayAudio();
+      }
+      this.mageazineDetailIndex = index;
+      this.mageazineDetailShow = true;
+    },
+    // 关闭画刊卡片
+    closeMagazineSentence() {
+      this.mageazineDetailShow = false;
+    },
+    // 切换主题色和文字大小
+    changeTheme(theme, size) {
+      if (theme !== "") this.sentenceTheme = theme;
+      if (size) this.fontSize = size;
+    },
+    getCurTime(curTime) {
+      this.curTime = curTime * 1000;
+      for (
+        let i = 0;
+        i < this.magazineList[this.activePage].hotspots.length;
+        i++
+      ) {
+        if (
+          this.curTime >= this.magazineList[this.activePage].hotspots[i].s &&
+          this.curTime < this.magazineList[this.activePage].hotspots[i].e
+        ) {
+          this.mageazineDetailIndex = i;
+          break;
+        } else {
+          this.mageazineDetailIndex = null;
+        }
+      }
+    },
+    emptyEd(flag) {
+      this.ed = undefined;
+      if (flag) {
+        this.showEd = false;
+      }
+    },
+    getIssuePages() {
+      this.magazineList = [];
+      this.pageIds = this.dataInfo.pageIds;
+      this.dataInfo.pageIds.forEach((item) => {
+        this.magazineList.push(this.dataInfo.pages[item]);
+      });
+
+      this.iss_name = this.dataInfo.title;
+    },
+    closePreviewArticle() {
+      this.$emit("closePreviewArticle");
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getIssuePages();
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  //生命周期-创建之前
+  beforeCreated() {},
+  //生命周期-挂载之前
+  beforeMount() {},
+  //生命周期-更新之前
+  beforUpdate() {},
+  //生命周期-更新之后
+  updated() {},
+  //生命周期-销毁之前
+  beforeDestory() {},
+  //生命周期-销毁完成
+  destoryed() {},
+  //如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+<style lang="scss" scoped>
+/* @import url(); 引入css类 */
+.magazine-inner {
+  padding-top: 66px;
+  background: #f2f3f5;
+  .btn-box {
+    width: 1108px;
+    margin: 0 auto;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .el-button {
+      width: 96px;
+      height: 32px;
+      padding: 0;
+      background: transparent;
+      border-color: #165dff;
+      color: #165dff;
+      font-weight: 400;
+      font-size: 14px;
+    }
+    .btn-left,
+    .explain-video {
+      .svg-icon {
+        margin-right: 8px;
+      }
+    }
+    .btn-right {
+      .svg-icon {
+        margin-left: 8px;
+      }
+    }
+    .explain-video {
+      background: #ffb224;
+      border-color: #ffb224;
+      color: #ffffff;
+      width: 110px;
+    }
+  }
+
+  .magazine-box {
+    position: relative;
+    padding-top: 24px;
+    min-height: 820px;
+    width: 1108px;
+    margin: 0 auto;
+    .btn-left,
+    .btn-right {
+      position: absolute;
+      color: #175dff;
+      top: 50%;
+      margin-top: 24px;
+      left: -57px;
+      .svg-icon {
+        width: 48px;
+        height: 48px;
+      }
+    }
+    .btn-right {
+      left: auto;
+      right: -100px;
+    }
+    .magazine {
+      background: #ffffff;
+      padding: 16px;
+      border: 1px solid #e5e6eb;
+      border-radius: 16px;
+      width: 1108px;
+      height: 783px;
+      position: absolute;
+      margin: 0 auto;
+      top: 24px;
+      left: 50%;
+      margin-left: -554px;
+      text-align: center;
+      overflow: hidden;
+      .img-box {
+        position: relative;
+        width: 1075px;
+        height: 751px;
+      }
+      img {
+        width: 100%;
+        height: 100%;
+      }
+      .position-item {
+        position: absolute;
+        z-index: 1;
+        cursor: pointer;
+        border: 3px solid transparent;
+        &.active {
+          border-color: #ff1616;
+        }
+        &:hover {
+          border-color: #ff1616;
+        }
+      }
+    }
+  }
+}
+.audio-box {
+  width: 1108px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin: 16px auto 0 auto;
+}
+.aduioLine-box {
+  width: 1108px;
+  height: 48px;
+  background: #ffffff;
+  border: 1px solid #ebebeb;
+  border-radius: 30px;
+  display: flex;
+  align-items: center;
+  padding: 8px 24px;
+  .wrapper {
+    width: 24px;
+    height: 24px;
+    flex-shrink: 0;
+    color: #175dff;
+    margin-left: 8px;
+  }
+  .Audio {
+    // width: 430px;
+  }
+}
+</style>
+<style lang="scss">
+.magazine-detail-dialog {
+  .el-dialog {
+    box-shadow: 0px 6px 30px 5px rgba(0, 0, 0, 0.05),
+      0px 16px 24px 2px rgba(0, 0, 0, 0.04),
+      0px 8px 10px -5px rgba(0, 0, 0, 0.08);
+    border-radius: 16px;
+    border: none;
+    position: absolute;
+    bottom: 50px;
+    left: 50%;
+    margin-left: -600px;
+  }
+}
+.navBar {
+  background: #fff;
+  padding: 8px 24px;
+  border-bottom: 1px solid #ebebeb;
+  display: flex;
+  justify-content: space-between;
+  height: 56px;
+  align-items: center;
+  position: fixed;
+  width: 100%;
+  left: 0;
+  top: 0;
+  z-index: 3;
+  &-left {
+    display: flex;
+    align-items: center;
+    p {
+      margin: 0 12px;
+      font-weight: 400;
+      font-size: 14px;
+      line-height: 22px;
+      color: #86909c;
+    }
+  }
+  .goback {
+    font-weight: 500;
+    font-size: 20px;
+    line-height: 28px;
+    color: #1d2129;
+    padding-right: 12px;
+    .el-icon-arrow-left {
+      margin-right: 8px;
+    }
+  }
+  .border {
+    width: 1px;
+    height: 20px;
+    background: #e5e6eb;
+  }
+}
+</style>