225 lines
6.5 KiB
Vue
225 lines
6.5 KiB
Vue
|
|
<template>
|
||
|
|
<div class="right-sidebar" :class="{ contracted: isContracted }">
|
||
|
|
<div class="device-status">
|
||
|
|
<div
|
||
|
|
v-for="(item, index) in deviceStatus"
|
||
|
|
:key="index"
|
||
|
|
class="device-item"
|
||
|
|
>
|
||
|
|
<div class="device-icon">
|
||
|
|
<img
|
||
|
|
:src="
|
||
|
|
require(`@/assets/img/device/${
|
||
|
|
item.state > 0 ? item.icon + '-h' + '.png' : item.icon + '.png'
|
||
|
|
}`)
|
||
|
|
"
|
||
|
|
alt=""
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
<div class="device-info">
|
||
|
|
<div class="device-name">{{ item.state }}</div>
|
||
|
|
<div class="device-num">/{{ item.num }}</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="markers">
|
||
|
|
<div class="title">
|
||
|
|
<img
|
||
|
|
src="@/assets/img/positionTitle.png"
|
||
|
|
alt=""
|
||
|
|
@click="handleTitleClick(true, 'all')"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
<ul>
|
||
|
|
<li
|
||
|
|
v-for="(item, index) in positionData"
|
||
|
|
:key="index"
|
||
|
|
@click="handlePositionClick(item)"
|
||
|
|
>
|
||
|
|
<div class="left">
|
||
|
|
<img src="@/assets/img/positionPiont.png" alt="" />
|
||
|
|
</div>
|
||
|
|
<div class="main">
|
||
|
|
<div class="top_main">
|
||
|
|
<div class="text">{{ item.name }}</div>
|
||
|
|
</div>
|
||
|
|
<div class="top_main">
|
||
|
|
<div class="text1">{{ item.address }}</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
<div class="right-contract" @click="handleContractClick">
|
||
|
|
<img :src="isContracted ? leftContract : rightContract" alt="" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
import { allPositions, allDevices } from "../index.js";
|
||
|
|
export default {
|
||
|
|
name: "RightSidebar",
|
||
|
|
props: {
|
||
|
|
homeData: {
|
||
|
|
type: Object,
|
||
|
|
default: () => ({})
|
||
|
|
}
|
||
|
|
},
|
||
|
|
data() {
|
||
|
|
return {
|
||
|
|
leftContract: require("@/assets/img/left-contracts.png"),
|
||
|
|
rightContract: require("@/assets/img/right-contracts.png"),
|
||
|
|
deviceStatus: [],
|
||
|
|
positionData: [],
|
||
|
|
isContracted: false,
|
||
|
|
homeView: {}
|
||
|
|
};
|
||
|
|
},
|
||
|
|
watch: {
|
||
|
|
homeData: {
|
||
|
|
handler(newVal) {
|
||
|
|
this.homeView = newVal;
|
||
|
|
this.positionData = newVal.positions;
|
||
|
|
},
|
||
|
|
deep: true
|
||
|
|
}
|
||
|
|
},
|
||
|
|
mounted() {
|
||
|
|
let time = setInterval(() => {
|
||
|
|
if (this.positionData.length > 0) {
|
||
|
|
clearInterval(time);
|
||
|
|
this.handleTitleClick(true, "all");
|
||
|
|
}
|
||
|
|
}, 500);
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
handleContractClick() {
|
||
|
|
this.isContracted = !this.isContracted; // 切换状态
|
||
|
|
},
|
||
|
|
handleTitleClick(show, type) {
|
||
|
|
if (type === "all") {
|
||
|
|
// 获取所有位置的设备数据
|
||
|
|
const allData = this.positionData.flatMap((item) => item.devices || []);
|
||
|
|
|
||
|
|
// 创建一个映射来统计每种 icon 的总数和在线数量
|
||
|
|
const deviceStats = {};
|
||
|
|
|
||
|
|
// 统计所有设备的数量
|
||
|
|
allData.forEach((device) => {
|
||
|
|
if (!deviceStats[device.icon]) {
|
||
|
|
deviceStats[device.icon] = {
|
||
|
|
total: 0,
|
||
|
|
online: 0,
|
||
|
|
name: device.model
|
||
|
|
};
|
||
|
|
}
|
||
|
|
deviceStats[device.icon].total += 1;
|
||
|
|
if (device.isOnline) {
|
||
|
|
deviceStats[device.icon].online += 1;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// 将统计结果转换为 deviceStatus 数组
|
||
|
|
this.deviceStatus = Object.entries(deviceStats).map(
|
||
|
|
([icon, stats], index) => ({
|
||
|
|
id: index + 1,
|
||
|
|
name: stats.name || `设备类型${icon}`,
|
||
|
|
icon: icon,
|
||
|
|
num: stats.total,
|
||
|
|
state: stats.online
|
||
|
|
})
|
||
|
|
);
|
||
|
|
allDevices(this.positionData, "all", true); // 显示所有设备信息
|
||
|
|
}
|
||
|
|
console.log(this.positionData, "this.positionData");
|
||
|
|
let positionData = this.processGeojsonData(this.positionData);
|
||
|
|
allPositions(positionData, show); // 显示所有位置信息
|
||
|
|
},
|
||
|
|
handlePositionClick(value) {
|
||
|
|
console.log(value, "value");
|
||
|
|
this.deviceStatus = [];
|
||
|
|
// 获取设备列表
|
||
|
|
const devices = value.devices || [];
|
||
|
|
|
||
|
|
// 创建一个映射来统计每种 icon 的总数和在线数量
|
||
|
|
const deviceStats = {};
|
||
|
|
|
||
|
|
// 统计设备数量
|
||
|
|
devices.forEach((device) => {
|
||
|
|
if (!deviceStats[device.icon]) {
|
||
|
|
deviceStats[device.icon] = {
|
||
|
|
total: 0,
|
||
|
|
online: 0,
|
||
|
|
name: device.model // 假设使用 model 作为名称,如果需要其他字段可以修改
|
||
|
|
};
|
||
|
|
}
|
||
|
|
deviceStats[device.icon].total += 1;
|
||
|
|
if (device.isOnline) {
|
||
|
|
deviceStats[device.icon].online += 1;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// 将统计结果转换为 deviceStatus 数组
|
||
|
|
this.deviceStatus = Object.entries(deviceStats).map(
|
||
|
|
([icon, stats], index) => ({
|
||
|
|
id: index + 1,
|
||
|
|
name: stats.name || `设备类型${icon}`, // 如果没有名称,使用默认值
|
||
|
|
icon: icon,
|
||
|
|
num: stats.total,
|
||
|
|
state: stats.online
|
||
|
|
})
|
||
|
|
);
|
||
|
|
this.handleTitleClick(false, "one");
|
||
|
|
let positionData = this.processGeojsonData([value]);
|
||
|
|
allPositions(positionData, true); // 显示所有位置信息
|
||
|
|
let deviceData = this.positionData.find((item) => item.id === value.id);
|
||
|
|
allDevices(deviceData, "one", true); // 显示所有设备信息
|
||
|
|
},
|
||
|
|
processGeojsonData(value) {
|
||
|
|
// 存储所有设备的 GeoJSON 数据
|
||
|
|
let geojsonArray = [];
|
||
|
|
// 遍历所有设备
|
||
|
|
value.forEach((item) => {
|
||
|
|
if (typeof item.regionJson === "string") {
|
||
|
|
item.regionJson = JSON.parse(item.regionJson); // 解析 GeoJSON 数据
|
||
|
|
}
|
||
|
|
if (item.regionJson?.type === "MultiPolygon") {
|
||
|
|
const polygons = item.regionJson.coordinates.map((polygon, index) => {
|
||
|
|
// 返回标准化的 GeoJSON Feature
|
||
|
|
return {
|
||
|
|
type: "Feature",
|
||
|
|
name: item.source,
|
||
|
|
geometry: {
|
||
|
|
type: "Polygon",
|
||
|
|
coordinates: polygon // 保持原始坐标
|
||
|
|
},
|
||
|
|
properties: {
|
||
|
|
shape: "polygon",
|
||
|
|
deviceId: item.id, // 添加设备 ID 以区分来源
|
||
|
|
source: item.source // 可选:添加设备名称
|
||
|
|
}
|
||
|
|
};
|
||
|
|
});
|
||
|
|
|
||
|
|
// 将当前设备的多边形添加到总数组
|
||
|
|
geojsonArray = geojsonArray.concat(polygons);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return geojsonArray; // 返回所有设备的 GeoJSON 数据
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style lang="scss" scoped>
|
||
|
|
.right-sidebar {
|
||
|
|
transition: transform 0.5s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.right-sidebar.contracted {
|
||
|
|
transform: translateX(90%);
|
||
|
|
}
|
||
|
|
</style>
|