liuxing 1 rok pred
rodič
commit
6e345eb0ab

+ 84 - 0
app/src/api/iot.js

@@ -0,0 +1,84 @@
+import { request } from "@zhgkpt/utils";
+
+// 总体情况
+export function getZtqk(params) {
+  return request({
+    url: "/system/xfwlw/ztqk/list",
+    method: "get",
+    params,
+  });
+}
+
+// 总体情况点位统计
+export function getZtqkDwtj(params) {
+  return request({
+    url: "/system/xfwlw/ztqk/jcdwtj/list",
+    method: "get",
+    params,
+  });
+}
+
+// 告警处置
+export function getGqcz(params) {
+  return request({
+    url: "/system/xfwlw/gjcz/list",
+    method: "get",
+    params,
+  });
+}
+
+// 获取排名
+export function getRank(type, params) {
+  if (type === "dq") {
+    // 电器火灾
+    return request({
+      url: "/system/xfwlw/qyfb/dqhzpm/list",
+      method: "get",
+      params,
+    });
+  } else if (type === "hz") {
+    // 区域分布火灾
+    return request({
+      url: "/system/xfwlw/qyfb/hzbjzjpm/list",
+      method: "get",
+      params,
+    });
+  } else if (type === "wlw") {
+    // 区域分布物联网接入
+    return request({
+      url: "/system/xfwlw/qyfb/ldpm/list",
+      method: "get",
+      params,
+    });
+  } else if (type === "smtd") {
+    // 区域分布生命通道
+    return request({
+      url: "/system/xfwlw/qyfb/smtdpm/list",
+      method: "get",
+      params,
+    });
+  } else if (type === "sy") {
+    // 区域分布水压
+    return request({
+      url: "/system/xfwlw/qyfb/sypm/list",
+      method: "get",
+      params,
+    });
+  } else if (type === "xfkzs") {
+    // 区域分布消防控制室
+    return request({
+      url: "/system/xfwlw/qyfb/xfkzspm/list",
+      method: "get",
+      params,
+    });
+  }
+}
+
+// 获取物联网设备列表
+export function getDeviceList(params) {
+  return request({
+    url: "/system/jqdt/sgdwxx/wlwsb/list",
+    method: "get",
+    params,
+  });
+}

+ 1 - 2
app/src/components/Camera.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="camera-continer">
-    <video :src="url" controls="controls" v-if="url" width="100%" height="100%">
+    <video :src="url" v-if="url" width="100%" height="100%" autoplay muted>
       您的浏览器不支持 video 标签。
     </video>
   </div>
