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

237 lines
7.0 KiB
Vue
Raw Normal View History

2025-03-31 15:26:29 +00:00
<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,
2025-04-12 15:15:32 +00:00
lastPositionsHash: null // 初始化为 null避免首次误判
2025-03-31 15:26:29 +00:00
};
},
watch: {
2025-04-12 15:15:32 +00:00
"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");
});
}
2025-03-31 15:26:29 +00:00
},
2025-04-12 15:15:32 +00:00
immediate: true // 初始加载时触发
2025-03-31 15:26:29 +00:00
}
},
2025-04-12 15:15:32 +00:00
mounted() {},
2025-03-31 15:26:29 +00:00
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);
2025-04-13 08:23:44 +00:00
allPositions(positionData, show, "all"); // 显示所有位置信息
2025-03-31 15:26:29 +00:00
},
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]);
2025-04-13 08:23:44 +00:00
allPositions(positionData, true, "one", value); // 显示所有位置信息
2025-03-31 15:26:29 +00:00
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>