|  | @@ -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>
 |