<script setup name="home">
|
import { ref, reactive, watch, computed, onMounted } from "vue";
|
import ycCard from "@/components/ycCard.vue";
|
import groupBar from "@/components/echarts/groupBar.vue";
|
import pie from "@/components/echarts/pie.vue";
|
import bar from "@/components/echarts/bar.vue";
|
import lineChart from "@/components/echarts/lineChart.vue";
|
import mapChart from "@/components/echarts/mapChart.vue";
|
import ledNum from "@/components/ledNum.vue";
|
import useWebSocket from "@/hooks/useWebSocket";
|
import IconDot from "@/components/icons/IconDot.vue";
|
|
const { message } = useWebSocket("staticSocket");
|
|
const devBar = ref();
|
const alarmPie = ref();
|
const testBar = ref();
|
const jhTestBar = ref();
|
const testLine = ref();
|
const alarmType = ref(0);
|
const devType = ref(0);
|
const jhTestType = ref(0);
|
const ytjTestType = ref(0);
|
const map = ref();
|
|
const devDatas = computed(() => {
|
let labels = ["充放电一体机", "锂电池均衡仪"],
|
datas = [
|
{ name: "在线", data: [] },
|
{ name: "离线", data: [] },
|
],
|
devs = [],
|
ytjCount = 0,
|
jhyCount = 0,
|
onLineCount = 0,
|
offLineCount = 0;
|
if (message.value) {
|
const {
|
code,
|
data2: {
|
devSatic: { dinf, state, type },
|
},
|
} = JSON.parse(message.value);
|
|
datas[0].data.push(state["a200"][1], state["actm"][1]);
|
datas[1].data.push(state["a200"][0], state["actm"][0]);
|
ytjCount = type[1];
|
jhyCount = type[2];
|
onLineCount = state["actm"][1] + state["a200"][1];
|
offLineCount = state["actm"][0] + state["a200"][0];
|
devs = dinf;
|
}
|
return { labels, datas, ytjCount, jhyCount, onLineCount, offLineCount, devs };
|
});
|
|
const weekTestDatas = computed(() => {
|
let jhyData = [
|
{ name: "充电测试", data: [] },
|
{ name: "放电测试", data: [] },
|
],
|
ytjData = [
|
{ name: "充电测试", data: [] },
|
{ name: "放电测试", data: [] },
|
],
|
dates = [];
|
if (message.value) {
|
const {
|
code,
|
data2: {
|
devTestByWeek: { actm, a200 },
|
},
|
} = JSON.parse(message.value);
|
Object.keys(actm).sort((a, b)=>{
|
return new Date(a).getTime() - new Date(b).getTime();
|
}).forEach((v) => {
|
let item = actm[v];
|
// 2 放电 3充电
|
jhyData[0].data.push(item[3]);
|
jhyData[1].data.push(item[2]);
|
|
dates.push(v);
|
});
|
Object.keys(a200).sort((a,b) => {
|
return new Date(a).getTime() - new Date(b).getTime();
|
}).forEach((v) => {
|
let item = a200[v];
|
// 2 放电 3充电
|
ytjData[0].data.push(item[3]);
|
ytjData[1].data.push(item[2]);
|
});
|
|
}
|
return { jhyData, ytjData, dates };
|
});
|
|
const testDatas = computed(() => {
|
// 2 放电 3 充电
|
let labels = ["放电测试", "充电测试"],
|
ytjMonthData = [],
|
ytjYearData = [],
|
jhyMonthData = [],
|
jhyYearData = [];
|
if (message.value) {
|
const {
|
code,
|
data2: {
|
devTinf: { actmMap, a200Map },
|
},
|
} = JSON.parse(message.value);
|
|
ytjMonthData.push(a200Map["a200MonthMap"][2], a200Map["a200MonthMap"][3]);
|
ytjYearData.push(a200Map["a200YearMap"][2], a200Map["a200YearMap"][3]);
|
jhyMonthData.push(actmMap["actmMonthMap"][2], actmMap["actmMonthMap"][3]);
|
jhyYearData.push(actmMap["actmYearMap"][2], actmMap["actmYearMap"][3]);
|
}
|
return {
|
labels,
|
ytjMonthData,
|
ytjYearData,
|
jhyMonthData,
|
jhyYearData,
|
};
|
});
|
function updateDevBar(params) {
|
devBar.value.updateChart(devDatas.value.labels, devDatas.value.datas);
|
}
|
function updateTestLine() {
|
let datas =
|
devType.value == 0
|
? weekTestDatas.value.ytjData
|
: weekTestDatas.value.jhyData;
|
testLine.value?.updateChart(weekTestDatas.value.dates, datas);
|
}
|
function updateYtjTest() {
|
let datas =
|
ytjTestType.value == 0
|
? testDatas.value.ytjMonthData
|
: testDatas.value.ytjYearData;
|
testBar.value?.updateChart(testDatas.value.labels, datas);
|
}
|
function updateJhTest() {
|
let datas =
|
jhTestType.value == 0
|
? testDatas.value.jhyMonthData
|
: testDatas.value.jhyYearData;
|
jhTestBar.value?.updateChart(testDatas.value.labels, datas);
|
}
|
function updateMap() {
|
const getColor = (onLine) => ["#aaa", "#0f0"][onLine];
|
let data = devDatas.value.devs;
|
map.value.updateChart(
|
data.map((v) => {
|
return {
|
...v,
|
label: v.devIdcode,
|
color: getColor(v.devOnline),
|
points: [v.longitude, v.latitude],
|
// 无实际意义
|
value: 100,
|
};
|
})
|
);
|
}
|
|
watch(message, () => {
|
updateTestLine();
|
updateYtjTest();
|
updateJhTest();
|
updateDevBar();
|
updateMap();
|
});
|
|
|
onMounted(() => {
|
setTimeout(() => {
|
alarmPie.value.updateChart([
|
{
|
name: "充放电一体机",
|
value: 0,
|
},
|
{
|
name: "锂电池均衡仪",
|
value: 0,
|
},
|
]);
|
}, 500);
|
});
|
</script>
|
|
<template>
|
<div class="page-home grid">
|
<yc-card class="item" title="设备状态统计">
|
<group-bar ref="devBar" unit="台"></group-bar>
|
</yc-card>
|
<yc-card class="item large">
|
<div class="card-content">
|
<div class="info">
|
<div class="info-item">
|
<div class="label">充放电一体机</div>
|
<div class="value">
|
<led-num :bits="4" :num="devDatas.ytjCount"></led-num>
|
</div>
|
<div class="unit">台</div>
|
</div>
|
<div class="info-item">
|
<div class="label">锂电池均衡仪</div>
|
<div class="value">
|
<led-num :bits="4" :num="devDatas.jhyCount"></led-num>
|
</div>
|
<div class="unit">台</div>
|
</div>
|
</div>
|
<div class="wrap-chart">
|
<map-chart ref="map" @mapMounted="updateMap">
|
<template #tools>
|
<div class="map-mark">
|
<div class="mark online">
|
<el-icon class="ico"><icon-dot /></el-icon>在线
|
<div class="count">{{ devDatas.onLineCount }}</div>
|
</div>
|
<div class="mark offline">
|
<el-icon class="ico"><icon-dot /></el-icon>离线
|
<div class="count">{{ devDatas.offLineCount }}</div>
|
</div>
|
</div>
|
</template>
|
</map-chart>
|
</div>
|
</div>
|
</yc-card>
|
<!-- <yc-card class="item" title="设备历史告警统计">
|
<template #tools>
|
<el-radio-group v-model="alarmType" size="small" is-button>
|
<el-radio-button :value="0">本月</el-radio-button>
|
<el-radio-button :value="1">本年</el-radio-button>
|
</el-radio-group>
|
</template>
|
<pie ref="alarmPie"></pie>
|
</yc-card> -->
|
<yc-card class="item" title="充放电一体机测试统计">
|
<template #tools>
|
<el-radio-group
|
v-model="ytjTestType"
|
@change="updateYtjTest"
|
size="small"
|
is-button
|
>
|
<el-radio-button :value="0">本月</el-radio-button>
|
<el-radio-button :value="1">本年</el-radio-button>
|
</el-radio-group>
|
</template>
|
<bar ref="testBar" unit="次"></bar>
|
</yc-card>
|
<yc-card class="item" title="近一周电池测试趋势统计">
|
<template #tools>
|
<el-radio-group
|
v-model="devType"
|
@change="updateTestLine"
|
size="small"
|
is-button
|
>
|
<el-radio-button :value="0">充放电一体机</el-radio-button>
|
<el-radio-button :value="1">锂电均衡仪</el-radio-button>
|
</el-radio-group>
|
</template>
|
<line-chart ref="testLine" unit="次"></line-chart>
|
</yc-card>
|
<yc-card class="item" title="锂电均衡仪测试统计">
|
<template #tools>
|
<el-radio-group
|
v-model="jhTestType"
|
@change="updateJhTest"
|
size="small"
|
is-button
|
>
|
<el-radio-button :value="0">本月</el-radio-button>
|
<el-radio-button :value="1">本年</el-radio-button>
|
</el-radio-group>
|
</template>
|
<bar ref="jhTestBar" unit="次"></bar>
|
</yc-card>
|
</div>
|
</template>
|
|
<style scoped lang="less">
|
.page-home {
|
height: 100%;
|
padding: 6px;
|
}
|
.grid {
|
display: grid;
|
grid-template-rows: 1fr 1fr;
|
grid-template-columns: 1fr 1.6fr 1fr;
|
gap: 6px;
|
.item {
|
// background: gray;
|
&.large {
|
grid-row-start: span 2;
|
}
|
}
|
}
|
.card-content {
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
.info {
|
padding-top: 8px;
|
display: flex;
|
.info-item {
|
flex: 1;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
.label {
|
color: #0ff;
|
font-size: 16px;
|
margin-right: 0.4em;
|
&::after {
|
content: ":";
|
}
|
}
|
.value {
|
height: 38px;
|
}
|
.unit {
|
font-size: 14px;
|
align-self: flex-end;
|
margin-left: 0.6em;
|
}
|
}
|
}
|
.wrap-chart {
|
flex: 1;
|
// position: relative;
|
}
|
|
.map-mark {
|
position: absolute;
|
right: 10px;
|
bottom: 10px;
|
.mark {
|
display: flex;
|
align-items: center;
|
.ico {
|
font-size: 14px;
|
margin-right: 0.4em;
|
}
|
.count {
|
margin-left: 1em;
|
}
|
&.online {
|
color: #0f0;
|
}
|
&.offline {
|
color: #aaa;
|
}
|
}
|
}
|
}
|
</style>
|