@@ -113,7 +127,7 @@ onBeforeRouteUpdate(() => {
{{ getTextRef(section.name) }}
- {{ section.value.value }}
+ {{ formatNumber(section.value) }}
@@ -222,7 +236,7 @@ onBeforeRouteUpdate(() => {
}
.number {
- font-size: 30px;
+ font-size: 27px;
font-weight: bold;
margin-top: 5px;
margin-left: 15px;
diff --git a/docs/components/scripts/i18n.ts b/docs/components/scripts/i18n.ts
index 632c6cf9..a7d3e0ab 100644
--- a/docs/components/scripts/i18n.ts
+++ b/docs/components/scripts/i18n.ts
@@ -13,6 +13,7 @@ const i18nData = {
forks: 'Forks',
issues: 'Issues',
prs: 'Pull Requests',
+ visitors: 'Visitor',
size: 'Size',
plugins: 'Plugins',
resources: 'Resources',
@@ -32,6 +33,7 @@ const i18nData = {
forks: '叉子',
issues: '开启议题',
prs: '合并请求',
+ visitors: '访客',
size: '大小',
plugins: '插件',
resources: '主题资源',
diff --git a/docs/components/scripts/statsApi.ts b/docs/components/scripts/statsApi.ts
index 5be22c81..8dea2b5b 100644
--- a/docs/components/scripts/statsApi.ts
+++ b/docs/components/scripts/statsApi.ts
@@ -1,10 +1,11 @@
-
// URL
export const OWNER = "LiteyukiStudio"
export const REPO = "LiteyukiBot"
const githubAPIUrl = "https://api.github.com"
const onlineFetchUrl = "https://api.liteyuki.icu/online";
const totalFetchUrl = "https://api.liteyuki.icu/count";
+const visitRecordUrl = "https://api.liteyuki.icu/visit";
+const visitCountUrl = "https://api.liteyuki.icu/visit_count";
export const RepoUrl = `https://github.com/${OWNER}/${REPO}`
export const StarMapUrl = "https://starmap.liteyuki.icu"
@@ -25,10 +26,11 @@ interface StatsApi {
getGithubStats: () => Promise;
getPluginNum: () => Promise;
getResourceNum: () => Promise;
+ getVisitCount: () => Promise;
}
-export type { GithubStats };
+export type {GithubStats};
// 实现接口
export const statsApi: StatsApi = {
@@ -90,5 +92,48 @@ export const statsApi: StatsApi = {
} catch (e) {
return -1;
}
+ },
+ getVisitCount: async () => {
+ try {
+ const res = await fetch(visitCountUrl);
+ const data = await res.json();
+ return data.count;
+ } catch (e) {
+ return -1;
+ }
}
-};
\ No newline at end of file
+};
+
+function getDeviceId(): string {
+ // 用户每次访问时生成一个唯一的设备ID,储存在localStorage中,用于统计用户数量
+ const deviceIdKey = 'deviceId';
+ let deviceId = localStorage.getItem(deviceIdKey);
+
+ if (!deviceId) {
+ deviceId = generateUUID();
+ localStorage.setItem(deviceIdKey, deviceId);
+ }
+ return deviceId;
+}
+
+export async function uploadVisitRecord() {
+ const deviceId = getDeviceId();
+ try {
+ await fetch(visitRecordUrl, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ },
+ body: new URLSearchParams({'device_id': deviceId}).toString(),
+ });
+ } catch (e) {
+ console.error('Failed to upload visit record:', e);
+ }
+}
+
+function generateUUID(): string {
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
+ return v.toString(16);
+ });
+}
\ No newline at end of file