|
@@ -5,74 +5,61 @@
|
|
|
<div class="base-data">
|
|
|
<div class="base-box base-data-device">
|
|
|
<span class="name">物联设备</span>
|
|
|
- <span class="num">230</span>
|
|
|
+ <span class="num">{{ basicsInfo.totalDevices }}</span>
|
|
|
</div>
|
|
|
<div class="base-box base-data-online">
|
|
|
<span class="name">在线数</span>
|
|
|
- <span class="num">230</span>
|
|
|
+ <span class="num">{{ basicsInfo.onlineDevices }}</span>
|
|
|
</div>
|
|
|
<div class="base-box base-data-unline">
|
|
|
<span class="name">离线数</span>
|
|
|
- <span class="num">230</span>
|
|
|
+ <span class="num">{{ basicsInfo.offlineDevices }}</span>
|
|
|
</div>
|
|
|
<div class="base-box base-data-ratio">
|
|
|
<span class="name">在线率</span>
|
|
|
- <span class="num">230</span>
|
|
|
+ <span class="num">{{ basicsInfo.onlineRate }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</titleBgBox>
|
|
|
|
|
|
<titleBgBox class="left-title-bg-box" title="设备类型">
|
|
|
+ <!-- 头部色彩比例块 -->
|
|
|
+ <colorDiv
|
|
|
+ class="color-box"
|
|
|
+ :data="deviceTypeArr"
|
|
|
+ :colorData="equipmentColor"
|
|
|
+ ></colorDiv>
|
|
|
<div class="device-type">
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #549bf1"></div>
|
|
|
- <span class="name">文明施工检测</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #67d470"></div>
|
|
|
- <span class="name">建筑物和构筑物结构安全监测</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #bcbf5c"></div>
|
|
|
- <span class="name">深基坑监测</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #0daee3"></div>
|
|
|
- <span class="name">玻璃幕墙监测</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #3182ea"></div>
|
|
|
- <span class="name">历史建筑保护</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #aa8a6e"></div>
|
|
|
- <span class="name">桥梁监测</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #5a70bc"></div>
|
|
|
- <span class="name">隧道检测</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #b2dfff"></div>
|
|
|
- <span class="name">边坡保护</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #5cabbf"></div>
|
|
|
- <span class="name">路面塌陷</span>
|
|
|
- <span class="num">20%</span>
|
|
|
- </div>
|
|
|
- <div class="device-type-item">
|
|
|
- <div class="icon-label" style="background-color: #2cecbc"></div>
|
|
|
- <span class="name">水环境监测</span>
|
|
|
- <span class="num">20%</span>
|
|
|
+ <div
|
|
|
+ class="device-type-item"
|
|
|
+ v-for="(item, index) in deviceTypeArr"
|
|
|
+ :key="index"
|
|
|
+ @click="selectCurrentKey(item)"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="icon-label"
|
|
|
+ :style="{
|
|
|
+ backgroundColor: equipmentColor[index % deviceTypeArr.length],
|
|
|
+ }"
|
|
|
+ ></div>
|
|
|
+ <span
|
|
|
+ class="name"
|
|
|
+ :style="{
|
|
|
+ color: selectDeviceType.includes(item.monitorScene)
|
|
|
+ ? '#FFD041'
|
|
|
+ : '',
|
|
|
+ }"
|
|
|
+ >{{ item.monitorScene }}</span
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ class="num"
|
|
|
+ :style="{
|
|
|
+ color: selectDeviceType.includes(item.monitorScene)
|
|
|
+ ? '#FFC85A'
|
|
|
+ : '',
|
|
|
+ }"
|
|
|
+ >{{ item.numRatio }}</span
|
|
|
+ >
|
|
|
</div>
|
|
|
</div>
|
|
|
</titleBgBox>
|
|
@@ -99,76 +86,42 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref } from "vue";
|
|
|
+import { onMounted, reactive, ref, computed } from "vue";
|
|
|
import titleBgBox from "./titleBgBox.vue";
|
|
|
+import colorDiv from "@/components/ColorDiv.vue";
|
|
|
+import {
|
|
|
+ QueryBasicsInfo,
|
|
|
+ QueryListEquipment,
|
|
|
+ QueryTrendsOnline,
|
|
|
+} from "../../../service/iotService";
|
|
|
|
|
|
-const deviceDistrubuteArr = ref([
|
|
|
- {
|
|
|
- name: "黄浦",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "徐汇",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "长宁",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "静安",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "普陀",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "虹口",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "杨浦",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "闵行",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "宝山",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "浦东",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "金山",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "黄浦",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "松江",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "青浦",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "奉贤",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "崇明",
|
|
|
- num: 231,
|
|
|
- },
|
|
|
+//设备类型统计数据
|
|
|
+const equipmentData = ref([]);
|
|
|
+const equipmentColor = ref([
|
|
|
+ "#549bf1",
|
|
|
+ "#67d470",
|
|
|
+ "#bcbf5c",
|
|
|
+ "#0daee3",
|
|
|
+ "#3182ea",
|
|
|
+ "#aa8a6e",
|
|
|
+ "#5a70bc",
|
|
|
+ " #b2dfff",
|
|
|
+ "#5cabbf",
|
|
|
+ "#2cecbc",
|
|
|
]);
|
|
|
|
|
|
+//基本情况obj
|
|
|
+const basicsInfo = reactive({
|
|
|
+ totalDevices: "",
|
|
|
+ onlineDevices: "",
|
|
|
+ offlineDevices: "",
|
|
|
+ unregisterDevices: "",
|
|
|
+ onlineRate: "",
|
|
|
+});
|
|
|
+
|
|
|
+//设备分类当前项选中
|
|
|
+const selectDeviceType = ref([]);
|
|
|
+
|
|
|
const getCount = (totalArr, num) => {
|
|
|
const total = totalArr
|
|
|
.map((item) => item.num)
|
|
@@ -178,6 +131,102 @@ const getCount = (totalArr, num) => {
|
|
|
console.log(total);
|
|
|
return (num / total) * 100;
|
|
|
};
|
|
|
+
|
|
|
+const getBasicsInfo = () => {
|
|
|
+ QueryBasicsInfo().then((res) => {
|
|
|
+ if (res.data.code == "200") {
|
|
|
+ basicsInfo.totalDevices = res.data.data.totalDevices;
|
|
|
+ basicsInfo.onlineDevices = res.data.data.onlineDevices;
|
|
|
+ basicsInfo.offlineDevices = res.data.data.offlineDevices;
|
|
|
+ basicsInfo.onlineRate = res.data.data.onlineRate;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+//设备类型/设备分布数据
|
|
|
+const getListEquipment = () => {
|
|
|
+ QueryListEquipment().then((res) => {
|
|
|
+ if (res.data.code == "200") {
|
|
|
+ const data = res.data.data;
|
|
|
+ const typeObj = {};
|
|
|
+ debugger
|
|
|
+ data.list.forEach((item) => {
|
|
|
+ if (typeObj[item.monitorScene]) {
|
|
|
+ typeObj[item.monitorScene].num++;
|
|
|
+ //onlineState: 设备状态 0:未激活;1:在线;2:离线
|
|
|
+ item.onlineState == 1 && typeObj[item.monitorScene].onlineNum++;
|
|
|
+ item.onlineState == 2 && typeObj[item.monitorScene].unlineNum++;
|
|
|
+ } else {
|
|
|
+ typeObj[item.monitorScene] = {
|
|
|
+ monitorScene: item.monitorScene, //监管场景
|
|
|
+ serialNumber: item.serialNumber,
|
|
|
+ district: item.district, //分布区域
|
|
|
+ num: 1,
|
|
|
+ onlineNum: 1,
|
|
|
+ unlineNum: 1,
|
|
|
+ total: data.total
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
+ equipmentData.value = Object.values(typeObj)
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+//获取设备分布数据
|
|
|
+const deviceDistrubuteArr = computed(() => {
|
|
|
+ const deviceDistruibute = {};
|
|
|
+ equipmentData.value.forEach((item) => {
|
|
|
+ if (
|
|
|
+ selectDeviceType.value.length > 0 &&
|
|
|
+ !selectDeviceType.value.includes(item.monitorScene)
|
|
|
+ ) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (deviceDistruibute[item.district]) {
|
|
|
+ deviceDistruibute[item.district].num += item.num;
|
|
|
+ } else {
|
|
|
+ deviceDistruibute[item.district] = {
|
|
|
+ name: item.district,
|
|
|
+ num: item.num,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return Object.values(deviceDistruibute);
|
|
|
+});
|
|
|
+
|
|
|
+const deviceTypeArr = computed(() => {
|
|
|
+ const result = equipmentData.value.map((item) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ numRatio: ((item.num * 100) / item.total).toFixed(0) + "%",
|
|
|
+ };
|
|
|
+ });
|
|
|
+ return result
|
|
|
+});
|
|
|
+
|
|
|
+//设备类型选中
|
|
|
+const selectCurrentKey = (params) => {
|
|
|
+ //暂时只支持单选,如果后续可以多选,将下行代码注释
|
|
|
+ selectDeviceType.value = [];
|
|
|
+
|
|
|
+ if (selectDeviceType.value.includes(params.monitorScene)) {
|
|
|
+ selectDeviceType.value = selectDeviceType.value.filter(
|
|
|
+ (item) => item != params.monitorScene
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ selectDeviceType.value.push(params.monitorScene);
|
|
|
+};
|
|
|
+
|
|
|
+const init = () => {
|
|
|
+ getBasicsInfo();
|
|
|
+ getListEquipment();
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ init();
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
@@ -191,7 +240,12 @@ const getCount = (totalArr, num) => {
|
|
|
font-size: 18px;
|
|
|
z-index: 99;
|
|
|
padding: 58px 0 44px 25px;
|
|
|
- background: linear-gradient(90deg, rgba(0,17,50,0.75), rgba(0,17,50,0.5), rgba(0,17,51,0));
|
|
|
+ background: linear-gradient(
|
|
|
+ 90deg,
|
|
|
+ rgba(0, 17, 50, 0.75),
|
|
|
+ rgba(0, 17, 50, 0.5),
|
|
|
+ rgba(0, 17, 51, 0)
|
|
|
+ );
|
|
|
.left-box {
|
|
|
box-sizing: border-box;
|
|
|
width: 100%;
|
|
@@ -201,6 +255,11 @@ const getCount = (totalArr, num) => {
|
|
|
background-repeat: no-repeat;
|
|
|
background-size: 100% 100%;
|
|
|
// background-position-x: -220px;
|
|
|
+ .color-box {
|
|
|
+ width: calc(100% - 30px);
|
|
|
+ padding-left: 3px;
|
|
|
+ margin-top: 5px;
|
|
|
+ }
|
|
|
.base-data {
|
|
|
position: relative;
|
|
|
width: 100%;
|
|
@@ -234,7 +293,7 @@ const getCount = (totalArr, num) => {
|
|
|
left: 30px;
|
|
|
bottom: 22px;
|
|
|
.num {
|
|
|
- color: #ffd041;
|
|
|
+ // color: #ffd041;
|
|
|
}
|
|
|
}
|
|
|
.base-data-unline {
|
|
@@ -293,12 +352,14 @@ const getCount = (totalArr, num) => {
|
|
|
.name {
|
|
|
font-size: 14px;
|
|
|
color: #bfd5e0;
|
|
|
+ width: 50px;
|
|
|
}
|
|
|
.num {
|
|
|
font-size: 18px;
|
|
|
font-family: "heitao";
|
|
|
- padding-left: 22px;
|
|
|
+ padding-left: 15px;
|
|
|
color: #c6daeb;
|
|
|
+ width: 30px;
|
|
|
}
|
|
|
.num1 {
|
|
|
font-size: 14px;
|
|
@@ -306,23 +367,27 @@ const getCount = (totalArr, num) => {
|
|
|
color: #c6daeb;
|
|
|
}
|
|
|
:deep(.el-progress) {
|
|
|
- width: calc(100% - 130px);
|
|
|
+ width: calc(100% - 160px);
|
|
|
margin-left: 13px;
|
|
|
.el-progress-bar__outer {
|
|
|
- background-color: rgba(35, 64, 95, 0.21);
|
|
|
- height: 6px!important;
|
|
|
+ background-color: rgba(35, 64, 95, 0.51);
|
|
|
+ height: 6px !important;
|
|
|
}
|
|
|
.el-progress-bar__inner {
|
|
|
// background-color: rgba(60, 139, 219, 1);
|
|
|
height: 6px;
|
|
|
- background: linear-gradient(to right, rgba(60, 139, 219, 1), rgba(60, 139, 219, 0.5));
|
|
|
+ background: linear-gradient(
|
|
|
+ to right,
|
|
|
+ rgba(60, 139, 219, 1),
|
|
|
+ rgba(60, 139, 219, 0.5)
|
|
|
+ );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
.left-title-bg-box {
|
|
|
:deep(.title-box) {
|
|
|
- width: calc(100% - 20px);
|
|
|
+ width: calc(100% - 25px);
|
|
|
}
|
|
|
}
|
|
|
}
|