You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
11 KiB
Vue

6 months ago
<template>
<div class="data-overview-wrap">
<!-- 检测总量汇总 -->
<div class="grid-container">
<div class="grid-item">
<div class="module-header">
<ContentHeader bgLayout="918">
<template #title>
<div class="w-[200px] bg_title bg_title_0"></div>
</template>
<template #extra>
<div>
<el-button type="primary" class="month-btn" @click="getList('month')"
:class="{ 'active-btn': activeBtn === 'month' }">
</el-button>
<el-button class="week-btn" @click="getList('week')" :class="{ 'active-btn': activeBtn === 'week' }">
</el-button>
</div>
</template>
</ContentHeader>
</div>
<div class="chart-container chart-container-bar">
<BarChart :xData="xData" :legendArr="legendArr" :datas="datas" :colorArr="colorArr" />
</div>
</div>
<!-- 设备信息 -->
<div class="grid-item">
<div class="module-header">
<ContentHeader bgLayout="918">
<template #title>
<div class="w-[200px] bg_title bg_title_1"></div>
</template>
<template #extra>
<div></div>
</template>
</ContentHeader>
</div>
<div class="device-info">
<div class="total-device">
<div class="device-icon"></div>
<div class="device-count">
<div>设备总数</div>
<div class="count-number">{{ deviceTotal }}</div>
6 months ago
</div>
</div>
<div class="device-list">
<div class="device-card">
<div class="mb-3">车体检测设备: {{ carDevice?.total || 0 }}</div>
<DeviceStatus :deviceStatus="carDevice" />
6 months ago
</div>
<div class="device-card">
<div class="mb-3">撑杆检测设备: {{ poleDevice?.total || 0 }}</div>
<DeviceStatus :deviceStatus="poleDevice" />
6 months ago
</div>
<div class="device-card">
<div class="mb-3">钩机检测设备: {{ excavatorDevice?.total || 0 }}</div>
<DeviceStatus :deviceStatus="excavatorDevice" />
</div>
</div>
6 months ago
</div>
</div>
</div>
<!-- 中部检测模块 -->
<div class="grid-container">
<ul class="flex grid-item grid-item-pie">
<li>
<div class="module-header">
<ContentHeader bgLayout="450">
<template #title>
<div class="w-[200px] bg_title bg_title_2"></div>
</template>
<template #extra>
<el-select v-model="searchForm.car" placeholder="时间" class="custom-select" @change="getCarFault()">
<el-option label="1月" value="1"></el-option>
<el-option label="2月" value="2"></el-option>
<el-option label="3月" value="3"></el-option>
<el-option label="4月" value="4"></el-option>
<el-option label="5月" value="5"></el-option>
<el-option label="6月" value="6"></el-option>
<el-option label="7月" value="7"></el-option>
<el-option label="8月" value="8"></el-option>
<el-option label="9月" value="9"></el-option>
<el-option label="10月" value="10"></el-option>
<el-option label="11月" value="11"></el-option>
<el-option label="12月" value="12"></el-option>
</el-select>
</template>
</ContentHeader>
</div>
<div class="chart-container chart-pie-bg">
<PieChart :data="carFaultTotal" :colors="[
'#FF7C09',
'#0032FF',
'#04FFF2',
'#D19EFF',
'#FF0103',
'#9EFFF3',
]" />
</div>
</li>
<li>
<div class="module-header">
<ContentHeader bgLayout="450">
<template #title>
<div class="w-[200px] bg_title bg_title_3"></div>
</template>
<template #extra>
<el-select v-model="searchForm.pole" placeholder="时间" class="custom-select" @change="getPoleFault()">
<el-option label="1月" value="1"></el-option>
<el-option label="2月" value="2"></el-option>
<el-option label="3月" value="3"></el-option>
<el-option label="4月" value="4"></el-option>
<el-option label="5月" value="5"></el-option>
<el-option label="6月" value="6"></el-option>
<el-option label="7月" value="7"></el-option>
<el-option label="8月" value="8"></el-option>
<el-option label="9月" value="9"></el-option>
<el-option label="10月" value="10"></el-option>
<el-option label="11月" value="11"></el-option>
<el-option label="12月" value="12"></el-option>
</el-select>
</template>
</ContentHeader>
</div>
<div class="chart-container chart-pie-bg">
<PieChartSmall :data="poleFaultTotal" :colors="['#9DFFF3', '#FFA179']" />
</div>
</li>
</ul>
6 months ago
<div class="grid-item">
<div class="module-header">
<ContentHeader bgLayout="918">
<template #title>
<div class="w-[200px] bg_title bg_title_4"></div>
</template>
<template #extra>
<div></div>
</template>
</ContentHeader>
</div>
<div class="monitor-images">
<div class="monitor-images-left">
<img :src="imageFault[0]?.url" />
<div class="fault-info">{{ imageFault[0]?.fault_type }}</div>
</div>
<div class="monitor-images-right">
<img :src="imageFault[1]?.url"/>
<div class="fault-info">{{ imageFault[1]?.fault_type }}</div>
</div>
</div>
</div>
6 months ago
</div>
<AlarmModal v-model:value="isAlarmOpen" :info="currentRow" :image="currFileList" @close="isAlarmOpen = false" />
</div>
6 months ago
</template>
<script lang="ts" setup>
import * as echarts from "echarts";
import ContentHeader from "@/components/ContentHeader.vue";
import BarChart from "./components/BarChart.vue";
import PieChart from "./components/PieChart.vue";
import PieChartSmall from "./components/PieChartSmall.vue";
import DeviceStatus from "./components/DeviceStatus.vue";
import { getDataOverviewApi, getDeviceInfowApi, getRecordFaultApi, getRealTimeApi } from '@/api/dashboard';
import { isSuccessApi } from "@/utils/forApi";
import AlarmModal from './components/AlarmModal.vue'
import { useWebSocketStore } from '@/stores/websocketStore';
import { onBeforeRouteLeave } from 'vue-router';
defineOptions({
name: "DataOverviewWrap"
});
const xData = ref(["1月", "2月", "3月", "4月", "5月"]);
const legendArr = ["车体检测", "撑杆检测"];
const datas = ref([
[1528, 1266.02, 2468.39, 2982.67, 3165.91],
[2844.44, 6505.07, 8016.12, 6350.87, 1474.61],
]);
const colorArr = [
["#3B9FFE", "#5070F2"],
["#FFDA8D", "#FFAC06"],
];
const deviceStatus = ref({
onlineCount: 50,
errorCount: 10,
outlineCount: 10
});
const searchForm = reactive({
car: "1",
pole: "1",
});
const deviceTotal = ref(0);
const carDevice = ref({});
const poleDevice = ref({});
const excavatorDevice = ref({});
const carFaultTotal = ref([]);
const poleFaultTotal = ref([]);
const imageFault = ref([]);
const activeBtn = ref("month");
const isAlarmOpen = ref<Boolean>(false); //详情弹窗
const currentRow = ref<Record<string, any>>({}); // 当前选中行
const currFileList = ref<Record<string, any>[]>([]); // 详情的文件列表
const websocketStore = useWebSocketStore();
// 监听 messages 的变化
watch(() => websocketStore.messages, (newMessages: string[], oldMessages: string[]) => {
if(newMessages?.length > 0 && !isAlarmOpen.value) {
currentRow.value = newMessages[newMessages?.length - 1];
currFileList.value = newMessages[newMessages?.length - 1]?.images;
isAlarmOpen.value = true;
}
}, { deep: true, immediate: true });
const getList = async (dateType: string = "month") => {
activeBtn.value = dateType
const res = await getDataOverviewApi({ dateType })
if (isSuccessApi(res)) {
const { data } = res
datas.value[0] = data.appearance
datas.value[1] = data.pole
if (dateType === "month") {
xData.value = data.dateArr.map((item: any) => {
if (dateType === 'month') {
return item + '月'
}
})
} else {
xData.value = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
}
// console.log(data, 'getList_data')
}
};
const getDeviceInfo = async () => {
try {
const res = await getDeviceInfowApi();
if (isSuccessApi(res)) {
const { data } = res;
deviceTotal.value = data.deviceTotal;
carDevice.value = data.appearance;
poleDevice.value = data.pole;
excavatorDevice.value = data.excavator;
// deviceStatus.value = data
}
} catch (error) {
console.error('获取设备信息出错:', error);
}
}
const getPoleFault = async () => {
try {
const res = await getRecordFaultApi({ dateType: 'month', value: searchForm.pole, type: "pole" });
if (isSuccessApi(res)) {
const { data } = res;
poleFaultTotal.value = data;
// deviceStatus.value = data
console.log(data);
}
} catch (error) {
console.error('获取设备信息出错:', error);
}
}
const getCarFault = async () => {
try {
const res = await getRecordFaultApi({ dateType: 'month', value: searchForm.car, type: "appearance" });
if (isSuccessApi(res)) {
const { data } = res;
carFaultTotal.value = data;
// deviceStatus.value = data
console.log(data);
}
} catch (error) {
console.error('获取设备信息出错:', error);
}
}
const getRealTime = async () => {
try {
const res = await getRealTimeApi({ deviceType: '' });
if (isSuccessApi(res)) {
const { data } = res;
imageFault.value = data;
// deviceStatus.value = data
console.log(data);
}
} catch (error) {
console.error('获取设备信息出错:', error);
}
}
onBeforeRouteLeave(() => {
isAlarmOpen.value = false;
currentRow.value = {};
currFileList.value = [];
});
6 months ago
onMounted(() => {
getList()
getDeviceInfo()
getCarFault()
getPoleFault()
getRealTime()
6 months ago
});
</script>
<style scoped lang="scss">
@import url("./DataOverview.scss");
</style>