ly-front/src/views/contentData/RightSidebar/index.vue

237 lines
7.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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,
lastPositionsHash: null // 初始化为 null避免首次误判
};
},
watch: {
"homeData.positions": {
handler(newPositions) {
newPositions = newPositions || [];
const currentHash = JSON.stringify(newPositions);
// 比较新旧数据(首次加载时 lastPositionsHash 为 null
if (
this.lastPositionsHash !== null &&
currentHash === this.lastPositionsHash
) {
return;
}
// 数据变化或首次加载
if (newPositions.length > 0) {
this.lastPositionsHash = currentHash; // 更新缓存
this.positionData = newPositions;
this.homeView = this.homeData;
this.$nextTick(() => {
this.handleTitleClick(true, "all");
});
}
},
immediate: true // 初始加载时触发
}
},
mounted() {},
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, "all"); // 显示所有位置信息
},
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, "one", value); // 显示所有位置信息
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>