|
|
@@ -1,6 +1,6 @@
|
|
|
<template>
|
|
|
- <div class="announcement">
|
|
|
- <el-popover :width="500">
|
|
|
+ <div class="announcement" :style="scrollStyle">
|
|
|
+ <el-popover :width="220">
|
|
|
<div v-if="data.systemUpdatesMessage">
|
|
|
系统更新通知:
|
|
|
<span style="color: red;text-decoration: underline">
|
|
|
@@ -14,21 +14,13 @@
|
|
|
系统更新期间请勿操作
|
|
|
</span>
|
|
|
</div>
|
|
|
- {{ data.scrollingMessages }}
|
|
|
+ 普通通知: {{ data.scrollingMessages }}
|
|
|
<template #reference>
|
|
|
- <div class='ad' ref="adRef" :style="scrollStyle">
|
|
|
- <div ref="scrollRef" class="scroll">
|
|
|
- {{
|
|
|
- data.systemUpdatesMessage ? '系统更新通知:' + data.systemUpdatesMessage : data.systemUpdatesMessage
|
|
|
- }}
|
|
|
- {{ data.scrollingMessages }}
|
|
|
- </div>
|
|
|
- <div class="scroll" v-if="whetherToScroll">
|
|
|
- {{
|
|
|
- data.systemUpdatesMessage ? '系统更新通知:' + data.systemUpdatesMessage : data.systemUpdatesMessage
|
|
|
- }}
|
|
|
- {{ data.scrollingMessages }}
|
|
|
- </div>
|
|
|
+ <div class="scroll_system_box">
|
|
|
+ <i class="iconfont icon-tongzhi"/>
|
|
|
+ <transition name="el-zoom-in-top">
|
|
|
+ <div class='ad' ref="adRef"/>
|
|
|
+ </transition>
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-popover>
|
|
|
@@ -36,39 +28,95 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup name='ScrollNotifications' lang="ts">
|
|
|
-
|
|
|
-import {ref, onMounted, Ref, nextTick} from "vue";
|
|
|
+import {ref, onMounted, Ref, nextTick, watch} from "vue";
|
|
|
import {$ref} from "vue/macros";
|
|
|
+import sleep from "../../utils/sleep";
|
|
|
+import {setCallback} from "@/utils/websocket";
|
|
|
+import {getSystemAnnouncement} from "@/api/public-api";
|
|
|
|
|
|
const props = defineProps({
|
|
|
data: Object
|
|
|
})
|
|
|
-
|
|
|
-
|
|
|
-const scrollRef: Ref<HTMLElement> = ref(null)
|
|
|
const adRef: Ref<HTMLElement> = ref(null)
|
|
|
|
|
|
let scrollStyle: object = $ref({
|
|
|
'--xc-translateX': 0,
|
|
|
+ '--xc-width': 40,
|
|
|
})
|
|
|
-let whetherToScroll = $ref(false)
|
|
|
let marginRight = 40
|
|
|
|
|
|
-onMounted(async () => {
|
|
|
+
|
|
|
+let data = $ref({
|
|
|
+ systemUpdatesMessage: '',
|
|
|
+ scrollingMessages: ''
|
|
|
+})
|
|
|
+
|
|
|
+watch(() => data, async () => {
|
|
|
await nextTick()
|
|
|
- let width = scrollRef.value?.clientWidth
|
|
|
+ if (data.systemUpdatesMessage || data.scrollingMessages) {
|
|
|
+ adRef.value.style.display = null
|
|
|
+ scrollStyle['--xc-width'] = 'max-content'
|
|
|
+ } else {
|
|
|
+ adRef.value.style.display = 'none'
|
|
|
+ scrollStyle['--xc-width'] = '30px'
|
|
|
+ }
|
|
|
+ adRef.value.innerHTML = null
|
|
|
+ let div1 = document.createElement('div')
|
|
|
+ let html = `
|
|
|
+ <span style="color: red">${data.systemUpdatesMessage}</span>
|
|
|
+ <span style="color: #0a84fd">${data.scrollingMessages}</span>
|
|
|
+ `
|
|
|
+ div1.innerHTML = html
|
|
|
+ adRef.value.append(div1)
|
|
|
+ let width = div1.clientWidth
|
|
|
if (width >= 220) {
|
|
|
- scrollRef.value.style.marginRight = '40px'
|
|
|
- whetherToScroll = true
|
|
|
+ div1.style.marginRight = '40px'
|
|
|
+ div1.className = 'scroll_system_message'
|
|
|
await nextTick()
|
|
|
scrollStyle['--xc-translateX'] = -(width + marginRight) + 'px'
|
|
|
+ let div2 = document.createElement('div')
|
|
|
+ div2.innerHTML = html
|
|
|
+ div2.className = 'scroll_system_message'
|
|
|
+ adRef.value.append(div2)
|
|
|
}
|
|
|
+}, {immediate: true})
|
|
|
+
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ setCallback("systemAnnouncement", async ({data: res}) => {
|
|
|
+ data = res
|
|
|
+ })
|
|
|
+ getSystemAnnouncement().then((res) => {
|
|
|
+ data = res
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
</script>
|
|
|
+<style lang="scss">
|
|
|
+
|
|
|
+@keyframes move {
|
|
|
+ 0% {
|
|
|
+ transform: translateX(0px);
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ transform: translateX(var(--xc-translateX));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.scroll_system_message {
|
|
|
+ animation: move 8s linear infinite normal;
|
|
|
+ animation-fill-mode: forwards;
|
|
|
+}
|
|
|
+</style>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
+.scroll_system_box {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
.red-point {
|
|
|
position: relative;
|
|
|
}
|
|
|
@@ -86,7 +134,11 @@ onMounted(async () => {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
- margin-left: 5px;
|
|
|
+ width: var(--xc-width);
|
|
|
+
|
|
|
+ i {
|
|
|
+ margin-left: 5px;
|
|
|
+ }
|
|
|
|
|
|
.ad {
|
|
|
width: max-content;
|
|
|
@@ -96,27 +148,15 @@ onMounted(async () => {
|
|
|
border-radius: 8px;
|
|
|
box-sizing: border-box;
|
|
|
justify-content: flex-start;
|
|
|
- font-size: 16px;
|
|
|
+ font-size: 13px;
|
|
|
color: #353535;
|
|
|
cursor: pointer;
|
|
|
padding: 5px;
|
|
|
white-space: nowrap;
|
|
|
overflow: hidden;
|
|
|
-
|
|
|
- .scroll {
|
|
|
- animation: move 8s linear infinite normal;
|
|
|
- animation-fill-mode: forwards;
|
|
|
- }
|
|
|
+ margin-left: 5px;
|
|
|
}
|
|
|
|
|
|
- @keyframes move {
|
|
|
- 0% {
|
|
|
- transform: translateX(0px);
|
|
|
- }
|
|
|
- 100% {
|
|
|
- transform: translateX(var(--xc-translateX));
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
}
|
|
|
|