iot-fontend/src/views/iot/deviceMap/index.vue
Kven 7c79c67c44 fix(iot): 修复产品编辑和地图展示相关问题
- 修改工作台数据面板中的产品数为告警数
- 优化设备地图页面布局和样式
-修复产品编辑页面中图标和预览图显示问题
- 优化地图标记点图标和样式
2025-03-27 21:35:08 +08:00

211 lines
7.1 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>
<a-layout>
<a-layout-sider style="width:300px;background-color: transparent;" :resize-directions="['right']">
<!-- 搜索框 -->
<a-card>
<a-input-search
v-model="searchKeyword"
placeholder="设备名称"
@change="handleSearch"
@search="handleSearch" style="margin-bottom: 16px"
/>
</a-card>
<!-- 设备列表容器 -->
<div class="device-list-container">
<a-row>
<a-col
:span="24"
v-for="device in deviceList"
:key="device.id"
@click="selectDevice(device)"
>
<a-card hoverable :style="{ margin: '5px', height: '100px' }">
<div
:style="{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
}"
>
<span
:style="{ display: 'flex', alignItems: 'center', color: '#1D2129' }"
>
<a-avatar
shape="square"
:size="70"
>
<a-image
:src="getImageUrl(device.previewId)"
/>
</a-avatar>
<a-descriptions layout="inline-horizontal" :style="{ marginLeft: '10px'}">
<a-descriptions-item label="设备名称" :span="3">{{ device.name }}</a-descriptions-item>
<a-descriptions-item label="所属产品">{{ device.productName }}</a-descriptions-item>
</a-descriptions>
</span>
</div>
</a-card>
</a-col>
</a-row>
</div>
</a-layout-sider>
<a-layout-content>
<div id="container"></div>
</a-layout-content>
</a-layout>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import AMapLoader from '@amap/amap-jsapi-loader';
import { DeviceRecord, queryDeviceByNameList, queryDeviceList } from '@/api/device';
import '@amap/amap-jsapi-types';
import router from '@/router';
import { Message } from '@arco-design/web-vue';
import { debounce } from '@arco-design/web-vue/es/_utils/debounce';
let map: any = null;
const deviceList = ref<DeviceRecord[]>([]);
const searchKeyword = ref(''); // 搜索关键字
const isLoading = ref(false); // 加载状态
let selectDevice = (device: DeviceRecord) => {
console.log(device);
};
// 获取图片 URL 的函数
const getImageUrl = (previewId: string) => {
if (!previewId) {
return 'https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp';
}
return `/api/rest/attachment/${previewId}`;
};
// 防抖搜索函数
const handleSearch = debounce(async (value: string) => {
try {
isLoading.value = true; // 开始加载
if (value) {
const res = await queryDeviceByNameList({
name: value,
});
deviceList.value = res.data;
} else {
// 如果搜索框为空,恢复显示全部设备列表
const response = await queryDeviceByNameList({});
deviceList.value = response.data;
}
} catch (error) {
Message.error('搜索失败,请稍后重试');
} finally {
isLoading.value = false; // 结束加载
}
}, 300); // 防抖时间设置为 300ms
// const handleImageError = (event: Event) => {
// const img = event.target as HTMLImageElement;
// img.src = 'https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp'; // 替换为默认图片
// };
AMapLoader.load({
key: 'a4e80eed798a56451b226dcfca81b846', // 申请好的Web端开发者Key首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap) => {
map = new AMap.Map('container', {
// 设置地图容器id
viewMode: '3D', // 是否为3D地图模式
zoom: 11, // 初始化地图级别
center: [116.397428, 39.90923], // 初始化地图中心点位置
});
selectDevice = (device: DeviceRecord) => {
if (device.longitude && device.latitude) {
const lngLat = [device.longitude, device.latitude];
const content = document.createElement('div');
content.className = 'custom-content-marker';
const markerIcon = device.warning === '1'
? `/api/rest/attachment/${device.iconId}` // 警告标记
: `/api/rest/attachment/${device.iconId}`; // 默认标记
content.innerHTML = `<img src="${markerIcon}" alt="标记点" width="30px" />`;
// 创建标记点
const marker = new AMap.Marker({
position: lngLat,
content,
});
// 将标记点添加到地图上
map.setCenter(lngLat);
map.setZoom(20);
map.add(marker);
const infoContent = [
`<br/><div style="width: 300px;margin-left: 20px;padding-bottom: 10px"><b>设备名称: ${device.name}</b>`,
`<span style="font-size: 16px; color: #333;">硬件版本: ${device.hardwareVersion}</span>`,
`<span style="font-size: 16px; color: #333;">固件版本: ${device.firmwareVersion}</span>`,
`<span style="font-size: 16px; color: #333;">所属产品: ${device.productName}</span>`,
`<a-button style="margin-left: 200px;color: #0960bd" onclick="handleViewDetail('${device.id}')">查看详情
</a-button></div>`,
];
window.handleViewDetail = (deviceId: number) => {
router.push({ name: 'deviceDetail', params: { id: deviceId } });
};
// 初始化信息窗体
const infoWindow = new AMap.InfoWindow({
content: infoContent.join('<br>'),
offset: new AMap.Pixel(10, 10), // 调整信息窗体的偏移量
});
// 绑定标记点点击事件
marker.on('click', () => {
infoWindow.open(map, lngLat); // 打开信息窗体
});
} else {
Message.error('设备缺少经纬度信息');
}
};
})
.catch((e) => {
Message.error('加载地图失败');
console.log(e);
});
// 将依赖于 AMap 的代码放在 then 回调中
onMounted(() => {
// 获取设备列表
queryDeviceByNameList({})
.then((response) => {
deviceList.value = response.data;
})
.catch(() => {
Message.error('获取设备列表失败');
});
});
// onUnmounted(() => {
// map?.destroy();
// });
</script>
<style scoped>
#container {
width: 100%;
height: 100vh;
}
.custom-content-marker img {
width: 100%;
height: 100%;
}
/* 设备列表容器样式 */
.device-list-container {
height: calc(100vh - 100px); /* 根据实际高度调整 */
overflow-y: auto; /* 添加垂直滚动条 */
}
</style>