339 lines
11 KiB
Vue
339 lines
11 KiB
Vue
|
|
<template>
|
|||
|
|
<div class="warning-page">
|
|||
|
|
<el-header>
|
|||
|
|
<div class="header-lf">
|
|||
|
|
<div @click="goHome" class="logo flx-center">
|
|||
|
|
<!-- <img src="@/assets/images/logo.svg" alt="logo" /> -->
|
|||
|
|
<img src="@/assets/images/login/china.png" style="margin: 0 15px" alt="logo" />
|
|||
|
|
<span>数字化政务监管平台</span>
|
|||
|
|
<!-- <span style="margin: 0 20px">|</span>
|
|||
|
|
<span>{{ `${title}` }}</span> -->
|
|||
|
|
</div>
|
|||
|
|
<ToolBarLeft />
|
|||
|
|
</div>
|
|||
|
|
<ToolBarRight />
|
|||
|
|
</el-header>
|
|||
|
|
<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 class="flx-justify-between">
|
|||
|
|
<img src="@/assets/images/AIwaring/视频.png" alt="" />
|
|||
|
|
<span class="middleSize">接入视频路数:{{ data.deviceNum }}</span>
|
|||
|
|
</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.questionNum }}</span>
|
|||
|
|
</div>
|
|||
|
|
<div>
|
|||
|
|
<span class="bottomSize">已整改问题数:{{ data.solveQuestionNum }}</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>{{ active === 0 ? infoWindowData.projectName : infoWindowData.engineeringName }}</span>
|
|||
|
|
<p @click="onClose">x</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="info-top">
|
|||
|
|
<div>设备名称:{{ infoWindowData.name }}</div>
|
|||
|
|
<div>最后一次上传时间:{{ infoWindowData.dustNoiseData?.createTime }}</div>
|
|||
|
|
|
|||
|
|
<div class="flx-wrap">
|
|||
|
|
<div class="card flx-column">
|
|||
|
|
<span :style="{ color: infoWindowData.dustNoiseData.temperatureAlarm ? '#cf2c22' : '' }"
|
|||
|
|
>{{ infoWindowData.dustNoiseData.temperature }}℃
|
|||
|
|
</span>
|
|||
|
|
<span>温度</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="card flx-column">
|
|||
|
|
<span :style="{ color: infoWindowData.dustNoiseData.windspeedAlarm ? '#cf2c22' : '' }"
|
|||
|
|
>{{ infoWindowData.dustNoiseData.windspeed }}/s
|
|||
|
|
</span>
|
|||
|
|
<span>风速</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="card flx-column">
|
|||
|
|
<span :style="{ color: infoWindowData.dustNoiseData.pm25Alarm ? '#cf2c22' : '' }"
|
|||
|
|
>{{ infoWindowData.dustNoiseData.pm25 }}ug/m³
|
|||
|
|
</span>
|
|||
|
|
<span>PM2.5</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="card flx-column">
|
|||
|
|
<span :style="{ color: infoWindowData.dustNoiseData.noiseAlarm ? '#cf2c22' : '' }"
|
|||
|
|
>{{ infoWindowData.dustNoiseData.noise }}dB
|
|||
|
|
</span>
|
|||
|
|
<span>噪音</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="card flx-column">
|
|||
|
|
<span :style="{ color: infoWindowData.dustNoiseData.pm10Alarm ? '#cf2c22' : '' }"
|
|||
|
|
>{{ infoWindowData.dustNoiseData.pm10 }}ug/m³
|
|||
|
|
</span>
|
|||
|
|
<span>PM10</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="card flx-column">
|
|||
|
|
<span :style="{ color: infoWindowData.dustNoiseData.humidityAlarm ? '#cf2c22' : '' }"
|
|||
|
|
>{{ infoWindowData.dustNoiseData.humidity }}%
|
|||
|
|
</span>
|
|||
|
|
<span>湿度</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="card flx-column">
|
|||
|
|
<span :style="{ color: infoWindowData.dustNoiseData.winddirectionAlarm ? '#cf2c22' : '' }"
|
|||
|
|
>{{ infoWindowData.dustNoiseData.winddirection }}°
|
|||
|
|
</span>
|
|||
|
|
<span>风向</span>
|
|||
|
|
</div>
|
|||
|
|
</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,
|
|||
|
|
getDustdetail
|
|||
|
|
} from "@/api/modules/goverment";
|
|||
|
|
import { useRoute, useRouter } from "vue-router";
|
|||
|
|
import { GlobalStore } from "@/stores";
|
|||
|
|
import { HOME_URL } from "@/enums/Home";
|
|||
|
|
import ToolBarLeft from "@/layouts/components/Header/ToolBarLeft.vue";
|
|||
|
|
import ToolBarRight from "@/layouts/components/Header/ToolBarRight.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: 6,
|
|||
|
|
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 infoWindowPage = ref();
|
|||
|
|
const infoWindowData = ref({
|
|||
|
|
createTime: "",
|
|||
|
|
name: "",
|
|||
|
|
projectName: "",
|
|||
|
|
environmentAlarmList: [],
|
|||
|
|
dustNoiseData: [],
|
|||
|
|
engineeringName: ""
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const map = shallowRef<AMap.Map>();
|
|||
|
|
|
|||
|
|
watch(
|
|||
|
|
() => active.value,
|
|||
|
|
value => {
|
|||
|
|
pages.value.pageNo = 1;
|
|||
|
|
pages.value.total = 0;
|
|||
|
|
if (value === 0) {
|
|||
|
|
getAIproPage();
|
|||
|
|
onSearch(records.value[0]);
|
|||
|
|
} else {
|
|||
|
|
getAIengPage();
|
|||
|
|
onSearch(records.value[0]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 页面的项目名称和工程名称的div点击事件
|
|||
|
|
const onSearch = async (params: ResAiEngineerPage | ResAiProjectPage) => {
|
|||
|
|
map.value?.clearMap();
|
|||
|
|
const res = await getDustMonitorDev(
|
|||
|
|
active.value === 0
|
|||
|
|
? { projectSn: (params as ResAiProjectPage).projectSn }
|
|||
|
|
: { engineeringSn: (params as ResAiEngineerPage).engineeringSn }
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
monitorList.value = res.result;
|
|||
|
|
// 判断后端返回来的经纬度为不为空
|
|||
|
|
monitorList.value[0]?.lng !== "" && monitorList.value[0]?.lng !== null
|
|||
|
|
? map.value?.setCenter([monitorList.value[0]?.lng, monitorList.value[0]?.lat])
|
|||
|
|
: map.value?.setCenter([116.481181, 39.90923]);
|
|||
|
|
|
|||
|
|
addMarker();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 页面的搜索按钮
|
|||
|
|
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 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;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 地图增加坐标点
|
|||
|
|
function addMarker() {
|
|||
|
|
const createMarkerImage = (state: string) => new URL(`./src/assets/images/AIwaring/${state}.png`, location.origin).href;
|
|||
|
|
map.value?.clearMap();
|
|||
|
|
monitorList.value.forEach(item => {
|
|||
|
|
// 创建一个 Icon
|
|||
|
|
let startIcon = new AMap.Icon({
|
|||
|
|
// 图标尺寸
|
|||
|
|
size: new AMap.Size(52, 52),
|
|||
|
|
// 图标的取图地址
|
|||
|
|
// image: "../../../../assets/images/AIwaring/正常.png",
|
|||
|
|
image: item.flag === false ? createMarkerImage("blueCloud") : createMarkerImage("redCloud"),
|
|||
|
|
// 图标所用图片大小
|
|||
|
|
imageSize: new AMap.Size(52, 52)
|
|||
|
|
});
|
|||
|
|
// 将 icon 传入 marker
|
|||
|
|
let startMarker = new AMap.Marker({
|
|||
|
|
position: new AMap.LngLat(Number(item.lng) || 113, Number(item.lat) || 21),
|
|||
|
|
icon: startIcon,
|
|||
|
|
offset: new AMap.Pixel(-13, -30)
|
|||
|
|
});
|
|||
|
|
map.value?.add([startMarker]);
|
|||
|
|
//鼠标点击marker弹出自定义的信息窗体
|
|||
|
|
startMarker.on("click", async function () {
|
|||
|
|
const res = await getDustdetail({ id: item.id });
|
|||
|
|
infoWindowData.value = res.result;
|
|||
|
|
if (!infoShow.value) {
|
|||
|
|
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: 10, center: [116.481181, 39.90923], viewMode: "2D", resizeEnable: true });
|
|||
|
|
addMarker();
|
|||
|
|
|
|||
|
|
//关闭信息窗体
|
|||
|
|
function closeInfoWindow() {
|
|||
|
|
map.value?.clearInfoWindow();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
mapData();
|
|||
|
|
//关闭信息窗体
|
|||
|
|
const onClose = () => {
|
|||
|
|
map.value?.clearInfoWindow();
|
|||
|
|
infoShow.value = false;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 获取项目名称分页
|
|||
|
|
const getAIproPage = async () => {
|
|||
|
|
const { result } = await getDustprojectPage(pages.value);
|
|||
|
|
records.value = result.records;
|
|||
|
|
pages.value.total = Number(result.total);
|
|||
|
|
};
|
|||
|
|
// 获取工程名称分页
|
|||
|
|
const getAIengPage = async () => {
|
|||
|
|
const { result } = await getDustengineeringPage(pages.value);
|
|||
|
|
records.value = result.records;
|
|||
|
|
pages.value.total = +result.total;
|
|||
|
|
};
|
|||
|
|
// 获取页面统计数字
|
|||
|
|
const getStatisticsList = async () => {
|
|||
|
|
const res = await getDuststatistics();
|
|||
|
|
mapTitleList.value = res.result;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const goHome = () => {
|
|||
|
|
router.push(HOME_URL[globalStore.accountType - 1]);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
onMounted(async () => {
|
|||
|
|
// getAIengPage();
|
|||
|
|
getStatisticsList();
|
|||
|
|
await getAIproPage();
|
|||
|
|
// getDustMonitorDev({ projectSn: projectPage.value.records[0].projectSn });
|
|||
|
|
onSearch(records.value[0]);
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
@import "./map.scss";
|
|||
|
|
@import "./index.scss";
|
|||
|
|
</style>
|