소스 검색

功能介绍

zhuliu 5 달 전
부모
커밋
609fcb46b1

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
src/icons/svg/视频.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
src/icons/svg/说明书.svg


+ 10 - 0
src/router/index.js

@@ -48,6 +48,16 @@ const routes = [
         },
         component: () => import('@/views/home/index.vue'),
       },
+      {
+        path: '/introduction',
+        name: 'Introduction',
+        meta: {
+          // title: '首页',
+          sign: 'introduction',
+          belong: 'introduction'
+        },
+        component: () => import('@/views/home/components/downLoad/introduction/index.vue'),
+      },
     ]
   }
 

+ 3 - 1
src/utils/model/index.js

@@ -4,12 +4,14 @@ import myInput from './input/index.vue'
 import myUpload from './upload/index.vue'
 import myTooltip from './tooltip/index.vue'
 import valueInput from './valueInput'
+import myVideo from './video'
 
 var models = {
   myInput,
   myUpload,
   myTooltip,
-  valueInput
+  valueInput,
+  myVideo
 }
 export default {
   install(Vue) {

+ 115 - 0
src/utils/model/video/index.vue

@@ -0,0 +1,115 @@
+<template>
+    <div class="myVideo">
+        <div class="title">{{ title }}</div>
+        <video 
+            ref="videoPlayer"
+            :src="url"
+            controls
+            width="600"
+            @play="onPlay"
+            @pause="onPause"
+            @ended="onEnded"
+        ></video>
+      <!-- <div>
+        <button @click="playVideo">播放</button>
+        <button @click="pauseVideo">暂停</button>
+      </div> -->
+    </div>
+</template>
+  
+<script>
+  export default {
+    props:{
+        url:{
+            type:String,
+            default:''
+        },
+        title:{
+            type:String,
+            default:''
+        }
+    },
+    data() {
+      return {
+        observer:null,
+        isPlay:false,
+      }
+    },
+    mounted(){
+        this.init()
+    },
+    beforeDestroy() {
+        // 取消对元素的观察
+        if (this.observer) {
+            this.observer.disconnect();
+        }
+    },
+    methods: {
+        init(){
+            if(!this.url){
+                return
+            }
+            var that = this
+            // 创建一个 Intersection Observer 实例
+            this.observer = new IntersectionObserver((entries, observer) => {
+                entries.forEach(entry => {
+                    if (!entry.isIntersecting) {
+                        // 可以在这里执行懒加载、动画触发等操作
+                        if(that.isPlay){
+                            that.pauseVideo()
+                        }
+                    }
+                });
+            }, {
+                root: null, // null 表示视口
+                rootMargin: '0px',
+                threshold: 0.3 // 当元素 10% 进入视口时触发
+            });
+
+            // 选择需要观察的元素
+            const elements = this.$refs['videoPlayer'];
+            this.observer.observe(elements);
+        },
+      playVideo() {
+        this.$refs.videoPlayer.play();
+      },
+      pauseVideo() {
+        this.$refs.videoPlayer.pause();
+      },
+      onPlay() {
+        console.log('视频开始播放');
+        this.isPlay = true
+      },
+      onPause() {
+        console.log('视频已暂停');
+        this.isPlay = false
+      },
+      onEnded() {
+        console.log('视频播放结束');
+        this.isPlay = false
+      }
+    }
+  }
+</script>
+  
+<style lang="scss" scoped>
+  /* 可以添加一些样式 */
+  video {
+    border: 1px solid #ccc;
+    margin-bottom: 10px;
+    width: 100%;
+    height: calc(100% - 50px);
+    background: white;
+  }
+  .myVideo{
+    width: 100%;
+    height: 100%;
+    
+    .title{
+        line-height: 35px;
+        font-weight: bold;
+        // color: white;
+        color: black;
+    }
+  }
+</style>

+ 94 - 13
src/views/home/components/downLoad/downLoad.vue

@@ -4,44 +4,65 @@
         <div>欢迎使用</div>
         <div>窍笔撰写辅助工具</div>
         <div class="downLoad">
-            <el-button round style="width:100%;color:black;font-size:16px;height:50px;font-weight:bold;" @click="downLoad">点击下载</el-button>
+            <el-button round style="width:100%;color:black;font-size:16px;height:60px;font-weight:bold;" @click="downLoad">
+              <div class="downLoad_title">点击下载</div>
+              <!-- <div class="version">当前版本:{{ version.versionNum }}</div> -->
+            </el-button>
         </div>
     </div>
-    
+    <div class="tool">
+      <div class="version">{{ version.versionNum }}</div>
+      <div class="fun" @click="getIntroduction">功能介绍</div>
+    </div>
+
   </div>
 </template>
 
 <script>
 import { downLoad2 } from '@/utils';
 export default {
-  components: {},
+  components: {
+  },
   props: {},
   data() {
     return {
       btnLoading:false,
+      version:{}
     };
   },
   watch: {},
   computed: {},
-  created() {},
+  created() {
+    this.queryPublicVersionLast()
+  },
   mounted() {},
   methods: {
-    downLoad(){
+    queryPublicVersionLast(){
       var params = {
       }
-      this.btnLoading = true
       this.$api.queryPublicVersionLast(params).then(response=>{
         if(response.code == 200){
-            var data = response.data
-            if(data.systemFile && data.systemFile.guid){
-              downLoad2(data.systemFile.guid,'窍笔')
-            }
-            this.btnLoading = false
+            this.version = response.data
         }
       }).catch(error=>{
-          this.btnLoading = false
       })
     },
+    downLoad(){
+      if(this.version.systemFile && this.version.systemFile.guid){
+        downLoad2(this.version.systemFile.guid,'窍笔')
+      }
+    },
+    // 功能介绍
+    getIntroduction(){
+      // this.$refs.introduction.open()
+      // return
+      const router = this.$router.resolve(
+        {
+          path:'introduction'
+        }
+      )
+      window.open(router.href,'_blank')
+    },
   },
 };
 </script>
@@ -51,7 +72,7 @@ export default {
     height: 100%;
     display: flex;
     align-items: center;
-    justify-content: space-around;
+    // justify-content: space-around;
     flex-direction: column;
     .title{
         width: 350px;
@@ -70,6 +91,66 @@ export default {
     }
     .downLoad{
         margin-top: 30px;
+        .downLoad_title{
+          font-size: 22px;
+          font-weight: bold;
+        }
+        .version{
+          margin-top: 5px;
+          font-size: 12px;
+          color: red;
+        }
+    }
+    .tool{
+      font-size: 16px;
+      width: 350px;
+      max-width: 80%;
+      text-align: center;
+      padding: 0 20px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      font-weight: bolder;
+      .version{
+        padding: 2px;
+        color: black;
+        position: relative;
+        font-size: 14px;
+      }
+      .version::before{
+        content: "";
+        position: absolute;
+        inset: 0;
+        margin: auto;
+        width: 100%;
+        height: 100%;
+        background: white;
+        // opacity: 0.3;
+        z-index: -1;
+        -webkit-filter: opacity(50%);
+        filter: opacity(50%);
+      }
+      .fun{
+        padding: 2px;
+        cursor: pointer;
+        color: black;
+        position: relative;
+        font-size: 14px;
+        
+      }
+      .fun::before{
+        content: "";
+        position: absolute;
+        inset: 0;
+        margin: auto;
+        width: 100%;
+        height: 100%;
+        background: white;
+        // opacity: 0.3;
+        z-index: -1;
+        -webkit-filter: opacity(50%);
+        filter: opacity(50%);
+      }
     }
 }
 </style>

+ 27 - 0
src/views/home/components/downLoad/introduction/index.vue

@@ -0,0 +1,27 @@
+<template>
+  <div class="height_100">
+    <introduction></introduction>
+  </div>
+</template>
+
+<script>
+import introduction from './introduction.vue';
+export default {
+  components: {
+    introduction
+  },
+  props: {},
+  data() {
+    return {
+        
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {},
+  mounted() {},
+  methods: {},
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 215 - 0
src/views/home/components/downLoad/introduction/introduction copy.vue

@@ -0,0 +1,215 @@
+<template>
+  <div class="introduction" :style="`background-image:url(${require('@/assets/image/background_home.jpg')})`">
+    <div class="logo">
+        <el-image :src="require('@/assets/image/logo3.png')" class="img" fit="contain"></el-image>
+    </div>
+   
+    <div class="introduction_container">
+        <div v-if="files && files.length" class="height_100 introduction_item_warp" >
+            <div class="menu">
+                <div class="top">
+                    <div>
+                        <svg-icon class="xiaoshiIcon" iconClass="说明书" iconName="说明书"></svg-icon>
+                    </div>
+                    <div>查看文档</div>
+                </div>
+                <div class="bottom">
+                    <div>
+                        <svg-icon class="xiaoshiIcon" iconClass="视频" iconName="视频"></svg-icon>
+                    </div>
+                    <div>查看演示视频</div>
+                </div>
+            </div>
+            <div v-for="(item,index) in files" :key="index" class="introduction_item " >
+                <div v-if="item.type != 'mp4'" style="width:100%;height:100%">
+                    <div class="title" >{{ (index + 1) + '、' + item.name }}</div>
+                    <iframe id="checkIframe" :src="getUrl(item)" frameborder="0" width="100%" height="800px"></iframe>
+                </div>
+                <div v-else class="video">
+                    <myVideo :url="`${baseUrl}${item.url}`" :title="(index + 1) + '、'+item.name"></myVideo>
+                </div>
+            </div>
+            <!-- <el-carousel :autoplay="false"  arrow="hover">
+                <el-carousel-item v-for="(item,index) in files" :key="index" class="introduction_item height_100" >
+                    <div v-if="item.type != 'mp4'" style="width:100%;height:100%">
+                        <div class="title" >{{ item.url }}</div>
+                        <iframe id="checkIframe" :src="getUrl(item)" frameborder="0" width="100%" height="90%"></iframe>
+                    </div>
+                    <div v-else class="height_100">
+                        <myVideo :url="`${baseUrl}${item.url}`" :title="item.url"></myVideo>
+                    </div>
+                </el-carousel-item>
+            </el-carousel> -->
+        </div>
+        <div class="empty" v-else>暂无介绍</div>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+import { Base64 } from 'js-base64';
+export default {
+  components: {},
+  props: {},
+  data() {
+    return {
+        files:[],
+        baseUrl:'https://xsip.cn/static/'
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {
+    this.init()
+  },
+  mounted() {},
+  methods: {
+    async init(){
+        await this.getIntroduction()
+    },
+    async getIntroduction(){
+        let url = `/static/qiaobiConfig.json`
+        await fetch(url).then(res =>  res.json() ).then(data => {
+            if(data && data.length){
+                data.forEach(item => {
+                    let type = this.getFileType(item)
+                    this.files.push(
+                        {
+                            type:type,
+                            url:item,
+                            name:item.slice(0, item.length - type.length - 1)
+                        }
+                    )
+                });
+                
+            }
+        })
+    },
+    getFileType(file){
+        let arr = file.split('.')
+        if(arr && arr.length>0){
+          return arr[arr.length-1]  
+        }
+        return '';
+    },
+    getUrl(file){
+        return `https://xsip.cn/onlinePreview/onlinePreview?url=` + encodeURIComponent(Base64.encode(this.baseUrl+file.url))
+    },
+  },
+};
+</script>
+<style lang="scss">
+.introduction{
+    .el-carousel{
+        height: calc(100% - 0px);
+        width: 100%;
+    }
+    .el-carousel__container{
+        height: calc(100% - 20px);
+        width: 100%;
+    }
+}
+    
+</style>
+<style lang="scss" scoped>
+.introduction{
+    position: relative;
+    background: white;
+    padding-bottom: 30px;
+    padding-top: 10px;
+    height:calc(100% - 50px);
+    width: calc(100% - 0px);
+    .logo{
+        position: absolute;
+        // top: 50px;
+        // left: 50px;
+        inset: 0;
+        height: 100px;
+        width: fit-content;
+        z-index: 9999;
+        .img{
+            width: 100%;
+            height: 100%;
+        }
+    }
+    
+    .introduction_container{
+        margin-top: 30px;
+        overflow-y: auto;
+        
+        padding: 0 30px;
+        height:calc(100% - 30px);
+        width: calc(100% - 60px);
+        
+    }
+    .introduction_item_warp{
+        border-radius: 8px;
+        width: calc(75% + 40px);
+        margin: auto;
+       
+        .menu{
+            width: 100px;
+            height: 180px !important;
+            position: absolute;
+            left:calc((100% - 75%) / 2);
+            top: calc(50% - 90px);
+            margin: auto;
+            font-size: 12px;
+            cursor: pointer;
+            .top{
+                color: white;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                flex-direction: column;
+                height: 75px;
+                background: #316192;
+                border-radius: 8px 8px 0 0;
+                border-bottom: 1px solid white;
+            }
+            .bottom{
+                color: white;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                flex-direction: column;
+                height: 75px;
+                background: #b31d28;
+                border-radius: 0 0 8px 8px ;
+                border-top: 1px solid white;
+            }
+            .xiaoshiIcon{
+                font-size: 24px;
+                color: white !important;
+            }
+        }
+    }
+    .introduction_item{
+        margin-top: 20px;
+        background: white;
+        width: 75%;
+        margin: auto;
+        padding: 20px;
+        // &:first-child{
+        //     border-radius: 8px 8px 0 0;
+        // }
+        // &:last-child{
+        //     border-radius:0 0 8px 8px ;
+        // }
+        .title{
+            line-height: 35px;
+            font-weight: bold;
+            // color: white;
+            color: black;
+        }
+        
+    }
+    .empty{
+        font-size: 20px;
+        color:#c2c5c9;
+        text-align: center;
+        line-height: 250px;
+    }
+}
+</style>

+ 274 - 0
src/views/home/components/downLoad/introduction/introduction.vue

@@ -0,0 +1,274 @@
+<template>
+  <div class="introduction" :style="`background-image:url(${require('@/assets/image/background_home.jpg')})`">
+    <div class="logo">
+        <el-image :src="require('@/assets/image/logo3.png')" class="img" fit="contain"></el-image>
+    </div>
+    <div class="menu">
+        <div class="top" @click="currentType = 'document'">
+            <div>
+                <svg-icon class="xiaoshiIcon" iconClass="说明书" iconName="说明书"></svg-icon>
+            </div>
+            <div>查看文档</div>
+        </div>
+        <div class="bottom" @click="currentType = 'video'">
+            <div>
+                <svg-icon class="xiaoshiIcon" iconClass="视频" iconName="视频"></svg-icon>
+            </div>
+            <div>查看演示视频</div>
+        </div>
+    </div>
+    <div class="introduction_container">
+        <!-- <div v-if="files && files.length" class="height_100 introduction_item_warp" >
+            <div v-for="(item,index) in files" :key="index" class="introduction_item " >
+                <div v-if="item.type != 'mp4'" style="width:100%;height:100%">
+                    <div class="title" >{{ (index + 1) + '、' + item.name }}</div>
+                    <iframe id="checkIframe" :src="getUrl(item)" frameborder="0" width="100%" height="800px"></iframe>
+                </div>
+                <div v-else class="video">
+                    <myVideo :url="`${baseUrl}${item.url}`" :title="(index + 1) + '、'+item.name"></myVideo>
+                </div>
+            </div>
+        </div> -->
+        <div v-show="currentType == 'document'" class="height_100 introduction_item_warp">
+            <div v-if="documents && videos.length" class="height_100">
+                <div class="introduction_item title" >
+                    <div v-for="(item,index) in documents" :key="index+'a'" class="title_item" @click="documentIndex = index">{{ (index + 1) + '、' + item.name }}
+                        <div v-if="index<documents.length-1" class="line"></div>
+                    </div>
+                </div>
+                <!-- <div v-for="(item,index) in documents" :key="index+'d'" class="introduction_item " >
+                    <iframe id="checkIframe" :src="getUrl(item)" frameborder="0" width="100%" :height="height - 200"></iframe>
+                </div> -->
+                <div class="introduction_item" >
+                    <iframe id="checkIframe" :src="getUrl(documents[documentIndex])" frameborder="0" width="100%" :height="height - 200"></iframe>
+                </div>
+            </div>
+            <div class="empty" v-else>暂无介绍</div>
+        </div>
+        <div v-show="currentType == 'video'" class="height_100 introduction_item_warp">
+            <div v-if="videos && videos.length">
+                <div class="introduction_item title1">窍笔演示视频</div>
+                <div v-for="(item,index) in videos" :key="index+'v'" class="introduction_item " >
+                    <myVideo :url="`${baseUrl}${item.url}`" :title="(index + 1) + '、'+item.name"></myVideo>
+                </div>
+            </div>
+            <div class="empty" v-else>暂无介绍</div>
+        </div>
+    </div>
+    
+  </div>
+</template>
+
+<script>
+import { Base64 } from 'js-base64';
+export default {
+  components: {},
+  props: {},
+  data() {
+    return {
+        files:[],
+        documents:[],
+        documentIndex:0,
+        videos:[],
+        currentType:'document',
+        baseUrl:'https://xsip.cn/static/',
+        height:document.documentElement.clientHeight,
+    };
+  },
+  watch: {},
+  computed: {},
+  created() {
+    this.init()
+  },
+  mounted() {},
+  methods: {
+    async init(){
+        await this.getIntroduction()
+    },
+    async getIntroduction(){
+        let url = `/static/qiaobiConfig.json`
+        await fetch(url).then(res =>  res.json() ).then(data => {
+            if(data && data.length){
+                data.forEach(item => {
+                    let type = this.getFileType(item)
+                    if(type == 'mp4'){
+                        this.videos.push(
+                            {
+                                type:type,
+                                url:item,
+                                name:item.slice(0, item.length - type.length - 1)
+                            }
+                        )
+                    }else{
+                       this.documents.push(
+                            {
+                                type:type,
+                                url:item,
+                                name:item.slice(0, item.length - type.length - 1)
+                            }
+                        ) 
+                    }
+                    this.files.push(
+                        {
+                            type:type,
+                            url:item,
+                            name:item.slice(0, item.length - type.length - 1)
+                        }
+                    )
+                });
+                
+            }
+        })
+    },
+    getFileType(file){
+        let arr = file.split('.')
+        if(arr && arr.length>0){
+          return arr[arr.length-1]  
+        }
+        return '';
+    },
+    getUrl(file){
+        return `https://xsip.cn/onlinePreview/onlinePreview?url=` + encodeURIComponent(Base64.encode(this.baseUrl+file.url))
+    },
+  },
+};
+</script>
+<style lang="scss">
+.introduction{
+    .el-carousel{
+        height: calc(100% - 0px);
+        width: 100%;
+    }
+    .el-carousel__container{
+        height: calc(100% - 20px);
+        width: 100%;
+    }
+}
+    
+</style>
+<style lang="scss" scoped>
+.introduction{
+    position: relative;
+    background: white;
+    padding-bottom: 30px;
+    padding-top: 10px;
+    height:calc(100% - 50px);
+    width: calc(100% - 0px);
+    .logo{
+        position: absolute;
+        // top: 50px;
+        // left: 50px;
+        inset: 0;
+        height: 100px;
+        width: fit-content;
+        z-index: 9999;
+        .img{
+            width: 100%;
+            height: 100%;
+        }
+    }
+    .menu{
+        width: 100px;
+        height: 180px !important;
+        position: absolute;
+        left:calc((100% - 75%) / 2);
+        top: calc(50% - 90px);
+        margin: auto;
+        font-size: 12px;
+        cursor: pointer;
+        .top{
+            color: white;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            flex-direction: column;
+            height: 75px;
+            background: #316192;
+            border-radius: 8px 8px 0 0;
+            border-bottom: 1px solid white;
+        }
+        .bottom{
+            color: white;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            flex-direction: column;
+            height: 75px;
+            background: #b31d28;
+            border-radius: 0 0 8px 8px ;
+            border-top: 1px solid white;
+        }
+        .xiaoshiIcon{
+            font-size: 24px;
+            color: white !important;
+        }
+    }
+    .introduction_container{
+        margin-top: 30px;
+        overflow-y: auto;
+        
+        padding: 0 30px;
+        height:calc(100% - 30px);
+        width: calc(100% - 60px);
+        
+    }
+    .introduction_item_warp{
+        border-radius: 8px;
+        width: calc(75% + 40px);
+        margin: auto;
+        .title{
+            border-bottom: 1px solid gray;
+            display: flex;
+            align-items: center;
+            .title_item{
+                min-width: 200px;
+                
+                overflow: hidden;
+                white-space: nowrap;
+                text-overflow:ellipsis;
+                cursor: pointer;
+                .line{
+                    width: 1px;
+                    height: 100%;
+                    background: gray;
+                }
+            }
+        }
+        .title1{
+            position: sticky;
+            top: 0;
+            background: white;
+            text-align: center;
+            font-weight: bold;
+            font-size: 18px;
+            border-bottom: 1px solid gray;
+        }
+    }
+    .introduction_item{
+        margin-top: 20px;
+        background: white;
+        width: 75%;
+        margin: auto;
+        padding: 20px;
+        // &:first-child{
+        //     border-radius: 8px 8px 0 0;
+        // }
+        // &:last-child{
+        //     border-radius:0 0 8px 8px ;
+        // }
+        .title{
+            line-height: 35px;
+            font-weight: bold;
+            // color: white;
+            color: black;
+        }
+        
+    }
+    .empty{
+        font-size: 20px;
+        color:#c2c5c9;
+        text-align: center;
+        line-height: 250px;
+    }
+}
+</style>

+ 2 - 2
src/views/layout/index.vue

@@ -1,6 +1,6 @@
 <template>
-  <div id="admin">
-    <section class="wrapper">
+  <div id="admin" class="height_100">
+    <section class="wrapper height_100">
       <router-view></router-view>
       <!-- <el-container>
         <el-container>