| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 
 | <template><div
 class="floating-ball"
 :class="styleBall"
 :style="{ top: position.top + 'px', left: position.left + 'px' }"
 @mousedown="startDragging"
 >
 <span class="ball-icon">{{ text }}</span>
 </div>
 </template>
 
 <script lang="ts" setup>
 import { reactive, onBeforeMount, computed } from 'vue';
 import { getChatStore } from '@/store';
 import { storeToRefs } from 'pinia';
 const chat = storeToRefs(getChatStore());
 const text = computed(() => {
 const status = {
 open: '已连接',
 close: '已断开',
 connecting: '重连中',
 };
 return status[chat.websoketStatus.value];
 });
 const styleBall = computed(() => {
 const status = {
 open: 'green',
 close: 'red',
 connecting: 'warning',
 };
 return status[chat.websoketStatus.value];
 });
 const position = reactive({
 top: 100,
 left: 100,
 });
 
 onBeforeMount(() => {
 // 获取浏览器窗口的宽高
 const width = document.documentElement.clientWidth || document.body.clientWidth;
 const height = document.documentElement.clientHeight || document.body.clientHeight;
 position.left = width - 70;
 position.top = height - 70;
 });
 
 let dragging = false;
 let mouseStart = { x: 0, y: 0 };
 let elementStart = { x: 0, y: 0 };
 
 const startDragging = (event) => {
 event.preventDefault();
 dragging = true;
 mouseStart.x = event.clientX;
 mouseStart.y = event.clientY;
 elementStart.x = position.left;
 elementStart.y = position.top;
 
 window.addEventListener('mousemove', doDrag);
 window.addEventListener('mouseup', stopDragging);
 };
 
 const doDrag = (event) => {
 if (dragging) {
 const dx = event.clientX - mouseStart.x;
 const dy = event.clientY - mouseStart.y;
 position.left = Math.max(0, elementStart.x + dx);
 position.top = Math.max(0, elementStart.y + dy);
 }
 };
 
 const stopDragging = () => {
 dragging = false;
 window.removeEventListener('mousemove', doDrag);
 window.removeEventListener('mouseup', stopDragging);
 };
 </script>
 
 <style scoped>
 .floating-ball {
 position: fixed;
 z-index: 9999;
 width: 50px;
 height: 50px;
 border-radius: 50%;
 display: flex;
 align-items: center;
 justify-content: center;
 cursor: move;
 color: #fff;
 }
 
 .green {
 background: rgba(134, 233, 173, 0.9);
 box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
 backdrop-filter: blur(4px);
 -webkit-backdrop-filter: blur(4px);
 border: 1px solid rgba(255, 255, 255, 0.18);
 }
 
 .red {
 background: rgba(233, 134, 134, 0.9);
 box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
 backdrop-filter: blur(4px);
 -webkit-backdrop-filter: blur(4px);
 border: 1px solid rgba(255, 255, 255, 0.18);
 }
 
 .warning {
 background: rgba(134, 144, 233, 0.9);
 box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
 backdrop-filter: blur(4px);
 -webkit-backdrop-filter: blur(4px);
 border: 1px solid rgba(255, 255, 255, 0.18);
 }
 
 .ball-icon {
 font-size: 14px;
 text-shadow: 0 2px 4px rgba(71, 97, 206, 0.36);
 font-weight: 700;
 }
 </style>
 
 
 |