1
0
forked from bot/app

📝 [docs]: 新增在线展示

This commit is contained in:
远野千束 2024-09-01 21:16:45 +08:00
parent 837447b6e4
commit 94cab8b743
3 changed files with 95 additions and 21 deletions

View File

@ -1,10 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import DefaultTheme from "vitepress/theme"; import DefaultTheme from "vitepress/theme";
import {ref, onMounted, onUnmounted} from "vue"; import {ref, onMounted, onUnmounted} from "vue";
import {statsApi, GithubStats} from "./scripts/statsApi"; import {statsApi, GithubStats, RepoUrl, StarMapUrl} from "./scripts/statsApi";
import {getTextRef, updateRef} from "./scripts/i18n"; import {getTextRef, updateRef} from "./scripts/i18n";
const {Layout} = DefaultTheme; const {Layout} = DefaultTheme;
let githubStats: GithubStats | null = null; let githubStats: GithubStats | null = null;
@ -13,32 +12,50 @@ const dataSections = {
total: { total: {
name: 'total', name: 'total',
color: '#00a6ff', color: '#00a6ff',
value: ref(0), value: ref(2005),
link: StarMapUrl
}, },
online: { online: {
name: 'online', name: 'online',
color: '#00ff00', color: '#00ff00',
value: ref(0), value: ref(1145),
link: StarMapUrl
}, },
stars: { stars: {
name: 'stars', name: 'stars',
color: '#ffcc00', color: '#ffcc00',
value: ref(0), value: ref(1234),
link: `${RepoUrl}/stargazers`
}, },
forks: { forks: {
name: 'forks', name: 'forks',
color: '#ff6600', color: '#ff6600',
value: ref(0), value: ref(9420),
link: `${RepoUrl}/forks`
}, },
issues: { issues: {
name: 'issues', name: 'issues',
color: '#ff0000', color: '#ff0000',
value: ref(0), value: ref(1145),
link: `${RepoUrl}/issues`
}, },
prs: { prs: {
name: 'prs', name: 'prs',
color: '#ff00ff', color: '#ff00ff',
value: ref(0), value: ref(6543),
link: `${RepoUrl}/pulls`
},
plugins: {
name: 'plugins',
color: '#ff003e',
value: ref(1763),
link: './store/plugin'
},
resources: {
name: 'resources',
color: '#ff00ff',
value: ref(6789),
link: './store/resource'
}, },
} }
@ -48,10 +65,15 @@ async function updateData() {
[ [
dataSections.online.value.value, dataSections.online.value.value,
dataSections.total.value.value, dataSections.total.value.value,
dataSections.plugins.value.value,
dataSections.resources.value.value,
githubStats, githubStats,
] = await Promise.all([ ] = await Promise.all([
statsApi.getOnline(), statsApi.getOnline(),
statsApi.getTotal(), statsApi.getTotal(),
statsApi.getPluginNum(),
statsApi.getResourceNum(),
statsApi.getGithubStats(), statsApi.getGithubStats(),
]); ]);
dataSections.stars.value.value = githubStats?.stars || 0; dataSections.stars.value.value = githubStats?.stars || 0;
@ -77,11 +99,13 @@ onMounted(() => {
<div class="stats-bar"> <div class="stats-bar">
<div class="stats-info"> <div class="stats-info">
<div v-for="section in Object.values(dataSections)" :key="section.name" class="section"> <div v-for="section in Object.values(dataSections)" :key="section.name" class="section">
<a :href="section.link" target="_blank">
<div class="section-tab"> <div class="section-tab">
<span class="dot" :style="{backgroundColor: section.color}"></span> <span class="dot" :style="{backgroundColor: section.color}"></span>
<span class="text">{{ getTextRef(section.name) }}</span> <span class="text">{{ getTextRef(section.name) }}</span>
</div> </div>
<div class="number">{{ section.value.value }}</div> <div class="number">{{ section.value.value }}</div>
</a>
</div> </div>
</div> </div>
<div class="starmap"> <div class="starmap">
@ -89,7 +113,6 @@ onMounted(() => {
</div> </div>
</div> </div>
</div> </div>
</template> </template>
</Layout> </Layout>
</template> </template>
@ -109,7 +132,7 @@ onMounted(() => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 20px; padding: 20px;
margin: 30px; margin: 10px;
border-radius: var(--border-radius-2); border-radius: var(--border-radius-2);
background-color: var(--vp-c-gray-1); background-color: var(--vp-c-gray-1);
flex-direction: column; /* 默认纵向布局 */ flex-direction: column; /* 默认纵向布局 */
@ -117,16 +140,35 @@ onMounted(() => {
.stats-info { .stats-info {
width: 100%; width: 100%;
padding: 10px;
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 15px; gap: 15px;
margin: 20px; margin: 10px;
} }
.section { .section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; /* 使伪元素相对于父元素定位 */
border-radius: var(--border-radius-2);
}
.section::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 0 solid transparent; /* 初始边框为透明 */
transition: border 0.1s ease-in-out; /* 添加过渡效果 */
border-radius: var(--border-radius-2);
pointer-events: none; /* 确保伪元素不会阻挡点击事件 */
}
.section:hover::before {
border: 1px solid #00a6ff; /* 悬停时添加边框 */
border-radius: var(--border-radius-2);
} }
.section-tab { .section-tab {
@ -176,10 +218,12 @@ onMounted(() => {
/* PC模式下的样式 */ /* PC模式下的样式 */
.stats-bar { .stats-bar {
flex-direction: row; flex-direction: row;
margin: 30px;
} }
.stats-info { .stats-info {
width: 40%; width: 40%;
margin: 20px;
} }
.starmap { .starmap {

View File

@ -11,6 +11,9 @@ const i18nData = {
forks: 'Forks', forks: 'Forks',
issues: 'Issues', issues: 'Issues',
prs: 'Pull Requests', prs: 'Pull Requests',
size: 'Size',
plugins: 'Plugins',
resources: 'Resources',
}, },
zh: { zh: {
online: '在线', online: '在线',
@ -19,8 +22,11 @@ const i18nData = {
fetching: '获取中', fetching: '获取中',
stars: '星星', stars: '星星',
forks: '叉子', forks: '叉子',
issues: '议题', issues: '开启议题',
prs: '合并请求', prs: '合并请求',
size: '大小',
plugins: '插件',
resources: '主题资源',
} }
} }

View File

@ -1,11 +1,13 @@
// URL // URL
const OWNER = "LiteyukiStudio" export const OWNER = "LiteyukiStudio"
const REPO = "LiteyukiBot" export const REPO = "LiteyukiBot"
const githubAPIUrl = "https://api.github.com" const githubAPIUrl = "https://api.github.com"
const onlineFetchUrl = "https://api.liteyuki.icu/online"; const onlineFetchUrl = "https://api.liteyuki.icu/online";
const totalFetchUrl = "https://api.liteyuki.icu/count"; const totalFetchUrl = "https://api.liteyuki.icu/count";
export const RepoUrl = `https://github.com/${OWNER}/${REPO}`
export const StarMapUrl = "https://starmap.liteyuki.icu"
type GithubStats = { type GithubStats = {
stars: number; stars: number;
@ -13,6 +15,7 @@ type GithubStats = {
watchers: number; watchers: number;
issues?: number; issues?: number;
prs?: number; prs?: number;
size?: number;
} }
// 异步接口 // 异步接口
@ -20,12 +23,13 @@ interface StatsApi {
getTotal: () => Promise<number>; getTotal: () => Promise<number>;
getOnline: () => Promise<number>; getOnline: () => Promise<number>;
getGithubStats: () => Promise<GithubStats>; getGithubStats: () => Promise<GithubStats>;
getPluginNum: () => Promise<number>;
getResourceNum: () => Promise<number>;
} }
export type { GithubStats }; export type { GithubStats };
// 实现接口 // 实现接口
export const statsApi: StatsApi = { export const statsApi: StatsApi = {
getTotal: async () => { getTotal: async () => {
@ -56,6 +60,7 @@ export const statsApi: StatsApi = {
watchers: data.watchers_count, watchers: data.watchers_count,
issues: data.open_issues_count, issues: data.open_issues_count,
prs: data.open_issues_count, prs: data.open_issues_count,
size: data.size,
}; };
} catch (e) { } catch (e) {
return { return {
@ -64,7 +69,26 @@ export const statsApi: StatsApi = {
watchers: -1, watchers: -1,
issues: -1, issues: -1,
prs: -1, prs: -1,
size: -1,
}; };
} }
}, },
getPluginNum: async () => {
try {
const res = await fetch('./plugins.json');
const data = await res.json();
return data.length;
} catch (e) {
return -1;
}
},
getResourceNum: async () => {
try {
const res = await fetch('./resources.json');
const data = await res.json();
return data.length;
} catch (e) {
return -1;
}
}
}; };