app/docs/components/StatsBar.vue

156 lines
3.2 KiB
Vue
Raw Normal View History

2024-09-01 18:25:37 +08:00
<script setup lang="ts">
import {ref, onMounted, onUnmounted} from "vue";
import getText from "./scripts/i18n";
2024-09-01 16:52:10 +08:00
const onlineText = getText('online');
2024-09-01 18:25:37 +08:00
const totalText = getText('total');
const onlineFetchUrl = "https://api.liteyuki.icu/online";
const totalFetchUrl = "https://api.liteyuki.icu/count";
const online = ref(0);
const total = ref(0);
function updateData() {
fetch(onlineFetchUrl)
.then(response => response.json())
.then(data => online.value = data.online)
.catch(error => console.error('Error fetching online data:', error));
fetch(totalFetchUrl)
.then(response => response.json())
.then(data => total.value = data.register)
.catch(error => console.error('Error fetching total data:', error));
2024-09-01 16:52:10 +08:00
}
2024-09-01 18:25:37 +08:00
onMounted(() => {
const intervalId = setInterval(updateData, 10000);
updateData();
onUnmounted(() => {
clearInterval(intervalId);
});
});
2024-09-01 16:52:10 +08:00
</script>
<template>
2024-09-01 17:57:21 +08:00
<div class="stats-bar">
<div class="stats-info">
<div id="total" class="section">
<div class="line">
<span class=dot style="background-color: #00a6ff"></span>
<span class="text">{{ totalText }}</span>
</div>
<div class="number">{{ total }}</div>
2024-09-01 16:52:10 +08:00
</div>
2024-09-01 17:57:21 +08:00
<div id="online" class="section">
<div class="line">
<span class=dot style="background-color: #00ff00"></span>
<span class="text">{{ onlineText }}</span>
</div>
<div class="number">{{ online }}</div>
2024-09-01 16:52:10 +08:00
</div>
2024-09-01 17:57:21 +08:00
</div>
<div class="starmap">
<iframe src="https://starmap.liteyuki.icu/" width="100%" height="300px"></iframe>
2024-09-01 16:52:10 +08:00
</div>
</div>
2024-09-01 17:57:21 +08:00
2024-09-01 16:52:10 +08:00
</template>
<style scoped>
2024-09-01 17:57:21 +08:00
.stats-bar {
2024-09-01 16:52:10 +08:00
display: flex;
2024-09-01 17:57:21 +08:00
justify-content: space-between;
2024-09-01 16:52:10 +08:00
padding: 20px;
2024-09-01 17:57:21 +08:00
margin: 30px 10px 10px 10px;
border-radius: var(--border-radius-2);
2024-09-01 16:52:10 +08:00
background-color: var(--vp-c-gray-1);
2024-09-01 17:57:21 +08:00
flex-direction: column; /* 默认纵向布局 */
}
.stats-info {
width: 100%;
padding: 10px;
display: flex;
justify-content: space-evenly;
margin-bottom: 20px;
}
.section {
display: flex;
flex-direction: column;
2024-09-01 16:52:10 +08:00
}
.section:not(:last-child) {
2024-09-01 17:57:21 +08:00
margin-right: 50px;
2024-09-01 16:52:10 +08:00
}
.line {
margin-bottom: 20px;
}
.dot {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 5px;
}
2024-09-01 17:57:21 +08:00
.text {
font-size: 14px;
}
2024-09-01 16:52:10 +08:00
.number {
font-size: 30px;
font-weight: bold;
margin-top: 5px;
}
2024-09-01 17:57:21 +08:00
.starmap {
position: relative;
width: 100%;
height: 200px;
overflow: hidden;
border-radius: var(--border-radius-2);
}
.starmap iframe {
position: absolute;
top: -150px; /* 根据需要调整裁剪位置 */
left: -40px; /* 根据需要调整裁剪位置 */;
width: calc(100% + 80px); /* 根据需要调整裁剪宽度 */
height: calc(100% + 300px); /* 根据需要调整裁剪高度 */
}
@media (min-width: 768px) {
/* PC模式下的样式 */
.stats-bar {
flex-direction: row;
}
.stats-info {
width: 40%;
}
.starmap {
width: 60%;
height: 400px;
}
.starmap iframe {
position: absolute;
top: -130px; /* 根据需要调整裁剪位置 */
left: -60px; /* 根据需要调整裁剪位置 */;
width: calc(100% + 120px); /* 根据需要调整裁剪宽度 */
height: calc(100% + 280px); /* 根据需要调整裁剪高度 */
}
}
2024-09-01 16:52:10 +08:00
</style>