2023-10-08 10:50:55 +08:00

470 lines
14 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="warning-page" v-waterMarker>
<layoutTop></layoutTop>
<div id="map-container" class="map"></div>
<LeftMenu
v-model="active"
:tabs="['项目名称', '工程名称']"
:records="records"
:pageable="pages"
class="LeftMenu"
@search="onSearchInput"
@change-page="onCurChange"
>
<template #default="{ data }">
<div class="leftProject" @click="onSearch(data)">
<span class="projectName">{{
(data as ResAiProjectPage).projectName || (data as ResAiEngineerPage).engineeringName
}}</span>
<div class="leftMenu_item flx-justify-between">
<div style="width: 100%; margin-top: 5px; display: flex; align-items: center">
<img src="@/assets/images/AIwaring/dustMap.png" alt="" />
<el-tooltip effect="dark" :content="data.projectAddress || data.address" placement="top-start">
<span class="middleSize">{{ data.projectAddress || data.address }}</span>
</el-tooltip>
</div>
<!-- <div>
<img src="@/assets/images/AIwaring/报警.png" alt="" />
<span class="middleSize">今日报警次数{{ data.todayAlarm }}</span>
</div> -->
</div>
<div class="bottom_item flx-justify-between" style="margin-top: 6px">
<div>
<span class="bottomSize">设备数量:{{ data.deviceNum }}</span>
</div>
<div>
<span class="bottomSize">状态{{ data.state === 1 ? "未开工" : "在建" }}</span>
</div>
</div>
</div>
</template>
</LeftMenu>
<MapTopData class="mapTopData" :data="mapTitleList" :title="mapTitle" />
<div class="infowindows" ref="infoWindowPage" v-show="infoShow">
<div class="title flx-justify-between">
<span>{{ infoName }}</span>
<p @click="onClose">x</p>
</div>
<div class="info-top">
<div class="ellipsisName">设备名称{{ infoWindowData.deviceName }}</div>
<div>最后一次上传时间{{ infoWindowData.dustNoiseData?.createTime }}</div>
<!-- <div class="flx-wrap" v-if="infoWindowData.dustNoiseData !== null"> -->
<div class="flx-wrap">
<div class="card flx-column">
<span :style="{ color: infoWindowData.dustNoiseData?.temperatureAlarm ? '#cf2c22' : '#00378F' }"
>{{ infoWindowData.dustNoiseData?.temperature }}
</span>
<span class="text-12">温度</span>
</div>
<div class="card flx-column">
<span :style="{ color: infoWindowData.dustNoiseData?.windspeedAlarm ? '#cf2c22' : '#00378F' }"
>{{ infoWindowData.dustNoiseData?.windspeed }}m/s
</span>
<span class="text-12">风速</span>
</div>
<div class="card flx-column">
<span :style="{ color: infoWindowData.dustNoiseData?.pm25Alarm ? '#cf2c22' : '#00378F' }"
>{{ infoWindowData.dustNoiseData?.pm25 }}μg/
</span>
<span class="text-12">PM2.5</span>
</div>
<div class="card flx-column">
<span :style="{ color: infoWindowData.dustNoiseData?.noiseAlarm ? '#cf2c22' : '#00378F' }"
>{{ infoWindowData.dustNoiseData?.noise }}dB
</span>
<span class="text-12">噪音</span>
</div>
<div class="card flx-column">
<span :style="{ color: infoWindowData.dustNoiseData?.pm10Alarm ? '#cf2c22' : '#00378F' }"
>{{ infoWindowData.dustNoiseData?.pm10 }}μg/
</span>
<span class="text-12">PM10</span>
</div>
<div class="card flx-column">
<span :style="{ color: infoWindowData.dustNoiseData?.humidityAlarm ? '#cf2c22' : '#00378F' }"
>{{ infoWindowData.dustNoiseData?.humidity }}%
</span>
<span class="text-12">湿度</span>
</div>
<div class="card flx-column">
<span :style="{ color: infoWindowData.dustNoiseData?.winddirectionAlarm ? '#cf2c22' : '#00378F' }"
>{{ infoWindowData.dustNoiseData?.winddirection }}
</span>
<span class="text-12">风向</span>
</div>
</div>
<!-- <div class="flx-center nodata" v-else>暂无数据~</div> -->
<div>报警记录</div>
<el-table
ref="proTable"
:header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
:data="infoWindowData.environmentAlarmList"
max-height="250"
style="background: transparent !important"
>
<el-table-column show-overflow-tooltip label="报警类型" property="type"> </el-table-column>
<el-table-column show-overflow-tooltip label="报警时间" property="createTime"> </el-table-column>
<el-table-column show-overflow-tooltip label="阈值" property="thresholdValue"> </el-table-column>
<el-table-column show-overflow-tooltip label="超标数据" property="alarmValue"> </el-table-column>
<el-table-column show-overflow-tooltip label="超标量" property="offsetValue"> </el-table-column>
<el-table-column show-overflow-tooltip label="报警原因" property="cause"> </el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch, shallowRef } from "vue";
import {
getDustprojectPage,
getDustengineeringPage,
getDuststatistics,
getDustMonitorDev,
AIproList,
AIengList,
getproDetail,
getengDetail
} from "@/api/modules/goverment";
import { useRoute, useRouter } from "vue-router";
import { GlobalStore } from "@/stores";
import { HOME_URL } from "@/enums/Home";
import layoutTop from "@/components/layoutTop/index.vue";
import initAMap from "@/components/AMap/AMap";
import LeftMenu from "@/components/LeftMenu/LeftMenu.vue";
import MapTopData from "@/components/MapTopData/index.vue";
import type { ResAiProjectPage, ResAiEngineerPage } from "@/api/types/government/AIwaring";
const router = useRouter();
const globalStore = GlobalStore();
const active = ref(0);
const pages = ref({
pageNo: 1,
pageSize: 7,
total: 0
});
const mapTitle = ref({
installed: "已安装扬尘噪声监控工程",
rate: "扬尘噪声监测覆盖率",
accumulate: "累计扬尘噪声预警"
});
const records = ref<ResAiEngineerPage[] | ResAiProjectPage[]>([]);
const monitorList = ref<projectPage[]>([]);
const mapTitleList = ref([]);
const AMapRef = ref();
const infoShow = ref(false);
// 点击弹窗的时候将项目名字存下来
const infoName = ref("");
const environAlarmFlag = ref(false);
const infoWindowPage = ref();
const infoWindowData = ref({
createTime: "",
name: "",
projectName: "",
environmentAlarmList: [],
dustNoiseData: [],
engineeringName: ""
});
const map = shallowRef<AMap.Map>();
// 页面的项目名称和工程名称的div点击事件
const onSearch = async (params: ResAiEngineerPage | ResAiProjectPage) => {
const curr = monitorList.value.find(item =>
active.value === 0 ? item.projectSn === params.projectSn : item.engineeringSn === params.engineeringSn
);
monitorList.value = monitorList.value.map(item => (item === curr ? { ...curr, showGif: true } : { ...item, showGif: false }));
if (params.longitude && params.latitude) {
console.log(111);
map.value?.setCenter([+params.longitude, +params.latitude]);
showInfoPage(curr);
}
// params.longitude !== "" && params.longitude !== null
// ? map.value?.setCenter([params.longitude, +params.latitude])
// : map.value?.setCenter([116.481181, 39.90923]);
};
// 展示信息窗口
const showInfoPage = async (obj: any) => {
const createMarkerImage = (state: string) => new URL(`../../../assets/images/AIwaring/${state}`, import.meta.url).href;
// 创建一个 选中的Icon
let selectIcon = getIcon(
"selected",
obj.environAlarmFlag === false ? createMarkerImage("clouding.gif") : createMarkerImage("warnclouding.gif")
);
// 将 icon 传入 marker
let startMarker = new AMapRef.value.Marker({
position: new AMapRef.value.LngLat(Number(obj.longitude) || 113, Number(obj.latitude) || 21),
icon: selectIcon,
offset: new AMapRef.value.Pixel(-13, -30)
});
map.value?.add([startMarker]);
monitorList.value = monitorList.value.map(val =>
val.latitude == obj.latitude && val.longitude == obj.longitude
? { ...obj, showGif: true }
: { ...val, showGif: false, showInfo: false }
);
const curr = monitorList.value.find(item => item.showGif);
curr.showInfo = !curr.showInfo;
// addMarker();
environAlarmFlag.value = obj.environAlarmFlag;
// e.target.setIcon(selectIcon);
if (active.value === 0) {
infoName.value = obj.projectName;
const res = await getproDetail({ projectId: obj.projectId });
// @ts-expect-error
infoWindowData.value = res.result;
} else {
infoName.value = obj.engineeringName;
const res = await getengDetail({ id: obj.id });
// @ts-expect-error
infoWindowData.value = res.result;
}
if (curr.showInfo) {
infoShow.value = true;
const infowindow = new AMapRef.value.InfoWindow({
isCustom: true, //使用自定义窗体
content: infoWindowPage.value,
offset: new AMap.Pixel(16, -45)
});
infowindow.open(map.value, startMarker.getPosition());
} else {
infoShow.value = false;
onClose();
}
};
// 页面的搜索按钮
const onSearchInput = async (params: string) => {
if (active.value === 0) {
const { result } = await getDustprojectPage({ projectName: params, ...pages.value });
records.value = result.records;
} else {
const { result } = await getDustengineeringPage({ engineeringName: params, ...pages.value });
records.value = result.records;
}
};
const getIcon = (val: "start" | "selected", icon: string) =>
val === "start"
? new AMapRef.value.Icon({
// 图标尺寸
size: new AMapRef.value.Size(52, 52),
// 图标的取图地址
// image: "../../../../assets/images/AIwaring/正常.png",
image: icon,
// 图标所用图片大小
imageSize: new AMapRef.value.Size(52, 52)
})
: new AMapRef.value.Icon({
// 图标尺寸
size: new AMapRef.value.Size(52, 52),
// 图标的取图地址
// image: "../../../../assets/images/AIwaring/正常.png",
image: icon,
// 图标所用图片大小
imageSize: new AMapRef.value.Size(52, 52)
});
// 页面的分页
const onCurChange = async (params: number) => {
if (active.value === 0) {
const { result } = await getDustprojectPage({ ...pages.value, pageNo: params });
records.value = result.records;
pages.value.total = +result.total;
} else {
const { result } = await getDustengineeringPage({ ...pages.value, pageNo: params });
records.value = result.records;
pages.value.total = +result.total;
}
// pages.value.total = +res.result.total;
};
// 地图增加坐标点
const addMarker = () => {
const createMarkerImage = (state: string) => new URL(`../../../assets/images/AIwaring/${state}`, import.meta.url).href;
map.value?.clearMap();
monitorList.value.forEach(item => {
// 创建一个 Icon
let startIcon = getIcon(
"start",
item.environAlarmFlag === false ? createMarkerImage("blueCloud.png") : createMarkerImage("redCloud.png")
);
// 创建一个 选中的Icon
let selectIcon = getIcon(
"selected",
item.environAlarmFlag === false ? createMarkerImage("clouding.gif") : createMarkerImage("warnclouding.gif")
);
// 将 icon 传入 marker
let startMarker = new AMapRef.value.Marker({
position: new AMapRef.value.LngLat(Number(item.longitude) || 113, Number(item.latitude) || 21),
icon: item.showGif ? selectIcon : startIcon,
offset: new AMapRef.value.Pixel(-13, -30)
});
map.value?.add([startMarker]);
//鼠标点击marker弹出自定义的信息窗体
startMarker.on("click", async function (e: any) {
monitorList.value = monitorList.value.map(val =>
val === item ? { ...item, showGif: true } : { ...val, showGif: false, showInfo: false }
);
const curr = monitorList.value.find(item => item.showGif);
curr.showInfo = !curr.showInfo;
// addMarker();
environAlarmFlag.value = item.environAlarmFlag;
// e.target.setIcon(selectIcon);
if (active.value === 0) {
infoName.value = item.projectName;
const res = await getproDetail({ projectId: item.projectId });
// @ts-expect-error
infoWindowData.value = res.result;
} else {
infoName.value = item.engineeringName;
const res = await getengDetail({ id: item.id });
// @ts-expect-error
infoWindowData.value = res.result;
}
if (curr.showInfo) {
infoShow.value = true;
const infowindow = new AMapRef.value.InfoWindow({
isCustom: true, //使用自定义窗体
content: infoWindowPage.value,
offset: new AMap.Pixel(16, -45)
});
infowindow.open(map.value, startMarker.getPosition());
} else {
infoShow.value = false;
onClose();
}
});
});
};
// 调用地图
const mapData = async () => {
const AMap = await initAMap();
AMapRef.value = AMap;
map.value = new AMap.Map("map-container", { zoom: 7, center: [116.481181, 39.90923], viewMode: "2D", resizeEnable: true });
// map.value?.on("click", function (e) {
// map.value?.clearInfoWindow();
// });
};
//关闭信息窗体
const onClose = () => {
map.value?.clearInfoWindow();
// showInfo 控制 弹窗的显示与关
monitorList.value = monitorList.value.map(item => ({ ...item, showInfo: false }));
infoShow.value = false;
};
// 获取项目名称分页
const getAIproPage = async () => {
const { result } = await getDustprojectPage(pages.value);
records.value = result.records;
records.value.map(item => {
let showGif = false;
item.showGif = showGif;
});
pages.value.total = Number(result.total);
};
// 获取工程名称分页
const getAIengPage = async () => {
const { result } = await getDustengineeringPage(pages.value);
records.value = result.records;
records.value.map(item => {
let showGif = false;
item.showGif = showGif;
});
pages.value.total = +result.total;
};
// 获取页面统计数字
const getStatisticsList = async () => {
const res = await getDuststatistics();
mapTitleList.value = res.result;
};
// 获取项目设备列表
const getproList = async () => {
const { result } = await AIproList({});
monitorList.value = result;
};
// 获取工程设备列表
const getengList = async () => {
const { result } = await AIengList({});
monitorList.value = result;
};
watch(
() => active.value,
async (value: number) => {
pages.value.pageNo = 1;
pages.value.total = 0;
// console.log(value);
if (value === 0) {
await getAIproPage();
await getproList();
onSearch(records.value[0]);
} else {
await getAIengPage();
await getengList();
onSearch(records.value[0]);
}
},
{
deep: true
}
);
watch(
() => monitorList.value,
() => {
addMarker();
// onSearch(records.value[0]);
}
);
onMounted(async () => {
await mapData();
// getAIengPage();
getStatisticsList();
getproList();
await getAIproPage();
onSearch(records.value[0]);
// addMarker();
});
</script>
<style lang="scss" scoped>
@import "./map.scss";
@import "./index.scss";
:deep(.el-header) {
margin-bottom: 0;
}
</style>