234 lines
6.7 KiB
Vue
234 lines
6.7 KiB
Vue
<template>
|
||
<div class="container">
|
||
<el-row class="el-row" :gutter="20">
|
||
<el-col :span="6" class="el-row-left"
|
||
><DeviceInfo :deviceInfo="deviceInfo" :paging="devicePaging" :api="getdeviceList" :list="deviceData" @click="handelClickDevice"
|
||
/></el-col>
|
||
<el-col :span="18" class="el-row-right scrollbar">
|
||
<MonitoringTop :funcList="funcList" />
|
||
<div v-if="deviceInfo?.status == 2">
|
||
<div class="monitoringMap" id="mapcontainer"></div>
|
||
<el-row :gutter="20" style="margin-top: 20px">
|
||
<el-col :span="12">
|
||
<DeviceHistory @change="handelRadio">
|
||
<template #chart>
|
||
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
||
</template>
|
||
</DeviceHistory>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<DeviceRecord :deviceInfo="deviceInfo" />
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
<div v-else>
|
||
<el-row :gutter="20" style="margin-top: 20px">
|
||
<el-col :span="24" style="height: 400px">
|
||
<DeviceHistory @change="handelRadio">
|
||
<template #chart>
|
||
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
||
</template>
|
||
</DeviceHistory>
|
||
</el-col>
|
||
<el-col :span="24" style="margin-top: 20px">
|
||
<DeviceRecord :deviceInfo="deviceInfo" />
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</template>
|
||
<script lang="ts" setup>
|
||
import DeviceInfo from "./deviceInfo.vue";
|
||
import MonitoringTop from "./monitoringTop.vue";
|
||
import DeviceHistory from "./deviceHistory.vue";
|
||
import DeviceRecord from "./deviceRecord.vue";
|
||
import { MapCustom } from "@/utils/mapCustom";
|
||
import * as echarts from "echarts";
|
||
import { deviceList, healthLatestData, warningRecord, locateRecord } from "@/api/index";
|
||
import { TDevice, THealthLatestData } from "@/api/index.d";
|
||
import { onMounted, onDeactivated, ref, reactive, onUnmounted } from "vue";
|
||
import { debounce, format } from "@/utils";
|
||
import heart from "@/assets/img/heart.png";
|
||
import temperature from "@/assets/img/temperature.png";
|
||
import blood from "@/assets/img/blood.png";
|
||
import location from "@/assets/img/location.png";
|
||
|
||
const chartRef = ref(null);
|
||
let myChart = null;
|
||
let newMap = null;
|
||
let Interval = null;
|
||
let funcList = ref([
|
||
{ title: "当前心率", en: "DANGQIANXINLV", icon: heart, unit: "次/分", num: 0, color: "#FF0303" },
|
||
{ title: "当前血氧", en: "DANGQIANXUEYANG", icon: blood, unit: "%", num: 0, color: "#8B51FD" },
|
||
{ title: "当前体表温度", en: "DANGQIANTIBIAOWENDU", icon: temperature, unit: "次/分", num: 0, color: "#FF6905" },
|
||
]);
|
||
|
||
const options = {
|
||
tooltip: {
|
||
trigger: "axis",
|
||
formatter: function (params) {
|
||
let unit = { 心率: "次/分", 血氧: "%", 体表温度: "℃" };
|
||
var res = format(options.times[params[0].dataIndex]) + "<br/>";
|
||
res += params
|
||
.map(function (param, index) {
|
||
return param.marker + param.seriesName + ":" + param.value + unit[param.seriesName] + "<br/>";
|
||
})
|
||
.join("");
|
||
return res;
|
||
},
|
||
},
|
||
times: [],
|
||
xAxis: {
|
||
type: "category",
|
||
data: [],
|
||
},
|
||
grid: {
|
||
left: "5%",
|
||
right: "4%",
|
||
},
|
||
yAxis: {
|
||
type: "value",
|
||
},
|
||
series: {
|
||
name: "",
|
||
data: [],
|
||
type: "line",
|
||
showSymbol: false,
|
||
itemStyle: {
|
||
color: "#ff4567", // 设置线条颜色
|
||
},
|
||
smooth: true,
|
||
},
|
||
};
|
||
|
||
const devicePaging = reactive({
|
||
page: 1,
|
||
size: 10,
|
||
mode: undefined,
|
||
useStatus: 1,
|
||
});
|
||
const HealthData = ref<THealthLatestData.TRes>();
|
||
|
||
const deviceInfo = ref<TDevice.IListRes>();
|
||
const deviceData = ref<TDevice.IListRes[]>([]);
|
||
|
||
const getdeviceList = async () => {
|
||
const res = await deviceList(devicePaging);
|
||
deviceData.value = res.records;
|
||
if (res.records.length > 0) {
|
||
deviceInfo.value = res.records[0];
|
||
getHealthLatestData();
|
||
getLocateRecord();
|
||
IntervalFn();
|
||
}
|
||
};
|
||
|
||
const getHealthLatestData = () => {
|
||
healthLatestData({ deviceId: deviceInfo.value.deviceId }).then((res) => {
|
||
HealthData.value = res;
|
||
funcList.value[0].num = res.hr;
|
||
funcList.value[1].num = res.bo;
|
||
funcList.value[2].num = res.temp;
|
||
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
||
});
|
||
};
|
||
|
||
const handelRadio = (val: number) => {
|
||
if (val == 1) {
|
||
getOptionsData(HealthData.value.hrArr, "心率", "#FF0303");
|
||
} else if (val == 2) {
|
||
getOptionsData(HealthData.value.boArr, "血氧", "#983AFC");
|
||
} else if (val == 3) {
|
||
getOptionsData(HealthData.value.tempArr, "体表温度", "#FFA91F");
|
||
}
|
||
};
|
||
const getOptionsData = (list: { time: string; value: number }[], name: string, color: string) => {
|
||
options.xAxis.data = [];
|
||
options.series.data = [];
|
||
if (list && list.length) {
|
||
list.forEach((item) => {
|
||
options.times.push(item.time);
|
||
options.xAxis.data.push(format(item.time, "HH:mm:ss"));
|
||
options.series.data.push(item.value);
|
||
});
|
||
options.series.name = name;
|
||
options.series.itemStyle.color = color;
|
||
}
|
||
|
||
myChart.setOption(options);
|
||
};
|
||
const getLocateRecord = () => {
|
||
let d = new Date();
|
||
locateRecord({
|
||
deviceId: deviceInfo.value.deviceId,
|
||
startDate: `${format(d, "YYYY-MM-DD")} 00:00:00`,
|
||
endDate: `${format(d, "YYYY-MM-DD")} 23:59:59`,
|
||
}).then((res) => {
|
||
if (res && res.length) {
|
||
let list = res;
|
||
newMap.clearMap();
|
||
newMap.setCenter([list[0].lng, list[0].lat]);
|
||
newMap.polyline(list);
|
||
let icon = newMap.newIcon(location);
|
||
list.forEach((item) => {
|
||
let marker = newMap.marker({ icon, position: [item.lng, item.lat] });
|
||
marker.setMap(newMap.map);
|
||
});
|
||
}
|
||
});
|
||
};
|
||
const handleResize = debounce(() => {
|
||
myChart.resize();
|
||
}, 200);
|
||
const IntervalFn = () => {
|
||
Interval = setInterval(() => {
|
||
getHealthLatestData();
|
||
getLocateRecord();
|
||
}, 60000);
|
||
};
|
||
const handelClickDevice = (val: TDevice.IListRes) => {
|
||
deviceInfo.value = val;
|
||
getHealthLatestData();
|
||
getLocateRecord();
|
||
};
|
||
onMounted(() => {
|
||
getdeviceList();
|
||
newMap = new MapCustom({ dom: "mapcontainer" });
|
||
if (chartRef.value) {
|
||
myChart = echarts.init(chartRef.value);
|
||
window.addEventListener("resize", handleResize);
|
||
}
|
||
});
|
||
onUnmounted(() => {
|
||
clearInterval(Interval);
|
||
window.removeEventListener("resize", handleResize);
|
||
});
|
||
</script>
|
||
<style scoped lang="less">
|
||
.container {
|
||
overflow: hidden;
|
||
display: flex;
|
||
.el-row {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
display: flex;
|
||
.el-row-left {
|
||
height: 100%;
|
||
display: flex;
|
||
overflow: hidden;
|
||
}
|
||
.el-row-right {
|
||
height: 100%;
|
||
overflow: auto;
|
||
}
|
||
}
|
||
}
|
||
.monitoringMap {
|
||
width: 100%;
|
||
height: 400px;
|
||
margin-top: 20px;
|
||
}
|
||
</style>
|