CzRger 1 год назад
Родитель
Сommit
6cd3137e43

+ 139 - 0
src/components/keda/VideoDialog.vue

@@ -0,0 +1,139 @@
+<template>
+  <!-- 视频播放弹窗 -->
+  <div class="video_dialog" ref="dialog2">
+    <div class="dia_title">
+      <div class="txt">视频详情</div>
+      <div class="btns">
+        <img @click="fullScreen" src="/image/icon/full_screen.png" alt/>
+        <!-- <span class="close">×</span> -->
+        <img @click="closedialog2" src="/image/icon/close.png"/>
+      </div>
+    </div>
+    <div class="container" id="container">
+      <!-- <video :src="videoURL" autoplay loop muted></video> -->
+    </div>
+  </div>
+</template>
+
+<script>
+import outputOptions from "./index.js";
+
+export default {
+  name: "VideoDialog",
+  components: {},
+  props: {},
+  data() {
+    return {
+      isFull: false,
+      video: ''
+    };
+  },
+  computed: {
+    // 是否显示视频详情弹窗 和 视频源
+    // ...mapState(["videoURL"]),
+    // videoURL() {
+    //   return JSON.parse(JSON.stringify(this.$store.state.videoURL));
+    // }
+
+  },
+  watch: {
+    videoURL(val) {
+      this.myfunction2();
+      this.myfunction(val)
+    }
+  },
+  mounted() {
+    this.myfunction(this.videoURL);
+  },
+  methods: {
+    myfunction(videos) {
+      this.video = new KMedia(outputOptions("#container", videos));
+    },
+    myfunction2() {
+      if (this.video != null) {
+        this.video.closeMedia();
+      }
+      this.video = null;
+      document.getElementById('container').innerHTML = "";
+    },
+    // 放大视频弹窗
+    fullScreen() {
+      let dialog2 = this.$refs.dialog2;
+      if (this.isFull) {
+        dialog2.classList.remove("dialog_big");
+      } else {
+        dialog2.classList.add("dialog_big");
+        dialog2.style.left = "2853px";
+        dialog2.style.top = "90px";
+      }
+      this.isFull = !this.isFull;
+    },
+    // 关闭视频弹窗
+    closedialog2() {
+      this.myfunction2();
+      this.$store.commit("changeVideoURL", null);
+    }
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.video_dialog {
+  z-index: 10099;
+  pointer-events: all;
+  width: 800px;
+  height: 500px;
+  z-index: 10;
+  left: 2930px;
+  top: 300px;
+  position: absolute;
+  display: flex;
+  background-color: rgba(9, 24, 40, 0.95);
+  flex-direction: column;
+
+  .dia_title {
+    height: 40px;
+    flex-shrink: 0;
+    display: flex;
+    background: linear-gradient(to right, #00cc66, #0085b2);
+    color: #fff;
+    font-size: 24px;
+    line-height: 40px;
+    font-weight: bold;
+    padding: 0 15px;
+    flex-shrink: 0;
+    justify-content: space-between;
+
+    .close {
+      font-size: 30px;
+    }
+
+    .btns {
+      width: 50px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+  }
+
+  .container {
+    flex: 1 1 100%;
+
+    video {
+      display: block;
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+
+.dialog_big {
+  width: 980px;
+  height: 980px;
+  // transform: translate(-90px, -240px);
+}
+
+.hide {
+  display: none;
+}
+</style>

+ 77 - 0
src/components/keda/demo.vue

@@ -0,0 +1,77 @@
+<template>
+  <div class="main">
+    <h1>科达demo</h1>
+    <div class="list">
+      <template v-for="item in videoList">
+        <KedaCom :videoCode="item"/>
+      </template>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useStore} from 'vuex'
+import {useRouter, useRoute} from 'vue-router'
+import outputOptions from "./options";
+import KedaCom from './keda-com.vue'
+
+export default defineComponent({
+  name: '',
+  components: {KedaCom},
+  setup() {
+    const store = useStore();
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      videoList: []
+    })
+    onMounted(() => {
+      window.addEventListener("message", function (event) {
+        const result = event.data;
+        if (result.videoData) {
+          state.videoList = result.videoData
+        }
+      });
+      window.parent.postMessage({
+        from: window.name,
+        variable: "videoIframeLoading",
+        value: true,
+      }, "*")
+    })
+    return {
+      ...toRefs(state),
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+.main {
+  width: 100%;
+  height: 100%;
+  padding: 20px;
+
+  .list {
+    display: flex;
+    flex-wrap: wrap;
+
+    > div {
+      margin-right: 10px;
+      margin-bottom: 10px;
+    }
+  }
+}
+</style>

+ 55 - 0
src/components/keda/index.js

@@ -0,0 +1,55 @@
+const option = {
+  selector: "#videOne",
+  mediaUrl: "./static/demo.mp4",
+  mediaType: "video",
+  playType: "liveStreaming",
+  progressDisplayTime: false,
+  theme: "blue",
+  autoplay: true,
+  muted: true,
+  videoFit:'cover',
+  noBorder: true,
+  hideControlsBar: true,
+  tools: [
+    "backward",
+    "play",
+    "forward",
+    "timings",
+    "playbackRate",
+    "backplay",
+    "ptz",
+    "videoClip",
+    "videoRecorder",
+    "digitalZoom",
+    "screenSplit",
+    "snapshot",
+    "multiShot",
+    "imgControl",
+    "loop",
+    "volume",
+    "requestFullscreen"
+  ],
+  restore: false,
+  loading: {
+    beforeStream: "初始化中",
+    beforePicture: "视频加载中",
+    timeout: "视频加载已超时"
+  },
+  mediaInfo: {
+    file: {},
+    liveStreaming: {
+      websocketUrl: "ws://59.212.10.165:8081",
+      devId: "46040052001321000402"
+    },
+    nonLiveStreaming: {}
+  },
+  onload: function () {}
+};
+
+function outputOptions(selector, devId) {
+  option.selector = selector;
+  option.mediaInfo.liveStreaming.devId = devId;
+  return option;
+}
+
+export default outputOptions;

+ 70 - 0
src/components/keda/keda-com.vue

@@ -0,0 +1,70 @@
+<template>
+  <div class="keda-com">
+    <div class="container" ref="ref_video"/>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useStore} from 'vuex'
+import {useRouter, useRoute} from 'vue-router'
+import outputOptions from "./options";
+
+export default defineComponent({
+  name: '',
+  components: {},
+  props: {
+    videoCode: { required: true, type: String }
+  },
+  setup(props) {
+    const store = useStore();
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      video: null,
+    })
+    const ref_video = ref()
+    watch(() => props.videoCode, (n) => {
+      console.log(n)
+      if (n) {
+        initVideo()
+      }
+    })
+    const initVideo = () => {
+      if (props.videoCode) {
+        state.video = new KMedia(outputOptions(ref_video.value, props.videoCode));
+      }
+    }
+    onMounted(() => {
+      initVideo()
+    })
+    return {
+      ...toRefs(state),
+      ref_video
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+  .keda-com {
+    width: 400px;
+    height: 300px;
+    display: flex;
+    .container {
+      flex: 1;
+    }
+  }
+</style>

Разница между файлами не показана из-за своего большого размера
+ 178 - 0
src/components/keda/kmedia-basic.js


Разница между файлами не показана из-за своего большого размера
+ 179 - 0
src/components/keda/kmedia.js


+ 55 - 0
src/components/keda/options.ts

@@ -0,0 +1,55 @@
+const option = {
+  selector: "#videOne",
+  mediaUrl: "./static/demo.mp4",
+  mediaType: "video",
+  playType: "liveStreaming",
+  progressDisplayTime: false,
+  theme: "blue",
+  autoplay: true,
+  muted: true,
+  videoFit:'cover',
+  noBorder: true,
+  hideControlsBar: true,
+  tools: [
+    "backward",
+    "play",
+    "forward",
+    "timings",
+    "playbackRate",
+    "backplay",
+    "ptz",
+    "videoClip",
+    "videoRecorder",
+    "digitalZoom",
+    "screenSplit",
+    "snapshot",
+    "multiShot",
+    "imgControl",
+    "loop",
+    "volume",
+    "requestFullscreen"
+  ],
+  restore: false,
+  loading: {
+    beforeStream: "初始化中",
+    beforePicture: "视频加载中",
+    timeout: "视频加载已超时"
+  },
+  mediaInfo: {
+    file: {},
+    liveStreaming: {
+      websocketUrl: "ws://59.212.10.165:8081",
+      devId: "46040052001321000402"
+    },
+    nonLiveStreaming: {}
+  },
+  onload: function () {}
+};
+
+function outputOptions(selector: any, devId: string) {
+  option.selector = selector;
+  option.mediaInfo.liveStreaming.devId = devId;
+  return option;
+}
+
+export default outputOptions;

BIN
src/views/screen/img/hainan.png


BIN
src/views/screen/img/jinzita.png


BIN
src/views/screen/img/left_bg-1.png


BIN
src/views/screen/img/num-back.png


BIN
src/views/screen/img/screen-item-title.png


BIN
src/views/screen/img/tooltips.png


BIN
src/views/screen/img/video-img.png


+ 560 - 37
src/views/screen/index.vue

@@ -64,49 +64,219 @@
         </div>
       </template>
     </div>
-    <div class="screen-left">
-      <div class="sl-head">
-        <img src="./img/left_icon-1.png"/>
-        <div>数据调用和使用</div>
+    <div class="screen-item screen-item-video">
+      <div class="si-head">
+        <div>视频监控</div>
       </div>
-      <div class="sl-content">
+      <div class="si-content">
+        <div class="sic-video">
+          <template v-for="(item, index) in videoList">
+            <div class="video-item" @dblclick.capture="fullScreen($event)" >
+              <div class="video-item-title">{{item.label}}</div>
+              <KedaCom class="video-keda" :video-code="item.code"/>
+            </div>
+          </template>
+        </div>
+      </div>
+    </div>
+    <div class="screen-item screen-item-tszhqk">
+      <div class="si-head">
+        <div>态势综合情况</div>
+      </div>
+      <div class="si-content">
+        <img class="hainan" src="./img/hainan.png"/>
+        <div class="list">
+          <div class="item">
+            <div class="line"/>
+            <div class="right">
+              <div class="title">实时用户数
+                <el-popover
+                    placement="top"
+                    trigger="hover"
+                    :width="230"
+                    content="数据来源:网信办手机信令统计"
+                >
+                  <template #reference>
+                    <img src="./img/tooltips.png"/>
+                  </template>
+                </el-popover>
+              </div>
+              <div class="count">
+                <CountTo :startVal="tszhqk.ssyhs.startVal" :endVal="tszhqk.ssyhs.endVal" :duration="1500"></CountTo>
+              </div>
+            </div>
+          </div>
+          <div class="item">
+            <div class="line"/>
+            <div class="right">
+              <div class="title">流动用户数<el-popover
+                  placement="top"
+                  trigger="hover"
+                  :width="230"
+                  content="数据来源:网信办手机信令统计"
+              >
+                <template #reference>
+                  <img src="./img/tooltips.png"/>
+                </template>
+              </el-popover>
+              </div>
+              <div class="count">
+                <CountTo :startVal="tszhqk.ldyhs.startVal" :endVal="tszhqk.ldyhs.endVal" :duration="1500"></CountTo>
+              </div>
+            </div>
+          </div>
+          <div class="item">
+            <div class="line"/>
+            <div class="right">
+              <div class="title">旅游用户数<el-popover
+                  placement="top"
+                  trigger="hover"
+                  :width="230"
+                  content="数据来源:网信办手机信令统计"
+              >
+                <template #reference>
+                  <img src="./img/tooltips.png"/>
+                </template>
+              </el-popover>
+              </div>
+              <div class="count">
+                <CountTo :startVal="tszhqk.lyyhs.startVal" :endVal="tszhqk.lyyhs.endVal" :duration="1500"></CountTo>
+              </div>
+            </div>
+          </div>
+          <div class="item">
+            <div class="line"/>
+            <div class="right">
+              <div class="title">过境用户数<el-popover
+                  placement="top"
+                  trigger="hover"
+                  :width="230"
+                  content="数据来源:网信办手机信令统计"
+              >
+                <template #reference>
+                  <img src="./img/tooltips.png"/>
+                </template>
+              </el-popover>
+              </div>
+              <div class="count">
+                <CountTo :startVal="tszhqk.gjyhs.startVal" :endVal="tszhqk.gjyhs.endVal" :duration="1500"></CountTo>
+              </div>
+            </div>
+          </div>
+          <div class="item">
+            <div class="line"/>
+            <div class="right">
+              <div class="title">境外用户数<el-popover
+                  placement="top"
+                  trigger="hover"
+                  :width="230"
+                  content="数据来源:网信办手机信令统计"
+              >
+                <template #reference>
+                  <img src="./img/tooltips.png"/>
+                </template>
+              </el-popover>
+              </div>
+              <div class="count">
+                <CountTo :startVal="tszhqk.jwyhs.startVal" :endVal="tszhqk.jwyhs.endVal" :duration="1500"></CountTo>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="screen-item screen-item-spzyqk">
+      <div class="si-head">
+        <div>视频资源情况</div>
+      </div>
+      <div class="si-content">
+        <img class="video-img" src="./img/video-img.png"/>
+        <div class="list">
+          <div class="item">
+            <div class="title">视频点位总数</div>
+            <div class="count">{{spzyqk.spdwzs}}</div>
+          </div>
+          <div class="item">
+            <div class="title">视频解析总数</div>
+            <div class="count">{{spzyqk.spjxzs}}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="screen-item screen-item-sjzycqk">
+      <div class="si-head">
+        <div>数据资源池情况</div>
+      </div>
+      <div class="si-content">
         <div class="slc-item">
           <div class="slc-item-icon"><img src="./img/left_icon-2.png"/></div>
-          <div class="slc-item-title"><span>实时用户数</span></div>
+          <div class="slc-item-title"><span>数据存储总量</span></div>
           <div  class="slc-item-count">
-            <CountTo :startVal="leftValue.ssyhs.startVal" :endVal="leftValue.ssyhs.endVal" :duration="1500"></CountTo>
+            {{sjzycqk.sjcczl}}TB
           </div>
         </div>
         <div class="slc-item">
           <div class="slc-item-icon"><img src="./img/left_icon-3.png"/></div>
-          <div class="slc-item-title"><span>流动用户数</span></div>
+          <div class="slc-item-title"><span>数据记录总量</span></div>
           <div  class="slc-item-count">
-            <CountTo :startVal="leftValue.ldyhs.startVal" :endVal="leftValue.ldyhs.endVal" :duration="1500"></CountTo>
+            {{sjzycqk.sjjlzl}}亿
           </div>
         </div>
         <div class="slc-item">
           <div class="slc-item-icon"><img src="./img/left_icon-4.png"/></div>
-          <div class="slc-item-title"><span>旅游用户数</span></div>
+          <div class="slc-item-title"><span>归集单位数量</span></div>
           <div  class="slc-item-count">
-            <CountTo :startVal="leftValue.lyyhs.startVal" :endVal="leftValue.lyyhs.endVal" :duration="1500"></CountTo>
+            {{sjzycqk.gjdwsl}}项
           </div>
         </div>
         <div class="slc-item">
           <div class="slc-item-icon"><img src="./img/left_icon-5.png"/></div>
-          <div class="slc-item-title"><span>过境用户数</span></div>
+          <div class="slc-item-title"><span>归集数据项数</span></div>
           <div  class="slc-item-count">
-            <CountTo :startVal="leftValue.gjyhs.startVal" :endVal="leftValue.gjyhs.endVal" :duration="1500"></CountTo>
+            {{sjzycqk.gjsjxs}}
           </div>
         </div>
         <div class="slc-item">
           <div class="slc-item-icon"><img src="./img/left_icon-6.png"/></div>
-          <div class="slc-item-title"><span>境外用户数</span></div>
+          <div class="slc-item-title"><span>本月新增记录</span></div>
           <div  class="slc-item-count">
-            <CountTo :startVal="leftValue.jwyhs.startVal" :endVal="leftValue.jwyhs.endVal" :duration="1500"></CountTo>
+            {{sjzycqk.byxzjl}}
           </div>
         </div>
       </div>
     </div>
+    <div class="screen-item screen-item-yjtjqk">
+      <div class="si-head">
+        <div>预警统计情况</div>
+        <div class="jjsy">截止上月</div>
+      </div>
+      <div class="si-content">
+        <div class="total">
+          <div class="title">预警统计总数</div>
+          <template v-for="item in String(yjtjqk.total)">
+            <div class="num">{{item}}</div>
+          </template>
+          <div class="title">项</div>
+        </div>
+        <img class="jinzita" src="./img/jinzita.png"/>
+        <div class="item item-ffld">
+          <div class="title">非法离岛</div>
+          <div class="count">{{yjtjqk.ffldNum}}({{yjtjqk.ffldPer}}%)</div>
+        </div>
+        <div class="item item-cqzl">
+          <div class="title">超期滞留</div>
+          <div class="count">{{yjtjqk.cqzlNum}}({{yjtjqk.cqzlPer}}%)</div>
+        </div>
+        <div class="item item-bbbzs">
+          <div class="title">不报备住宿</div>
+          <div class="count">{{yjtjqk.bbbzsNum}}({{yjtjqk.bbbzsPer}}%)</div>
+        </div>
+        <div class="item item-qt">
+          <div class="title">其他</div>
+          <div class="count">{{yjtjqk.qtNum}}({{yjtjqk.qtPer}}%)</div>
+        </div>
+      </div>
+    </div>
     <div v-show="showInfo" class="info-dialog" ref="ref_infoDialog">
       <template v-for="(item, index) in InfoMapper">
         <div class="info-dialog-block animate__animated">
@@ -157,11 +327,12 @@ import {useStore} from 'vuex'
 import {bgImgMapper, infoMapper, logoIcon} from '../common/static'
 import MessageCom from './message/index.vue'
 import CountTo from '@/components/vue-count-to/vue-countTo.vue';
+import KedaCom from '@/components/keda/keda-com.vue';
 import axios from "axios";
 
 export default defineComponent({
   name: 'App',
-  components: {MessageCom, CountTo},
+  components: {MessageCom, CountTo, KedaCom},
   setup() {
     const store = useStore()
     const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
@@ -177,7 +348,7 @@ export default defineComponent({
       infoInput: '',
       LogoIcon: logoIcon,
       showMessage: false,
-      leftValue: {
+      tszhqk: {
         ssyhs: {
           startVal: 0,
           endVal: 0
@@ -198,6 +369,29 @@ export default defineComponent({
           startVal: 0,
           endVal: 0
         },
+      },
+      videoList: <any>[],
+      sjzycqk: {
+        sjcczl: 0,
+        sjjlzl: 0,
+        gjdwsl: 0,
+        gjsjxs: 0,
+        byxzjl: 0,
+      },
+      spzyqk: {
+        spdwzs: 0,
+        spjxzs: 0
+      },
+      yjtjqk: {
+        total: 0,
+        ffldNum: 0,
+        ffldPer: 0,
+        cqzlNum: 0,
+        cqzlPer: 0,
+        bbbzsNum: 0,
+        bbbzsPer: 0,
+        qtNum: 0,
+        qtPer: 0
       }
     });
     const switchInfo = (ind) => {
@@ -225,22 +419,22 @@ export default defineComponent({
     const toHref = (val: { href: string | URL | undefined }) => {
       window.open(that.$util.formatUrlByInfo(val.href), '_blank')
     }
-    const initLeftCount = () => {
+    const initTSZHQK = () => {
       const handle = () => {
         axios.get(`/${store.state.app.apiProxy.wazxApi}/populationTrend/getUserCount?token=5224E73006490F8D878ABD2CA5A39E78`).then(res => {
           try {
             if (res.status === 200 && res.data?.status === 200) {
               res.data?.data?.forEach((v: any) => {
                 if (v.userType === 1) {
-                  state.leftValue.ssyhs.endVal = v.count
+                  state.tszhqk.ssyhs.endVal = v.count
                 } else if (v.userType === 3) {
-                  state.leftValue.ldyhs.endVal = v.count
+                  state.tszhqk.ldyhs.endVal = v.count
                 } else if (v.userType === 4) {
-                  state.leftValue.lyyhs.endVal = v.count
+                  state.tszhqk.lyyhs.endVal = v.count
                 } else if (v.userType === 9) {
-                  state.leftValue.gjyhs.endVal = v.count
+                  state.tszhqk.gjyhs.endVal = v.count
                 } else if (v.userType === 5) {
-                  state.leftValue.jwyhs.endVal = v.count
+                  state.tszhqk.jwyhs.endVal = v.count
                 }
               })
             }
@@ -254,8 +448,66 @@ export default defineComponent({
         handle()
       }, 10000)
     }
+    const initVideo = () => {
+      state.videoList = [
+        {label: '1公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '2公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '3公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '4公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '5公安类—博鳌—XX点位_B公安类—博鳌—XX点位_B公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '6公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '7公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '8公安类—博鳌—XX点位_B', code: '460123123123123'},
+        {label: '9公安类—博鳌—XX点位_B', code: '460123123123123'},
+      ]
+    }
+    const fullScreen = (event: any) => {
+      const deep: any = (el: any) => {
+        if (el.className.includes('video-item')) {
+          return el
+        } else {
+          return deep(el.parentElement)
+        }
+      }
+      deep(event.target).requestFullscreen()
+    }
+    const initSJZYCQK = () => {
+      state.sjzycqk = {
+        sjcczl: 0,
+        sjjlzl: 0,
+        gjdwsl: 0,
+        gjsjxs: 0,
+        byxzjl: 0,
+      }
+      state.spzyqk.spdwzs = 0
+    }
+    const initSPJXZS = () => {
+      state.spzyqk.spjxzs = 0
+    }
+    const initYJTJQK = () => {
+      state.yjtjqk = {
+        total: 0,
+        ffldNum: 0,
+        ffldPer: 0,
+        cqzlNum: 0,
+        cqzlPer: 0,
+        bbbzsNum: 0,
+        bbbzsPer: 0,
+        qtNum: 0,
+        qtPer: 0
+      }
+    }
     onMounted(() => {
-      initLeftCount()
+      initTSZHQK()
+      initVideo()
+      initSJZYCQK()
+      initSPJXZS()
+      initYJTJQK()
+      window.addEventListener('dblclick', (e) => {
+        if (document.fullscreenElement) {
+          document.exitFullscreen()
+        }
+      })
       setInterval(() => {
         const len = BgImgMapper.length - 1
         if (state.bgImgIndex === len) {
@@ -280,7 +532,8 @@ export default defineComponent({
       switchInfo,
       ref_infoDialog,
       ref_screenBg,
-      toHref
+      toHref,
+      fullScreen
     }
   }
 })
@@ -497,23 +750,19 @@ export default defineComponent({
         }
       }
     }
-    $screenLeftHeight: 511px;
-    .screen-left {
-      height: $screenLeftHeight;
+    .screen-item {
       position: absolute;
       z-index: 2;
-      left: 27px;
-      top: calc((100% - #{$screenLogoHeight} - #{$screenHrefHeight} - #{$screenLeftHeight}) / 2 + #{$screenLogoHeight});
-      .sl-head {
-        background: url('./img/left_bg-1.png');
+      display: flex;
+      flex-direction: column;
+      .si-head {
+        background: url('./img/screen-item-title.png');
         width: 401px;
         height: 46px;
         display: flex;
         align-items: center;
-        >img {
-          margin: 0 10px 0 26px;
-        }
         >div {
+          margin-left: 42px;
           font-size: 26px;
           font-family: Microsoft YaHei;
           font-weight: bold;
@@ -523,13 +772,80 @@ export default defineComponent({
           -webkit-text-fill-color: transparent;
         }
       }
-      .sl-content {
+      .si-content {
+        margin-top: 10px;
+        background-color: rgba(44, 80, 139, 0.9);
+        height: calc(100% - 46px - 10px);
+      }
+    }
+    .screen-item-video {
+      left: 18px;
+      top: 156px;
+      height: calc(100% - 147px - 227px);
+      .si-content {
+        width: 806px;
+        .sic-video {
+          margin: 12px;
+          width: calc(100% - 24px);
+          height: calc(100% - 24px);
+          display: grid;
+          grid-template-columns: repeat(3, 1fr);
+          grid-template-rows: repeat(4, 1fr);
+          column-gap: 12px;
+          row-gap: 8px;
+          .video-item {
+            background: rgba(28, 45, 65, 0);
+            border: 2px solid rgba(18, 87, 201, 0.4);
+            border-radius: 4px;
+            position: relative;
+            &:first-child {
+              grid-column-start: 1;
+              grid-column-end: 3;
+              grid-row-start: 1;
+              grid-row-end: 3;
+            }
+            .video-item-title {
+              position: absolute;
+              align-items: center;
+              width: 100%;
+              height: 24px;
+              background: rgba(2, 23, 48, 0.4);
+              border-radius: 2px;
+              font-size: 12px;
+              font-family: SimHei;
+              font-weight: 400;
+              color: #FEFEFE;
+              padding: 0 6px;
+              box-sizing: border-box;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+              line-height: 24px;
+              z-index: 2;
+            }
+            .video-keda {
+              z-index: 1;
+              width: 100%;
+              height: 100%;
+            }
+          }
+        }
+      }
+    }
+    .screen-item-sjzycqk {
+      right: 30px;
+      top: 343px;
+      .si-content {
+        background-color: transparent;
         .slc-item {
           margin-top: 10px;
           background: url("./img/left_bg-2.png");
           width: 404px;
           height: 83px;
           position: relative;
+          &:first-child {
+            margin-top: 0;
+          }
           .slc-item-icon {
             position: absolute;
             left: 15px;
@@ -546,7 +862,7 @@ export default defineComponent({
             padding-left: 25px;
             box-sizing: border-box;
             >span {
-              width: 100px;
+              width: 200px;
               font-size: 18px;
               font-family: Microsoft YaHei;
               font-weight: 400;
@@ -571,6 +887,213 @@ export default defineComponent({
         }
       }
     }
+    .screen-item-tszhqk {
+      top: 88px;
+      right: 30px;
+      width: 812px;
+      .si-content {
+        height: 190px;
+        display: flex;
+        .hainan {
+          width: 169px;
+          height: 130px;
+          margin-top: 40px;
+          margin-left: 28px;
+        }
+        .list {
+          display: flex;
+          flex-wrap: wrap;
+          margin-left: 74px;
+          width: 500px;
+          align-self: center;
+          .item {
+            margin: 12px 52px 12px 0;
+            display: flex;
+            align-items: center;
+            &:last-child {
+              margin-right: 0;
+            }
+            .line {
+              width: 3px;
+              height: 46px;
+              background-color: #32DCFB;
+            }
+            .right {
+              margin-left: 10px;
+              display: flex;
+              flex-direction: column;
+              .title {
+                font-size: 18px;
+                font-family: Microsoft YaHei;
+                font-weight: 400;
+                font-style: italic;
+                color: #D1D6DF;
+                background: linear-gradient(0deg, #ACDDFF 0%, #FFFFFF 100%);
+                -webkit-background-clip: text;
+                -webkit-text-fill-color: transparent;
+                display: flex;
+                align-items: center;
+                >img {
+                  width: 18px;
+                  height: 18px;
+                  margin-left: 7px;
+                  cursor: pointer;
+                }
+              }
+              .count {
+                font-size: 30px;
+                font-family: fantasy;
+                font-weight: 400;
+                color: #32DCFB;
+                letter-spacing: 3px;
+                margin-top: 8px;
+              }
+            }
+          }
+        }
+      }
+    }
+    .screen-item-spzyqk {
+      right: 443px;
+      top: 343px;
+      .si-content {
+        width: 402px;
+        height: 152px;
+        display: flex;
+        align-items: center;
+        .video-img {
+          width: 130px;
+          height: 122px;
+          margin-left: 36px;
+        }
+        .list {
+          margin-left: auto;
+          margin-right: 36px;
+          .item {
+            display: flex;
+            flex-direction: column;
+            align-items: end;
+            .title {
+              font-size: 20px;
+              font-family: Microsoft YaHei;
+              font-weight: 400;
+              font-style: italic;
+              color: #D1D6DF;
+              background: linear-gradient(0deg, #ACDDFF 0%, #FFFFFF 100%);
+              -webkit-background-clip: text;
+              -webkit-text-fill-color: transparent;
+              width: 160px;
+            }
+            .count {
+              font-size: 30px;
+              font-family: fantasy;
+              font-weight: 400;
+              color: #32DCFB;
+              letter-spacing: 3px;
+              margin-top: 8px;
+            }
+          }
+        }
+      }
+    }
+    .screen-item-yjtjqk {
+      right: 443px;
+      top: 558px;
+      .si-head {
+        width: 402px;
+        .jjsy {
+          margin-left: auto;
+          font-size: 12px;
+          font-family: Microsoft YaHei;
+          font-weight: 400;
+          font-style: italic;
+          color: #D1D6DF;
+          background: linear-gradient(0deg, #ACDDFF 0%, #FFFFFF 100%);
+          -webkit-background-clip: text;
+          -webkit-text-fill-color: transparent;
+        }
+      }
+      .si-content {
+        width: 402px;
+        height: 240px;
+        position: relative;
+        .total {
+          width: 100%;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          margin-top: 15px;
+          .title {
+            padding: 0 4px;
+            font-size: 16px;
+            font-family: Microsoft YaHei;
+            font-weight: 400;
+            font-style: italic;
+            color: #D1D6DF;
+            background: linear-gradient(0deg, #ACDDFF 0%, #FFFFFF 100%);
+            -webkit-background-clip: text;
+            -webkit-text-fill-color: transparent;
+            &:first-child {
+              margin-right: 8px;
+            }
+          }
+          .num {
+            width: 33px;
+            height: 42px;
+            background: url("./img/num-back.png");
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-size: 30px;
+            font-family: PangMenZhengDao;
+            font-weight: 400;
+            color: #01FFF6;
+            margin: 0 1px;
+          }
+        }
+        .jinzita {
+          position: absolute;
+          top:  94px;
+          left: 25px;
+        }
+        .item {
+          position: absolute;
+          display: flex;
+          flex-direction: column;
+          .title {
+            font-size: 16px;
+            font-family: Adobe Heiti Std;
+            font-weight: normal;
+            color: #CBE8FF;
+          }
+          .count {
+            margin-top: 10px;
+            font-size: 16px;
+            font-family: Source Han Sans CN;
+            font-weight: bold;
+            color: #01FFF6;
+          }
+          &.item-ffld {
+            top: 74px;
+            right: 235px;
+            align-items: flex-end;
+          }
+          &.item-cqzl {
+            top: 100px;
+            left: 259px;
+          }
+          &.item-bbbzs {
+            top: 132px;
+            right: 270px;
+            align-items: flex-end;
+          }
+          &.item-qt {
+            top: 157px;
+            left: 291px;
+          }
+        }
+      }
+    }
     $infoItemWidth: 350px;
     $infoItemActiveWidth: 1425px;
     $infoItemSplit: 10px;

+ 1 - 1
src/views/screen/video-resource/important-area-focus-keda.vue

@@ -39,7 +39,7 @@ import {
 import {useStore} from 'vuex'
 import axios from "axios";
 import {ElMessage, ElMessageBox} from "element-plus";
-import KedaCom from "./keda/keda-com.vue";
+import KedaCom from "@/components/keda/keda-com.vue";
 
 export default defineComponent({
   name: 'App',

+ 4 - 4
vite.config.ts

@@ -21,8 +21,8 @@ export default defineConfig({
     proxy: {
       '/api/': {
         // target: 'http://localhost:8080/',
-        // target: 'http://127.0.0.1:3001/',
-        target: 'http://10.110.35.47/',
+        target: 'http://127.0.0.1:3001/',
+        // target: 'http://10.110.35.47/',
         changeOrigin: true,
         rewrite: path => {
           return path.replace(/^\/api/, '')
@@ -30,8 +30,8 @@ export default defineConfig({
       },
       '/api-gateway/': {
         // target: 'http://localhost:8080/',
-        // target: 'http://127.0.0.1:3002/',
-        target: 'http://10.110.32.62/',
+        target: 'http://127.0.0.1:3002/',
+        // target: 'http://10.110.32.62/',
         changeOrigin: true,
         rewrite: path => {
           return path.replace(/^\/api-gateway/, '')