@@ -28,7 +28,6 @@ export default {
     getData() {
       // TO-DO
       getCameraUrl(this.id).then(res => {
-        console.log(res);
         this.url = res.data.data[0].mp4
       })
       // console.log(this.id);

+ 270 - 259
app/src/views/Iot/components/AlarmHandling.vue

@@ -1,283 +1,294 @@
 <template>
-    <div class="maintenance-supervision" >
-      <div class="maintenance-supervision_header" >
-        <div style="display: flex; ">
-          <el-select v-model="value" placeholder="告警年限">
-            <el-option
-              v-for="item in options"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value"
-            >
-            </el-option>
-          </el-select>
-          <el-select v-model="value" placeholder="告警类型">
-            <el-option
-              v-for="item in options"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value"
-            >
-            </el-option>
-          </el-select>
-          <el-select v-model="value" placeholder="处置状态">
-            <el-option
-              v-for="item in options"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value"
-            >
-            </el-option>
-          </el-select>
-        </div>
-  
-        <el-button>搜索</el-button>
+  <div class="maintenance-supervision">
+    <div class="maintenance-supervision_header">
+      <div style="display: flex">
+        <el-select v-model="param.warningType" placeholder="告警类型">
+          <el-option
+            v-for="item in options"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+        <el-select v-model="param.czzt" placeholder="处置状态">
+          <el-option
+            v-for="item in czztOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
       </div>
-      <div >
-        <div class="row header">
-          <span class="num">序号</span>
-          <span class="time">区域</span>
-          <span class="person">未处理</span>
-          <span class="result">已处理</span>
-        </div>
-        <VueSeamlessScroll :data="list1" :class-option="classOption" class="warp">
-          <ul class="item">
-            <li class="row" v-for="(item, index) in list1" :key="index">
-              <span class="num">{{ index + 1 }}</span>
-              <span class="time">{{ item[0] }}</span>
-              <span class="person">{{ item[1] }}</span>
-              <span class="result">{{ item[2] }}</span>
-            </li>
-          </ul>
-        </VueSeamlessScroll>
+
+      <el-button @click="getList">搜索</el-button>
+    </div>
+    <div>
+      <div class="row header">
+        <span class="num">序号</span>
+        <span class="time">区域</span>
+        <span class="person">未处理</span>
+        <span class="result">已处理</span>
       </div>
+      <VueSeamlessScroll :data="list1" :class-option="classOption" class="warp">
+        <ul class="item">
+          <li class="row" v-for="(item, index) in list1" :key="index">
+            <span class="num">{{ index + 1 }}</span>
+            <span class="time">{{ item[0] }}</span>
+            <span class="person">{{ item[1] }}</span>
+            <span class="result">{{ item[2] }}</span>
+          </li>
+        </ul>
+      </VueSeamlessScroll>
     </div>
-  </template>
+  </div>
+</template>
   <script>
-  import VueSeamlessScroll from "vue-seamless-scroll";
-  
-  export default {
-    name: "MaintenanceSupervision",
-    data() {
+import VueSeamlessScroll from "vue-seamless-scroll";
+import { getGqcz } from "@/api/iot.js";
+export default {
+  name: "MaintenanceSupervision",
+  props: ["qx"],
+  data() {
+    return {
+      search: "",
+      param: {
+        czzt: null,
+        qx: this.qx,
+        warningType: null,
+        pageNum: 1,
+        pageSize: 100,
+      },
+      options: [
+        {
+          value: "1",
+          label: "1111",
+        },
+        {
+          value: "2",
+          label: "2222",
+        },
+        {
+          value: "3",
+          label: "3333",
+        },
+      ],
+      czztOptions: [
+        {
+          value: "未处理",
+          label: "未处理",
+        },
+        {
+          value: "已处理",
+          label: "已处理",
+        },
+      ],
+      list1: [
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+        ["万州区", "1200", "8765"],
+      ],
+      value: "",
+
+      checked: 0,
+    };
+  },
+  components: {
+    VueSeamlessScroll,
+  },
+  computed: {
+    classOption() {
       return {
-        search: "",
-        options: [
-          {
-            value: '1',
-            label: '1111'
-          },
-          {
-            value: '2',
-            label: '2222'
-          },
-          {
-            value: '3',
-            label: '3333'
-          }
-        ],
-        list1: [
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-          ["万州区", "1200", "8765"],
-        ],
-        value: "",
-  
-        checked: 0,
+        singleHeight: 43,
       };
     },
-    components: {
-      VueSeamlessScroll,
+  },
+  methods: {
+    resultType(text) {
+      return {
+        合格: "#23f59d",
+        不合格: "#df575b",
+        是: "#23f59d",
+        否: "#df575b",
+      }[text];
     },
-    computed: {
-      classOption() {
-        return {
-          singleHeight: 43,
-        };
-      },
+    getList() {
+      getGqcz(this.param).then((res) => {
+        console.log(res);
+      });
     },
-    methods: {
-      change(idx) {
-        this.checked = idx;
-        console.log("切换索引", idx);
-      },
-      resultType(text) {
-        return {
-          合格: "#23f59d",
-          不合格: "#df575b",
-          是: "#23f59d",
-          否: "#df575b",
-        }[text];
-      },
-    },
-  };
-  </script>
+  },
+  created() {
+    this.getList();
+  },
+};
+</script>
   
   <style scoped lang="less">
-  .maintenance-supervision {
-    // padding: 10px 10px 0px 20px;
-    ::v-deep(.el-input__inner) {
-      border: none;
-      background: linear-gradient(360deg, rgba(0,148,255, .5) 0%, rgba(0,148,255, .31) 100%);
-      color: #fff;
-    }
-    ::v-deep(.el-button) {
-      border: none;
-      background: linear-gradient(360deg, #0094ff90 0%, #0094ff10 100%);
-      color: #fff;
-    }
-    .maintenance-supervision_header {
-      display: flex;
-      justify-content: space-around;
-      border-bottom: 1px solid #154956;
-      padding-bottom: 2px;
-      margin: 10px 6px 6px;
-      font-size: 12px;
-      color: rgb(79, 149, 186);
-    }
-    .warp {
-      height: 520px;
+.maintenance-supervision {
+  // padding: 10px 10px 0px 20px;
+  ::v-deep(.el-input__inner) {
+    border: none;
+    background: linear-gradient(
+      360deg,
+      rgba(0, 148, 255, 0.5) 0%,
+      rgba(0, 148, 255, 0.31) 100%
+    );
+    color: #fff;
+  }
+  ::v-deep(.el-button) {
+    border: none;
+    background: linear-gradient(360deg, #0094ff90 0%, #0094ff10 100%);
+    color: #fff;
+  }
+  .maintenance-supervision_header {
+    display: flex;
+    justify-content: space-between;
+    border-bottom: 1px solid #154956;
+    padding-bottom: 2px;
+    margin: 10px 6px 6px;
+    font-size: 12px;
+    color: rgb(79, 149, 186);
+  }
+  .warp {
+    height: 520px;
+    margin: 0 auto;
+    overflow: hidden;
+    .item {
+      list-style: none;
+      padding: 0;
       margin: 0 auto;
-      overflow: hidden;
-      .item {
-        list-style: none;
-        padding: 0;
-        margin: 0 auto;
-        cursor: pointer;
-      }
-    }
-  
-    .header {
-      color: #fff;
-      height: 33px !important;
-      line-height: 33px !important;
-      background-color: rgba(0, 163, 255, 0.3) !important;
-      color: #61dbff;
-      margin-top: 15px;
-      margin-bottom: 6px;
-    }
-  
-    .row,
-    li,
-    a {
-      display: block;
-      height: 39px;
-      line-height: 39px;
-      margin-bottom: 4px;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      font-size: 14px;
-      background-color: rgba(0, 0, 0, 0.2);
-      .time,
-      .num,
-      .person,
-      .result {
-        flex: 0.33;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-      }
-      .result {
-        color: #68D1FF;
-      }
-      .num {
-        flex: 0.15;
-      }
+      cursor: pointer;
     }
   }
-  
-  
-  /deep/.el-input__inner {
-    background-color: #184254;
-    width: 100px;
-    height: 30px;
-    margin-bottom: 5px;
-    margin-right: 5px;
+
+  .header {
+    color: #fff;
+    height: 33px !important;
+    line-height: 33px !important;
+    background-color: rgba(0, 163, 255, 0.3) !important;
+    color: #61dbff;
+    margin-top: 15px;
+    margin-bottom: 6px;
   }
 
-  /deep/.el-button {
-    width: 120px;
-    height: 32px;
+  .row,
+  li,
+  a {
+    display: block;
+    height: 39px;
+    line-height: 39px;
+    margin-bottom: 4px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
     font-size: 14px;
-    line-height: 2px;
-    background: #184254;
-    margin: 0 20px 0 30px;
-    color: #fff;
-    border-radius: 5px;
-    border: none;
+    background-color: rgba(0, 0, 0, 0.2);
+    .time,
+    .num,
+    .person,
+    .result {
+      flex: 0.33;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .result {
+      color: #68d1ff;
+    }
+    .num {
+      flex: 0.15;
+    }
   }
-  // /deep/.el-select-dropdown{
-  
-  //     background-color:#184254 !important;
-  //     position: fixed;
-  
-  //   }
+}
 
-  // /deep/.el-select-dropdown{
-  //      border: none;
-  //      background-color: #184254 ;
-  //  }
-  //输入框
-  //  /deep/.el-input__inner{
-  //      color:#eee;
-  //      border-color: #00fff6;
-  //      background-color: rgba(1, 28, 82, 0.8);
-  //  }
-  //  //聚焦时的样式
-  //  /deep/.el-select .el-input.is-focus .el-input__inner{
-  //      border-color: #0B61AA;
-  //      background-color: rgba(1, 28, 82, 0.8);
-  //      color:#00D3E9;
-  //  }
-  //  //下拉框选中
-  //  /deep/.el-select-dropdown__item{
-  //      color: #eee;
-  //  }
-  //  //鼠标经过下拉框
-  //  /deep/.el-select-dropdown__item.hover,
-  //  /deep/.el-select-dropdown__item:hover{
-  //      color:#00D3E9;
-  //      background-color: #0F3360;
-  //  }
-  </style>
+/deep/.el-input__inner {
+  background-color: #184254;
+  width: 100px;
+  height: 30px;
+  margin-bottom: 5px;
+  margin-right: 5px;
+}
+
+/deep/.el-button {
+  width: 120px;
+  height: 32px;
+  font-size: 14px;
+  line-height: 2px;
+  background: #184254;
+  margin: 0 20px 0 30px;
+  color: #fff;
+  border-radius: 5px;
+  border: none;
+}
+// /deep/.el-select-dropdown{
+
+//     background-color:#184254 !important;
+//     position: fixed;
+
+//   }
+
+// /deep/.el-select-dropdown{
+//      border: none;
+//      background-color: #184254 ;
+//  }
+//输入框
+//  /deep/.el-input__inner{
+//      color:#eee;
+//      border-color: #00fff6;
+//      background-color: rgba(1, 28, 82, 0.8);
+//  }
+//  //聚焦时的样式
+//  /deep/.el-select .el-input.is-focus .el-input__inner{
+//      border-color: #0B61AA;
+//      background-color: rgba(1, 28, 82, 0.8);
+//      color:#00D3E9;
+//  }
+//  //下拉框选中
+//  /deep/.el-select-dropdown__item{
+//      color: #eee;
+//  }
+//  //鼠标经过下拉框
+//  /deep/.el-select-dropdown__item.hover,
+//  /deep/.el-select-dropdown__item:hover{
+//      color:#00D3E9;
+//      background-color: #0F3360;
+//  }
+</style>
   
   
   <style>
-  
-  .el-select-dropdown.el-popper {
-    background-color: #4167a0;
-  }
-  .el-popper[x-placement^=bottom] .popper__arrow::after  {
-    border-bottom-color: #4167a0 !important;
-  }
-  .el-select-dropdown.el-popper {
-    border: 1px solid rgba(0, 213, 255, 0.6) !important;
-  }
-  .el-select-dropdown.el-popper li.el-select-dropdown__item span {
-    color: #fff;
-  }
-  .el-select-dropdown.el-popper
-    li.el-select-dropdown__item.selected
-    span {
-    color: #2f7df2;
-  }
-  .el-select-dropdown.el-popper .el-select-dropdown__item.hover {
-    background-color: #2f7df2;
-  }
-  .el-select-dropdown.el-popper
-    li.el-select-dropdown__item.hover.selected
-    span {
-    color: #fff !important;
-  }
- .select_btn {
-margin-left: -10px;
-  }
-  </style>
+.el-select-dropdown.el-popper {
+  background-color: #4167a0;
+}
+.el-popper[x-placement^="bottom"] .popper__arrow::after {
+  border-bottom-color: #4167a0 !important;
+}
+.el-select-dropdown.el-popper {
+  border: 1px solid rgba(0, 213, 255, 0.6) !important;
+}
+.el-select-dropdown.el-popper li.el-select-dropdown__item span {
+  color: #fff;
+}
+.el-select-dropdown.el-popper li.el-select-dropdown__item.selected span {
+  color: #2f7df2;
+}
+.el-select-dropdown.el-popper .el-select-dropdown__item.hover {
+  background-color: #2f7df2;
+}
+.el-select-dropdown.el-popper li.el-select-dropdown__item.hover.selected span {
+  color: #fff !important;
+}
+.select_btn {
+  margin-left: -10px;
+}
+</style>
   

+ 69 - 5
app/src/views/Iot/components/IotVideo.vue

@@ -1,11 +1,55 @@
 <template>
   <div class="v-ideo">
-    <div class="v-one">视频1</div>
-    <div class="v-one">视频2</div>
+    <el-carousel trigger="click" height="450px" :interval="20000">
+      <el-carousel-item v-for="i in count" :key="i">
+        <div class="v-one" v-if="getVideo(i)">
+          <Camera :id="getVideo(i).sbbm" />
+          <div class="txt">{{ getVideo(i).sbmc }}</div>
+          <div class="mask" @click="showVideo(getVideo(i).sbbm)"></div>
+        </div>
+        <div class="v-one" v-if="getVideo(i + 1)">
+          <Camera :id="getVideo(i + 1).sbbm" />
+          <div class="txt">{{ getVideo(i).sbmc }}</div>
+          <div class="mask" @click="showVideo(getVideo(i + 1).sbbm)"></div>
+        </div>
+      </el-carousel-item>
+    </el-carousel>
   </div>
 </template>
 
-<script></script>
+<script>
+import Camera from "@/components/Camera.vue";
+export default {
+  name: "IotName",
+  props: ["list"],
+  data() {
+    return {
+      count: 5,
+    };
+  },
+  components: {
+    Camera,
+  },
+  methods: {
+    getVideo(no) {
+      if (this.list.length > no) {
+        return this.list[no];
+      }
+      return null;
+    },
+    showVideo(id) {
+      console.log(id);
+
+      // 弹窗显示视频播放组件
+    }
+  },
+  created() {
+    console.log(this.list);
+    this.count = this.list.length / 2;
+    console.log(this.count);
+  },
+};
+</script>
 
 <style lang="less" scoped>
 .v-ideo {
@@ -14,11 +58,31 @@
   padding: 10px 15px;
 
   .v-one {
-    width: 100%;
+    width: calc(100% - 2px);
     height: 185px;
     border: 1px solid #ccc;
+    position: relative;
+    .txt {
+      position: absolute;
+      font-family: "Abel";
+      font-style: normal;
+      font-weight: 400;
+      font-size: 14px;
+      line-height: 24px;
+      right: 11px;
+      top: 6px;
+    }
+    .mask {
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      top: 0;
+      left: 0;
+      z-index: 99;
+      cursor: pointer;
+    }
   }
-  .v-one:first-child{
+  .v-one:first-child {
     margin-bottom: 10px;
   }
 }

+ 75 - 28
app/src/views/Iot/components/RegionalDistribution.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="regional-distribution">
     <div>
-      <el-select v-model="selectOption" style="width: 100%;" size="mini">
+      <el-select v-model="selectOption" style="width: 100%" size="mini">
         <el-option
-            v-for="item in options"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          >
+          v-for="item in options"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value"
+        >
         </el-option>
       </el-select>
     </div>
@@ -36,33 +36,35 @@
 
 <script>
 import VueSeamlessScroll from "vue-seamless-scroll";
+import { getRank } from "@/api/iot.js";
 export default {
   name: "RegionalDistribution",
   components: {
     VueSeamlessScroll,
   },
+  props: ["qx"],
   data() {
     return {
       list: [
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
-        ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
+        // ["万州区", "1200", 8765, "23%"],
       ],
       options: [
-        {label: '已建物联网排名', value: 1},
-        {label: '已建物水压监测排名', value: 2},
-        {label: '已建电器火灾监测排名', value: 3},
-        {label: '已建消防通道检测排名', value: 4},
-        {label: '已建火灾报警主机监测排名', value: 5},
-        {label: '已建消防控制室人员离岗监控排名', value: 6},
+        { label: "已建物联网排名", value: "wlw" },
+        { label: "已建物水压监测排名", value: "sy" },
+        { label: "已建电器火灾监测排名", value: "dq" },
+        { label: "已建消防通道检测排名", value: "smtd" },
+        { label: "已建火灾报警主机监测排名", value: "hz" },
+        { label: "已建消防控制室人员离岗监控排名", value: "xfkzs" },
       ],
-      selectOption: 1
+      selectOption: "wlw",
     };
   },
   computed: {
@@ -72,16 +74,61 @@ export default {
       };
     },
   },
+  methods: {
+    getList() {
+      const param = {
+        pageNum: 1,
+        pageSize: 100,
+        qx: this.qx,
+      };
+      getRank(this.selectOption, param).then((res) => {
+        const list = [];
+        if (res.data.rows) {
+          res.data.rows.forEach((p) => {
+            if (this.selectOption === "wlw") {
+              list.push([p.qx, p.ldsl, p.jrsbzs, p.fgl]);
+            } else if (this.selectOption === "sy") {
+              list.push([p.qx, p.ldsl, p.syzs, p.fgl]);
+            } else if (this.selectOption === "dq") {
+              list.push([p.qx, p.ldsl, p.dqhzzs, p.fgl]);
+            } else if (this.selectOption === "smtd") {
+              list.push([p.qx, p.ldsl, p.smtdzs, p.fgl]);
+            } else if (this.selectOption === "hz") {
+              list.push([p.qx, p.ldsl, p.hzbjzjzs, p.fgl]);
+            } else if (this.selectOption === "xfkzs") {
+              list.push([p.qx, p.ldsl, p.xfkzszs, p.fgl]);
+            }
+          });
+        }
+        this.list = list;
+      });
+    },
+  },
+  watch: {
+    qx() {
+      this.getList();
+    },
+    selectOption() {
+      this.getList();
+    },
+  },
+  created() {
+    this.getList();
+  },
 };
 </script>
 <style scoped lang="less">
 .regional-distribution {
   padding: 9px 8px 0px 8px;
-   // padding: 10px 10px 0px 20px;
-   ::v-deep(.el-input__inner) {
+  // padding: 10px 10px 0px 20px;
+  ::v-deep(.el-input__inner) {
     text-align: right;
     border: none;
-    background: linear-gradient(360deg, rgba(0,148,255, .5) 0%, rgba(0,148,255, .31) 100%);
+    background: linear-gradient(
+      360deg,
+      rgba(0, 148, 255, 0.5) 0%,
+      rgba(0, 148, 255, 0.31) 100%
+    );
     color: #fff;
   }
 }
@@ -98,7 +145,7 @@ export default {
 }
 
 .header {
-  color: #61DBFF !important;
+  color: #61dbff !important;
   height: 38px !important;
   background-color: rgba(0, 163, 255, 0.3) !important;
   margin-top: 2px;
@@ -144,7 +191,7 @@ a {
   }
 
   .idx {
-    flex: .1;
+    flex: 0.1;
   }
 
   .area {
@@ -155,7 +202,7 @@ a {
   }
   .tim {
     flex: 0.25;
-    color: #61DBFF;
+    color: #61dbff;
   }
   .percent {
     flex: 0.15;

+ 187 - 117
app/src/views/Iot/components/TotalityInfo.vue

@@ -35,45 +35,47 @@
     <div class="ala-n">
       <div v-for="(item, index) in lineList" :key="index" class="alarm">
         <div class="alarm-host">
-          <img :src="item.imgs" alt="">
-          <div style="width: 90%;">
+          <img :src="item.imgs" alt="" />
+          <div style="width: 90%">
             <div class="inline-bor">
               <span style="font-size: 14px">{{ item.text }}</span>
-              <span class="calc-percent">{{item.allnum}}/{{ item.average }}</span>个/栋
+              <span class="calc-percent"
+                >{{ item.allnum }}/{{ item.average }}</span
+              >个/栋
             </div>
             <div class="on-line">
-             <div>
+              <div>
                 <span class="online lines"></span>
-              <span  style="font-size: 20px;">{{ item.line }}</span
-              >(个/栋)
-             </div>
+                <span style="font-size: 20px">{{ item.line }}</span
+                >(个/栋)
+              </div>
               <div>
                 <span class="offline lines"></span>
-              <span style="font-size: 20px;">{{ item.offNum }}</span
-              >(个/栋)
+                <span style="font-size: 20px">{{ item.offNum }}</span
+                >(个/栋)
               </div>
             </div>
           </div>
         </div>
       </div>
-      <div class="last-line"> 
+      <div class="last-line">
         <img src="../../../assets/images/Group 1321314604.png" alt="" />
-        <div style="width: 86%;">
-            <div class="inline-bor">
-              <span style="font-size: 14px">消防控制室人员离岗</span>
-              <span> <span class="calc-percent">10731/676</span>个/栋</span>
-            </div>
-            <div class="on-line">
-             <div>
-              <span class="online lines" style="font-size: 18px;">2613</span
+        <div style="width: 86%">
+          <div class="inline-bor">
+            <span style="font-size: 14px">消防控制室人员离岗</span>
+            <span> <span class="calc-percent">{{dwData.xfkzszs}}/{{dwData.xfkzsds}}</span>个/栋</span>
+          </div>
+          <div class="on-line">
+            <div>
+              <span class="online lines" style="font-size: 18px">{{dwData.xfkzszxs}}</span
               >(个/栋)
-             </div>
-              <div>
-                <span class="lines offline" style="font-size: 18px;">613</span
+            </div>
+            <div>
+              <span class="lines offline" style="font-size: 18px">{{dwData.xfkzsgjs}}</span
               >(个/栋)
-              </div>
             </div>
           </div>
+        </div>
       </div>
     </div>
   </div>
@@ -85,61 +87,62 @@ export default {
   data() {
     return {
       list: [
-        {
-          num: 1542,
-          title: "已完成物联网建筑数(栋)",
-          text: "设备总数",
-          allNum: 1276,
-        },
-        {
-          num: 1542,
-          title: "在线建筑数(栋)",
-          text: "在线",
-          allNum: 1200,
-        },
-        {
-          num: 542,
-          title: "告警建筑数(栋)",
-          text: "报警",
-          allNum: 768,
-        },
+        // {
+        //   num: 1542,
+        //   title: "已完成物联网建筑数(栋)",
+        //   text: "设备总数",
+        //   allNum: 1276,
+        // },
+        // {
+        //   num: 1542,
+        //   title: "在线建筑数(栋)",
+        //   text: "在线",
+        //   allNum: 1200,
+        // },
+        // {
+        //   num: 542,
+        //   title: "告警建筑数(栋)",
+        //   text: "报警",
+        //   allNum: 768,
+        // },
       ],
       lineList: [
-        {
-          imgs: imgs,
-          text: "火灾报警主机",
-          allnum: 10731,
-          average: 676,
-          line: 2613,
-          offNum: 613,
-        },
-        {
-          imgs: imgs,
-          text: "水压",
-          allnum: 10731,
-          average: 676,
-          line: 2613,
-          offNum: 613,
-        },
-        {
-          imgs: imgs,
-          text: "点起火灾",
-          allnum: 10731,
-          average: 676,
-          line: 2613,
-          offNum: 613,
-        },
-        {
-          imgs: imgs,
-          text: "生命通道",
-          allnum: 10731,
-          average: 676,
-          line: 2613,
-          offNum: 613,
-        },
+        // {
+        //   imgs: imgs,
+        //   text: "火灾报警主机",
+        //   allnum: 10731,
+        //   average: 676,
+        //   line: 2613,
+        //   offNum: 613,
+        // },
+        // {
+        //   imgs: imgs,
+        //   text: "水压",
+        //   allnum: 10731,
+        //   average: 676,
+        //   line: 2613,
+        //   offNum: 613,
+        // },
+        // {
+        //   imgs: imgs,
+        //   text: "点起火灾",
+        //   allnum: 10731,
+        //   average: 676,
+        //   line: 2613,
+        //   offNum: 613,
+        // },
+        // {
+        //   imgs: imgs,
+        //   text: "生命通道",
+        //   allnum: 10731,
+        //   average: 676,
+        //   line: 2613,
+        //   offNum: 613,
+        // },
       ],
     };
   },
+  props: ["data", "dwData"],
   methods: {
     changaColor(text) {
       return {
@@ -149,12 +152,68 @@ export default {
       }[text];
     },
   },
+  created() {
+    this.list = [
+      {
+        num: this.data.wlwlds,
+        title: "已完成物联网建筑数(栋)",
+        text: "设备总数",
+        allNum: this.data.jrsbzs,
+      },
+      {
+        num: this.data.zxjzs,
+        title: "在线建筑数(栋)",
+        text: "在线",
+        allNum: this.data.jrsbzxs,
+      },
+      {
+        num: this.data.gjlds,
+        title: "告警建筑数(栋)",
+        text: "报警",
+        allNum: this.data.jrsbgjgs,
+      },
+    ];
+    this.lineList = [
+      {
+        imgs: imgs,
+        text: "火灾报警主机",
+        allnum: this.dwData.hzbjzjzs,
+        average: this.dwData.hzbjzjds,
+        line: this.dwData.hzbjzjzxs,
+        offNum: this.dwData.hzbjzjgjs,
+      },
+      {
+        imgs: imgs,
+        text: "水压",
+        allnum: this.dwData.syds,
+        average: this.dwData.syzs,
+        line: this.dwData.syzxs,
+        offNum: this.dwData.sygjs,
+      },
+      {
+        imgs: imgs,
+        text: "电器火灾",
+        allnum: this.dwData.dqhzds,
+        average: this.dwData.dqhzzs,
+        line: this.dwData.dqhzzxs,
+        offNum: this.dwData.dqhzgjs,
+      },
+      {
+        imgs: imgs,
+        text: "生命通道",
+        allnum: this.dwData.smtdlds,
+        average: this.dwData.smtdzs,
+        line: this.dwData.smtdzxs,
+        offNum: this.dwData.smtdgjs,
+      },
+    ];
+  },
 };
 </script>
 
 <style lang="less" scoped>
 .iot {
-  margin: 13px 5px 0px 5px ;
+  margin: 13px 5px 0px 5px;
   .all-unit {
     display: flex;
     justify-content: space-between;
@@ -163,7 +222,11 @@ export default {
   .iot-num {
     width: 168px;
     height: 88px;
-    background: linear-gradient(360deg, rgba(0,148,255, 0) 0%, rgba(0,148,255, .6) 100%);;
+    background: linear-gradient(
+      360deg,
+      rgba(0, 148, 255, 0) 0%,
+      rgba(0, 148, 255, 0.6) 100%
+    );
     border: 1px solid #1a5878;
     display: flex;
     flex-direction: column;
@@ -183,7 +246,7 @@ export default {
 .PointStatistics {
   width: 94%;
   height: 37px;
-  background: rgba(0,213,255, .24); //渐变
+  background: rgba(0, 213, 255, 0.24); //渐变
   margin: 10px 0;
   color: #fff;
   display: flex;
@@ -222,7 +285,11 @@ export default {
 .alarm {
   width: 264px;
   height: 81px;
-  background: linear-gradient(360deg, rgba(61,220,255, .30) 0%,rgba(61, 232, 255, .0)  100%);
+  background: linear-gradient(
+    360deg,
+    rgba(61, 220, 255, 0.3) 0%,
+    rgba(61, 232, 255, 0) 100%
+  );
   line-height: 40px;
   margin-top: 10px;
   letter-spacing: 1px;
@@ -241,57 +308,60 @@ export default {
     width: 52px;
     height: 49px;
   }
-  .inline-bor{
+  .inline-bor {
     // width: 124px;
-    border-bottom: 1px dotted #7789CD;
+    border-bottom: 1px dotted #7789cd;
     .calc-percent {
-      color: #44F1FF;
+      color: #44f1ff;
       font-size: 18px;
     }
   }
 }
 .lines::before {
-    content: "";
-    display: inline-block;
-    border-radius: 50%;
-    width: 10px;
-    height: 10px;
-    margin-right: 6px;
+  content: "";
+  display: inline-block;
+  border-radius: 50%;
+  width: 10px;
+  height: 10px;
+  margin-right: 6px;
 }
-.on-line{
-    display: flex;
-    justify-content: space-between;
-    width: 100%;
+.on-line {
+  display: flex;
+  justify-content: space-between;
+  width: 100%;
 }
-.last-line{
-    width: 100%;
-    height: 80px;
-    background: linear-gradient(360deg, rgba(61,220,255, .30) 0%,rgba(61, 232, 255, .0)  100%);
-    margin-top: 5px;
-    line-height: 40px;
+.last-line {
+  width: 100%;
+  height: 80px;
+  background: linear-gradient(
+    360deg,
+    rgba(61, 220, 255, 0.3) 0%,
+    rgba(61, 232, 255, 0) 100%
+  );
+  margin-top: 5px;
+  line-height: 40px;
+  display: flex;
+  align-items: center;
+  img {
+    display: inline-block;
+    width: 52px;
+    height: 49px;
+  }
+  .inline-bor {
     display: flex;
-    align-items: center;
-    img {
-      display: inline-block;
-      width: 52px;
-      height: 49px;
-    }
-    .inline-bor{
-        display: flex;
-        justify-content: space-between;
-        font-size: 16px;
-        border-bottom: 1px dotted #7789CD;
-        .calc-percent {
-          color: #44F1FF;
-          font-size: 18px;
-        }
-    }
-    .on-line {
-      display: flex;
-      justify-content: start;
-      gap: 20px;
-      padding: 0px 10px;
+    justify-content: space-between;
+    font-size: 16px;
+    border-bottom: 1px dotted #7789cd;
+    .calc-percent {
+      color: #44f1ff;
+      font-size: 18px;
     }
-
+  }
+  .on-line {
+    display: flex;
+    justify-content: start;
+    gap: 20px;
+    padding: 0px 10px;
+  }
 }
 </style>

+ 129 - 38
app/src/views/Iot/index.vue

@@ -1,81 +1,172 @@
 <template>
   <div style="padding: 0px 35px; display: flex; justify-content: space-between">
-    <div style="z-index: 100;">
+    <div style="z-index: 100">
       <border-panel
-        height="492px"  
-        :header-type="4" 
-        width="544px"  
+        height="492px"
+        :header-type="4"
+        width="544px"
         style="margin-bottom: 6px"
-        title="总体情况            "
+        title="总体情况"
       >
-      <TotalityInfo/>
+        <TotalityInfo
+          :data="ztqkData"
+          v-if="ztqkData && ztqkDwtjData"
+          :dwData="ztqkDwtjData"
+        />
       </border-panel>
-      <border-panel height="450px"  :header-type="4" 
-        width="544px"   style="margin-bottom: 6px" title="视频监控">
-          <IotVideo/>
+      <border-panel
+        height="450px"
+        :header-type="4"
+        width="544px"
+        style="margin-bottom: 6px"
+        title="视频监控"
+      >
+        <IotVideo
+          :list="caremaData"
+          v-if="caremaData && caremaData.length > 0"
+        />
       </border-panel>
     </div>
     <div style="">
       <div class="map-container cover">
-        <MapContainer  />
+        <MapCharts />
       </div>
     </div>
-    <div style="z-index: 100;">
+    <div style="z-index: 100">
       <border-panel
         height="469px"
-        width="540px" :header-type="4" 
+        width="540px"
+        :header-type="4"
         style="margin-bottom: 10px"
         title="区域分布"
       >
-       <RegionalDistribution />
+        <RegionalDistribution :qx="qx" />
       </border-panel>
       <border-panel
         height="469px"
-        width="540px" :header-type="4" 
+        width="540px"
+        :header-type="4"
         style="margin-bottom: 6px"
         title="告警处置"
       >
-      <AlarmHandling/>
+        <AlarmHandling :qx="qx" />
       </border-panel>
     </div>
   </div>
 </template>
 <script>
-
-import MapContainer from "@/components/Map.vue";
-import TotalityInfo from './components/TotalityInfo.vue';
-import IotVideo from './components/IotVideo.vue'
-import AlarmHandling from './components/AlarmHandling.vue'
+import TotalityInfo from "./components/TotalityInfo.vue";
+import IotVideo from "./components/IotVideo.vue";
+import AlarmHandling from "./components/AlarmHandling.vue";
 import RegionalDistribution from "./components/RegionalDistribution.vue";
+import MapCharts from "../Home/components/MapCharts.vue";
+import {
+  getZtqk,
+  getZtqkDwtj,
+  getGqcz,
+  getDeviceList,
+} from "@/api/iot.js";
+
 export default {
-  components: {  TotalityInfo, RegionalDistribution, IotVideo,AlarmHandling, MapContainer },
+  name: "Iot",
+  components: {
+    TotalityInfo,
+    RegionalDistribution,
+    IotVideo,
+    AlarmHandling,
+    MapCharts
+  },
+  data() {
+    return {
+      qx: null,
+      ztqkData: null,
+      ztqkDwtjData: null,
+      caremaData: [],
+    };
+  },
+  methods: {
+    async getList() {
+      // 获取总体情况
+      const ztqkParam = {
+        pageNum: 1,
+        pageSize: 100,
+        name: this.qx,
+      };
+      getZtqk(ztqkParam).then((res) => {
+        this.ztqkData = res.data.rows[0];
+      });
+
+      // 检测点位统计
+      const ztqkDwtjParam = {
+        pageNum: 1,
+        pageSize: 100,
+        name: this.qx,
+      };
+      getZtqkDwtj(ztqkDwtjParam).then((res) => {
+        this.ztqkDwtjData = res.data.rows[0];
+      });
+
+      let caremaData = [];
+      // 获取视频数据
+      const deviceParam = {
+        pageNum: 1,
+        pageSize: 100,
+        qx: this.qx,
+        zt: "在线",
+        sblx: "生命通道监测",
+      };
+      const res = await getDeviceList(deviceParam);
+      caremaData = caremaData.concat(res.data.rows);
+
+      const deviceParam2 = {
+        pageNum: 1,
+        pageSize: 100,
+        qx: this.qx,
+        zt: "在线",
+        sblx: "消防控制室监控",
+      };
+      const res2 = await getDeviceList(deviceParam2);
+      caremaData = caremaData.concat(res2.data.rows);
+
+      // 随机取10个
+      const showCaremarData = [];
+      for (let i = 0; i < 10; i++) {
+        const no = Math.ceil(Math.random() * caremaData.length);
+        showCaremarData.push(caremaData.find((p, j) => j === no));
+      }
+
+      this.caremaData = showCaremarData;
+    },
+  },
+  created() {
+    this.getList();
+  },
 };
 </script>
 
 <style scoped lang="less">
 .map-container {
-z-index: 50;
-position: fixed;
-top: 100px; 
-left: 50%; 
-transform: translateX(-50%); 
-width: 1100px;
-height: 90%;
+  z-index: 50;
+  position: fixed;
+  top: 25%;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 1100px;
+  height: 90%;
 }
 
 .map-container::after {
-position: absolute;
-content: '';
-width: 100%;
-height: 100%;
-top: 0;
-left: 0;
-box-shadow:0 0 100px 100px #070b13 inset;
-pointer-events: none;
+  position: absolute;
+  content: "";
+  width: 100%;
+  height: 100%;
+  top: 0;
+  left: 0;
+  box-shadow: 0 0 100px 100px #070b13 inset;
+  pointer-events: none;
 }
 
 iframe {
-border: none;
+  border: none;
 }
-
 </style>

+ 1 - 0
package.json

@@ -31,6 +31,7 @@
   "dependencies": {
     "@amap/amap-jsapi-loader": "^1.0.1",
     "echarts": "^5.4.2",
+    "echarts-gl": "^2.0.9",
     "element-ui": "^2.15.9",
     "vue": "^2.7.8"
   }