<template>
|
<flex-layout direction="row" class="page-real-time" :no-bg="true">
|
<!-- 充放电一体机 -->
|
<content-box
|
style="margin-left: 4px; margin-right: 4px"
|
:title="battFullName"
|
>
|
<div slot="box-tools" class="box-tools">
|
<el-tooltip
|
class="item"
|
effect="dark"
|
content="历史数据"
|
placement="bottom"
|
>
|
<i class="iconfont el-icon-jinru" @click="syncPage"></i>
|
</el-tooltip>
|
</div>
|
<div
|
slot="box-tools"
|
class="box-tools"
|
style="right: 40px"
|
v-if="esVideoSn"
|
>
|
<el-tooltip
|
class="item"
|
effect="dark"
|
content="视频监控"
|
placement="bottom"
|
>
|
<i
|
class="el-iconfont el-icon-video-camera-solid"
|
@click="esVideoDialog = true"
|
></i>
|
</el-tooltip>
|
</div>
|
<!-- <div slot="box-tools" class="box-tools" style="right: 40px;">
|
<el-tooltip class="item" effect="dark" content="历史实时数据" placement="bottom">
|
<i class="el-iconfont el-icon-s-marketing" @click="historyRealTimeDataDialog.show=true"></i>
|
</el-tooltip>
|
</div> -->
|
<flex-layout :no-bg="true">
|
<div class="content-header" slot="header" :model="inputs">
|
<div class="table-layout">
|
<div class="table-row">
|
<div class="table-cell text-right w80">电池状态:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.batt_state"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
<div class="table-cell text-right w80">端电压:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.group_online_vol"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
<div class="table-cell text-right w80">电池电流:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.group_curr"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
<div class="table-cell text-right w80">更新日期:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.rec_datetime"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
</div>
|
<div class="table-row">
|
<div class="table-cell text-right w80">测试时长:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.batt_test_tlong"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
<div class="table-cell text-right w80">测试容量:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.batt_test_cap"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
<div class="table-cell text-right w80">剩余容量:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.batt_syrl_cap"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
<div class="table-cell text-right w80">续航时长:</div>
|
<div class="table-cell">
|
<el-input
|
:value="backInputs.sysc"
|
size="small"
|
:disabled="true"
|
></el-input>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="page-content">
|
<div class="page-content-tools" v-if="control.show && isCanTest">
|
<el-cascader
|
v-model="dataSource.value"
|
size="mini"
|
:disabled="esState == -1 || diagram.type != 0 || groupVol1 >= 54 || groupVol2 >= 54"
|
:options="dataSource.options"
|
@click.native="prompt"
|
@change="changeDataSource"
|
></el-cascader>
|
<el-popover placement="bottom" trigger="hover">
|
<div class="hdw-menu-list">
|
<ul>
|
<li
|
class="hdw-menu-item"
|
v-if="control.data.startCharge.show"
|
>
|
<a @click="boot('charge')" href="javascript:void(0);"
|
>启动充电</a
|
>
|
</li>
|
<li class="hdw-menu-item" v-if="control.data.stopCharge.show">
|
<a @click="stopCharge" href="javascript:void(0);"
|
>停止充电</a
|
>
|
</li>
|
<li
|
class="hdw-menu-item"
|
v-if="control.data.startDischarge.show"
|
>
|
<a @click="boot('discharge')" href="javascript:void(0);"
|
>启动放电</a
|
>
|
</li>
|
<li
|
class="hdw-menu-item"
|
v-if="control.data.stopDischarge.show"
|
>
|
<a @click="stopDischarge" href="javascript:void(0);"
|
>停止放电</a
|
>
|
</li>
|
<li
|
class="hdw-menu-item"
|
v-if="control.data.startActivate.show"
|
>
|
<a @click="boot('activate')" href="javascript:void(0);"
|
>启动活化</a
|
>
|
</li>
|
<li
|
class="hdw-menu-item"
|
v-if="control.data.stopActivate.show"
|
>
|
<a @click="stopActivate" href="javascript:void(0);"
|
>停止活化</a
|
>
|
</li>
|
<li class="hdw-menu-item" v-if="control.data.clearAlerm.show">
|
<a @click="clearAlerm" href="javascript:void(0);"
|
>清除告警</a
|
>
|
</li>
|
<li class="hdw-menu-item" v-if="control.data.clearAlerm.show">
|
<a @click="showVideoDialog" href="javascript:void(0);"
|
>内窥镜</a
|
>
|
</li>
|
<!-- <li class="hdw-menu-item" v-if="control.data.pause.show">
|
<a @click="pause(type)" href="javascript:void(0);">暂停{{typeStr}}}</a>
|
</li> -->
|
</ul>
|
</div>
|
<button class="hdw-btn transparentBtn" slot="reference">
|
<span class="light-color">远程管理</span>
|
<i class="hdw-icon el-icon-caret-bottom"></i>
|
</button>
|
</el-popover>
|
</div>
|
<el-tabs
|
v-model="acTabs"
|
type="border-card"
|
class="flex-layout noborder"
|
@tab-click="tabClick"
|
>
|
<el-tab-pane label="电路拓扑图" class="tab-eleLine" name="eleLine">
|
<div class="left">
|
<science-box :top="8" class="panel-box" :left="8" no-header>
|
<div class="hdw-state-list table-layout">
|
<div
|
v-for="state in stateList"
|
:key="state.text"
|
v-show="state.show"
|
class="table-row"
|
:class="state.type"
|
>
|
<div class="table-cell text-right">
|
<i
|
v-if="state.icon"
|
class="iconfont"
|
:class="state.icon"
|
></i
|
>{{ state.text }}
|
</div>
|
<div class="table-cell" v-if="state.name == 'alarm'">
|
<hdw-light class="ywbj" :type="state.value"></hdw-light>
|
</div>
|
<div v-else class="table-cell">
|
{{ state.value }}{{ state.unit }}
|
</div>
|
</div>
|
</div>
|
<!-- 确认烟雾报警 -->
|
<div v-if="confirmBtnShow" class="row">
|
<el-button @click="confirmAlarm" type="primary" size="mini"
|
>确认烟雾报警</el-button
|
>
|
</div>
|
</science-box>
|
<!-- <science-box :top="8" :left="8" class="panel-box second" no-header>
|
<div class="hdw-state-list table-layout">
|
</div>
|
</science-box> -->
|
</div>
|
<circuit-diagram
|
ref="circuitDiagram"
|
:width="diagramOpt.width"
|
:height="diagramOpt.height"
|
wrap-class="wrap"
|
:levelArr="['staticL', 'stateL', 'flushL']"
|
@ratioChanged="ratioChanged"
|
@debugClick="debugClick"
|
>
|
<div class="info-panel title" :style="getStyle('title', ratio)">
|
{{ diagram.desc }}
|
</div>
|
<div
|
:class="['info-panel', 'strong', { online: L1 }]"
|
:style="getStyle('batts1', ratio)"
|
>
|
<div class="">{{ groupVol1 }} V</div>
|
<div class="">{{ groupCurr1 }} A</div>
|
</div>
|
<div
|
:class="['info-panel', 'strong', { online: L2 }]"
|
:style="getStyle('batts2', ratio)"
|
>
|
<div class="">{{ groupVol2 }} V</div>
|
<div class="">{{ groupCurr2 }} A</div>
|
</div>
|
<div
|
class="info-panel strong online"
|
:style="getStyle('online', ratio)"
|
>
|
<div class="">{{ onlineVol }} V</div>
|
</div>
|
<!-- 电感线圈充能动画 -->
|
<div
|
:class="[
|
'ani-panel',
|
{ charge: flag && isCharge, disCharge: flag && !isCharge },
|
]"
|
:style="getStyle('inductance', ratio)"
|
></div>
|
<div
|
slot="mask"
|
v-if="
|
-1 == diagram.type || 1 == diagram.type || 3 == diagram.type
|
"
|
:class="[
|
'mask',
|
'iconfont',
|
{
|
'el-icon-duankailianjie': diagram.type == -1,
|
'el-icon-zanting': diagram.type == 1 || diagram.type == 3,
|
},
|
]"
|
></div>
|
</circuit-diagram>
|
</el-tab-pane>
|
<el-tab-pane label="电压" name="vol">
|
<bar-chart ref="vol" id="vol" unit="V" right-menu></bar-chart>
|
</el-tab-pane>
|
|
<el-tab-pane
|
label="数据表格"
|
name="tblData"
|
class="el-table-wrapper"
|
>
|
<el-table stripe size="small" :data="table.datas" height="100%">
|
<el-table-column
|
v-for="header in table.headers"
|
:key="header.prop"
|
:prop="header.prop"
|
:label="header.label"
|
:width="header.width"
|
align="center"
|
></el-table-column>
|
</el-table>
|
</el-tab-pane>
|
</el-tabs>
|
</div>
|
</flex-layout>
|
</content-box>
|
<!-- 活化参数设置 -->
|
<el-dialog
|
:title="dialogTitle"
|
width="800px"
|
:visible.sync="dialog.show"
|
:close-on-click-modal="false"
|
top="0"
|
class="dialog-center"
|
:modal-append-to-body="false"
|
>
|
<activate-dialog-content
|
v-if="dialog.show"
|
:type="dialog.type"
|
:batt="batt"
|
:workstate="diagram.type"
|
@startok="dialog.show = false"
|
></activate-dialog-content>
|
</el-dialog>
|
<!-- <el-dialog title="内窥镜" width="800px" :visible.sync="videoDialog.show" :close-on-click-modal="false"-->
|
<!-- top="0" class="dialog-center" :modal-append-to-body="false">-->
|
<!-- <endoscope-video v-if="videoDialog.show"></endoscope-video>-->
|
<!-- </el-dialog>-->
|
<el-dialog
|
title="内窥镜"
|
width="960px"
|
:visible.sync="videoDialog.show"
|
:close-on-click-modal="false"
|
top="0"
|
class="dialog-center"
|
:modal-append-to-body="false"
|
>
|
<endoscope-image
|
v-if="videoDialog.show"
|
:dev-id="batt.FBSDeviceId"
|
:state="esState"
|
></endoscope-image>
|
</el-dialog>
|
<el-dialog
|
title="视频监控"
|
width="600px"
|
:visible.sync="esVideoDialog"
|
:close-on-click-modal="false"
|
top="0"
|
class="dialog-center"
|
:modal-append-to-body="false"
|
>
|
<ez-video v-if="esVideoDialog" :sn="esVideoSn"></ez-video>
|
</el-dialog>
|
</flex-layout>
|
</template>
|
|
<script>
|
import ContentBox from "@/components/ContentBox";
|
import BarChart from "@/components/chart/BarChart";
|
import ActivateDialogContent from "./components/activateDialogContent";
|
import {
|
realTimeSearch,
|
realTimeGroup,
|
realTimePowerOff,
|
realTimeAlarm,
|
} from "@/assets/js/realTime";
|
|
import {
|
Timeout,
|
getBarNum,
|
sethoubeiTime,
|
regEquipType,
|
formatSeconds,
|
isHasPermit,
|
} from "@/assets/js/tools";
|
|
import {
|
list,
|
panelPos,
|
// ,resetFirstTime
|
update,
|
updateBalls,
|
stop,
|
} from "./js/draw_diagram";
|
|
import battGroupMager from "@/assets/js/apis/dataMager/battGroupMager";
|
import getMarkLineData from "@/components/chart/js/getMarkLineData";
|
|
import CircuitDiagram from "@/components/diagram/diagram";
|
import ScienceBox from "@/components/ScienceBox";
|
|
import Diagram from "@/components/diagram/js/diagram";
|
import common from "@/components/diagram/js/common";
|
let interval = common.interval;
|
|
import { const_aio } from "@/assets/js/const";
|
import RtmpVideo from "@/components/rtmpVideo";
|
import EndoscopeVideo from "@/pages/dataTest/components/endoscopeVideo";
|
import HdwLight from "../dataMager/components/HdwLight.vue";
|
import EndoscopeImage from "@/pages/dataTest/dialogs/endoscopeImage";
|
import ezVideo from "@/components/ezVideo";
|
|
let vol, resChart, conduct, currChart, leakVol;
|
let staticL, stateL, flushL;
|
let tblData = [];
|
let ballList = [];
|
export default {
|
name: "realTimeAio",
|
components: {
|
EndoscopeImage,
|
EndoscopeVideo,
|
RtmpVideo,
|
ContentBox,
|
BarChart,
|
ScienceBox,
|
ActivateDialogContent,
|
CircuitDiagram,
|
HdwLight,
|
ezVideo,
|
},
|
watch: {
|
"$route.params.BattGroupId"(BattGroupId) {
|
// console.log('watch', BattGroupId);
|
this.$nextTick(() => {
|
this.getBattGroupInfo(BattGroupId);
|
});
|
},
|
"$store.state.theme.collapse"() {
|
// console.log(123);
|
this.$nextTick(() => {
|
this.resize();
|
});
|
},
|
"diagram.type"(n) {
|
if (n == 2 || n == 4) {
|
this.flag = true;
|
this.resetState();
|
} else {
|
this.flag = false;
|
}
|
},
|
"dataSource.value"(n) {
|
switch (n[1]) {
|
case 0:
|
this.L1 = true;
|
this.L2 = true;
|
break;
|
case 1:
|
this.L1 = true;
|
this.L2 = false;
|
break;
|
case 2:
|
this.L1 = false;
|
this.L2 = true;
|
break;
|
}
|
},
|
},
|
data() {
|
let permits = this.$store.state.user.permits;
|
let isCanTest = isHasPermit("batt_test_op_permit", permits);
|
let stateList = const_aio.stateList;
|
return {
|
acTabs: "eleLine",
|
isCanTest: isCanTest,
|
dialogTitle: "充电参数设置",
|
barCartTitle: '',
|
type: "", // 当前状态 charge discharge activate
|
moveBall: null,
|
stateList: stateList,
|
esVideoDialog: false,
|
esVideoSn: "",
|
esState: -1, // -1通讯故障, 0停止显示 1开始显示
|
// k4状态
|
main: false,
|
confirmBtnShow: 0,
|
ratio: 1,
|
L1: false,
|
L2: false,
|
// 上次停止原因
|
lastStopReason: "",
|
/* 电池状态 模块 组端展示 */
|
dev_captest_onlinevol: 0, // 在线模块在线电压
|
inputs: {
|
group_vol: 0 /* 端电压-组端电压 */,
|
online_vol: 0 /* 端电压-在线电压 */,
|
group_curr: 0 /* 电池电流 */,
|
batt_test_tlong: "0:00:00" /* 测试时长 */,
|
rec_datetime: 0 /* 更新日期 */,
|
batt_test_cap: 0 /* 测试容量 */,
|
batt_rest_cap: 0, // 剩余容量
|
batt_state: 0 /* 电池状态 */,
|
},
|
// 拓扑图上的实时组端电流电压
|
groupVol1: 0,
|
groupVol2: 0,
|
groupCurr1: 0,
|
groupCurr2: 0,
|
onlineVol: 0,
|
control: {
|
show: true,
|
data: {
|
startCharge: {
|
// 启动充电
|
show: true,
|
typeShow: false,
|
id: 11,
|
},
|
stopCharge: {
|
// 停止充电
|
show: true,
|
typeShow: false,
|
id: 12,
|
},
|
startDischarge: {
|
// 启动放电
|
show: true,
|
typeShow: false,
|
id: 13,
|
},
|
stopDischarge: {
|
// 停止放电
|
show: true,
|
typeShow: false,
|
id: 14,
|
},
|
startActivate: {
|
// 启动活化
|
show: true,
|
typeShow: false,
|
id: 15,
|
},
|
stopActivate: {
|
// 停止活化
|
show: true,
|
typeShow: false,
|
id: 16,
|
},
|
clearAlerm: {
|
show: true,
|
typeshow: false,
|
id: 17,
|
},
|
},
|
},
|
dialog: {
|
show: false,
|
type: "",
|
},
|
timer: new Timeout("movingRingSysteRrealTime"),
|
timer2: new Timeout(),
|
table: {
|
headers: [
|
{
|
prop: "num1",
|
label: "单体编号",
|
width: "",
|
},
|
{
|
prop: "vol1",
|
label: "电压(V)",
|
width: "",
|
},
|
// {
|
// prop: "temp1",
|
// label: "温度(℃)",
|
// width: ""
|
// },
|
],
|
datas: [],
|
},
|
batt: {},
|
diagram: {
|
update: true,
|
type: -1,
|
desc: "",
|
powerCut: 1,
|
temp: 0, // 设备温度
|
},
|
diagramOpt: {
|
width: 1600,
|
height: 860,
|
},
|
sta: {
|
Q1: false,
|
Q2: false,
|
Q3: false,
|
Q4: false,
|
Q5: false,
|
},
|
videoDialog: {
|
show: false,
|
},
|
// 储能状态
|
isCharge: true,
|
count: 0,
|
flag: false,
|
dataSource: {
|
value: ["source", 0],
|
options: [
|
{
|
value: "source",
|
label: "数据来源",
|
children: [
|
{
|
value: 0,
|
label: "未设置",
|
},
|
{
|
value: 1,
|
label: "电池组1",
|
},
|
{
|
value: 2,
|
label: "电池组2",
|
},
|
],
|
},
|
],
|
},
|
// 上一次有效的数据来源
|
lastSource: 0,
|
battName: ''
|
};
|
},
|
computed: {
|
battFullName() {
|
let batt = this.batt;
|
if (batt.StationName && batt.BattGroupName) {
|
return (
|
batt.StationName1 +
|
"->" +
|
batt.StationName2 +
|
"->" +
|
batt.StationName5 +
|
"->" +
|
batt.StationName3 +
|
"->" +
|
batt.StationName4
|
);
|
}
|
return "电池组全称";
|
},
|
backInputs() {
|
const list = {
|
batt_state: "未知",
|
group_online_vol: "在线:0.00V; 组端:0.00V",
|
dev_captest_onlinevol: 0, // 在线模块在线电压
|
group_curr: "0.00A",
|
rec_datetime: "1982-01-01 00:00:00",
|
batt_test_tlong: formatSeconds(0),
|
batt_test_cap: "0Ah",
|
batt_syrl_cap: "---",
|
sysc: "------",
|
};
|
if (this.diagram.type == -1) {
|
return list;
|
}
|
let batt_state_text = '';
|
// 停电 => 停止; 有电 || 未选择 => 浮充
|
if (this.onlineVol < 51.5) {
|
batt_state_text = '停止';
|
} else if (!this.dataSource.value[1]) {
|
batt_state_text = '浮充';
|
} else {
|
batt_state_text = this.diagram.desc;
|
}
|
list.batt_state = batt_state_text;
|
list.group_online_vol = `在线:${this.inputs.online_vol.toFixed(
|
2
|
)}V; 组端:${this.inputs.group_vol.toFixed(2)}V`;
|
list.group_curr = this.inputs.group_curr.toFixed(2) + "A";
|
list.rec_datetime = this.inputs.rec_datetime;
|
list.batt_test_tlong = formatSeconds(this.inputs.batt_test_tlong);
|
list.dev_captest_onlinevol = this.dev_captest_onlinevol;
|
|
list.batt_test_cap = this.inputs.batt_test_cap.toFixed(1) + "AH";
|
if (this.inputs.batt_state === 2) {
|
list.batt_syrl_cap = "---";
|
} else {
|
list.batt_syrl_cap = this.inputs.batt_rest_cap.toFixed(1) + "AH";
|
}
|
if (this.inputs.batt_state === 3) {
|
list.sysc = sethoubeiTime(
|
parseFloat(this.inputs.batt_rest_cap) /
|
parseFloat(this.inputs.group_curr)
|
);
|
} else {
|
list.sysc = "------";
|
}
|
return list;
|
},
|
},
|
methods: {
|
resize() {
|
// if(this.acTabs === "powerInfo") {
|
// this.powerInfoChartResize();
|
// }else {
|
// this.$G.chartManage.resize(this.acTabs);
|
// }
|
this.$G.chartManage.resize(this.acTabs);
|
},
|
tabClick(tab) {
|
// 根据tab更新电路图
|
if (this.acTabs === "eleLine") {
|
this.$refs.circuitDiagram.resizeHandle();
|
this.timer2.restart();
|
} else {
|
this.timer2.stop();
|
}
|
// 更新图表
|
this.setChart();
|
|
// 重置图表的大小
|
this.$nextTick(() => {
|
this.resize();
|
// 设置表格的数据
|
if (this.acTabs == "tblData") {
|
this.table.datas = tblData;
|
}
|
});
|
},
|
initChart() {
|
// 电压
|
vol = {
|
title: {
|
show: true,
|
text: "最大值=0V;最小值=0V;平均值=0V",
|
x: "center",
|
textStyle: {
|
fontSize: "14",
|
},
|
},
|
series: [
|
{
|
name: "电压",
|
type: "bar",
|
data: [],
|
markLine: {
|
data: getMarkLineData(),
|
},
|
},
|
],
|
};
|
|
|
|
// 设置配置项
|
this.setChart();
|
},
|
setChart() {
|
let acTabs = this.acTabs;
|
switch (acTabs) {
|
case "vol":
|
this.$refs.vol.setOption(vol);
|
break;
|
}
|
},
|
getBattGroupInfo(BattGroupId) {
|
// console.log(BattGroupId, 'battGroupId');
|
this.$apis.dataMager.battGroupMager
|
.getBattGroupInfo(BattGroupId)
|
.then((res) => {
|
let rs = JSON.parse(res.data.result);
|
// console.log(rs, 'rs');
|
if (rs.code == 1) {
|
this.leafClick(rs.data[0]);
|
} else {
|
this.$layer.msg("未获取到电池组的信息");
|
}
|
})
|
.catch((error) => {
|
console.log(error);
|
});
|
},
|
leafClick(data) {
|
this.batt = data;
|
this.diagram.desc = "";
|
this.esVideoSn = data.videoUrl;
|
this.realTimeAlarmss();
|
// 开启循环请求
|
this.startTimer();
|
},
|
realTimeAlarmss() {
|
var batt = this.batt;
|
realTimeAlarm({
|
dev_id: batt.FBSDeviceId,
|
}).then((res) => {
|
let rs = JSON.parse(res.data.result);
|
if (rs.code == 1) {
|
let list = rs.data;
|
// 单体电压
|
this.setChartMarkLine(vol, "Voltage", "Batt_Alarm_Type_MonVol", list);
|
}
|
});
|
},
|
setChartMarkLine(chartData, name, alm_name, list) {
|
let batt = this.batt;
|
// 遍历list
|
for (let i = 0; i < list.length; i++) {
|
let item = list[i];
|
if (item.alm_name == alm_name) {
|
let high = 0;
|
let low = 0;
|
switch (name) {
|
case "Voltage": // 电压告警
|
//单体电压
|
let std_mon_vol = batt.MonVolStd;
|
high = parseFloat(std_mon_vol * item.alm_high_coe).toHold(3);
|
low = parseFloat(std_mon_vol * item.alm_low_coe).toHold(3);
|
break;
|
case "Temperature":
|
//单体温度
|
let std_mon_tmp = 25;
|
high = parseFloat(std_mon_tmp * item.alm_high_coe).toHold(1);
|
low = parseFloat(std_mon_tmp * item.alm_low_coe).toHold(1);
|
break;
|
}
|
// 低告警
|
chartData.series[0].markLine.data[0].yAxis = low;
|
// 高告警
|
chartData.series[0].markLine.data[1].yAxis = high;
|
break;
|
}
|
}
|
},
|
/* echars图表 */
|
realTimeSearch() {
|
var batt = this.batt;
|
realTimeSearch({
|
BattGroupId: batt.BattGroupId,
|
}).then((res) => {
|
let rs = JSON.parse(res.data.result);
|
// console.log(rs, 'rs===========');
|
let data = [];
|
if (rs.code == 1) {
|
let temp0 = const_aio.getItemByName("temp0", this.stateList).value;
|
data = rs.data.map((item, i) => {
|
if (i < 3) {
|
// console.log('===', temp0, 'temp0', item.mon_tmp);
|
// this.stateList[i + 2].value = item.mon_tmp;
|
this.setStateList(
|
"temp" + (i + 1),
|
item.mon_tmp,
|
item.mon_tmp > temp0 ? "alarm" : ""
|
);
|
}
|
return {
|
num1: "#" + item.mon_num,
|
vol1: item.mon_vol,
|
res1: item.mon_res,
|
temp1: item.mon_tmp,
|
conduct1: item.mon_res
|
? ((1 / item.mon_res) * 1000).toFixed(0)
|
: 0,
|
curr1: item.mon_JH_curr,
|
leakVol1: item.mon_LY_vol,
|
};
|
});
|
}
|
// 更新表格
|
if (this.acTabs == "tblData") {
|
this.table.datas = data;
|
} else {
|
tblData = data;
|
}
|
|
// 电压值
|
let volTempVol = [];
|
if (rs.code == 1) {
|
volTempVol = rs.data.map((item) => {
|
return ["#" + item.mon_num, item.mon_vol];
|
});
|
}
|
let volBarNum = getBarNum(volTempVol);
|
vol.title.text =
|
this.battName +
|
" 最大值=" +
|
volBarNum.max.toFixed(2) +
|
"V;最小值=" +
|
volBarNum.min.toFixed(2) +
|
"V;平均值=" +
|
volBarNum.avg.toFixed(2) +
|
"V";
|
vol.series[0].data = volTempVol;
|
|
// 更新电压图表
|
this.setChart();
|
});
|
},
|
// 向父级发送同步页面的指令
|
syncPage() {
|
let batt = this.batt;
|
let search =
|
"?province=" +
|
batt.StationName1 +
|
"&city=" +
|
batt.StationName2 +
|
"&county=" +
|
batt.StationName5 +
|
"&home=" +
|
batt.StationName3 +
|
"&batt=" +
|
batt.BattGroupId;
|
window.parent.postMessage(
|
{
|
cmd: "syncPage",
|
params: {
|
pageInfo: {
|
label: "历史数据",
|
name: "history",
|
src: "#/history" + search,
|
closable: true,
|
},
|
},
|
},
|
"*"
|
);
|
},
|
// 设置stateList的值
|
setStateList(name, value, type, show) {
|
show = undefined === show ? true : show;
|
let stateList = this.stateList;
|
for (let i = 0; i < stateList.length; i++) {
|
let state = stateList[i];
|
if (state.name == name) {
|
state.value = value;
|
state.type = type ? type : "";
|
state.show = show;
|
}
|
}
|
},
|
/* 实时组端信息 */
|
realTimeGroupss() {
|
var batt = this.batt;
|
realTimeGroup(batt.BattGroupId).then((res) => {
|
let rsa = JSON.parse(res.data.result);
|
// console.log(rsa, '??', rsa.data[0]);
|
if (rsa.code == 1) {
|
this.inputs = rsa.data[0];
|
// 上一次来源
|
this.lastSource = rsa.data[0].a059_num;
|
// console.log(this.inputs.rec_datetime, '??更新时间');
|
}
|
});
|
},
|
/* 查询电路图开关状态和信息 */
|
realTimePowerOffs() {
|
let batt = this.batt;
|
|
// 查询后台数据
|
realTimePowerOff({
|
dev_id: batt.FBSDeviceId,
|
}).then((res) => {
|
let rs = JSON.parse(res.data.result);
|
// console.log('状态:', rs);
|
let outTime = 2 * 60; //设备超时时间(2分钟)
|
let isOutTime = true; //通讯中断 判断设备是否通讯中断 true:中断 false:正常
|
if (rs.code == 1) {
|
let data = rs.data[0];
|
// const isPowerOff = data.dev_captest_onlinevol <= 51.5;
|
this.onlineVol = data.dev_captest_onlinevol;
|
this.groupVol1 = data.a059_group_vol1;
|
this.groupVol2 = data.a059_group_vol2;
|
this.groupCurr1 = data.a059_group_curr1;
|
this.groupCurr2 = data.a059_group_curr2;
|
|
// 设置内窥镜图片更新状态
|
this.esState = data.dev_station_poff_cnt;
|
// 设置数据来源
|
this.$set(this.dataSource, "value", [
|
"source",
|
// isPowerOff ? 0 : data.dev_onlinevollow
|
data.dev_onlinevollow
|
]);
|
let battIdx = 0,
|
battNames = ['未选中', '电池组1', '电池组2'];
|
if (data.devOnlinevollow > 0) {
|
battIdx = data.devOnlinevollow;
|
} else {
|
battIdx = this.lastSource;
|
}
|
this.battName = '(' + battNames[battIdx] + ')';
|
// 表格 和 单体电压柱状图修改标题
|
this.table.headers[0].label = '单体编号 ' + this.battName;
|
// vol.title.text = this.battName + ' ' + vol.title.text;
|
// 烟感报警 > 0为报警状态
|
// this.stateList[4].value = data.dev_temp > 0 ? 1 : 0;
|
this.setStateList("alarm", data.dev_temp > 0 ? 1 : 0);
|
this.confirmBtnShow = data.dev_res_test_state;
|
// 当值大于0x80之后 这边需要减去0x80之后再对应下表并把上次停止原因标红
|
let reason = data.dev_last_captest_stop_type;
|
let alarm = false;
|
if (reason > 0x80) {
|
alarm = true;
|
reason -= 0x80;
|
}
|
this.setStateList(
|
"stopreason",
|
const_aio.stopreasons[reason],
|
alarm ? "alarm" : ""
|
);
|
// console.log(data, 'rt');
|
// 判断是否超时
|
var nowTime = new Date(data.note).getTime(); //当前时间
|
var record = new Date(data.record_datetime).getTime();
|
if (Math.abs(nowTime - record) / 1000 > outTime) {
|
this.disconnect();
|
} else {
|
// 未超时执行逻辑
|
// 基础信息
|
this.setEquipBase(data);
|
|
let dev_id = batt.FBSDeviceId;
|
this.diagram.powerCut = 0;
|
//
|
this.diagram.type = data.dev_workstate;
|
// 活化状态
|
let workstates =
|
data.dev_batt_xuhang_tlong > 0
|
? "活化 " + const_aio.HHWorkstates[data.dev_batt_xuhang_tlong]
|
: const_aio.workstates[data.dev_workstate];
|
this.diagram.desc = workstates;
|
this.setStateList("workState", workstates);
|
// 活化阶段
|
if (data.dev_batt_xuhang_tlong > 0) {
|
let str =
|
data.dev_restest_monindex + "/" + data.dev_restest_moncount;
|
this.setStateList("activateCounter", str, "", true);
|
} else {
|
this.setStateList("activateCounter", "", "", false);
|
}
|
// 如果是充电 则显示充电类型
|
if (data.dev_workstate == 4) {
|
let chargeType = const_aio.chargeType[data.dev_eachgroup_battsum];
|
this.setStateList("chargeType", chargeType, "", true);
|
} else {
|
this.setStateList("chargeType", "", "", false);
|
}
|
this.main = !data.batt_online_state;
|
this.dev_captest_onlinevol = data.dev_captest_onlinevol;
|
}
|
} else {
|
// 设备处于未连接
|
this.disconnect();
|
}
|
});
|
},
|
disconnect() {
|
// 设备未连接
|
this.diagram.type = -1;
|
this.setStateList("workState", "未连接");
|
this.diagram.desc = "设备未连接";
|
this.main = false;
|
// 设置内窥镜图片更新状态
|
this.esState = -1;
|
this.onlineVol = 0;
|
this.groupVol1 = 0;
|
this.groupVol2 = 0;
|
this.groupCurr1 = 0;
|
this.groupCurr2 = 0;
|
this.dataSource.value[1] = 0;
|
},
|
// 基础信息
|
setEquipBase(data) {
|
// 设备的温度
|
this.diagram.temp = data.dev_temp;
|
},
|
startTimer() {
|
this.timer.start(() => {
|
this.$axios
|
.all([
|
this.realTimeSearch(),
|
this.realTimeGroupss(),
|
this.realTimePowerOffs(),
|
this.getTempLimit(),
|
])
|
.then(() => {
|
this.timer.open();
|
})
|
.catch(() => {
|
this.timer.open();
|
});
|
}, 3000);
|
},
|
// 获取温度报警阀值
|
getTempLimit() {
|
this.$apis.aio.realtime
|
.getTempLimit(this.batt.FBSDeviceId)
|
.then((res) => {
|
res = JSON.parse(res.data.result);
|
// this.setStateList('temp0', 1);
|
// console.log(res, '==res');
|
if (res.code) {
|
this.setStateList("temp0", res.data[0].CharHighTmp);
|
}
|
})
|
.catch((err) => {
|
console.error(err);
|
});
|
},
|
monitorPage() {
|
// 获取缓存的session
|
let name = sessionStorage.getItem("acTabs");
|
// console.log(name, 'session acTabs');
|
if (name === "movingRingSystemRealTime" && this.acTabs === "eleLine") {
|
this.diagram.update = true;
|
} else {
|
this.diagram.update = false;
|
}
|
// 启动监控
|
requestAnimationFrame(() => {
|
this.monitorPage();
|
});
|
},
|
stopCharge() {
|
// console.log('stopcharge');
|
this.$layer.confirm(
|
"停止充电",
|
{
|
icon: 3,
|
},
|
(index) => {
|
// 关闭询问层
|
this.$layer.close(index);
|
let loading = this.$layer.loading();
|
this.$apis.aio.realtime
|
.sendCmd({
|
dev_id: this.batt.FBSDeviceId,
|
op_cmd: const_aio.cmd.stopCharge,
|
})
|
.then((res) => {
|
res = JSON.parse(res.data.result);
|
this.$layer.close(loading);
|
// console.log(res, 'res');
|
if (res.code) {
|
this.$layer.msg("停止充电成功!");
|
} else {
|
this.$layer.msg("停止充电失败!");
|
}
|
})
|
.catch((err) => {
|
this.$layer.close(loading);
|
console.log(err);
|
this.$layer.msg("停止充电失败, 请求异常!");
|
});
|
}
|
);
|
},
|
stopDischarge() {
|
// console.log('stopdischarge');
|
this.$layer.confirm(
|
"停止放电",
|
{
|
icon: 3,
|
},
|
(index) => {
|
// 关闭询问层
|
this.$layer.close(index);
|
let loading = this.$layer.loading();
|
this.$apis.aio.realtime
|
.sendCmd({
|
dev_id: this.batt.FBSDeviceId,
|
op_cmd: const_aio.cmd.stopDisCharge,
|
})
|
.then((res) => {
|
res = JSON.parse(res.data.result);
|
this.$layer.close(loading);
|
// console.log(res, 'res');
|
if (res.code) {
|
this.$layer.msg("停止放电成功!");
|
} else {
|
this.$layer.msg("停止放电失败!");
|
}
|
})
|
.catch((err) => {
|
this.$layer.close(loading);
|
console.log(err);
|
this.$layer.msg("停止放电失败, 请求异常!");
|
});
|
}
|
);
|
},
|
stopActivate() {
|
// console.log('stopActivate');
|
this.$layer.confirm(
|
"停止活化",
|
{
|
icon: 3,
|
},
|
(index) => {
|
// 关闭询问层
|
this.$layer.close(index);
|
let loading = this.$layer.loading();
|
this.$apis.aio.realtime
|
.sendCmd({
|
dev_id: this.batt.FBSDeviceId,
|
op_cmd: const_aio.cmd.stopActivate,
|
})
|
.then((res) => {
|
res = JSON.parse(res.data.result);
|
this.$layer.close(loading);
|
// console.log(res, 'res');
|
if (res.code) {
|
this.$layer.msg("停止活化成功!");
|
} else {
|
this.$layer.msg("停止活化失败!");
|
}
|
})
|
.catch((err) => {
|
this.$layer.close(loading);
|
console.log(err);
|
this.$layer.msg("停止活化失败, 请求异常!");
|
});
|
}
|
);
|
},
|
// 启动
|
boot(type) {
|
// console.log(type);
|
switch (type) {
|
case "charge":
|
this.dialogTitle = "充电参数设置";
|
break;
|
case "discharge":
|
this.dialogTitle = "放电参数设置";
|
break;
|
case "activate":
|
this.dialogTitle = "活化参数设置";
|
break;
|
}
|
this.dialog.type = type;
|
this.dialog.show = true;
|
},
|
// 暂停
|
// ,pause (type) {
|
// console.log('暂停', type)
|
// }
|
clearAlerm() {
|
// console.log('clearAlerm');
|
// 清除告警
|
this.$layer.confirm(
|
"清除设备告警",
|
{
|
icon: 3,
|
title: "系统提示",
|
},
|
(index) => {
|
// 关闭弹出框
|
this.$layer.close(index);
|
// 开启加载等待
|
let load = this.$layer.loading(1);
|
// 执行清除告警
|
let batt = this.batt;
|
this.$apis.system
|
.clearWarn(batt.FBSDeviceId)
|
.then((res) => {
|
let rs = JSON.parse(res.data.result);
|
// console.log('??', rs);
|
if (rs.code == 1) {
|
this.$layer.msg("清除设备告警成功!");
|
} else {
|
this.$layer.msg("清除设备告警失败!");
|
}
|
// 关闭等待
|
this.$layer.close(load);
|
})
|
.catch((error) => {
|
console.log(error);
|
// 关闭等待
|
this.$layer.close(load);
|
});
|
}
|
);
|
},
|
ratioChanged(ratio) {
|
// console.log(ratio);
|
this.ratio = ratio;
|
staticL && staticL.setRatio(ratio);
|
flushL && flushL.setRatio(ratio);
|
stateL && stateL.setRatio(ratio);
|
},
|
init() {
|
// console.log(this.$refs.circuitDiagram);
|
let circuitDiagram = this.$refs.circuitDiagram;
|
// console.log(circuitDiagram.$refs.staticL[0]);
|
let opts = {
|
count: 60,
|
};
|
staticL = new Diagram(circuitDiagram.$refs.staticL[0], opts);
|
stateL = new Diagram(circuitDiagram.$refs.stateL[0], opts);
|
flushL = new Diagram(circuitDiagram.$refs.flushL[0], opts);
|
this.moveBall = updateBalls(flushL, ballList);
|
},
|
drawStatic() {
|
staticL.importObjList(list);
|
// drawPanel(staticL);
|
staticL.drawAll();
|
},
|
drawFlush() {},
|
// 调试时的点击
|
debugClick(o) {
|
let point = {
|
x: o.offsetX,
|
y: o.offsetY,
|
};
|
let inObj = staticL.mousePointInObj([point.x, point.y], undefined);
|
let canvas_obj_id_arr = staticL.getObjIdArr();
|
let canvas_obj = staticL.getObjList();
|
if (inObj) {
|
for (let i = 0, j = canvas_obj_id_arr.length; i < j; i++) {
|
let id = canvas_obj_id_arr[i];
|
let _inObj = staticL.mousePointInObj([point.x, point.y], id);
|
if (_inObj) {
|
let _obj = canvas_obj[id];
|
console.log("----obj", _obj, id);
|
break;
|
}
|
}
|
}
|
},
|
|
loop() {
|
this.timer2.start(() => {
|
// console.log('loop');
|
this.count++;
|
// 两秒切换一次状态
|
if (this.count == 2) {
|
this.count = 0;
|
this.isCharge = !this.isCharge;
|
}
|
update(
|
this.moveBall,
|
stateL,
|
{
|
state: this.diagram.type,
|
main: this.main,
|
onlineVol: this.onlineVol,
|
groupVol1: this.groupVol1,
|
groupVol2: this.groupVol2,
|
isCharge: this.isCharge,
|
source: this.dataSource.value[1],
|
},
|
ballList
|
);
|
this.timer2.open();
|
}, 1000);
|
},
|
getStyle(type, ratio) {
|
if (!staticL) {
|
return {};
|
}
|
let pos = panelPos[type];
|
// let ratio = staticL.ratio;
|
return {
|
top: pos.top * ratio + "px",
|
left: pos.left * ratio + "px",
|
width: pos.width * ratio + "px",
|
height: pos.height * ratio + "px",
|
};
|
},
|
showVideoDialog() {
|
this.videoDialog.show = true;
|
},
|
// 确认烟雾告警
|
confirmAlarm() {
|
this.$apis.aio.realtime
|
.confirmAlarm(this.batt.FBSDeviceId)
|
.then((res) => {
|
res = JSON.parse(res.data.result);
|
// console.log(res, 'confirm');
|
})
|
.catch((err) => {
|
console.error(err);
|
});
|
},
|
resetState() {
|
this.count = 0;
|
this.isCharge = true;
|
},
|
prompt () {
|
if (this.diagram.type != 0) {
|
this.$layer.msg('非停止状态不能切换');
|
return;
|
}
|
if (this.groupVol1 >= 54 || this.groupVol2 >= 54) {
|
this.$layer.msg('不在安全电压范围');
|
}
|
},
|
changeDataSource() {
|
let batt = this.batt;
|
// if (this.groupVol1 >= 54 || this.groupVol2 >= 54) {
|
// this.$layer.msg('不在安全电压范围');
|
// return false;
|
// }
|
let num = this.dataSource.value[1];
|
this.timer.stop();
|
let loading = this.$layer.loading();
|
this.$apis.aio.realtime
|
.changeDataSource(batt.FBSDeviceId, num)
|
.then((res) => {
|
this.$layer.close(loading);
|
let rs = JSON.parse(res.data.result);
|
let timeLong = 4000;
|
if (rs.code == 1) {
|
this.$layer.msg("切换电池组成功");
|
} else {
|
this.$layer.msg("切换电池组失败");
|
timeLong = 0;
|
}
|
setTimeout(() => {
|
this.startTimer();
|
}, timeLong);
|
})
|
.catch((error) => {
|
this.$layer.close(loading);
|
this.startTimer();
|
this.$layer.msg("切换电池组失败");
|
});
|
},
|
},
|
mounted() {
|
// console.log(this.$route.params, 'mounted');
|
let BattGroupId = this.$route.params.BattGroupId;
|
this.getBattGroupInfo(BattGroupId);
|
this.initChart();
|
this.$nextTick(() => {
|
this.$G.chartManage.resize(this.acTabs);
|
});
|
// 屏幕缩放时触发
|
window.addEventListener("resize", this.resize);
|
// 监控是否已经切换到当前页面
|
this.monitorPage();
|
|
this.init();
|
interval(this.drawStatic, 100, 50);
|
// this.drawStatic();
|
this.loop();
|
this.timer2.open();
|
},
|
beforeDestroy() {
|
this.timer.stop();
|
this.timer2.stop();
|
stop();
|
},
|
};
|
</script>
|
|
<style scoped>
|
.page-real-time {
|
color: #ffffff;
|
}
|
.table-row .table-cell {
|
padding-top: 12px;
|
vertical-align: middle;
|
}
|
.page-content {
|
position: relative;
|
padding-top: 8px;
|
padding-bottom: 2px;
|
box-sizing: border-box;
|
height: 100%;
|
}
|
.page-content-tools {
|
position: absolute;
|
top: 14px;
|
right: 8px;
|
z-index: 99;
|
}
|
|
.hdw-btn {
|
display: inline-block;
|
color: #fff;
|
background-color: #409eff;
|
border-color: #409eff;
|
line-height: 1;
|
white-space: nowrap;
|
cursor: pointer;
|
-webkit-appearance: none;
|
text-align: center;
|
box-sizing: border-box;
|
outline: none;
|
margin: 0;
|
transition: 0.1s;
|
font-weight: 500;
|
-webkit-user-select: none;
|
-moz-user-select: none;
|
-ms-user-select: none;
|
user-select: none;
|
padding: 6px 10px;
|
font-size: 14px;
|
border-radius: 4px;
|
}
|
|
.hdw-btn:hover {
|
background-color: #3c91e6;
|
}
|
|
.hdw-menu-list {
|
border: 1px solid #409eff;
|
}
|
|
.hdw-menu-list .hdw-menu-item {
|
border-top: 1px solid #0e5194;
|
}
|
|
.hdw-menu-list .hdw-menu-item:first-child {
|
border-top: none;
|
}
|
|
.hdw-menu-item a {
|
display: block;
|
text-align: center;
|
padding: 8px;
|
color: #ffffff;
|
cursor: pointer;
|
background-color: rgba(30, 125, 219, 0.767);
|
}
|
|
.hdw-menu-item a:hover {
|
background-color: rgb(60, 135, 211);
|
}
|
|
.hdw-menu-item a:active {
|
background-color: rgb(34, 100, 167);
|
}
|
.info-panel {
|
position: absolute;
|
text-align: left;
|
/* background: #999; */
|
}
|
.info-panel.title {
|
/* text-align: right; */
|
font-size: 18px;
|
}
|
.info-panel.strong {
|
font-size: 22px;
|
font-weight: bold;
|
}
|
.info-panel.strong.online {
|
color: #ffe329;
|
}
|
>>> .wrap {
|
/* background: rgba(66, 66, 66, 1); */
|
}
|
.mask {
|
position: absolute;
|
left: 0;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
background: rgba(0, 0, 0, 0.4);
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
font-size: 140px;
|
color: rgba(200, 200, 200, 0.6);
|
}
|
.panel-box {
|
position: relative;
|
display: inline-block;
|
align-self: flex-start;
|
}
|
.tab-eleLine {
|
display: flex;
|
}
|
>>> .hdw-light-wrapper {
|
justify-content: start;
|
}
|
.row {
|
text-align: center;
|
margin-top: 6px;
|
}
|
.alarm .table-cell {
|
/* color: #ff5503; */
|
color: transparent !important;
|
-webkit-animation: ani 1s infinite;
|
animation: ani 1s infinite;
|
text-shadow: 0 0 0 #ff5503;
|
}
|
.left {
|
display: inline-block;
|
}
|
.second .table-row .table-cell {
|
padding-top: 0;
|
}
|
.ywbj {
|
height: 2.5rem;
|
}
|
.ywbj >>> .hdw-light {
|
transform: scale(1.6, 1.6);
|
}
|
.dialog-confirm >>> .el-dialog {
|
background: #fff;
|
}
|
.dialog-confirm .content {
|
padding: 10px;
|
}
|
.ani-panel {
|
position: absolute;
|
}
|
.ani-panel::before {
|
content: "";
|
position: absolute;
|
background: rgb(127, 255, 127);
|
left: 0;
|
top: 0;
|
height: 100%;
|
width: 0;
|
opacity: 0.8;
|
}
|
.ani-panel.charge::before {
|
-webkit-animation: charge 2s linear forwards;
|
animation: charge 2s linear forwards;
|
}
|
.ani-panel.disCharge::before {
|
-webkit-animation: disCharge linear 2s forwards;
|
animation: disCharge 2s linear forwards;
|
}
|
.ani-panel::after {
|
content: "";
|
position: absolute;
|
top: 140%;
|
left: 0;
|
width: 5em;
|
text-align: left;
|
color: #00f7f9;
|
font-size: 16px;
|
}
|
.ani-panel.charge::after {
|
content: "储能中...";
|
}
|
.ani-panel.disCharge::after {
|
content: "释放中...";
|
color: #ccc;
|
}
|
@-webkit-keyframes charge {
|
0% {
|
width: 0;
|
background: rgb(127, 255, 127);
|
}
|
50% {
|
background: rgb(49, 184, 49);
|
width: 50%;
|
}
|
100% {
|
background: rgb(0, 255, 0);
|
width: 100%;
|
}
|
}
|
@keyframes charge {
|
0% {
|
background: rgb(127, 255, 127);
|
width: 0;
|
}
|
50% {
|
background: rgb(49, 184, 49);
|
width: 50%;
|
}
|
100% {
|
background: rgb(0, 255, 0);
|
width: 100%;
|
}
|
}
|
@-webkit-keyframes disCharge {
|
0% {
|
background: rgb(0, 255, 0);
|
width: 100%;
|
}
|
50% {
|
background: rgb(49, 184, 49);
|
width: 50%;
|
}
|
100% {
|
background: rgb(127, 255, 127);
|
width: 0;
|
}
|
}
|
@keyframes disCharge {
|
0% {
|
background: rgb(0, 255, 0);
|
width: 100%;
|
}
|
50% {
|
background: rgb(49, 184, 49);
|
width: 50%;
|
}
|
100% {
|
background: rgb(127, 255, 127);
|
width: 0;
|
}
|
}
|
|
@keyframes ani {
|
0%,
|
20% {
|
/* color: #ff5703; */
|
text-shadow: 0 0 0 #ff5503;
|
}
|
|
50% {
|
/* color: #ff5703b7; */
|
text-shadow: 0 0 0 #ff5703b7;
|
/* color: rgba(255, 87, 03, 183); */
|
}
|
|
80%,
|
100% {
|
text-shadow: 0 0 0 #ffe329aa;
|
/* color: #ffe329aa; */
|
}
|
}
|
@-webkit-keyframes ani {
|
0%,
|
20% {
|
text-shadow: 0 0 0 #ff5503;
|
/* color: #ff5703; */
|
}
|
50% {
|
text-shadow: 0 0 0 #ff5703b7;
|
/* color: #ff5703b7; */
|
}
|
80%,
|
100% {
|
text-shadow: 0 0 0 #ffe329aa;
|
/* color: #ffe329aa; */
|
}
|
}
|
.data-source {
|
font-size: 14px;
|
cursor: pointer;
|
}
|
</style>
|