|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
- <div style="position: fixed; z-index: 999; right: 95px; top: 18px; color: #fff">
|
|
|
+ <div style="position: fixed; z-index: 999; right: 120px; top: 20px; color: #fff">
|
|
|
<div class="btn" @click="showWarningBroad">
|
|
|
<a-badge :dot="isWarningDot">
|
|
|
<BellOutlined style="font-size: 22px; color: #fff; margin-right: 20px" />
|
|
@@ -9,24 +9,23 @@
|
|
|
<div class="title">
|
|
|
<div class="message-title">预警通知</div>
|
|
|
<div class="badge-box">
|
|
|
- <SoundOutlined :class="{ 'no-play': !isBroad }" style="font-size: 20px; color: #000" @click="handleBroad" />
|
|
|
+ <SoundOutlined :class="{ 'no-play': !isBroad }" style="font-size: 16px; color: #fff" @click="handleBroad" />
|
|
|
+
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="broadcast-context">
|
|
|
<div class="context-tab">
|
|
|
- <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 0 }" @click="toSelectList(0)">全部</div>
|
|
|
- <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 1 }" @click="toSelectList(1)">未读</div>
|
|
|
- <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 2 }" @click="toSelectList(2)">已读</div>
|
|
|
+ <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 0 }" @click="toSelectList(0)">
|
|
|
+ 全部</div>
|
|
|
+ <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 1 }" @click="toSelectList(1)">
|
|
|
+ 未读</div>
|
|
|
+ <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 2 }" @click="toSelectList(2)">
|
|
|
+ 已读</div>
|
|
|
</div>
|
|
|
<div class="context-box">
|
|
|
<div v-if="broadcastList.length == 0" class="no-context">暂无内容</div>
|
|
|
- <div
|
|
|
- class="context-detail"
|
|
|
- v-else
|
|
|
- v-for="(item, index) in broadcastList"
|
|
|
- :key="index"
|
|
|
- :style="{ color: item['isok'] == 0 ? 'red' : '#000' }"
|
|
|
- >
|
|
|
+ <div class="context-detail" v-else v-for="(item, index) in broadcastList" :key="index"
|
|
|
+ :style="{ color: item['isok'] == 0 ? 'red' : '#eee' }">
|
|
|
<div>{{ item['createTime'] }}</div>
|
|
|
<div>{{ item['devicekind_dictText'] }}</div>
|
|
|
<div>{{ item['wardescrip'] || item['nwartype_dictText'] }}</div>
|
|
@@ -39,197 +38,232 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script lang="ts">
|
|
|
- import { Tooltip, Badge } from 'ant-design-vue';
|
|
|
- import { SoundOutlined, BellOutlined, WarningOutlined } from '@ant-design/icons-vue';
|
|
|
- import Icon from '/@/components/Icon';
|
|
|
- import { defineComponent, ref, unref, onMounted } from 'vue';
|
|
|
- import { defHttp } from '/@/utils/http/axios';
|
|
|
- import { useRouter } from 'vue-router';
|
|
|
- import { connectWebSocket, onWebSocket } from '/@/hooks/web/useWebSocket';
|
|
|
- import { getToken } from '/@/utils/auth';
|
|
|
- import { useUserStore } from '/@/store/modules/user';
|
|
|
- import { useGlobSetting } from '/@/hooks/setting';
|
|
|
- import SpeakVoice from './notify/speakVoice';
|
|
|
-
|
|
|
- export default defineComponent({
|
|
|
- name: 'VoiceBroadcast',
|
|
|
- components: { Icon, Tooltip, Badge, SoundOutlined, BellOutlined, WarningOutlined },
|
|
|
-
|
|
|
- setup() {
|
|
|
- const speakVoice = new SpeakVoice();
|
|
|
- const userStore = useUserStore();
|
|
|
- const glob = useGlobSetting();
|
|
|
- const router = useRouter();
|
|
|
- const list = (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params });
|
|
|
- const activeKey = ref(0);
|
|
|
- const isShowWarningBroad = ref(false);
|
|
|
- const isBroad = ref(true);
|
|
|
- const isWarningDot = ref(false);
|
|
|
- const broadcastList = ref([]);
|
|
|
- function showWarningBroad() {
|
|
|
- isShowWarningBroad.value = !isShowWarningBroad.value;
|
|
|
- if (isShowWarningBroad.value) {
|
|
|
- toSelectList(0);
|
|
|
- }
|
|
|
- }
|
|
|
+import { Tooltip, Badge } from 'ant-design-vue';
|
|
|
+import { SoundOutlined, BellOutlined, WarningOutlined } from '@ant-design/icons-vue';
|
|
|
+import Icon from '/@/components/Icon';
|
|
|
+import { defineComponent, ref, unref, onMounted } from 'vue';
|
|
|
+import { defHttp } from '/@/utils/http/axios';
|
|
|
+import { useRouter } from 'vue-router';
|
|
|
+import { connectWebSocket, onWebSocket } from '/@/hooks/web/useWebSocket';
|
|
|
+import { getToken } from '/@/utils/auth';
|
|
|
+import { useUserStore } from '/@/store/modules/user';
|
|
|
+import { useGlobSetting } from '/@/hooks/setting';
|
|
|
+import SpeakVoice from './notify/speakVoice';
|
|
|
|
|
|
- function handleBroad() {
|
|
|
- isBroad.value = !isBroad.value;
|
|
|
- }
|
|
|
+export default defineComponent({
|
|
|
+ name: 'VoiceBroadcast',
|
|
|
+ components: { Icon, Tooltip, Badge, SoundOutlined, BellOutlined, WarningOutlined },
|
|
|
|
|
|
- async function toSelectList(key) {
|
|
|
- activeKey.value = key;
|
|
|
- const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null });
|
|
|
- broadcastList.value = res['records'];
|
|
|
- // const isHasWarning = broadcastList.value.findIndex((item) => !item['isok']);
|
|
|
- // isWarningDot.value = isHasWarning > -1 ? true : false;
|
|
|
+ setup() {
|
|
|
+ const speakVoice = new SpeakVoice();
|
|
|
+ const userStore = useUserStore();
|
|
|
+ const glob = useGlobSetting();
|
|
|
+ const router = useRouter();
|
|
|
+ const list = (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params });
|
|
|
+ const activeKey = ref(0);
|
|
|
+ const isShowWarningBroad = ref(false);
|
|
|
+ const isBroad = ref(true);
|
|
|
+ const isWarningDot = ref(false);
|
|
|
+ const broadcastList = ref([]);
|
|
|
+ function showWarningBroad() {
|
|
|
+ isShowWarningBroad.value = !isShowWarningBroad.value;
|
|
|
+ if (isShowWarningBroad.value) {
|
|
|
+ toSelectList(0);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- async function toMore() {
|
|
|
- await router.push({ path: '/monitorChannel/device-monitor/warningHistory' });
|
|
|
- showWarningBroad();
|
|
|
- }
|
|
|
+ function handleBroad() {
|
|
|
+ isBroad.value = !isBroad.value;
|
|
|
+ }
|
|
|
|
|
|
- // 初始化 WebSocket
|
|
|
- function initWebSocket() {
|
|
|
- let token = getToken();
|
|
|
- //将登录token生成一个短的标识
|
|
|
- // let wsClientId = md5(token);
|
|
|
- // let userId = unref(userStore.getUserInfo).id + '_' + wsClientId;
|
|
|
- let userId = unref(userStore.getUserInfo).id + '?token=' + token;
|
|
|
- // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
|
|
|
- let url = glob.wsUrl?.replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId;
|
|
|
- connectWebSocket(url);
|
|
|
- onWebSocket(onWebSocketMessage);
|
|
|
- }
|
|
|
+ async function toSelectList(key) {
|
|
|
+ activeKey.value = key;
|
|
|
+ const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null });
|
|
|
+ broadcastList.value = res['records'];
|
|
|
+ // const isHasWarning = broadcastList.value.findIndex((item) => !item['isok']);
|
|
|
+ // isWarningDot.value = isHasWarning > -1 ? true : false;
|
|
|
+ }
|
|
|
|
|
|
- function onWebSocketMessage(data) {
|
|
|
- // console.log('WebSocket 监测消息--------------》', data);
|
|
|
- if (data.topic === 'warn' || data.cmd === 'user') {
|
|
|
- if (isBroad.value) {
|
|
|
- const messageText = data['warndata'];
|
|
|
- // const messageText = '这是一个测试';
|
|
|
- speakVoice.handleReply(messageText);
|
|
|
- }
|
|
|
- if (!isShowWarningBroad.value) {
|
|
|
- isWarningDot.value = true;
|
|
|
- } else {
|
|
|
- isWarningDot.value = false;
|
|
|
- }
|
|
|
- setTimeout(() => {
|
|
|
- if (isShowWarningBroad.value) {
|
|
|
- toSelectList(0);
|
|
|
- }
|
|
|
- }, 0);
|
|
|
+ async function toMore() {
|
|
|
+ await router.push({ path: '/monitorChannel/device-monitor/warningHistory' });
|
|
|
+ showWarningBroad();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化 WebSocket
|
|
|
+ function initWebSocket() {
|
|
|
+ let token = getToken();
|
|
|
+ //将登录token生成一个短的标识
|
|
|
+ // let wsClientId = md5(token);
|
|
|
+ // let userId = unref(userStore.getUserInfo).id + '_' + wsClientId;
|
|
|
+ let userId = unref(userStore.getUserInfo).id + '?token=' + token;
|
|
|
+ // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
|
|
|
+ let url = glob.wsUrl?.replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId;
|
|
|
+ connectWebSocket(url);
|
|
|
+ onWebSocket(onWebSocketMessage);
|
|
|
+ }
|
|
|
+
|
|
|
+ function onWebSocketMessage(data) {
|
|
|
+ // console.log('WebSocket 监测消息--------------》', data);
|
|
|
+ if (data.topic === 'warn' || data.cmd === 'user') {
|
|
|
+ if (isBroad.value) {
|
|
|
+ const messageText = data['warndata'];
|
|
|
+ // const messageText = '这是一个测试';
|
|
|
+ speakVoice.handleReply(messageText);
|
|
|
}
|
|
|
+ if (!isShowWarningBroad.value) {
|
|
|
+ isWarningDot.value = true;
|
|
|
+ } else {
|
|
|
+ isWarningDot.value = false;
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ if (isShowWarningBroad.value) {
|
|
|
+ toSelectList(0);
|
|
|
+ }
|
|
|
+ }, 0);
|
|
|
}
|
|
|
- onMounted(() => {
|
|
|
- initWebSocket();
|
|
|
- });
|
|
|
+ }
|
|
|
+ onMounted(() => {
|
|
|
+ initWebSocket();
|
|
|
+ });
|
|
|
|
|
|
- return { showWarningBroad, isShowWarningBroad, activeKey, toSelectList, broadcastList, toMore, isBroad, handleBroad, isWarningDot };
|
|
|
- },
|
|
|
- });
|
|
|
+ return { showWarningBroad, isShowWarningBroad, activeKey, toSelectList, broadcastList, toMore, isBroad, handleBroad, isWarningDot };
|
|
|
+ },
|
|
|
+});
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
- .btn {
|
|
|
- line-height: 30px;
|
|
|
- margin-right: 20px;
|
|
|
- cursor: pointer;
|
|
|
- display: flex;
|
|
|
- }
|
|
|
- .no-play {
|
|
|
- background: linear-gradient(
|
|
|
- to bottom left,
|
|
|
+.btn {
|
|
|
+ line-height: 30px;
|
|
|
+ margin-right: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ display: flex;
|
|
|
+}
|
|
|
+
|
|
|
+.no-play {
|
|
|
+ background: linear-gradient(to bottom left,
|
|
|
transparent 0%,
|
|
|
transparent calc(50% - 1px),
|
|
|
#000000 50%,
|
|
|
transparent calc(50% + 1px),
|
|
|
- transparent 100%
|
|
|
- );
|
|
|
- }
|
|
|
- .broadcast {
|
|
|
- width: 400px;
|
|
|
- height: 250px;
|
|
|
- border-radius: 4px;
|
|
|
- position: fixed;
|
|
|
- top: 42px;
|
|
|
- right: 20px;
|
|
|
- background-color: rgb(255, 255, 255);
|
|
|
- z-index: 9999999;
|
|
|
- color: #000;
|
|
|
- .title {
|
|
|
- height: 48px;
|
|
|
- padding: 0 20px;
|
|
|
- box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
|
|
|
- :deep(.ant-badge:not(.ant-badge-status)) {
|
|
|
- margin-right: 40px !important;
|
|
|
- }
|
|
|
+ transparent 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.broadcast {
|
|
|
+ width: 400px;
|
|
|
+ height: 250px;
|
|
|
+ border-radius: 4px;
|
|
|
+ position: fixed;
|
|
|
+ top: 50px;
|
|
|
+ right: 20px;
|
|
|
+ background-color: rgb(255, 255, 255);
|
|
|
+ background: url('../../../../assets/images/warn-dialog-bg.png') no-repeat center;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ z-index: 9999999;
|
|
|
+ color: #FFF;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 20px;
|
|
|
+
|
|
|
+ :deep(.ant-badge:not(.ant-badge-status)) {
|
|
|
+ margin-right: 40px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 5px;
|
|
|
+
|
|
|
+ .message-title {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .badge-box {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- margin-bottom: 5px;
|
|
|
- .message-title {
|
|
|
- font-size: 20px;
|
|
|
- // font-weight: 600;
|
|
|
+
|
|
|
+ .badge-title {
|
|
|
+ display: inline-block;
|
|
|
+ width: 62px;
|
|
|
+ line-height: 32px;
|
|
|
+ background-color: #2174f0;
|
|
|
+ border-radius: 26px;
|
|
|
+ text-align: center;
|
|
|
+ color: #fff;
|
|
|
+ padding-bottom: 2px;
|
|
|
}
|
|
|
- .badge-box {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- .badge-title {
|
|
|
- display: inline-block;
|
|
|
- width: 62px;
|
|
|
- line-height: 24px;
|
|
|
- background-color: #2174f0;
|
|
|
- border-radius: 26px;
|
|
|
- text-align: center;
|
|
|
- color: #fff;
|
|
|
- padding-bottom: 2px;
|
|
|
- }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .broadcast-context {
|
|
|
+ .context-tab {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ .context-tab-item {
|
|
|
+ line-height: 24px;
|
|
|
+ background-color: #6b6b6b;
|
|
|
+ border-radius: 24px;
|
|
|
+ text-align: center;
|
|
|
+ padding: 0 10px;
|
|
|
+ color: #fff;
|
|
|
+ margin: 5px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .context-tab-item-active {
|
|
|
+ background-color: #2174f0;
|
|
|
}
|
|
|
}
|
|
|
- .broadcast-context {
|
|
|
- .context-tab {
|
|
|
+
|
|
|
+ .context-box {
|
|
|
+ flex: 1;
|
|
|
+ padding: 0 10px;
|
|
|
+ height: 178px;
|
|
|
+ overflow-y: auto;
|
|
|
+
|
|
|
+ .no-context {
|
|
|
display: flex;
|
|
|
- .context-tab-item {
|
|
|
- line-height: 30px;
|
|
|
- background-color: #6b6b6b;
|
|
|
- border-radius: 26px;
|
|
|
- text-align: center;
|
|
|
- padding: 0 10px;
|
|
|
- color: #fff;
|
|
|
- margin: 5px;
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
- .context-tab-item-active {
|
|
|
- background-color: #2174f0;
|
|
|
- }
|
|
|
+ justify-content: center;
|
|
|
+ padding-top: 30px;
|
|
|
+ font-size: 16px;
|
|
|
}
|
|
|
- .context-box {
|
|
|
- flex: 1;
|
|
|
- padding: 0 10px;
|
|
|
- height: 150px;
|
|
|
- overflow-y: auto;
|
|
|
- .no-context {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- padding-top: 30px;
|
|
|
- font-size: 16px;
|
|
|
- }
|
|
|
- .context-detail {
|
|
|
+
|
|
|
+ .context-detail {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ line-height: 24px;
|
|
|
+ padding: 0px 3px;
|
|
|
+
|
|
|
+ div {
|
|
|
display: flex;
|
|
|
- div {
|
|
|
- padding: 0 3px;
|
|
|
- line-height: 24px;
|
|
|
+ justify-content: flex-start;
|
|
|
+
|
|
|
+ &:nth-child(1) {
|
|
|
+ width: 40%;
|
|
|
}
|
|
|
- }
|
|
|
- .more {
|
|
|
- cursor: pointer;
|
|
|
- &:hover {
|
|
|
- color: #2174f0;
|
|
|
+
|
|
|
+ &:nth-child(2) {
|
|
|
+ width: 20%;
|
|
|
}
|
|
|
+
|
|
|
+ &:nth-child(3) {
|
|
|
+ width: 25%;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:nth-child(4) {
|
|
|
+ width: 15%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .more {
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #2174f0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
</style>
|