index.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. <template>
  2. <div></div>
  3. <!-- <div
  4. draggable="true"
  5. @dragstart="startDrag"
  6. @dragend="stopDrag"
  7. :style="{ left: x + 'px', top: y + 'px' }"
  8. style="cursor: pointer; position: absolute; z-index: 999"
  9. >
  10. <el-badge
  11. :value="warnLength"
  12. :class="{ active: warnLength && !displayAlarms ? false : true }"
  13. >
  14. <div class="alarmDeligo" @click="displayAlarm" v-if="warnLength">
  15. <img src="@assets/imgs/ygj.png" class="trans" />
  16. <img src="@assets/imgs/ygj1.png" />
  17. </div>
  18. <div class="alarmDeligo" @dblclick="setting" v-if="!warnLength">
  19. <img src="@assets/imgs/wgj.png" class="trans" />
  20. <img src="@assets/imgs/wgj1.png" />
  21. </div>
  22. </el-badge>
  23. <deligo-alarm-list
  24. :dialogList="warnList.slice(0, 12)"
  25. @setConfig="displaySetting = true"
  26. @confirmed="handleConfirm"
  27. ref="deligoChild"
  28. @close="displayClose"
  29. v-if="displayAlarms == true"
  30. ></deligo-alarm-list>
  31. <alarmSetting
  32. v-if="displaySetting"
  33. @saveConfig="getAlarmConfig"
  34. @cancleConfig="displaySetting = false"
  35. :alarmConfigArray="alarmConfigArray"
  36. />
  37. </div> -->
  38. </template>
  39. <script>
  40. import deligoAlarmList from "@/components/deligoAlarmList";
  41. import alarmSetting from "@/components/alarm-badge/alarm-setting.vue";
  42. import { ElNotification } from "element-plus";
  43. import { alarm_history } from "@/api/zhbj/index.js";
  44. import dayjs from "dayjs";
  45. export default {
  46. name: "alarmBadge",
  47. components: {
  48. deligoAlarmList,
  49. alarmSetting,
  50. },
  51. data() {
  52. return {
  53. //实时报警弹窗ws
  54. socketObj1: "", // websocket实例对象
  55. //心跳检测
  56. heartCheck1: {
  57. vueThis1: this, // vue实例
  58. timeout1: 30000, // 超时时间
  59. timeoutObj1: null, // 计时器对象——向后端发送心跳检测
  60. serverTimeoutObj1: null, // 计时器对象——等待后端心跳检测的回复
  61. // 心跳检测重置
  62. reset: function () {
  63. clearTimeout(this.timeoutObj1);
  64. clearTimeout(this.serverTimeoutObj1);
  65. return this;
  66. },
  67. // 心跳检测启动
  68. start: function () {
  69. this.timeoutObj1 && clearTimeout(this.timeoutObj1);
  70. this.serverTimeoutObj1 && clearTimeout(this.serverTimeoutObj1);
  71. this.timeoutObj1 = setTimeout(() => {
  72. // 这里向后端发送一个心跳检测,后端收到后,会返回一个心跳回复
  73. this.vueThis1.socketObj1.send("HeartBeat");
  74. console.log("发送心跳检测1");
  75. this.serverTimeoutObj1 = setTimeout(() => {
  76. // 如果超过一定时间还没重置计时器,说明websocket与后端断开了
  77. console.log("未收到心跳检测回复1");
  78. // 关闭WebSocket
  79. this.vueThis1.socketObj1.close();
  80. }, this.timeout1);
  81. }, this.timeout1);
  82. },
  83. },
  84. socketReconnectTimer1: null, // 计时器对象——重连
  85. socketReconnectLock1: false, // WebSocket重连的锁
  86. socketLeaveFlag1: false, // 离开标记(解决 退出登录再登录 时出现的 多次相同推送 问题,出现的本质是多次建立了WebSocket连接)
  87. alarmList: [],
  88. dialogList: [],
  89. realList: [],
  90. //实时报警图标相关
  91. x: null,
  92. y: null,
  93. currentX: 0,
  94. currentY: 0,
  95. displayAlarms: false,
  96. indexNum: 0,
  97. data1: 0,
  98. dragging: false,
  99. initialX: 0,
  100. initialY: 0,
  101. timer: null,
  102. firstTime: null,
  103. lastTime: null,
  104. key: false,
  105. //请求参数
  106. requestAlarmHistoryParams: [
  107. {
  108. alarmType: "booststation",
  109. deviceType: "",
  110. },
  111. {
  112. alarmType: "inverter",
  113. deviceType: "",
  114. },
  115. {
  116. alarmType: "windturbine",
  117. deviceType: "",
  118. },
  119. {
  120. alarmType: "custom",
  121. deviceType: "inverter",
  122. },
  123. {
  124. alarmType: "custom",
  125. deviceType: "windturbine",
  126. },
  127. ],
  128. alarmConfigArray: [],
  129. displaySetting: false,
  130. seriousWarning: false,
  131. audioElement: null,
  132. };
  133. },
  134. computed: {
  135. warnLength() {
  136. return this.$store.state.warnList.length;
  137. },
  138. warnList() {
  139. return this.$store.state.warnList;
  140. },
  141. isLogined() {
  142. return this.$store.state.user?.loginState;
  143. },
  144. },
  145. created() {
  146. this.getAlarmConfig();
  147. this.x = window.innerWidth - 82;
  148. this.y = window.innerHeight - 32;
  149. let requestResult = [];
  150. this.requestAlarmHistoryParams.forEach(({ alarmType, deviceType }) => {
  151. requestResult.push(this.getAlarmHistory(alarmType, deviceType));
  152. });
  153. Promise.all(requestResult)
  154. .then((promiseResult) => {
  155. promiseResult.forEach(({ data }) => {
  156. data?.ls?.forEach((ele) => {
  157. this.pushALarmItem(ele);
  158. });
  159. });
  160. this.dialogList.sort((a, b) => {
  161. return b.ts - a.ts;
  162. });
  163. this.realList.sort((a, b) => {
  164. return b.ts - a.ts;
  165. });
  166. this.$store.commit("changeAlarmlist", this.alarmList);
  167. this.$store.commit("setWarning", this.dialogList);
  168. this.$store.commit("setWarningList", this.realList);
  169. if (!this.socketLeaveFlag) {
  170. // 没有离开——重连
  171. // websocket重连
  172. this.socketReconnect1();
  173. }
  174. })
  175. .catch(() => {
  176. requestResult.forEach((ele, index) => {
  177. ele
  178. .then(({ data }) => {
  179. data?.ls?.forEach((ele) => {
  180. this.pushALarmItem(ele);
  181. });
  182. })
  183. .catch((error) => {
  184. ElNotification({
  185. type: "error",
  186. title: "查询历史未处理报警请求出错!",
  187. dangerouslyUseHTMLString: true,
  188. message: `<div class="currentRequestErrorNotification">
  189. <p><span>主要参数:</p>
  190. <p style="color:var(--el-color-primary)"><span class="errorTitle">alarmType:</span><span class="errorDesc">"${this.requestAlarmHistoryParams[index].alarmType}"</span></p>
  191. <p style="color:var(--el-color-primary)"><span class="errorTitle">deviceType:</span><span class="errorDesc">"${this.requestAlarmHistoryParams[index].deviceType}"</span></p>
  192. <p style="color:var(--el-color-danger)"><span class="errorTitle">错误正文:</span><span class="errorDesc">${error}</span></p>
  193. </div>`,
  194. });
  195. });
  196. });
  197. });
  198. },
  199. mounted() {},
  200. unmounted() {
  201. console.log("离开标记", this.socketLeaveFlag);
  202. },
  203. methods: {
  204. setting() {
  205. this.displaySetting = true;
  206. },
  207. handleConfirm(flag) {
  208. this.playAudioEffect();
  209. if (flag) {
  210. this.dialogList = [];
  211. this.$store.commit("setWarning", this.dialogList);
  212. setTimeout(() => {
  213. this.$refs.deligoChild && this.$refs.deligoChild.init(this.warnList);
  214. }, 0);
  215. }
  216. },
  217. playAudioEffect() {
  218. // const lv1Config = this.getConfigItem(1);
  219. // let lv1Play = false;
  220. // if (lv1Config.isAlarmSound) {
  221. // lv1Play = this.dialogList.some((ele) => {
  222. // return ele.lv === 1 && !ele.confirm;
  223. // });
  224. // }
  225. // const lv2Config = this.getConfigItem(2);
  226. // let lv2Play = false;
  227. // if (lv2Config.isAlarmSound) {
  228. // lv2Play = this.dialogList.some((ele) => {
  229. // return ele.lv === 2 && !ele.confirm;
  230. // });
  231. // }
  232. // const lv3Config = this.getConfigItem(3);
  233. // let lv3Play = false;
  234. // if (lv3Config.isAlarmSound) {
  235. // lv3Play = this.dialogList.some((ele) => {
  236. // return ele.lv === 3 && !ele.confirm;
  237. // });
  238. // }
  239. // const lv4Config = this.getConfigItem(4);
  240. // let lv4Play = false;
  241. // if (lv4Config.isAlarmSound) {
  242. // lv4Play = this.dialogList.some((ele) => {
  243. // return ele.lv === 4 && !ele.confirm;
  244. // });
  245. // }
  246. // const lv5Config = this.getConfigItem(5);
  247. // let lv5Play = false;
  248. // if (lv5Config.isAlarmSound) {
  249. // lv5Play = this.dialogList.some((ele) => {
  250. // return ele.lv === 5 && !ele.confirm;
  251. // });
  252. // }
  253. // // console.log(lv1Play, lv2Play, lv3Play, lv4Play, lv5Play);
  254. // if (lv5Play && !this.seriousWarning) {
  255. // this.seriousWarning = true;
  256. // this.audioElement = new Audio();
  257. // this.audioElement.src = "./static/sound/lv5.mp3";
  258. // this.audioElement.loop = true;
  259. // this.audioElement?.play();
  260. // } else if (
  261. // (lv1Play || lv2Play || lv3Play || lv4Play) &&
  262. // !this.seriousWarning
  263. // ) {
  264. // this.audioElement = new Audio();
  265. // this.audioElement.src = "./static/sound/lv4.mp3";
  266. // this.audioElement.addEventListener("ended", () => {
  267. // this.audioElement?.removeEventListener(
  268. // "ended",
  269. // this.stopPlayAudioEffect
  270. // );
  271. // });
  272. // this.audioElement?.play();
  273. // } else {
  274. // if (!this.seriousWarning) {
  275. // this.stopPlayAudioEffect();
  276. // }
  277. // }
  278. },
  279. stopPlayAudioEffect() {
  280. // this.seriousWarning = false;
  281. // if (this.audioElement) {
  282. // this.audioElement.pause();
  283. // this.audioElement.currentTime = 0;
  284. // this.audioElement.loop = false;
  285. // }
  286. // this.audioElement = null;
  287. },
  288. //获取报警配置
  289. getAlarmConfig() {
  290. if (localStorage.getItem("alarmConfigArray")) {
  291. this.alarmConfigArray = JSON.parse(
  292. localStorage.getItem("alarmConfigArray")
  293. );
  294. } else {
  295. this.alarmConfigArray = [
  296. {
  297. id: "1",
  298. alarmLevel: 1,
  299. isAlart: false,
  300. isAlarmSound: false,
  301. isContinuousAlarm: false,
  302. },
  303. {
  304. id: "2",
  305. alarmLevel: 2,
  306. isAlart: false,
  307. isAlarmSound: false,
  308. isContinuousAlarm: false,
  309. },
  310. {
  311. id: "3",
  312. alarmLevel: 3,
  313. isAlart: false,
  314. isAlarmSound: false,
  315. isContinuousAlarm: false,
  316. },
  317. {
  318. id: "4",
  319. alarmLevel: 4,
  320. isAlart: true,
  321. isAlarmSound: true,
  322. isContinuousAlarm: false,
  323. },
  324. {
  325. id: "5",
  326. alarmLevel: 5,
  327. isAlart: true,
  328. isAlarmSound: true,
  329. isContinuousAlarm: true,
  330. },
  331. ];
  332. localStorage.setItem(
  333. "alarmConfigArray",
  334. JSON.stringify(this.alarmConfigArray)
  335. );
  336. }
  337. },
  338. getAlarmName(alarmItem) {
  339. let alarmName = "";
  340. if (alarmItem.deviceType === "booststation") {
  341. alarmName = "升压站报警";
  342. } else if (alarmItem.deviceType === "inverter") {
  343. alarmName = "光伏报警";
  344. } else if (alarmItem.deviceType === "windturbine") {
  345. alarmName = "设备报警";
  346. } else if (alarmItem.deviceType === "station") {
  347. alarmName = "场站";
  348. }
  349. if (alarmItem.alarmType === "custom") {
  350. alarmName = "自定义报警";
  351. }
  352. return alarmName;
  353. },
  354. getLvName(alarmItem) {
  355. if (alarmItem.rank === 1) {
  356. return "低级";
  357. } else if (alarmItem.rank === 2) {
  358. return "低中级";
  359. } else if (alarmItem.rank === 3) {
  360. return "中级";
  361. } else if (alarmItem.rank === 4) {
  362. return "中高级";
  363. } else if (alarmItem.rank === 5) {
  364. return "高级";
  365. }
  366. },
  367. //查历史报警
  368. getAlarmHistory(alarmType, deviceType) {
  369. let params = {
  370. pageNum: 1,
  371. pageSize: 50,
  372. alarmId: "",
  373. alarmType,
  374. deviceType,
  375. stationid: "",
  376. deviceid: "",
  377. modelId: "",
  378. components: "",
  379. description: "",
  380. isclose: false,
  381. begin: dayjs().add(-1, "hour").format("YYYY-MM-DD HH:mm:ss"),
  382. end: dayjs().format("YYYY-MM-DD HH:mm:ss"),
  383. };
  384. if (params.alarmType == "windturbine") {
  385. params.stationid = "SXJ_KGDL_DJY_FDC_STA";
  386. } else if (params.alarmType == "inverter") {
  387. params.stationid = "SXJ_KGDL_JR_GDC_STA";
  388. }
  389. return alarm_history(params, 12000);
  390. },
  391. pushALarmItem(alarmItem, type) {
  392. const configItem = this.getConfigItem(alarmItem.rank);
  393. const alarmOption = {
  394. id: alarmItem.id ? alarmItem.id : alarmItem.tbname,
  395. lv: alarmItem.rank,
  396. lvName: this.getLvName(alarmItem),
  397. rank: alarmItem.rank,
  398. confirmed: alarmItem.confirmed,
  399. class: `animate__bounceInRight lv${alarmItem.rank}`,
  400. deviceId: alarmItem.deviceId,
  401. faultCause: alarmItem.faultCause,
  402. resolvent: alarmItem.resolvent,
  403. characteristic: alarmItem.characteristic,
  404. code: alarmItem.code,
  405. wpName: alarmItem.stationName
  406. ? alarmItem.stationName
  407. : alarmItem.wpName,
  408. stationId: alarmItem.stationId ? alarmItem.stationId : alarmItem.wpId,
  409. isClose: alarmItem.closeTime ? true : alarmItem.endts ? true : false,
  410. isCloseName: alarmItem.closeTime
  411. ? "已解除"
  412. : alarmItem.endts
  413. ? "已解除"
  414. : "未解除",
  415. alarmId: alarmItem.alarmId,
  416. alarmType: alarmItem.alarmType,
  417. alarmName: this.getAlarmName(alarmItem),
  418. description: alarmItem.description,
  419. deviceType: alarmItem.deviceType,
  420. oval: alarmItem.oval,
  421. triggerType: alarmItem.triggerType,
  422. ts: alarmItem.ts
  423. ? dayjs(alarmItem.ts).valueOf()
  424. : dayjs(alarmItem.updateTime).valueOf(),
  425. endts: alarmItem.endts
  426. ? dayjs(alarmItem.endts).format("YYYY-MM-DD HH:mm:ss")
  427. : null,
  428. closeTime: alarmItem.closeTime
  429. ? dayjs(alarmItem.closeTime).format("YYYY-MM-DD HH:mm:ss")
  430. : null,
  431. deviceName: alarmItem.deviceName
  432. ? alarmItem.deviceName
  433. : alarmItem.code,
  434. tsName: alarmItem.ts
  435. ? new Date(alarmItem.ts).formatDate("MM-dd hh:mm:ss")
  436. : new Date(alarmItem.updateTime).formatDate("MM-dd hh:mm:ss"),
  437. fullTsName: alarmItem.ts
  438. ? new Date(alarmItem.ts).formatDate("yyyy-MM-dd hh:mm:ss")
  439. : new Date(alarmItem.updateTime).formatDate("yyyy-MM-dd hh:mm:ss"),
  440. };
  441. if (
  442. alarmOption.alarmType == "booststation" &&
  443. alarmOption.deviceType != "custom"
  444. ) {
  445. if (
  446. configItem.isAlarmSound ||
  447. configItem.isAlart ||
  448. configItem.isContinuousAlarm
  449. ) {
  450. let a = {};
  451. a[`${alarmOption.stationId}`] =
  452. alarmOption.closeTime || alarmOption.confirmed ? false : true;
  453. this.alarmList.push(a);
  454. this.alarmList = [
  455. ...new Set(this.alarmList.map((t) => JSON.stringify(t))),
  456. ].map((s) => JSON.parse(s));
  457. }
  458. }
  459. if (
  460. configItem.isAlarmSound ||
  461. configItem.isAlart ||
  462. configItem.isContinuousAlarm
  463. ) {
  464. if (type && type == "ws") {
  465. this.dialogList.unshift(alarmOption);
  466. } else {
  467. this.dialogList.push(alarmOption);
  468. }
  469. }
  470. if (type && type == "ws") {
  471. this.realList.unshift(alarmOption);
  472. } else {
  473. this.realList.push(alarmOption);
  474. }
  475. // && alarmOption.deviceType != "custom"
  476. this.playAudioEffect();
  477. },
  478. getConfigItem(lv) {
  479. return (
  480. this.alarmConfigArray.find((ele) => {
  481. return ele.alarmLevel === lv;
  482. }) || {}
  483. );
  484. },
  485. // 拖拽相关
  486. startDrag(event) {
  487. this.currentX = event.clientX;
  488. this.currentY = event.clientY;
  489. },
  490. stopDrag(event) {
  491. let x = event.clientX - this.currentX;
  492. let y = event.clientY - this.currentY;
  493. this.x += x;
  494. if (this.x < 60) {
  495. this.x = 60;
  496. } else if (this.x > window.innerWidth - 20) {
  497. this.x = window.innerWidth - 82;
  498. }
  499. this.y += y;
  500. if (this.y > window.innerHeight - 20) {
  501. this.y = window.innerHeight - 32;
  502. } else if (this.y < 0) {
  503. this.y = 0;
  504. }
  505. },
  506. //开关列表
  507. displayAlarm(val) {
  508. this.displayAlarms = !this.displayAlarms;
  509. if (this.displayAlarms == true) {
  510. setTimeout(() => {
  511. this.$refs.deligoChild && this.$refs.deligoChild.init(this.warnList);
  512. }, 0);
  513. }
  514. },
  515. displayClose() {
  516. this.displayAlarms = false;
  517. },
  518. // websocket启动
  519. createWebSocket1() {
  520. // let webSocketLink = `ws://192.168.1.102:6014/websocket/${this.$store.state.user.userId}_${this.$store.state.user.authToken}`;
  521. let webSocketLink1 = `ws://10.81.3.154:6014/websocket/${this.$store.state.user.userId}_${this.$store.state.user.authToken}`; // webSocket地址
  522. try {
  523. if ("WebSocket" in window) {
  524. this.socketObj1 = new WebSocket(webSocketLink1);
  525. }
  526. // websocket事件绑定
  527. this.socketEventBind1();
  528. } catch (e) {
  529. console.log("catch" + e);
  530. // websocket重连
  531. this.socketReconnect1();
  532. }
  533. },
  534. // websocket事件绑定
  535. socketEventBind1() {
  536. // 连接成功建立的回调
  537. this.socketObj1.onopen = this.onopenCallback1;
  538. // 连接发生错误的回调
  539. this.socketObj1.onerror = this.onerrorCallback1;
  540. // 连接关闭的回调
  541. this.socketObj1.onclose = this.oncloseCallback1;
  542. // 向后端发送数据的回调
  543. this.socketObj1.onsend = this.onsendCallback1;
  544. // 接收到消息的回调
  545. this.socketObj1.onmessage = this.getMessageCallback1;
  546. //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
  547. window.onbeforeunload = () => {
  548. this.socketObj1.close();
  549. };
  550. },
  551. // websocket重连
  552. socketReconnect1() {
  553. if (this.socketReconnectLock1) {
  554. return;
  555. }
  556. this.socketReconnectLock1 = true;
  557. this.socketReconnectTimer1 && clearTimeout(this.socketReconnectTimer1);
  558. this.socketReconnectTimer1 = setTimeout(() => {
  559. console.log("WebSocket1:重连中...");
  560. this.socketReconnectLock1 = false;
  561. // websocket启动
  562. this.createWebSocket1();
  563. }, 4000);
  564. },
  565. // 连接成功建立的回调
  566. onopenCallback1: function (event) {
  567. console.log("WebSocket1:已连接");
  568. // 心跳检测重置
  569. this.heartCheck1.reset().start();
  570. },
  571. // 连接发生错误的回调
  572. onerrorCallback1: function (event) {
  573. console.log("WebSocket1:发生错误");
  574. // websocket重连
  575. this.socketReconnect1();
  576. },
  577. // 连接关闭的回调
  578. oncloseCallback1: function (event) {
  579. console.log("WebSocket1:已关闭");
  580. // 心跳检测重置
  581. this.heartCheck1.reset();
  582. if (!this.socketLeaveFlag1) {
  583. // 没有离开——重连
  584. // websocket重连
  585. this.socketReconnect1();
  586. }
  587. },
  588. // 向后端发送数据的回调
  589. onsendCallback1: function () {
  590. console.log("WebSocket1:发送信息给后端");
  591. },
  592. // 接收到消息的回调
  593. getMessageCallback1: function (msg) {
  594. // console.log(msg);
  595. if (Object.keys(msg) && msg.data == "ok") {
  596. // 心跳回复——心跳检测重置
  597. // 收到心跳检测回复就说明连接正常
  598. console.log("收到心跳检测回复1");
  599. // 心跳检测重置
  600. this.heartCheck1.reset().start();
  601. } else {
  602. // 普通推送——正常处理
  603. let data = JSON.parse(msg.data);
  604. // 相关处理
  605. if (data) {
  606. // console.log("收到推送消息1", data);
  607. this.pushALarmItem(data, "ws");
  608. // this.dialogList.sort((a, b) => {
  609. // return b.lv - a.lv;
  610. // });
  611. this.$store.commit("changeAlarmlist", this.alarmList);
  612. this.$store.commit("setWarning", this.dialogList);
  613. this.$store.commit("setWarningList", this.realList);
  614. }
  615. }
  616. },
  617. },
  618. watch: {
  619. isLogined: {
  620. handler(res) {
  621. if (!res && this.socketObj1) {
  622. // 离开标记
  623. this.socketLeaveFlag1 = true;
  624. // 关闭WebSocket
  625. this.socketObj1.close();
  626. }
  627. },
  628. immediate: true,
  629. },
  630. },
  631. };
  632. </script>
  633. <style lang="less" scoped>
  634. .alarmDeligo {
  635. z-index: 2003;
  636. position: relative;
  637. img {
  638. width: 43px;
  639. max-width: 43px;
  640. height: 43px;
  641. z-index: 3;
  642. }
  643. img:first-child {
  644. width: 53px;
  645. height: 57px;
  646. max-width: 53px;
  647. top: -7px;
  648. left: -5px;
  649. position: absolute;
  650. z-index: 3;
  651. }
  652. }
  653. .el-badge {
  654. &.active {
  655. .el-badge__content--danger {
  656. opacity: 0 !important;
  657. }
  658. }
  659. }
  660. .el-badge__content--danger {
  661. background: #ff4e00 !important;
  662. border: none !important;
  663. }
  664. .el-badge__content.is-fixed {
  665. top: 7px !important;
  666. right: 14px !important;
  667. z-index: 2003 !important;
  668. }
  669. .trans {
  670. animation: circleProgess 3s linear infinite;
  671. }
  672. @keyframes circleProgess {
  673. 0% {
  674. transform: rotateZ(360deg);
  675. }
  676. 25% {
  677. transform: rotateZ(270deg);
  678. }
  679. 50% {
  680. transform: rotateZ(180deg);
  681. }
  682. 75% {
  683. transform: rotateZ(90deg);
  684. }
  685. 100% {
  686. transform: rotateZ(0deg);
  687. }
  688. }
  689. </style>