|
|
@@ -35,284 +35,294 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script lang="ts">
|
|
|
-import { SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
|
|
-import { defineComponent, ref, unref, onMounted, nextTick, computed } from 'vue';
|
|
|
-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';
|
|
|
+ import { SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
|
|
+ import { defineComponent, ref, unref, onMounted, onUnmounted, nextTick } from 'vue';
|
|
|
+ import { useRouter } from 'vue-router';
|
|
|
+ import { connectWebSocket, onWebSocket, offWebSocket } from '/@/hooks/web/useWebSocket';
|
|
|
+ import { getToken } from '/@/utils/auth';
|
|
|
+ import { useUserStore } from '/@/store/modules/user';
|
|
|
+ import { usePermission } from '/@/hooks/web/usePermission';
|
|
|
+ import { usePermissionStore } from '/@/store/modules/permission';
|
|
|
+ import SpeakVoice from './notify/speakVoice';
|
|
|
+ import dayjs from 'dayjs';
|
|
|
|
|
|
-import { useDrag } from '@/hooks/event/useDrag';
|
|
|
-export default defineComponent({
|
|
|
- name: 'VoiceBroadcast',
|
|
|
- components: { SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined, CloseOutlined },
|
|
|
+ import { useDrag } from '@/hooks/event/useDrag';
|
|
|
+ export default defineComponent({
|
|
|
+ name: 'VoiceBroadcast',
|
|
|
+ components: { SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined, CloseOutlined },
|
|
|
|
|
|
- setup() {
|
|
|
- let speakVoice;
|
|
|
- let broadcastList = ref<any[]>([]);
|
|
|
- const userStore = useUserStore();
|
|
|
- const glob = useGlobSetting();
|
|
|
- const router = useRouter();
|
|
|
- const activeKey = ref(0);
|
|
|
- const isShowWarningBroad = ref(false);
|
|
|
- const isBroad = ref(false);
|
|
|
- const isWarningDot = ref(false);
|
|
|
+ setup() {
|
|
|
+ let speakVoice;
|
|
|
+ let broadcastList = ref<any[]>([]);
|
|
|
+ const userStore = useUserStore();
|
|
|
+ const { hasPermission } = usePermission();
|
|
|
+ const permissionStore = usePermissionStore();
|
|
|
+ const router = useRouter();
|
|
|
+ const activeKey = ref(0);
|
|
|
+ const isShowWarningBroad = ref(false);
|
|
|
+ const isBroad = ref(false);
|
|
|
+ const isWarningDot = ref(false);
|
|
|
|
|
|
- //点击切换预警信息弹窗显示
|
|
|
- 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);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //点击关闭预警信息弹窗
|
|
|
+ function closeWarningBroad() {
|
|
|
+ isShowWarningBroad.value = false;
|
|
|
+ }
|
|
|
+ function handleBroad() {
|
|
|
+ isBroad.value = !isBroad.value;
|
|
|
+ }
|
|
|
+ async function clearInfo() {
|
|
|
+ broadcastList.value = [];
|
|
|
+ localStorage.removeItem('messageArr');
|
|
|
}
|
|
|
- }
|
|
|
- //点击关闭预警信息弹窗
|
|
|
- function closeWarningBroad() {
|
|
|
- isShowWarningBroad.value = false;
|
|
|
- }
|
|
|
- function handleBroad() {
|
|
|
- isBroad.value = !isBroad.value;
|
|
|
- }
|
|
|
- async function clearInfo() {
|
|
|
- broadcastList.value = [];
|
|
|
- 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 = 'http://' + window.location.hostname + ':9999'?.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) {
|
|
|
- console.log('WebSocket 监测消息--------------》', data);
|
|
|
- if (data.topic === 'warn') {
|
|
|
- const messageText = data['warndata'];
|
|
|
- const msgList = [...broadcastList.value];
|
|
|
- if (msgList.length <= 20) {
|
|
|
- msgList.push({ label: messageText });
|
|
|
- localStorage.removeItem('messageArr');
|
|
|
- localStorage.setItem('messageArr', msgList as any);
|
|
|
- } else {
|
|
|
- msgList.shift();
|
|
|
- msgList.push({ label: messageText });
|
|
|
- localStorage.removeItem('messageArr');
|
|
|
- localStorage.setItem('messageArr', msgList as any);
|
|
|
- }
|
|
|
- broadcastList.value = msgList;
|
|
|
- if (isBroad.value) {
|
|
|
- await speakVoice.getSpeechCnVoices();
|
|
|
- speakVoice.handleReply(messageText);
|
|
|
- const time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
|
- console.log(time + '语音播报开始报警------>', data);
|
|
|
- }
|
|
|
- // const messageText = '这是一个测试';
|
|
|
- if (!isShowWarningBroad.value) {
|
|
|
- isWarningDot.value = true;
|
|
|
- } else {
|
|
|
- isWarningDot.value = false;
|
|
|
+ async function onWebSocketMessage(data) {
|
|
|
+ console.log('WebSocket 监测消息--------------》', data);
|
|
|
+ if (hasPermission('show:noWarning')) return;
|
|
|
+ if (!permissionStore.getPermCodeList?.length) return;
|
|
|
+ if (data.topic === 'warn') {
|
|
|
+ const messageText = data['warndata'];
|
|
|
+ const msgList = [...broadcastList.value];
|
|
|
+ if (msgList.length <= 20) {
|
|
|
+ msgList.push({ label: messageText });
|
|
|
+ localStorage.removeItem('messageArr');
|
|
|
+ localStorage.setItem('messageArr', msgList as any);
|
|
|
+ } else {
|
|
|
+ msgList.shift();
|
|
|
+ msgList.push({ label: messageText });
|
|
|
+ localStorage.removeItem('messageArr');
|
|
|
+ localStorage.setItem('messageArr', msgList as any);
|
|
|
+ }
|
|
|
+ broadcastList.value = msgList;
|
|
|
+ if (isBroad.value) {
|
|
|
+ await speakVoice.getSpeechCnVoices();
|
|
|
+ speakVoice.handleReply(messageText);
|
|
|
+ const time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
|
+ console.log(time + '语音播报开始报警------>', data);
|
|
|
+ }
|
|
|
+ // const messageText = '这是一个测试';
|
|
|
+ if (!isShowWarningBroad.value) {
|
|
|
+ isWarningDot.value = true;
|
|
|
+ } else {
|
|
|
+ isWarningDot.value = false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- onMounted(() => {
|
|
|
- speakVoice = new SpeakVoice();
|
|
|
- nextTick(async () => {
|
|
|
- initWebSocket();
|
|
|
+ onMounted(() => {
|
|
|
+ speakVoice = new SpeakVoice();
|
|
|
+ nextTick(async () => {
|
|
|
+ initWebSocket();
|
|
|
+ });
|
|
|
+ window.speechSynthesis.onvoiceschanged = () => {
|
|
|
+ console.log('语音列表已更新');
|
|
|
+ };
|
|
|
});
|
|
|
- window.speechSynthesis.onvoiceschanged = () => {
|
|
|
- console.log('语音列表已更新');
|
|
|
- };
|
|
|
- });
|
|
|
|
|
|
- return {
|
|
|
- showWarningBroad,
|
|
|
- isShowWarningBroad,
|
|
|
- activeKey,
|
|
|
- broadcastList,
|
|
|
- toMore,
|
|
|
- clearInfo,
|
|
|
- isWarningDot,
|
|
|
- handleBroad,
|
|
|
- closeWarningBroad,
|
|
|
- isBroad,
|
|
|
- };
|
|
|
- },
|
|
|
-});
|
|
|
+ onUnmounted(() => {
|
|
|
+ offWebSocket(onWebSocketMessage);
|
|
|
+ window.speechSynthesis?.cancel();
|
|
|
+ });
|
|
|
+
|
|
|
+ return {
|
|
|
+ showWarningBroad,
|
|
|
+ isShowWarningBroad,
|
|
|
+ activeKey,
|
|
|
+ broadcastList,
|
|
|
+ toMore,
|
|
|
+ clearInfo,
|
|
|
+ isWarningDot,
|
|
|
+ handleBroad,
|
|
|
+ closeWarningBroad,
|
|
|
+ isBroad,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ });
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
-.btn {
|
|
|
- line-height: 30px;
|
|
|
- margin-right: 10px;
|
|
|
- cursor: pointer;
|
|
|
- display: flex;
|
|
|
-}
|
|
|
-
|
|
|
-.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%
|
|
|
- );
|
|
|
+ .btn {
|
|
|
+ line-height: 30px;
|
|
|
+ margin-right: 10px;
|
|
|
+ cursor: pointer;
|
|
|
+ display: flex;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-.broadcast {
|
|
|
- width: 500px;
|
|
|
- height: 350px;
|
|
|
- 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;
|
|
|
+ .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%
|
|
|
+ );
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- margin-bottom: 5px;
|
|
|
-
|
|
|
- .message-title {
|
|
|
- font-size: 18px;
|
|
|
- padding-top: 10px;
|
|
|
- }
|
|
|
+ .broadcast {
|
|
|
+ width: 500px;
|
|
|
+ height: 350px;
|
|
|
+ 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;
|
|
|
|
|
|
- .badge-box {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- padding-top: 10px;
|
|
|
+ .title {
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 20px;
|
|
|
|
|
|
- .badge-title {
|
|
|
- display: inline-block;
|
|
|
- width: 62px;
|
|
|
- line-height: 32px;
|
|
|
- background-color: #2174f0;
|
|
|
- border-radius: 26px;
|
|
|
- text-align: center;
|
|
|
- color: #fff;
|
|
|
- padding-bottom: 2px;
|
|
|
+ :deep(.ant-badge:not(.ant-badge-status)) {
|
|
|
+ margin-right: 40px !important;
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- .broadcast-context {
|
|
|
- .context-tab {
|
|
|
display: flex;
|
|
|
- padding: 20px;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 5px;
|
|
|
|
|
|
- .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;
|
|
|
+ .message-title {
|
|
|
+ font-size: 18px;
|
|
|
+ padding-top: 10px;
|
|
|
}
|
|
|
|
|
|
- .context-tab-item-active {
|
|
|
- background-color: #2174f0;
|
|
|
+ .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;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .context-box {
|
|
|
- flex: 1;
|
|
|
- padding: 0 10px;
|
|
|
- height: 200px;
|
|
|
- overflow-y: auto;
|
|
|
-
|
|
|
- .no-context {
|
|
|
+ .broadcast-context {
|
|
|
+ .context-tab {
|
|
|
display: flex;
|
|
|
- justify-content: center;
|
|
|
- padding-top: 30px;
|
|
|
- font-size: 16px;
|
|
|
+ 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-active {
|
|
|
+ background-color: #2174f0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- .context-detail {
|
|
|
- width: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- line-height: 24px;
|
|
|
- padding: 0px 16px;
|
|
|
+ .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;
|
|
|
+ }
|
|
|
|
|
|
- // div {
|
|
|
- // display: flex;
|
|
|
- // justify-content: flex-start;
|
|
|
+ .context-detail {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ line-height: 24px;
|
|
|
+ padding: 0px 16px;
|
|
|
|
|
|
- // &:nth-child(1) {
|
|
|
- // width: 44%;
|
|
|
- // }
|
|
|
+ // div {
|
|
|
+ // display: flex;
|
|
|
+ // justify-content: flex-start;
|
|
|
|
|
|
- // &:nth-child(2) {
|
|
|
- // width: 40%;
|
|
|
- // }
|
|
|
+ // &:nth-child(1) {
|
|
|
+ // width: 44%;
|
|
|
+ // }
|
|
|
|
|
|
- // &:nth-child(3) {
|
|
|
- // width: 25%;
|
|
|
- // }
|
|
|
+ // &:nth-child(2) {
|
|
|
+ // width: 40%;
|
|
|
+ // }
|
|
|
|
|
|
- // &:nth-child(4) {
|
|
|
- // width: 15%;
|
|
|
- // }
|
|
|
- // }
|
|
|
+ // &:nth-child(3) {
|
|
|
+ // width: 25%;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // &: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) {
|
|
|
- width: 8px;
|
|
|
- height: 8px;
|
|
|
-}
|
|
|
+ :deep(.zxm-badge-count) {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ }
|
|
|
</style>
|