123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- <template>
- <div class="alarmBox" :class="alarmList?.length ? 'notEmpty' : ''">
- <div
- :class="`${index < 6 ? item.class + ' alarmItem animate__animated' : ''}`"
- v-for="(item, index) in alarmList"
- :key="index"
- >
- <template v-if="index < 6">
- <div class="alarmTitle">{{ item.alarmName }}</div>
- <div class="alarmContent">
- <div class="contentItem">报警描述: {{ item.description }}</div>
- <div class="contentItem">报警时间: {{ item.tsName }}</div>
- </div>
- <div class="btnBox" :class="`lv${item.lv}BdColor`">
- <div class="btnItem" :class="`lv${item.lv}BdColor lv${item.lv}`">
- <el-button
- class="comfirmBtn"
- size="small"
- type="text"
- @click="comfirm(item)"
- >确认本条</el-button
- >
- </div>
- <div class="btnItem" :class="`lv${item.lv}`">
- <el-button
- class="comfirmBtn"
- size="small"
- type="text"
- @click="comfirmAll"
- >全部确认</el-button
- >
- </div>
- </div>
- </template>
- </div>
- </div>
- </template>
- <script>
- import { confirmAlart } from "@api/api.js";
- export default {
- data() {
- return {
- alarmList: [],
- seriousWarning: false,
- audioElement: null,
- ws: null,
- timeConnect: 0,
- limitConnect: 5,
- };
- },
- created() {
- this.webSocketInit(
- `ws://10.81.3.154:6014/websocket/${this.$store.state.user.authToken}`
- );
- },
- unmounted() {
- this.ws?.close();
- },
- methods: {
- getAlarmName(alarmItem) {
- let alarmName = "";
- if (alarmItem.deviceType === "booststation") {
- alarmName = "升压站报警";
- } else if (alarmItem.deviceType === "inverter") {
- alarmName = "逆变器报警";
- } else if (alarmItem.deviceType === "windturbine") {
- alarmName = "设备报警";
- } else if (alarmItem.deviceType === "station") {
- alarmName = "场站";
- }
- if (alarmItem.alarmType === "custom") {
- alarmName = "自定义报警";
- }
- return alarmName;
- },
- getLvName(alarmItem) {
- if (alarmItem.rank === 1) {
- return "低级";
- } else if (alarmItem.rank === 2) {
- return "低中级";
- } else if (alarmItem.rank === 3) {
- return "中级";
- } else if (alarmItem.rank === 4) {
- return "中高级";
- } else if (alarmItem.rank === 5) {
- return "高级";
- }
- },
- comfirm(item) {
- this.$confirm("您确定要执行此操作吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }).then(() => {
- item.class = `animate__bounceOutRight lv${item.lv}`;
- item.confirm = true;
- setTimeout(() => {
- item.class = `animate__bounceOutRight hidden lv${item.lv}`;
- confirmAlart([item]).then((res) => {
- if (res.code === 200) {
- this.BASE.showMsg({
- type: "success",
- msg: "确认成功",
- });
- this.$store.commit("removeWarning", item);
- this.playAudioEffect();
- }
- });
- }, 500);
- });
- },
- comfirmAll() {
- this.$confirm("您确定要执行此操作吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }).then(() => {
- for (let i = 0; i < this.alarmList.length; i++) {
- if (!this.alarmList[i].comfirm) {
- this.alarmList[
- i
- ].class = `animate__bounceOutRight lv${this.alarmList[i].lv}`;
- this.alarmList[i].confirm = true;
- setTimeout(() => {
- this.alarmList[
- i
- ].class = `animate__bounceOutRight hidden lv${this.alarmList[i].lv}`;
- }, 500);
- }
- }
- confirmAlart(this.alarmList).then((res) => {
- if (res.code === 200) {
- this.BASE.showMsg({
- type: "success",
- msg: "全部确认成功",
- });
- this.$store.commit("emptyWarning");
- this.playAudioEffect();
- }
- });
- this.playAudioEffect();
- });
- },
- getRandomNumber(min, max) {
- return Math.floor(Math.random() * (max - min + 1)) + min;
- },
- playAudioEffect() {
- const fiveLvWarning = this.alarmList.some((ele) => {
- return ele.lv === 5 && !ele.confirm;
- });
- const fourLvWarning = this.alarmList.some((ele) => {
- return ele.lv === 4 && !ele.confirm;
- });
- if (fiveLvWarning && !this.seriousWarning) {
- this.seriousWarning = true;
- this.audioElement = new Audio();
- this.audioElement.src = "./static/sound/lv5.mp3";
- this.audioElement.loop = true;
- this.audioElement?.play();
- } else if (fourLvWarning && !this.seriousWarning) {
- this.audioElement = new Audio();
- this.audioElement.src = "./static/sound/lv4.mp3";
- this.audioElement.addEventListener("ended", () => {
- this.audioElement.removeEventListener(
- "ended",
- this.stopPlayAudioEffect
- );
- });
- this.audioElement?.play();
- } else {
- if (!this.seriousWarning) {
- this.stopPlayAudioEffect();
- }
- }
- },
- stopPlayAudioEffect() {
- this.seriousWarning = false;
- if (this.audioElement) {
- this.audioElement.pause();
- this.audioElement.currentTime = 0;
- this.audioElement.loop = false;
- }
- this.audioElement = null;
- },
- webSocketInit(serveIP) {
- if ("WebSocket" in window) {
- this.ws = new WebSocket(serveIP);
- this.ws.onmessage = (res) => {
- let alarmItem = JSON.parse(res.data);
- if (alarmItem) {
- const alarmOption = {
- id: alarmItem.id,
- lv: alarmItem.rank,
- lvName: this.getLvName(alarmItem),
- rank: alarmItem.rank,
- class: `animate__bounceInRight lv${alarmItem.rank}`,
- isClose: alarmItem.isClose,
- isCloseName: alarmItem.isClose ? "是" : "否",
- alarmType: alarmItem.alarmType,
- alarmName: this.getAlarmName(alarmItem),
- description: alarmItem.description,
- deviceType: alarmItem.deviceType,
- oval: alarmItem.oval,
- triggerType: alarmItem.triggerType,
- ts: alarmItem.ts,
- tsName: new Date(alarmItem.ts).formatDate("yyyy-MM-dd hh:mm:ss"),
- deviceId: alarmItem.deviceId,
- deviceType: alarmItem.deviceType,
- faultCause: alarmItem.faultCause,
- resolvent: alarmItem.resolvent,
- characteristic: alarmItem.characteristic,
- code: alarmItem.code,
- };
- this.alarmList.push(alarmOption);
- this.$store.commit("setWarning", alarmOption);
- this.alarmList.sort((a, b) => {
- return b.lv - a.lv;
- });
- this.playAudioEffect();
- }
- };
- this.ws.onclose = () => {
- this.ws = null;
- };
- this.ws.onopen = () => {
- this.timeConnect = 0;
- console.log("WebSocket 服务已建立");
- };
- this.ws.onerror = () => {
- this.reconnect(serveIP);
- };
- } else {
- this.BASE.showMsg({
- msg: "当前浏览器不支持 WebSocket ,请更换浏览器后重试",
- });
- }
- },
- reconnect(serveIP) {
- if (this.timeConnect < this.limitConnect) {
- console.log(`webSocket 连接失败,第 ${++this.timeConnect} 次重连`);
- setTimeout(() => {
- this.webSocketInit(serveIP);
- }, 2000);
- } else {
- console.log("webSocket 连接已超时");
- this.BASE.showMsg({
- showClose: true,
- duration: 0,
- msg: `webSocket 连接超时,实时报警获取失败`,
- });
- this.ws?.close();
- }
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .alarmBox {
- width: 240px;
- height: calc(100% - 85px);
- padding: 0 12px 0 30px;
- position: absolute;
- right: 0;
- bottom: 0;
- z-index: 5000;
- display: flex;
- flex-direction: column-reverse;
- align-items: center;
- font-size: 12px;
- overflow-y: scroll;
- pointer-events: none;
- border-radius: 8px;
- transition: 0.2s;
- .alarmItem {
- width: 100%;
- box-sizing: border-box;
- border-radius: 8px;
- border: 1px solid #ebeef5;
- background: #1890ff;
- margin-bottom: 4px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- color: #fff;
- pointer-events: auto;
- cursor: pointer;
- .alarmTitle {
- display: flex;
- justify-content: flex-start;
- align-content: center;
- width: calc(100% - 16px);
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- padding: 0 8px;
- margin-top: 8px;
- }
- .alarmContent {
- width: calc(100% - 16px);
- display: flex;
- justify-content: flex-start;
- align-items: flex-start;
- flex-wrap: wrap;
- margin-top: 4px;
- padding: 0 8px;
- .contentItem {
- width: 100%;
- display: flex;
- justify-content: flex-start;
- align-items: center;
- margin-bottom: 2px;
- word-wrap: break-word;
- &:last-child {
- margin-bottom: 0;
- }
- }
- }
- .btnBox {
- display: flex;
- width: 100%;
- justify-content: center;
- align-items: center;
- margin-top: 4px;
- border-top: 1px solid red;
- .btnItem {
- width: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 4px 0;
- .el-button {
- padding: 0;
- width: 45%;
- height: 20px;
- min-height: 20px;
- }
- &.lv1 .el-button,
- &.lv2 .el-button,
- &.lv3 .el-button {
- color: var(--el-color-info) !important;
- }
- &.lv4 .el-button {
- color: rgb(50, 65, 87) !important;
- }
- &.lv5 .el-button {
- color: #242f42;
- }
- &:first-child {
- border-right: 1px solid red;
- }
- }
- }
- &.lv5 {
- background: #fef0f0;
- border: 1px solid #242f42;
- color: #242f42;
- }
- &.lv4 {
- background: #f0f9eb;
- border: 1px solid rgb(50, 65, 87);
- color: rgb(50, 65, 87);
- }
- &.lv1,
- &.lv2,
- &.lv3 {
- background: #fdf6ec;
- border: 1px solid var(--el-color-info);
- color: var(--el-color-info);
- }
- .lv1BdColor,
- .lv2BdColor,
- .lv3BdColor {
- border-color: var(--el-color-info) !important;
- }
- .lv4BdColor {
- border-color: rgb(50, 65, 87) !important;
- }
- .lv5BdColor {
- border-color: #242f42 !important;
- }
- &.hidden {
- height: 0;
- padding: 0;
- margin-bottom: 0;
- border: 0;
- transition: 0.2s;
- overflow: hidden;
- }
- }
- &::-webkit-scrollbar {
- width: 0; /* 隐藏Webkit浏览器的滚动条宽度 */
- height: 0; /* 隐藏Webkit浏览器的滚动条高度 */
- }
- &.notEmpty:hover {
- background: rgba(0, 0, 0, 0.12);
- box-shadow: 0 0 12px rgba(0, 0, 0, 0.12);
- transition: 0.2s;
- }
- }
- </style>
|