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.

361 lines
11 KiB
Vue

6 months ago
<script lang="ts" setup>
import * as echarts from "echarts";
import TotalChart from "@/components/Charts/totalChart.vue";
import PoleMonitorChart from "@/components/Charts/poleMonitorChart.vue";
import VehicleMonitorChart from "@/components/Charts/vehicleMonitorChart.vue";
import HomeSubTitle from "@/components/HeaderBar/homeSubTitle.vue";
import DeviceStatus from "./components/DeviceStatus.vue";
import car_device_icon from "@/assets/home/car_device_icon.png";
import pole_device_icon from "@/assets/home/pole_device_icon.png";
import excavator_device_icon from "@/assets/home/excavator_device_icon.png";
import {
getDataOverviewApi,
getDeviceInfowApi,
getRecordFaultApi,
getRealTimeApi,
} from "@/api/dashboard";
import { isSuccessApi } from "@/utils/forApi";
import { isArray } from "@/utils/is";
import AlarmModal from "./components/AlarmModal.vue";
import { dataViewConfig } from "@/config/dataView";
import { useWebSocketStore } from "@/stores/websocketStore";
import { onBeforeRouteLeave } from "vue-router";
defineOptions({
name: "DataOverviewWrap",
});
// TODO 需要转移到mock中
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 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 deviceInfo = reactive({
list: [
{
name: "车体检测设备",
bindVal: {
total: 0,
},
icon: car_device_icon,
},
{
name: "撑杆检测设备",
bindVal: {
total: 0,
},
icon: pole_device_icon,
},
{
name: "钩机检测设备",
bindVal: {
total: 0,
},
icon: excavator_device_icon,
},
],
});
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;
deviceInfo.list = [
{
name: "车体检测设备",
bindVal: data?.appearance,
icon: car_device_icon,
},
{
name: "撑杆检测设备",
bindVal: data?.pole,
icon: pole_device_icon,
},
{
name: "钩机检测设备",
bindVal: data?.excavator,
icon: excavator_device_icon,
},
];
}
} catch (error) {
console.error("获取设备信息出错:", error);
}
};
const fetchPoleMonitorData = 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 fetchTrainMonitorData = 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;
if (isArray(data)) {
// TODO 暂时使用接口图重复填充
imageFault.value = data.concat(data).concat(data).splice(0, 4);
}
// 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();
fetchTrainMonitorData();
fetchPoleMonitorData();
getRealTime();
6 months ago
});
</script>
<template>
<div class="flex data-overview-wrap">
<!-- 检测总量汇总 -->
<div class="grid-container">
<div class="grid-item">
<div class="module-header">
<HomeSubTitle title="检测总量汇总">
<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>
</HomeSubTitle>
</div>
<div class="chart-container">
<TotalChart
:xData="xData"
:legendArr="legendArr"
:datas="datas"
:colorArr="colorArr"
/>
</div>
</div>
<div class="grid-item">
<div class="module-header">
<HomeSubTitle title="车体监测">
<template #extra>
<div class="flex items-center text-[14px] px-[16px]">
<span>时间</span>
<el-select
v-model="searchForm.pole"
placeholder="时间"
class="custom-select mini-size"
@change="fetchPoleMonitorData()"
>
<el-option
v-for="v in dataViewConfig.monthArr"
:key="v?.value"
:label="v?.name"
:value="v?.value"
></el-option>
</el-select>
</div>
</template>
</HomeSubTitle>
</div>
<div class="chart-container chart-pie-bg">
<!-- <PieChart :data="carFaultTotal" :colors="[
'#FF7C09',
'#0032FF',
'#04FFF2',
'#D19EFF',
'#FF0103',
'#9EFFF3',
]" /> -->
<VehicleMonitorChart />
</div>
</div>
<div class="grid-item">
<div class="module-header">
<HomeSubTitle title="撑杆监测">
<template #extra>
<div class="flex items-center text-[14px] px-[16px]">
<span>时间</span>
<el-select
v-model="searchForm.pole"
placeholder="时间"
class="custom-select mini-size"
@change="fetchPoleMonitorData()"
>
<el-option
v-for="v in dataViewConfig.monthArr"
:key="v?.value"
:label="v?.name"
:value="v?.value"
></el-option>
</el-select>
</div>
</template>
</HomeSubTitle>
</div>
<div class="chart-container chart-pie-bg">
<PoleMonitorChart />
<!-- <PieChartSmall :data="poleFaultTotal" :colors="['#9DFFF3', '#FFA179']" /> -->
</div>
</div>
</div>
<!-- 中部检测模块 -->
<div class="realTime-monitor-box">
<div class="w-full h-[35px] fg-title px-[16px] py-[20px]">
实时监测画面
</div>
<ul class="flex monitor-images">
<li class="monitor-images-item" v-for="(v, i) in imageFault" :key="i">
<img :src="v?.url" />
<div class="fault-info">{{ v?.fault_type }}</div>
</li>
</ul>
</div>
<!-- 设备信息 -->
<div class="device-info-box">
<div class="module-header">
<HomeSubTitle title="设备信息"> </HomeSubTitle>
</div>
<div class="device-info">
<div class="flex items-center justify-center total-device">
<div class="device-total-icon mt-[24px]"></div>
<div class="device-count ml-[24px]">
<div class="fg-mark1 text-[32px] font-bold">
{{ deviceTotal }}
</div>
<div class="text-[14px]">设备总数</div>
</div>
</div>
<ul class="device-list">
<li class="device-card" v-for="(v, k) in deviceInfo.list" :key="k">
<div
class="device-card-head text-[16px] flex items-center mb-[12px]"
>
<img :src="v.icon" alt="" class="w-[32px]" />
<span class="ml-[12px]">{{ v.name }}</span>
<span class="font-bold">{{ v.bindVal?.total || 0 }}</span>
</div>
<!-- //TODO 使用echarts重构 https://echarts.zhangmuchen.top/#/detail?cid=164bb-40c1-e483-b7c9b-6cb171ad -->
<DeviceStatus :deviceStatus="v.bindVal" />
</li>
</ul>
</div>
</div>
<AlarmModal
v-model:value="isAlarmOpen"
:info="currentRow"
:image="currFileList"
@close="isAlarmOpen = false"
/>
</div>
</template>
6 months ago
<style scoped lang="scss">
@import url("./DataOverview.scss");
</style>