|
@@ -1,180 +1,186 @@
|
|
|
<template>
|
|
|
- <div>
|
|
|
- <div class="btn" @click="showWarningBroad">
|
|
|
- <a-badge :dot="isWarningDot" style="display: flex; flex-direction: row">
|
|
|
- <BellOutlined style="font-size: 22px; color: #fff; margin-right: 10px" />
|
|
|
- <WarningOutlined style="font-size: 22px; color: #fff" />
|
|
|
- </a-badge>
|
|
|
+ <div>
|
|
|
+ <div class="btn" @click="showWarningBroad">
|
|
|
+ <a-badge :dot="isWarningDot" style="display: flex; flex-direction: row">
|
|
|
+ <BellOutlined style="font-size: 22px; color: #fff; margin-right: 10px" />
|
|
|
+ <WarningOutlined style="font-size: 22px; color: #fff" />
|
|
|
+ </a-badge>
|
|
|
+ </div>
|
|
|
+ <div v-if="isShowWarningBroad" class="broadcast" ref="VoiceBroadcastRef" id="VoiceBroadcast">
|
|
|
+ <div class="title">
|
|
|
+ <div class="message-title">预警通知</div>
|
|
|
+ <div class="badge-box">
|
|
|
+ <ClearOutlined style="font-size: 20px; color: #fff" @click="clearInfo" />
|
|
|
+ <!-- <SoundOutlined :class="{ 'no-play': !isBroad }" style="font-size: 20px; color: #fff" @click="handleBroad" /> -->
|
|
|
</div>
|
|
|
- <div v-if="isShowWarningBroad" class="broadcast" ref="VoiceBroadcastRef" id="VoiceBroadcast">
|
|
|
- <div class="title">
|
|
|
- <div class="message-title">预警通知</div>
|
|
|
- <div class="badge-box">
|
|
|
- <ClearOutlined style="font-size: 20px; color: #fff" @click="clearInfo" />
|
|
|
- <!-- <SoundOutlined :class="{ 'no-play': !isBroad }" style="font-size: 20px; 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 }"> 全部</div>
|
|
|
- <!-- <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 1 }"
|
|
|
+ </div>
|
|
|
+ <div class="broadcast-context">
|
|
|
+ <div class="context-tab">
|
|
|
+ <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 0 }"> 全部</div>
|
|
|
+ <!-- <div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 1 }"
|
|
|
> 未解决</div>
|
|
|
<div class="context-tab-item" :class="{ 'context-tab-item-active': activeKey == 2 }"
|
|
|
> 已解决</div> -->
|
|
|
- </div>
|
|
|
- <div class="context-box">
|
|
|
- <div v-if="(broadcastList && broadcastList.length == 0) || !broadcastList" class="no-context">暂无内容
|
|
|
- </div>
|
|
|
- <div class="context-detail" v-else v-for="(item, index) in broadcastList" :key="index"
|
|
|
- :style="{ color: item['isok'] == 0 ? '#f73210' : '#eee', fontWeight: item['isok'] == 0 ? '600' : '500' }">
|
|
|
- <div>{{ item['label'] }}</div>
|
|
|
- <!-- <div>{{ item['createTime'] }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="context-box">
|
|
|
+ <div v-if="(broadcastList && broadcastList.length == 0) || !broadcastList" class="no-context">暂无内容 </div>
|
|
|
+ <div
|
|
|
+ class="context-detail"
|
|
|
+ v-else
|
|
|
+ v-for="(item, index) in broadcastList"
|
|
|
+ :key="index"
|
|
|
+ :style="{ color: item['isok'] == 0 ? '#f73210' : '#eee', fontWeight: item['isok'] == 0 ? '600' : '500' }"
|
|
|
+ >
|
|
|
+ <div>{{ item['label'] }}</div>
|
|
|
+ <!-- <div>{{ item['createTime'] }}</div>
|
|
|
<div>{{ item['devicename'] }}</div>
|
|
|
<div>{{ item['wardescrip'] || item['nwartype_dictText'] }}</div>
|
|
|
<div>{{ item['isok'] ? '已解决' : '未解决' }}</div> -->
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div v-if="broadcastList" class="more" @click="toMore">更多>></div>
|
|
|
- <!-- <div v-if="broadcastList.length > 0" class="more" @click.self="test()">测试>></div> -->
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+ <div v-if="broadcastList" class="more" @click="toMore">更多>></div>
|
|
|
+ <!-- <div v-if="broadcastList.length > 0" class="more" @click.self="test()">测试>></div> -->
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
<script lang="ts">
|
|
|
-import { Tooltip, Badge } from 'ant-design-vue';
|
|
|
-import { SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined } from '@ant-design/icons-vue';
|
|
|
-import Icon from '/@/components/Icon';
|
|
|
-import { defineComponent, ref, unref, onMounted, nextTick, computed } 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 { Tooltip, Badge } from 'ant-design-vue';
|
|
|
+ import { SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined } from '@ant-design/icons-vue';
|
|
|
+ import Icon from '/@/components/Icon';
|
|
|
+ import { defineComponent, ref, unref, onMounted, nextTick, computed } 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 { useDrag } from '@/hooks/event/useDrag';
|
|
|
-export default defineComponent({
|
|
|
+ import { useDrag } from '@/hooks/event/useDrag';
|
|
|
+ export default defineComponent({
|
|
|
name: 'VoiceBroadcast',
|
|
|
components: { Icon, Tooltip, Badge, SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined },
|
|
|
|
|
|
setup() {
|
|
|
- let websocketMsg = ref<any[]>([])
|
|
|
- const userStore = useUserStore();
|
|
|
- const glob = useGlobSetting();
|
|
|
- const router = useRouter();
|
|
|
- const activeKey = ref(0);
|
|
|
- const isShowWarningBroad = ref(false);
|
|
|
- const isWarningDot = ref(false);
|
|
|
- let broadcastList = computed(() => {
|
|
|
- return localStorage.getItem('messageArr');
|
|
|
- })
|
|
|
+ let websocketMsg = ref<any[]>([]);
|
|
|
+ const userStore = useUserStore();
|
|
|
+ const glob = useGlobSetting();
|
|
|
+ const router = useRouter();
|
|
|
+ const activeKey = ref(0);
|
|
|
+ const isShowWarningBroad = ref(false);
|
|
|
+ const isWarningDot = ref(false);
|
|
|
+ let broadcastList = computed(() => {
|
|
|
+ return localStorage.getItem('messageArr');
|
|
|
+ });
|
|
|
|
|
|
- //点击切换预警信息弹窗显示
|
|
|
- function showWarningBroad() {
|
|
|
- isShowWarningBroad.value = !isShowWarningBroad.value;
|
|
|
- if (isShowWarningBroad.value) {
|
|
|
- nextTick(() => {
|
|
|
- const dom = document.getElementById('VoiceBroadcast');
|
|
|
- if (dom) useDrag(dom);
|
|
|
- });
|
|
|
- }
|
|
|
+ //点击切换预警信息弹窗显示
|
|
|
+ function showWarningBroad() {
|
|
|
+ isShowWarningBroad.value = !isShowWarningBroad.value;
|
|
|
+ if (isShowWarningBroad.value) {
|
|
|
+ nextTick(() => {
|
|
|
+ const dom = document.getElementById('VoiceBroadcast');
|
|
|
+ if (dom) useDrag(dom);
|
|
|
+ });
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- async function clearInfo() {
|
|
|
- localStorage.removeItem('messageArr');
|
|
|
- }
|
|
|
+ async function clearInfo() {
|
|
|
+ localStorage.removeItem('messageArr');
|
|
|
+ }
|
|
|
|
|
|
- //点击跳转预警历史详情
|
|
|
- async function toMore() {
|
|
|
- await router.push({ path: '/monitorChannel/device-monitor/warningHistory/company/home' });
|
|
|
- showWarningBroad();
|
|
|
- }
|
|
|
+ //点击跳转预警历史详情
|
|
|
+ async function toMore() {
|
|
|
+ await router.push({ path: '/monitorChannel/device-monitor/warningHistory/company/home' });
|
|
|
+ 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);
|
|
|
- }
|
|
|
+ // 初始化 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 = 'http://' + window.location.hostname + ':9999'?.replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId;
|
|
|
+ connectWebSocket(url);
|
|
|
+ onWebSocket(onWebSocketMessage);
|
|
|
+ }
|
|
|
|
|
|
- async function onWebSocketMessage(data) {
|
|
|
- debugger;
|
|
|
- console.log('WebSocket 监测消息--------------》', data);
|
|
|
- if (data.topic === 'warn' || data.cmd === 'user') {
|
|
|
- const messageText = data['warndata'];
|
|
|
- if (websocketMsg.value.length <= 20) {
|
|
|
- websocketMsg.value.push({ label: messageText })
|
|
|
- localStorage.removeItem('messageArr')
|
|
|
- localStorage.setItem('messageArr', websocketMsg.value as any);
|
|
|
- } else {
|
|
|
- websocketMsg.value.push({ label: messageText })
|
|
|
- websocketMsg.value.splice(0, 1)
|
|
|
- localStorage.removeItem('messageArr')
|
|
|
- localStorage.setItem('messageArr', websocketMsg.value as any);
|
|
|
- }
|
|
|
- // const messageText = '这是一个测试';
|
|
|
- if (!isShowWarningBroad.value) {
|
|
|
- isWarningDot.value = true;
|
|
|
- } else {
|
|
|
- isWarningDot.value = false;
|
|
|
- }
|
|
|
- }
|
|
|
+ async function onWebSocketMessage(data) {
|
|
|
+ debugger;
|
|
|
+ console.log('WebSocket 监测消息--------------》', data);
|
|
|
+ if (data.topic === 'warn' || data.cmd === 'user') {
|
|
|
+ const messageText = data['warndata'];
|
|
|
+ if (websocketMsg.value.length <= 20) {
|
|
|
+ websocketMsg.value.push({ label: messageText });
|
|
|
+ localStorage.removeItem('messageArr');
|
|
|
+ localStorage.setItem('messageArr', websocketMsg.value as any);
|
|
|
+ } else {
|
|
|
+ websocketMsg.value.push({ label: messageText });
|
|
|
+ websocketMsg.value.splice(0, 1);
|
|
|
+ localStorage.removeItem('messageArr');
|
|
|
+ localStorage.setItem('messageArr', websocketMsg.value as any);
|
|
|
+ }
|
|
|
+ // const messageText = '这是一个测试';
|
|
|
+ if (!isShowWarningBroad.value) {
|
|
|
+ isWarningDot.value = true;
|
|
|
+ } else {
|
|
|
+ isWarningDot.value = false;
|
|
|
+ }
|
|
|
}
|
|
|
- onMounted(() => {
|
|
|
- nextTick(async () => {
|
|
|
- initWebSocket();
|
|
|
- });
|
|
|
- // window.speechSynthesis.onvoiceschanged = () => {
|
|
|
- // console.log('语音列表已更新');
|
|
|
- // };
|
|
|
+ }
|
|
|
+ onMounted(() => {
|
|
|
+ nextTick(async () => {
|
|
|
+ initWebSocket();
|
|
|
});
|
|
|
+ // window.speechSynthesis.onvoiceschanged = () => {
|
|
|
+ // console.log('语音列表已更新');
|
|
|
+ // };
|
|
|
+ });
|
|
|
|
|
|
- return {
|
|
|
- showWarningBroad,
|
|
|
- isShowWarningBroad,
|
|
|
- activeKey,
|
|
|
- broadcastList,
|
|
|
- toMore,
|
|
|
- clearInfo,
|
|
|
- isWarningDot,
|
|
|
- };
|
|
|
+ return {
|
|
|
+ showWarningBroad,
|
|
|
+ isShowWarningBroad,
|
|
|
+ activeKey,
|
|
|
+ broadcastList,
|
|
|
+ toMore,
|
|
|
+ clearInfo,
|
|
|
+ isWarningDot,
|
|
|
+ };
|
|
|
},
|
|
|
-});
|
|
|
+ });
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
-.btn {
|
|
|
+ .btn {
|
|
|
line-height: 30px;
|
|
|
margin-right: 20px;
|
|
|
cursor: pointer;
|
|
|
display: flex;
|
|
|
-}
|
|
|
+ }
|
|
|
|
|
|
-.no-play {
|
|
|
+ .no-play {
|
|
|
position: relative;
|
|
|
|
|
|
&::after {
|
|
|
- position: absolute;
|
|
|
- width: 70%;
|
|
|
- height: 100%;
|
|
|
- content: '';
|
|
|
- left: 15%;
|
|
|
- top: 0;
|
|
|
- background: linear-gradient(to bottom left,
|
|
|
- transparent 0%,
|
|
|
- transparent calc(50% - 1px),
|
|
|
- #ffffff 50%,
|
|
|
- transparent calc(50% + 1px),
|
|
|
- transparent 100%);
|
|
|
+ position: absolute;
|
|
|
+ width: 70%;
|
|
|
+ height: 100%;
|
|
|
+ content: '';
|
|
|
+ left: 15%;
|
|
|
+ top: 0;
|
|
|
+ background: linear-gradient(
|
|
|
+ to bottom left,
|
|
|
+ transparent 0%,
|
|
|
+ transparent calc(50% - 1px),
|
|
|
+ #ffffff 50%,
|
|
|
+ transparent calc(50% + 1px),
|
|
|
+ transparent 100%
|
|
|
+ );
|
|
|
}
|
|
|
-}
|
|
|
+ }
|
|
|
|
|
|
-.broadcast {
|
|
|
+ .broadcast {
|
|
|
width: 500px;
|
|
|
height: 350px;
|
|
|
border-radius: 4px;
|
|
@@ -188,121 +194,121 @@ export default defineComponent({
|
|
|
color: #fff;
|
|
|
|
|
|
.title {
|
|
|
- height: 32px;
|
|
|
- padding: 0 20px;
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 20px;
|
|
|
|
|
|
- :deep(.ant-badge:not(.ant-badge-status)) {
|
|
|
- margin-right: 40px !important;
|
|
|
- }
|
|
|
+ :deep(.ant-badge:not(.ant-badge-status)) {
|
|
|
+ margin-right: 40px !important;
|
|
|
+ }
|
|
|
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- margin-bottom: 5px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 5px;
|
|
|
|
|
|
- .message-title {
|
|
|
- font-size: 18px;
|
|
|
- padding-top: 10px;
|
|
|
- }
|
|
|
+ .message-title {
|
|
|
+ font-size: 18px;
|
|
|
+ padding-top: 10px;
|
|
|
+ }
|
|
|
|
|
|
- .badge-box {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- padding-top: 10px;
|
|
|
+ .badge-box {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding-top: 10px;
|
|
|
|
|
|
- .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-title {
|
|
|
+ display: inline-block;
|
|
|
+ width: 62px;
|
|
|
+ line-height: 32px;
|
|
|
+ background-color: #2174f0;
|
|
|
+ border-radius: 26px;
|
|
|
+ text-align: center;
|
|
|
+ color: #fff;
|
|
|
+ padding-bottom: 2px;
|
|
|
}
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.broadcast-context {
|
|
|
- .context-tab {
|
|
|
- display: flex;
|
|
|
- padding: 20px;
|
|
|
+ .context-tab {
|
|
|
+ display: flex;
|
|
|
+ padding: 20px;
|
|
|
|
|
|
- .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 {
|
|
|
+ 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;
|
|
|
- }
|
|
|
+ .context-tab-item-active {
|
|
|
+ background-color: #2174f0;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- .context-box {
|
|
|
- flex: 1;
|
|
|
- padding: 0 10px;
|
|
|
- height: 200px;
|
|
|
- overflow-y: auto;
|
|
|
+ .context-box {
|
|
|
+ flex: 1;
|
|
|
+ padding: 0 10px;
|
|
|
+ height: 200px;
|
|
|
+ overflow-y: auto;
|
|
|
|
|
|
- .no-context {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- padding-top: 30px;
|
|
|
- font-size: 16px;
|
|
|
- }
|
|
|
+ .no-context {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding-top: 30px;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
|
|
|
- .context-detail {
|
|
|
- width: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- line-height: 24px;
|
|
|
- padding: 0px 16px;
|
|
|
+ .context-detail {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ line-height: 24px;
|
|
|
+ padding: 0px 16px;
|
|
|
|
|
|
- // div {
|
|
|
- // display: flex;
|
|
|
- // justify-content: flex-start;
|
|
|
+ // div {
|
|
|
+ // display: flex;
|
|
|
+ // justify-content: flex-start;
|
|
|
|
|
|
- // &:nth-child(1) {
|
|
|
- // width: 44%;
|
|
|
- // }
|
|
|
+ // &:nth-child(1) {
|
|
|
+ // width: 44%;
|
|
|
+ // }
|
|
|
|
|
|
- // &:nth-child(2) {
|
|
|
- // width: 40%;
|
|
|
- // }
|
|
|
+ // &:nth-child(2) {
|
|
|
+ // width: 40%;
|
|
|
+ // }
|
|
|
|
|
|
- // &:nth-child(3) {
|
|
|
- // width: 25%;
|
|
|
- // }
|
|
|
+ // &:nth-child(3) {
|
|
|
+ // width: 25%;
|
|
|
+ // }
|
|
|
|
|
|
- // &:nth-child(4) {
|
|
|
- // width: 15%;
|
|
|
- // }
|
|
|
- // }
|
|
|
- }
|
|
|
+ // &:nth-child(4) {
|
|
|
+ // width: 15%;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- .more {
|
|
|
- position: absolute;
|
|
|
- left: 24px;
|
|
|
- bottom: 10px;
|
|
|
- cursor: pointer;
|
|
|
+ .more {
|
|
|
+ position: absolute;
|
|
|
+ left: 24px;
|
|
|
+ bottom: 10px;
|
|
|
+ cursor: pointer;
|
|
|
|
|
|
- &:hover {
|
|
|
- color: #2174f0;
|
|
|
- }
|
|
|
+ &:hover {
|
|
|
+ color: #2174f0;
|
|
|
}
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
+ }
|
|
|
|
|
|
-:deep(.zxm-badge-count) {
|
|
|
+ :deep(.zxm-badge-count) {
|
|
|
width: 8px;
|
|
|
height: 8px;
|
|
|
-}
|
|
|
+ }
|
|
|
</style>
|