feat: 实时在线用户统计

This commit is contained in:
ray
2024-08-25 08:42:03 +08:00
parent f8003bc93a
commit bba48e448f

View File

@@ -45,22 +45,22 @@
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<div class="flex-x-between"> <div class="flex-x-between">
<span class="text-[var(--el-text-color-secondary)]" <span class="text-[var(--el-text-color-secondary)]">
>在线用户</span 在线用户
> </span>
<el-tag type="success" size="small">-</el-tag> <el-tag type="success" size="small">{{ onlineUserCount }}</el-tag>
</div> </div>
</template> </template>
<div class="flex-x-between mt-2"> <div class="flex-x-between mt-2">
<span class="text-lg"> 1</span> <span class="text-lg">1</span>
<svg-icon icon-class="user" size="2em" /> <svg-icon icon-class="user" size="2em" />
</div> </div>
<div <div
class="flex-x-between mt-2 text-sm text-[var(--el-text-color-secondary)]" class="flex-x-between mt-2 text-sm text-[var(--el-text-color-secondary)]"
> >
<span> 总用户数 </span> <span>总用户数</span>
<span>5 </span> <span>5</span>
</div> </div>
</el-card> </el-card>
</el-col> </el-col>
@@ -102,9 +102,9 @@
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<div class="flex-x-between"> <div class="flex-x-between">
<span class="text-[var(--el-text-color-secondary)]">{{ <span class="text-[var(--el-text-color-secondary)]">
item.title {{ item.title }}
}}</span> </span>
<el-tag :type="item.tagType" size="small"> <el-tag :type="item.tagType" size="small">
{{ item.granularity }} {{ item.granularity }}
</el-tag> </el-tag>
@@ -113,7 +113,7 @@
<div class="flex-x-between mt-2"> <div class="flex-x-between mt-2">
<div class="flex-y-center"> <div class="flex-y-center">
<span class="text-lg"> {{ item.todayCount }}</span> <span class="text-lg">{{ item.todayCount }}</span>
<span <span
:class="[ :class="[
'text-xs', 'text-xs',
@@ -132,8 +132,8 @@
<div <div
class="flex-x-between mt-2 text-sm text-[var(--el-text-color-secondary)]" class="flex-x-between mt-2 text-sm text-[var(--el-text-color-secondary)]"
> >
<span>{{ item.title }} </span> <span>{{ item.title }}</span>
<span> {{ item.totalCount }} </span> <span>{{ item.totalCount }}</span>
</div> </div>
</el-card> </el-card>
</template> </template>
@@ -151,12 +151,13 @@
<template #header> <template #header>
<div class="flex-x-between"> <div class="flex-x-between">
<div class="flex-y-center"> <div class="flex-y-center">
通知公告<el-icon class="ml-1"><Notification /></el-icon> 通知公告
<el-icon class="ml-1"><Notification /></el-icon>
</div> </div>
<el-link type="primary"> <el-link type="primary">
<span class="text-xs">查看更多</span <span class="text-xs">查看更多</span>
><el-icon class="text-xs"><ArrowRight /></el-icon <el-icon class="text-xs"><ArrowRight /></el-icon>
></el-link> </el-link>
</div> </div>
</template> </template>
@@ -192,12 +193,15 @@ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}); });
import { Client } from "@stomp/stompjs";
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { NoticeTypeEnum, getNoticeLabel } from "@/enums/NoticeTypeEnum"; import { NoticeTypeEnum, getNoticeLabel } from "@/enums/NoticeTypeEnum";
import { TOKEN_KEY } from "@/enums/CacheEnum";
import StatsAPI, { VisitStatsVO } from "@/api/log"; import StatsAPI, { VisitStatsVO } from "@/api/log";
const userStore = useUserStore(); const userStore = useUserStore();
const socketEndpoint = ref(import.meta.env.VITE_APP_WS_ENDPOINT);
const date: Date = new Date(); const date: Date = new Date();
const greetings = computed(() => { const greetings = computed(() => {
const hours = date.getHours(); const hours = date.getHours();
@@ -237,6 +241,8 @@ const statisticData = ref([
}, },
]); ]);
const onlineUserCount = ref(0);
const visitStatsLoading = ref(true); const visitStatsLoading = ref(true);
const visitStatsList = ref<VisitStats[] | null>(Array(3).fill({})); const visitStatsList = ref<VisitStats[] | null>(Array(3).fill({}));
interface VisitStats { interface VisitStats {
@@ -384,8 +390,36 @@ const getNoticeLevelTag = (type: number) => {
} }
}; };
let stompClient: Client;
function connectWebSocket() {
stompClient = new Client({
brokerURL: socketEndpoint.value,
connectHeaders: {
Authorization: localStorage.getItem(TOKEN_KEY) || "",
},
debug: (str) => {
console.log(str);
},
onConnect: () => {
console.log("连接成功");
stompClient.subscribe("/topic/onlineUserCount", (message) => {
onlineUserCount.value = JSON.parse(message.body);
});
},
onStompError: (frame) => {
console.error("Broker reported error: " + frame.headers["message"]);
console.error("Additional details: " + frame.body);
},
onDisconnect: () => {},
});
stompClient.activate();
}
onMounted(() => { onMounted(() => {
loadVisitStatsData(); loadVisitStatsData();
connectWebSocket();
}); });
</script> </script>