<template>
|
<div class="p-main">
|
<div class="left flex-c">
|
<div class="row">
|
<card>
|
<big-screen-card title="电池类型">
|
<battery-pie-chart ref="batteryChart"></battery-pie-chart>
|
</big-screen-card>
|
</card>
|
</div>
|
<div class="row">
|
<card>
|
<big-screen-card title="设备工作状态">
|
<div class="dev-wrap">
|
<circle-box
|
class="item"
|
:type="0"
|
:value="workState[0]"
|
@click.native="goDevWorkState(4)"
|
></circle-box>
|
<circle-box
|
ref="devWorkState1"
|
class="item"
|
:type="1"
|
:value="workState[1]"
|
@click.native="goDevWorkState(2)"
|
></circle-box>
|
<circle-box
|
ref="devWorkState2"
|
class="item"
|
:type="2"
|
:value="workState[2]"
|
@click.native="goDevWorkState(0)"
|
></circle-box>
|
<circle-box
|
ref="devWorkState3"
|
class="item"
|
:type="3"
|
:value="workState[3]"
|
@click.native="goDevAlarm"
|
></circle-box>
|
</div>
|
</big-screen-card>
|
</card>
|
</div>
|
<div class="row">
|
<card>
|
<big-screen-card title="整组容量">
|
<div class="mon-box-container">
|
<div class="mon-info-box">
|
<div class="mon-info-title">大于95%比例:</div>
|
<div class="mon-info-value">{{ cap.level0 }}</div>
|
</div>
|
<div class="mon-info-box box2">
|
<div class="mon-info-title">95%~85%比例:</div>
|
<div class="mon-info-value">{{ cap.level1 }}</div>
|
</div>
|
<div class="mon-info-box box3">
|
<div class="mon-info-title">85%~60%比例:</div>
|
<div class="mon-info-value">{{ cap.level2 }}</div>
|
</div>
|
</div>
|
<div class="mon-box-container mgt16">
|
<div class="mon-info-box box2">
|
<div class="mon-info-title">60%~50%比例:</div>
|
<div class="mon-info-value">{{ cap.level3 }}</div>
|
</div>
|
<div class="mon-info-box box3">
|
<div class="mon-info-title">小于50%:</div>
|
<div class="mon-info-value">{{ cap.level4 }}</div>
|
</div>
|
</div>
|
</big-screen-card>
|
</card>
|
</div>
|
</div>
|
<div class="center flex-c">
|
<div class="row row1">
|
<card :miniCor="true">
|
<div class="info">
|
<div class="item" @click="goStations">
|
<div class="name">站点</div>
|
<div class="num">
|
<led-num color="#f00" :num="stationNum"></led-num>
|
</div>
|
</div>
|
<div class="item">
|
<div class="name">设备</div>
|
<div class="num">
|
<led-num color="#f00" :num="devCount"></led-num>
|
</div>
|
</div>
|
<div class="item" @click="goBatt">
|
<div class="name">电池组</div>
|
<div class="num">
|
<led-num color="#f00" :num="battGroupCount"></led-num>
|
</div>
|
</div>
|
</div>
|
</card>
|
</div>
|
<div class="row row2">
|
<card :inside="false">
|
<div class="flex-map-contain">
|
<div class="inner">
|
<map-chart ref="map">
|
<map-mark-list slot="tools"></map-mark-list>
|
</map-chart>
|
</div>
|
</div>
|
</card>
|
</div>
|
<div class="row">
|
<card>
|
<big-screen-card title="实时放电信息">
|
<div class="scroller-wrap">
|
<div class="inner">
|
<el-table
|
ref="elTbl"
|
stripe
|
size="small"
|
:data="tbl.data"
|
height="100%"
|
:row-class-name="
|
(row) =>
|
row.deviceWorkState == 3
|
? 'power-off cursor-pointer'
|
: 'cursor-pointer'
|
"
|
@row-dblclick="goRealTime"
|
class="tableCent"
|
>
|
<el-table-column
|
v-for="header in tbl.headers"
|
:key="header.prop"
|
:prop="header.prop"
|
:label="header.label"
|
:width="header.width"
|
:min-width="header.minWidth"
|
:sortable="header.sortable"
|
align="center"
|
></el-table-column>
|
<el-table-column label="操作" width="110" align="center">
|
<template slot-scope="scope">
|
<el-button
|
type="primary"
|
size="mini"
|
@click="goRealTime(scope.row)"
|
>实时</el-button
|
>
|
</template>
|
</el-table-column>
|
</el-table>
|
<!-- <div class="empty-msg" v-else>最近一周无记录</div> -->
|
</div>
|
</div>
|
</big-screen-card>
|
</card>
|
</div>
|
</div>
|
<div class="right flex-c">
|
<div class="row" v-show="isShowPower">
|
<card>
|
<big-screen-card title="电源品牌">
|
<!-- <pie3d ref="powerChart"></pie3d>-->
|
<power-pie-chart ref="powerChart"></power-pie-chart>
|
</big-screen-card>
|
</card>
|
</div>
|
<div class="row">
|
<card>
|
<big-screen-card title="测试信息">
|
<template #tools>
|
<!-- :disabled="!chartData.test.length" -->
|
<el-radio-group
|
size="mini"
|
@input="testLevelChange"
|
v-model="testLevel"
|
>
|
<el-radio-button :label="0">本月</el-radio-button>
|
<el-radio-button :label="1">本季度</el-radio-button>
|
<el-radio-button :label="2">本年</el-radio-button>
|
</el-radio-group>
|
</template>
|
<bar3d ref="bar3d"></bar3d>
|
</big-screen-card>
|
</card>
|
</div>
|
<div class="row">
|
<card>
|
<big-screen-card title="告警统计">
|
<template #tools>
|
<el-radio-group
|
size="mini"
|
v-model="alarmType"
|
@input="alarmTypeChangede"
|
>
|
<el-radio-button :label="0">告警类型</el-radio-button>
|
<el-radio-button :label="1">告警等级</el-radio-button>
|
</el-radio-group>
|
</template>
|
<div class="chart-wrap">
|
<div class="inner">
|
<bar-chart-alarm
|
v-if="alarmType == 1"
|
ref="chart_alarm"
|
></bar-chart-alarm>
|
<pie-chart
|
ref="alarmPieChart"
|
:values="alarms"
|
v-else
|
></pie-chart>
|
</div>
|
</div>
|
</big-screen-card>
|
</card>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import card from "./components/card-corner";
|
import BigScreenCard from "@/components/bigScreenPage/big_screen_card.vue";
|
import BatteryPieChart from "@/components/myCharts/BatteryPieChart.vue";
|
import MapChart from "@/components/myCharts/MapChart.vue";
|
import MapMarkList from "@/components/mapMarkList.vue";
|
import pie3d from "./components/pie3d";
|
import bar3d from "./components/bar-3d";
|
import circleBox from "./components/circle.vue";
|
import BarChart from "@/components/myCharts/BarChart.vue";
|
import LedNum from "@/components/ledNum";
|
import pieChart from "./components/pieCharts";
|
import BarChartAlarm from "./components/batt-chart-alarm";
|
import PowerPieChart from "@/components/myCharts/PieRoseChart.vue";
|
|
import createWs from "@/assets/js/websocket";
|
import { sethoubeiTime, formatSeconds } from "@/assets/js/tools";
|
const WSMixin = createWs("screen_km");
|
|
export default {
|
name: "",
|
mixins: [WSMixin],
|
data() {
|
return {
|
isShowPower: true,
|
otherPwrProd: [],
|
testData: [],
|
alarmData: [[], [], []],
|
testLevel: 2,
|
workState: [0, 0, 0, 0],
|
nxType: 0,
|
alarmType: 0,
|
alarms: [0, 0, 0],
|
devCount: 0,
|
stationNum: 0,
|
battGroupCount: 0,
|
cap: {
|
level0: 0,
|
level1: 0,
|
level2: 0,
|
level3: 0,
|
level4: 0,
|
},
|
tbl: {
|
headers: [
|
// {
|
// prop: "stationArea",
|
// label: "区域",
|
// minWidth: 260,
|
// sortable: false,
|
// },
|
{
|
prop: "stationName3",
|
label: "站点",
|
minWidth: 160,
|
sortable: false,
|
},
|
{
|
prop: "battTestStarttime",
|
label: "放电开始时间",
|
minWidth: 160,
|
sortable: false,
|
},
|
{
|
prop: "battTestTimelong",
|
label: "已放电时长",
|
minWidth: 110,
|
},
|
{
|
prop: "xuhang",
|
label: "预估续航时长",
|
minWidth: 110,
|
},
|
],
|
data: [],
|
},
|
};
|
},
|
components: {
|
card,
|
BigScreenCard,
|
BatteryPieChart,
|
MapChart,
|
MapMarkList,
|
circleBox,
|
BarChart,
|
pie3d,
|
LedNum,
|
pieChart,
|
BarChartAlarm,
|
bar3d,
|
PowerPieChart,
|
},
|
methods: {
|
alarmTypeChangede(value) {
|
if (!value) {
|
this.$nextTick(() => {
|
this.$refs.alarmPieChart.update();
|
});
|
} else {
|
this.$nextTick(() => {
|
this.$refs.chart_alarm.setData(this.alarmData);
|
});
|
}
|
},
|
onWSMessage(res) {
|
res = JSON.parse(res.data);
|
// console.log(res, "=====111data");
|
let {
|
devStates,
|
stationCount,
|
battGroupInfo,
|
powerProducerCount,
|
devCountMap,
|
resTestdataInfAnalysis,
|
groupCap,
|
alarmsLevel,
|
dischargingBattery,
|
} = res.data;
|
// 站点数量统计更新
|
this.updateSiteDev(devCountMap);
|
// 更新设备工作状态
|
this.updateWorkState(devStates);
|
// 更新整组容量
|
this.updateGroupCap(groupCap);
|
// 电池类型
|
this.updateBattInfo(battGroupInfo);
|
// 电源品牌
|
this.updatePowerProd(powerProducerCount);
|
// 测试信息
|
this.updateTestData(resTestdataInfAnalysis);
|
// 更新地图
|
this.updateMap(devCountMap);
|
// 更新告警统计
|
this.updateAlarms(alarmsLevel);
|
// 实时放电信息
|
this.updateDischargeInfo(dischargingBattery);
|
},
|
updateSiteDev(data) {
|
const { devCount, stationNum, battGroupCount } = data.data2;
|
this.devCount = devCount;
|
this.stationNum = stationNum;
|
this.battGroupCount = battGroupCount;
|
},
|
updateWorkState(data) {
|
data = data.data2;
|
this.workState = [
|
data["内阻测试数量"],
|
data["核容测试数量"],
|
data["直连充电数量"],
|
data["通讯故障数量"],
|
];
|
},
|
updateGroupCap(obj) {
|
const { code, data, data3 } = obj;
|
let level0 = 0,
|
level1 = 0,
|
level2 = 0,
|
level3 = 0,
|
level4 = 0;
|
if (code && data) {
|
level0 = data3[1];
|
level1 = data3[2];
|
level2 = data3[3];
|
level3 = data3[4];
|
level4 = data3[5];
|
}
|
this.cap.level0 = level0;
|
this.cap.level1 = level1;
|
this.cap.level2 = level2;
|
this.cap.level3 = level3;
|
this.cap.level4 = level4;
|
},
|
// 电池统计
|
updateBattInfo(obj) {
|
let { code, data, data2 } = obj;
|
let vol2 = 0,
|
vol12 = 0,
|
producer = [{ name: "电池品牌", value: 0 }];
|
if (code && data) {
|
vol2 = data2.monVol["2.0"];
|
vol12 = data2.monVol["12.0"];
|
let arr = Object.keys(data2.producer)
|
.map((v) => ({ name: v, value: data2.producer[v] }))
|
.sort((a, b) => b.value - a.value);
|
if (arr.length <= 5) {
|
producer = arr;
|
} else {
|
let name = "其他";
|
let value = 0;
|
arr.splice(4).forEach((v) => {
|
value += v.value * 1;
|
});
|
arr.push({ name, value });
|
producer = arr;
|
}
|
}
|
this.$refs.batteryChart.setData(vol2, vol12, producer);
|
},
|
// 电源品牌
|
updatePowerProd(obj) {
|
let power = obj.data2.data;
|
let res = { sData: [] };
|
|
let arr = Object.keys(power)
|
.map((v) => ({ name: v, value: power[v] }))
|
.sort((a, b) => {
|
return b.value - a.value;
|
});
|
|
let total = 0;
|
arr.map((v) => {
|
total += v.value * 1;
|
});
|
|
this.otherPwrProd = [];
|
if (arr.length <= 5) {
|
res.sData = arr;
|
} else {
|
let name = "其他";
|
let value = 0;
|
// let otherList = [];
|
arr.splice(4).forEach((v) => {
|
value += v.value * 1;
|
this.otherPwrProd.push(v.name);
|
// let percent = (total ? v.value / total : 0).toHold(4);
|
// otherList.push({
|
// name: v.name,
|
// value: v.value,
|
// percent: (percent * 100).toHold(2) + "%",
|
// });
|
});
|
|
// this.otherPwrProd = otherList;
|
|
res.sData = arr;
|
res.sData.push({ name, value });
|
}
|
let total_datas = 0;
|
res.sData.map((item) => {
|
total_datas += item.value;
|
});
|
const option = {
|
title: {
|
show: true,
|
text: "总数",
|
subtext: total_datas,
|
textStyle: {
|
color: "#f2f2f2",
|
fontSize: 20,
|
align: "center",
|
},
|
subtextStyle: {
|
fontSize: 18,
|
color: ["#ff9d19"],
|
},
|
x: "center",
|
y: "center",
|
},
|
series: [
|
{
|
name: "电源品牌",
|
data: res.sData,
|
},
|
],
|
};
|
|
// 存在电源品牌显示电源品牌图形
|
if (total) {
|
this.isShowPower = true;
|
} else {
|
this.isShowPower = false;
|
}
|
|
this.$nextTick(() => {
|
this.$refs.bar3d?.resize();
|
this.$refs.chart_alarm?.resize();
|
this.$refs.alarmPieChart?.resize();
|
});
|
this.$refs.powerChart.setData(option);
|
},
|
updateTestData(obj) {
|
const { month, year, quarter } = obj.data2;
|
let test = [];
|
[month, quarter, year].forEach((item) => {
|
test.push({
|
// xLabel: ["核容放电", "核容充电", "监测放电", "监测充电", "停电放电"],
|
xLabel: ["核容放电", "核容充电", "监测放电", "监测充电"],
|
sData: [
|
item.hrdisNum,
|
item.hrchNum,
|
item.jcdisNum,
|
item.jcchNum,
|
// item.dddisNum,
|
],
|
});
|
});
|
this.testData = test;
|
this.$refs.bar3d.setData(test[this.testLevel]);
|
},
|
testLevelChange(value) {
|
this.$refs.bar3d.setData(this.testData[value]);
|
},
|
// 更新地图
|
updateMap(obj) {
|
let data = obj.data2.stationInfList;
|
const getColor = (o) => {
|
let res = 0;
|
res = o.devWorkState <= 3 ? o.devWorkState : 0;
|
return ["#0081ff", "#66f842", "#ff6b6c", "#7668f9"][res];
|
};
|
this.$refs.map.setData(
|
data.map((v) => {
|
return {
|
...v,
|
label: v.stationName3,
|
color: getColor(v),
|
points: [v.stationLongitude, v.stationLatitude],
|
// 无实际意义
|
value: 100,
|
};
|
})
|
);
|
},
|
// 更新告警统计
|
updateAlarms(obj) {
|
let { level1, level2, level3, level4 } = obj.data2.data;
|
this.alarms = [
|
level1.powerAlarmCount,
|
level1.deviceAlarmCount,
|
level1.battAlarmCount,
|
];
|
this.alarmData = [
|
[
|
level1.powerAlarmCount,
|
level2.powerAlarmCount,
|
level3.powerAlarmCount,
|
level4.powerAlarmCount,
|
],
|
[
|
level1.deviceAlarmCount,
|
level2.deviceAlarmCount,
|
level3.deviceAlarmCount,
|
level4.deviceAlarmCount,
|
],
|
[
|
level1.battAlarmCount,
|
level2.battAlarmCount,
|
level3.battAlarmCount,
|
level4.battAlarmCount,
|
],
|
];
|
if (this.$refs.alarmPieChart) {
|
this.$refs.alarmPieChart.update();
|
}
|
|
if (this.$refs.chart_alarm) {
|
this.$refs.chart_alarm.setData(this.alarmData);
|
}
|
},
|
goDevWorkState(num) {
|
let status = num;
|
this.$router.push({
|
path: "/dataTest/btsStatus?pageFlag=" + Math.random(),
|
query: {
|
status,
|
},
|
});
|
},
|
goToPowerMagerPage(producer) {
|
// 跳转到对应的页面
|
this.$router.push({
|
path: "/dataMager/powerMager",
|
query: {
|
producer: JSON.stringify(producer),
|
pageFlag: Math.random(),
|
},
|
});
|
},
|
updateDischargeInfo(obj) {
|
const { code, data, data2, msg } = obj;
|
let list = [];
|
if (code && data) {
|
let outTime = 2 * 60; //设备超时时间(2分钟)
|
let nowTime = new Date(msg).getTime(); //当前时间
|
list = data2
|
.filter((v) => {
|
// 判断是否超时
|
let record = new Date(v.battTestRecordtime).getTime();
|
return Math.abs(nowTime - record) / 1000 <= outTime;
|
})
|
.map((v) => {
|
// v.stationArea =
|
// v.stationName1 + " " + v.stationName2 + " " + v.stationName5;
|
v.battTestTimelong = formatSeconds(v.battTestTlong);
|
let xuhang = v.loadCurr ? v.battRealCap / v.loadCurr : 0;
|
v.xuhang = xuhang ? sethoubeiTime(xuhang) : "---";
|
return v;
|
});
|
}
|
this.tbl.data = list;
|
},
|
goDevAlarm() {
|
this.$router.push({
|
path: "/alarmMager/deviceTimequery",
|
query: {
|
pageFlag: Math.random(),
|
fromType: "fromIndex",
|
alarmId: "119020",
|
},
|
});
|
},
|
|
goRealTime(obj) {
|
// console.log(obj);
|
let search =
|
"?province=" +
|
obj.stationName1 +
|
"&city=" +
|
obj.stationName2 +
|
"&county=" +
|
obj.stationName5 +
|
"&home=" +
|
obj.stationName3 +
|
"&batt=" +
|
obj.battGroupId +
|
"&pageFlag=" +
|
Math.random();
|
let url = "/dataTest/movingRingSystem/" + search + "&listReload=1";
|
this.$router.push(url);
|
},
|
goStations() {
|
this.$router.push("/dataMager/totalStation?pageFlag=" + Math.random());
|
},
|
goBatt() {
|
this.$router.push("/dataMager/battGroupMager");
|
},
|
initEvent() {
|
// 电池类型
|
this.$refs.batteryChart.getChart().on("click", this.goBatt);
|
|
// 电源品牌
|
this.$refs.powerChart.getChart().on("click", (params) => {
|
let producer = [params.name];
|
if ("其他" == params.name) {
|
producer = this.otherPwrProd;
|
}
|
this.goToPowerMagerPage(producer);
|
});
|
},
|
},
|
|
mounted() {
|
if (this.$refs.alarmPieChart) {
|
this.$refs.alarmPieChart.update();
|
}
|
this.initEvent();
|
},
|
};
|
</script>
|
|
<style scoped lang="less">
|
.p-main {
|
height: 100%;
|
display: flex;
|
/deep/ .big-screen-card {
|
padding: 0;
|
}
|
}
|
.flex-c {
|
display: flex;
|
flex-direction: column;
|
}
|
.row + .row {
|
margin-top: 10px;
|
}
|
.left,
|
.right {
|
flex: 1;
|
}
|
.center {
|
margin-left: 10px;
|
margin-right: 10px;
|
flex: 1.52;
|
.row1 {
|
flex: 0.2;
|
}
|
.row2 {
|
flex: 1.8;
|
}
|
}
|
.row {
|
flex: 1;
|
}
|
|
.mon-box-container {
|
text-align: center;
|
box-sizing: border-box;
|
padding-top: 8px;
|
}
|
|
.mon-info-box {
|
display: inline-block;
|
margin-left: 8px;
|
width: 139px;
|
height: 86px;
|
background-image: url("~@/components/bigScreenPage/images/mon_info_box1.png");
|
background-size: 100% 100%;
|
text-align: center;
|
padding-top: 1px;
|
box-sizing: border-box;
|
}
|
|
.mon-info-box.box2 {
|
background-image: url("~@/components/bigScreenPage/images/mon_info_box2.png");
|
}
|
|
.mon-info-box.box3 {
|
background-image: url("~@/components/bigScreenPage/images/mon_info_box3.png");
|
}
|
|
.mon-info-title {
|
margin-top: 32px;
|
font-size: 13px;
|
}
|
|
.mon-info-value {
|
font-size: 16px;
|
color: #ffff00;
|
font-weight: bold;
|
}
|
.flex-map-contain {
|
height: 100%;
|
position: relative;
|
.inner {
|
position: absolute;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
}
|
}
|
.scroller-wrap {
|
position: relative;
|
height: 100%;
|
.inner {
|
position: absolute;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
}
|
// /deep/ .my-list {
|
// font-size: 14px;
|
// }
|
}
|
.dev-wrap {
|
height: 100%;
|
padding: 0 10px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
.item {
|
width: 22%;
|
// &~.item {
|
// margin-left: 6px;
|
// }
|
}
|
}
|
.info {
|
height: 100%;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 0 10px;
|
.item {
|
cursor: pointer;
|
display: flex;
|
// border-radius: 6px;
|
align-items: center;
|
.name {
|
background: #0ff;
|
border-radius: 6px;
|
color: #333;
|
font-size: 18px;
|
font-weight: bold;
|
padding: 0 10px;
|
}
|
.num {
|
width: 3em;
|
height: 1.5em;
|
padding: 0 10px;
|
}
|
}
|
}
|
.chart-wrap {
|
position: relative;
|
height: 100%;
|
.inner {
|
position: absolute;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
}
|
}
|
/deep/ .mark-list-container {
|
bottom: 0.4rem;
|
right: 0.4rem;
|
}
|
/deep/ .cursor-pointer {
|
cursor: pointer;
|
}
|
/deep/ .el-table tr.power-off.power-off td {
|
color: #f00;
|
}
|
</style>
|