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