| | |
| | | <script setup name="home"> |
| | | import { ref } from "vue"; |
| | | 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]; |
| | | // 3 放电 2充电 |
| | | jhyData[0].data.push(item[2]); |
| | | jhyData[1].data.push(item[3]); |
| | | |
| | | dates.push(v); |
| | | }); |
| | | Object.keys(a200).sort((a,b) => { |
| | | return new Date(a).getTime() - new Date(b).getTime(); |
| | | }).forEach((v) => { |
| | | let item = a200[v]; |
| | | // 3 放电 2充电 |
| | | ytjData[0].data.push(item[2]); |
| | | ytjData[1].data.push(item[3]); |
| | | }); |
| | | |
| | | } |
| | | return { jhyData, ytjData, dates }; |
| | | }); |
| | | |
| | | const testDatas = computed(() => { |
| | | // 3 放电 2 充电 |
| | | let labels_yt = ["放电测试", "充电测试"], |
| | | labels_jh = ["放电", "充电", '均衡'], |
| | | ytjMonthData = [], |
| | | ytjYearData = [], |
| | | jhyMonthData = [], |
| | | jhyYearData = []; |
| | | if (message.value) { |
| | | const { |
| | | code, |
| | | data2: { |
| | | devTinf: { actmMap, a200Map }, |
| | | }, |
| | | } = JSON.parse(message.value); |
| | | |
| | | ytjMonthData.push(a200Map["a200MonthMap"][3], a200Map["a200MonthMap"][2]); |
| | | ytjYearData.push(a200Map["a200YearMap"][3], a200Map["a200YearMap"][2]); |
| | | jhyMonthData.push(actmMap["actmMonthMap"][3], actmMap["actmMonthMap"][2], actmMap["actmMonthMap"][4]); |
| | | jhyYearData.push(actmMap["actmYearMap"][3], actmMap["actmYearMap"][2], actmMap["actmYearMap"][4]); |
| | | } |
| | | return { |
| | | labels_jh, |
| | | labels_yt, |
| | | 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_yt, datas); |
| | | } |
| | | function updateJhTest() { |
| | | let datas = |
| | | jhTestType.value == 0 |
| | | ? testDatas.value.jhyMonthData |
| | | : testDatas.value.jhyYearData; |
| | | jhTestBar.value?.updateChart(testDatas.value.labels_jh, 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"> |
| | | <div class="item"> |
| | | 设备状态统计 |
| | | <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> |
| | | <div class="item"> |
| | | 充放电一体机 |
| | | 锂电池均衡仪 |
| | | </div> |
| | | <div class="item"> |
| | | 设备历史告警统计 |
| | | </div> |
| | | <div class="item"> |
| | | 充放电一体机测试统计 |
| | | </div> |
| | | <div class="item"> |
| | | 近一周电池测试趋势统计 |
| | | </div> |
| | | <div class="item"> |
| | | 锂电均衡仪测试统计 |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="less"> |
| | |
| | | grid-template-columns: 1fr 1.6fr 1fr; |
| | | gap: 6px; |
| | | .item { |
| | | |
| | | // background: gray; |
| | | &.large { |
| | | grid-row-start: span 2; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | .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> |