|  | @@ -1,43 +1,131 @@
 | 
	
		
			
				|  |  |  <template>
 | 
	
		
			
				|  |  | -  <div class="notice__content" :title="msg.msg" v-show="msg.isShow">
 | 
	
		
			
				|  |  | -    <div class="notice__img">
 | 
	
		
			
				|  |  | -      <img :src="msg.avatar">
 | 
	
		
			
				|  |  | -    </div>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    <div class="notice__main">
 | 
	
		
			
				|  |  | -      <div class="notice__name">
 | 
	
		
			
				|  |  | -        <span style="color: red">
 | 
	
		
			
				|  |  | +  <transition name="notice_an">
 | 
	
		
			
				|  |  | +    <div class="notice__content"
 | 
	
		
			
				|  |  | +         :title="msg.msg"
 | 
	
		
			
				|  |  | +         v-show="isShow"
 | 
	
		
			
				|  |  | +         @mouseout="mouseEvent(false)"
 | 
	
		
			
				|  |  | +         @mouseover="mouseEvent(true)">
 | 
	
		
			
				|  |  | +      <div class="notice__img">
 | 
	
		
			
				|  |  | +        <img :src="msg.avatar">
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <div class="notice__main">
 | 
	
		
			
				|  |  | +        <div class="notice__name">
 | 
	
		
			
				|  |  | +        <span style="color: #E6A23C">
 | 
	
		
			
				|  |  | +          {{ msg.title }}
 | 
	
		
			
				|  |  | +        </span>
 | 
	
		
			
				|  |  | +          <br>
 | 
	
		
			
				|  |  | +          <span style="color: red">
 | 
	
		
			
				|  |  |            {{ msg.deptName }}
 | 
	
		
			
				|  |  |          </span>
 | 
	
		
			
				|  |  | -        <span style="color: #0a84fd;margin-left: 10px">
 | 
	
		
			
				|  |  | +          <span style="color: #0a84fd;margin-left: 3px">
 | 
	
		
			
				|  |  |           {{ msg.name }}
 | 
	
		
			
				|  |  |          </span>
 | 
	
		
			
				|  |  | -      </div>
 | 
	
		
			
				|  |  | -      <div class="notice__msg">
 | 
	
		
			
				|  |  | -        {{ msg.msg }}
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +        <div class="notice__msg">
 | 
	
		
			
				|  |  | +          {{ msg.msg }}
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  |        </div>
 | 
	
		
			
				|  |  |      </div>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  </div>
 | 
	
		
			
				|  |  | +  </transition>
 | 
	
		
			
				|  |  |  </template>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  <script setup name='Notice' lang="ts">
 | 
	
		
			
				|  |  | -import {ref} from 'vue'
 | 
	
		
			
				|  |  | +import {onMounted, ref} from 'vue'
 | 
	
		
			
				|  |  | +import sleep from "@/utils/sleep";
 | 
	
		
			
				|  |  | +import {setCallback} from '@/utils/websocket'
 | 
	
		
			
				|  |  | +import store from '@/store'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const isShow = ref(false)
 | 
	
		
			
				|  |  | +const displaySeconds = 1000 * 2
 | 
	
		
			
				|  |  | +const isMouse = ref(false)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const msg = ref({
 | 
	
		
			
				|  |  | -  avatar: 'https://wework.qpic.cn/wwpic/983610_ph9-6vq4Tky3osn_1670953406/0',
 | 
	
		
			
				|  |  | -  deptName: '信息科',
 | 
	
		
			
				|  |  | -  name: '肖蟾',
 | 
	
		
			
				|  |  | -  msg: '阿苏和对啊是对啊哈佛啊ui是发哈送iu和导师案说法伽世界科幻大师返回八艘i的话关乎端是更好的大祭司第哦啊是',
 | 
	
		
			
				|  |  | -  isShow: false
 | 
	
		
			
				|  |  | +  avatar: '',
 | 
	
		
			
				|  |  | +  deptName: '',
 | 
	
		
			
				|  |  | +  name: '',
 | 
	
		
			
				|  |  | +  msg: '',
 | 
	
		
			
				|  |  | +  title: '',
 | 
	
		
			
				|  |  | +  countDown: 2,
 | 
	
		
			
				|  |  | +})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +let queue = new Queue()
 | 
	
		
			
				|  |  | +const fillData = async () => {
 | 
	
		
			
				|  |  | +  let temp = queue.poll()
 | 
	
		
			
				|  |  | +  if (temp === null) {
 | 
	
		
			
				|  |  | +    return
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  isShow.value = true
 | 
	
		
			
				|  |  | +  msg.value = temp;
 | 
	
		
			
				|  |  | +  // 显示时间
 | 
	
		
			
				|  |  | +  await sleep(displaySeconds);
 | 
	
		
			
				|  |  | +  // 鼠标移入等待
 | 
	
		
			
				|  |  | +  do {
 | 
	
		
			
				|  |  | +    await sleep(100)
 | 
	
		
			
				|  |  | +  } while (isMouse.value)
 | 
	
		
			
				|  |  | +  // 关闭
 | 
	
		
			
				|  |  | +  isShow.value = false;
 | 
	
		
			
				|  |  | +  // 等待关闭动画结束
 | 
	
		
			
				|  |  | +  await sleep(500);
 | 
	
		
			
				|  |  | +  // 如果还有数据就执行自己,没有数据的结束
 | 
	
		
			
				|  |  | +  if (queue.size() > 0) {
 | 
	
		
			
				|  |  | +    await fillData()
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    open = true
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const mouseEvent = (flag) => {
 | 
	
		
			
				|  |  | +  isMouse.value = flag
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 是否开启显示通知
 | 
	
		
			
				|  |  | +let open = true
 | 
	
		
			
				|  |  | +onMounted(() => {
 | 
	
		
			
				|  |  | +  setCallback('avatarNotification', async (value) => {
 | 
	
		
			
				|  |  | +    let newCount = store.state.app.unreadMessageCount + value.count
 | 
	
		
			
				|  |  | +    store.commit('app/setUnreadMessageCount', newCount)
 | 
	
		
			
				|  |  | +    // 把消息放到队列中
 | 
	
		
			
				|  |  | +    queue.enqueue(value)
 | 
	
		
			
				|  |  | +    if (open) {
 | 
	
		
			
				|  |  | +      open = false
 | 
	
		
			
				|  |  | +      await fillData()
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  })
 | 
	
		
			
				|  |  |  })
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +function Queue() {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  let items = []
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Queue.prototype.enqueue = element => {
 | 
	
		
			
				|  |  | +    items.push(element)
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Queue.prototype.poll = () => {
 | 
	
		
			
				|  |  | +    if (items.length === 0) {
 | 
	
		
			
				|  |  | +      return null;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    let temp = items[0];
 | 
	
		
			
				|  |  | +    items.shift();
 | 
	
		
			
				|  |  | +    return temp;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Queue.prototype.getElement = () => {
 | 
	
		
			
				|  |  | +    return items;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Queue.prototype.size = () => {
 | 
	
		
			
				|  |  | +    return items.length;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  </script>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  <style scoped lang="scss">
 | 
	
		
			
				|  |  | -$height: 50px;
 | 
	
		
			
				|  |  | +$height: 70px;
 | 
	
		
			
				|  |  |  $width: 290px;
 | 
	
		
			
				|  |  | -$img_size: 40px;
 | 
	
		
			
				|  |  | +$img_size: 50px;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  .notice__content {
 | 
	
		
			
				|  |  |    position: fixed;
 | 
	
	
		
			
				|  | @@ -68,14 +156,14 @@ $img_size: 40px;
 | 
	
		
			
				|  |  |    .notice__main {
 | 
	
		
			
				|  |  |      width: $width - $img_size - 10 - 20;
 | 
	
		
			
				|  |  |      padding: 0 10px;
 | 
	
		
			
				|  |  | -    height: 40px;
 | 
	
		
			
				|  |  | +    height: 50px;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      .notice__name {
 | 
	
		
			
				|  |  |        width: 100%;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      .notice__msg {
 | 
	
		
			
				|  |  | -      margin-top: 10px;
 | 
	
		
			
				|  |  | +      margin-top: 7px;
 | 
	
		
			
				|  |  |        width: 100%;
 | 
	
		
			
				|  |  |        white-space: nowrap;
 | 
	
		
			
				|  |  |        overflow: hidden;
 | 
	
	
		
			
				|  | @@ -84,7 +172,28 @@ $img_size: 40px;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +.notice_an-leave-active {
 | 
	
		
			
				|  |  | +  animation: notice .2s reverse;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +.notice_an-enter-active {
 | 
	
		
			
				|  |  | +  animation: notice .2s;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +@keyframes notice {
 | 
	
		
			
				|  |  | +  0% {
 | 
	
		
			
				|  |  | +    top: 0;
 | 
	
		
			
				|  |  | +    opacity: 0;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  100% {
 | 
	
		
			
				|  |  | +    top: 2%;
 | 
	
		
			
				|  |  | +    opacity: 1;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  </style>
 |