|
@@ -14,6 +14,7 @@
|
|
|
<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>
|
|
@@ -45,275 +46,283 @@
|
|
|
</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, nextTick } 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';
|
|
|
- import { useDrag } from '@/hooks/event/useDrag';
|
|
|
- import dayjs from 'dayjs';
|
|
|
- export default defineComponent({
|
|
|
- name: 'VoiceBroadcast',
|
|
|
- components: { Icon, Tooltip, Badge, SoundOutlined, BellOutlined, WarningOutlined },
|
|
|
+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 } 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';
|
|
|
+import { useDrag } from '@/hooks/event/useDrag';
|
|
|
+import dayjs from 'dayjs';
|
|
|
+export default defineComponent({
|
|
|
+ name: 'VoiceBroadcast',
|
|
|
+ components: { Icon, Tooltip, Badge, SoundOutlined, ClearOutlined, BellOutlined, WarningOutlined },
|
|
|
|
|
|
- setup() {
|
|
|
- // debugger;
|
|
|
- let 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);
|
|
|
- nextTick(() => {
|
|
|
- const dom = document.getElementById('VoiceBroadcast');
|
|
|
- if (dom) useDrag(dom);
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- function handleBroad() {
|
|
|
- isBroad.value = !isBroad.value;
|
|
|
+ setup() {
|
|
|
+ // debugger;
|
|
|
+ let speakVoice;
|
|
|
+ const userStore = useUserStore();
|
|
|
+ const glob = useGlobSetting();
|
|
|
+ const router = useRouter();
|
|
|
+ const list = (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params });
|
|
|
+ const cleanAlarm = () => defHttp.get({ url: '/safety/ventanalyAlarmLog/cleanAlarmLog' });
|
|
|
+ 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);
|
|
|
+ nextTick(() => {
|
|
|
+ const dom = document.getElementById('VoiceBroadcast');
|
|
|
+ if (dom) useDrag(dom);
|
|
|
+ });
|
|
|
}
|
|
|
+ }
|
|
|
+ function handleBroad() {
|
|
|
+ isBroad.value = !isBroad.value;
|
|
|
+ }
|
|
|
|
|
|
- async function toSelectList(key) {
|
|
|
- activeKey.value = key;
|
|
|
- const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null, sort: 'createTime' });
|
|
|
- broadcastList.value = res['records'];
|
|
|
- const isHasWarning = broadcastList.value.findIndex((item) => !item['isok']);
|
|
|
- if (key !== 2) isWarningDot.value = isHasWarning > -1 ? true : false;
|
|
|
- }
|
|
|
+ async function clearInfo() {
|
|
|
+ cleanAlarm();
|
|
|
+ const res = await list({ pageSize: 20, devicetype: '', sort: 'createTime', delFlag: 0 });
|
|
|
+ broadcastList.value = res['records'];
|
|
|
+ }
|
|
|
|
|
|
- async function toMore() {
|
|
|
- await router.push({ path: '/monitorChannel/device-monitor/warningHistory/home' });
|
|
|
- showWarningBroad();
|
|
|
- }
|
|
|
+ async function toSelectList(key) {
|
|
|
+ activeKey.value = key;
|
|
|
+ const res = await list({ pageSize: 20, devicetype: '', isok: key == 1 ? 0 : key == 2 ? 1 : null, sort: 'createTime' });
|
|
|
+ broadcastList.value = res['records'];
|
|
|
+ const isHasWarning = broadcastList.value.findIndex((item) => !item['isok']);
|
|
|
+ if (key !== 2) isWarningDot.value = isHasWarning > -1 ? true : false;
|
|
|
+ }
|
|
|
|
|
|
- // 初始化 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 toMore() {
|
|
|
+ await router.push({ path: '/monitorChannel/device-monitor/warningHistory/home' });
|
|
|
+ showWarningBroad();
|
|
|
+ }
|
|
|
|
|
|
- async function onWebSocketMessage(data) {
|
|
|
- console.log('WebSocket 监测消息--------------》', data);
|
|
|
- if (data.topic === 'warn' || data.cmd === 'user') {
|
|
|
- if (isBroad.value) {
|
|
|
- await speakVoice.getSpeechCnVoices();
|
|
|
- const messageText = data['warndata'];
|
|
|
- // const messageText = '这是一个测试';
|
|
|
- speakVoice.handleReply(messageText);
|
|
|
- const time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
|
- console.log(time + '语音播报开始报警------>', data);
|
|
|
- }
|
|
|
- if (!isShowWarningBroad.value) {
|
|
|
- isWarningDot.value = true;
|
|
|
- } else {
|
|
|
- isWarningDot.value = false;
|
|
|
- }
|
|
|
- setTimeout(() => {
|
|
|
- if (isShowWarningBroad.value) {
|
|
|
- toSelectList(0);
|
|
|
- }
|
|
|
- }, 0);
|
|
|
+ // 初始化 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 onWebSocketMessage(data) {
|
|
|
+ console.log('WebSocket 监测消息--------------》', data);
|
|
|
+ if (data.topic === 'warn' || data.cmd === 'user') {
|
|
|
+ if (isBroad.value) {
|
|
|
+ await speakVoice.getSpeechCnVoices();
|
|
|
+ const messageText = data['warndata'];
|
|
|
+ // const messageText = '这是一个测试';
|
|
|
+ speakVoice.handleReply(messageText);
|
|
|
+ const time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|
|
+ console.log(time + '语音播报开始报警------>', data);
|
|
|
}
|
|
|
+ if (!isShowWarningBroad.value) {
|
|
|
+ isWarningDot.value = true;
|
|
|
+ } else {
|
|
|
+ isWarningDot.value = false;
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ if (isShowWarningBroad.value) {
|
|
|
+ toSelectList(0);
|
|
|
+ }
|
|
|
+ }, 0);
|
|
|
}
|
|
|
- onMounted(() => {
|
|
|
- speakVoice = new SpeakVoice();
|
|
|
- nextTick(async () => {
|
|
|
- initWebSocket();
|
|
|
- await toSelectList(1);
|
|
|
- });
|
|
|
- window.speechSynthesis.onvoiceschanged = () => {
|
|
|
- console.log('语音列表已更新');
|
|
|
- };
|
|
|
+ }
|
|
|
+ onMounted(() => {
|
|
|
+ speakVoice = new SpeakVoice();
|
|
|
+ nextTick(async () => {
|
|
|
+ initWebSocket();
|
|
|
+ await toSelectList(1);
|
|
|
});
|
|
|
-
|
|
|
- return {
|
|
|
- showWarningBroad,
|
|
|
- isShowWarningBroad,
|
|
|
- activeKey,
|
|
|
- toSelectList,
|
|
|
- broadcastList,
|
|
|
- toMore,
|
|
|
- isBroad,
|
|
|
- handleBroad,
|
|
|
- isWarningDot,
|
|
|
+ window.speechSynthesis.onvoiceschanged = () => {
|
|
|
+ console.log('语音列表已更新');
|
|
|
};
|
|
|
- },
|
|
|
- });
|
|
|
+ });
|
|
|
+
|
|
|
+ return {
|
|
|
+ showWarningBroad,
|
|
|
+ isShowWarningBroad,
|
|
|
+ activeKey,
|
|
|
+ toSelectList,
|
|
|
+ broadcastList,
|
|
|
+ toMore,
|
|
|
+ isBroad,
|
|
|
+ handleBroad,
|
|
|
+ clearInfo,
|
|
|
+ isWarningDot,
|
|
|
+ };
|
|
|
+ },
|
|
|
+});
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
- .btn {
|
|
|
- line-height: 30px;
|
|
|
- margin-right: 20px;
|
|
|
- cursor: pointer;
|
|
|
- display: flex;
|
|
|
- }
|
|
|
+.btn {
|
|
|
+ line-height: 30px;
|
|
|
+ margin-right: 20px;
|
|
|
+ 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%
|
|
|
- );
|
|
|
- }
|
|
|
+.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%
|
|
|
+ );
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- .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;
|
|
|
+.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;
|
|
|
+ .title {
|
|
|
+ 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;
|
|
|
|
|
|
+ .message-title {
|
|
|
+ font-size: 18px;
|
|
|
+ padding-top: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .badge-box {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- margin-bottom: 5px;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- .message-title {
|
|
|
- font-size: 18px;
|
|
|
- padding-top: 10px;
|
|
|
+ .broadcast-context {
|
|
|
+ .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;
|
|
|
}
|
|
|
|
|
|
- .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-tab-item-active {
|
|
|
+ background-color: #2174f0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .broadcast-context {
|
|
|
- .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-box {
|
|
|
+ flex: 1;
|
|
|
+ padding: 0 10px;
|
|
|
+ height: 200px;
|
|
|
+ overflow-y: auto;
|
|
|
|
|
|
- .context-tab-item-active {
|
|
|
- background-color: #2174f0;
|
|
|
- }
|
|
|
+ .no-context {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding-top: 30px;
|
|
|
+ font-size: 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;
|
|
|
- }
|
|
|
+ .context-detail {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ line-height: 24px;
|
|
|
+ padding: 0px 16px;
|
|
|
|
|
|
- .context-detail {
|
|
|
+ div {
|
|
|
display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- line-height: 24px;
|
|
|
- padding: 0px 16px;
|
|
|
-
|
|
|
- div {
|
|
|
- display: flex;
|
|
|
- justify-content: flex-start;
|
|
|
+ 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) {
|
|
|
- width: 8px;
|
|
|
- height: 8px;
|
|
|
- }
|
|
|
+}
|
|
|
+:deep(.zxm-badge-count) {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+}
|
|
|
</style>
|