app/docs/components/scripts/statsApi.ts

139 lines
3.8 KiB
TypeScript
Raw Normal View History

2024-09-01 20:39:51 +08:00
// URL
2024-09-01 21:16:45 +08:00
export const OWNER = "LiteyukiStudio"
export const REPO = "LiteyukiBot"
2024-09-01 20:39:51 +08:00
const githubAPIUrl = "https://api.github.com"
const onlineFetchUrl = "https://api.liteyuki.icu/online";
const totalFetchUrl = "https://api.liteyuki.icu/count";
2024-09-02 00:13:37 +08:00
const visitRecordUrl = "https://api.liteyuki.icu/visit";
const visitCountUrl = "https://api.liteyuki.icu/visit_count";
2024-09-01 20:39:51 +08:00
2024-09-01 21:16:45 +08:00
export const RepoUrl = `https://github.com/${OWNER}/${REPO}`
export const StarMapUrl = "https://starmap.liteyuki.icu"
2024-09-01 20:39:51 +08:00
type GithubStats = {
stars: number;
forks: number;
watchers: number;
issues?: number;
prs?: number;
2024-09-01 21:16:45 +08:00
size?: number;
2024-09-01 20:39:51 +08:00
}
// 异步接口
interface StatsApi {
getTotal: () => Promise<number>;
getOnline: () => Promise<number>;
getGithubStats: () => Promise<GithubStats>;
2024-09-01 21:16:45 +08:00
getPluginNum: () => Promise<number>;
getResourceNum: () => Promise<number>;
2024-09-02 00:13:37 +08:00
getVisitCount: () => Promise<number>;
2024-09-01 20:39:51 +08:00
}
2024-09-02 00:13:37 +08:00
export type {GithubStats};
2024-09-01 20:39:51 +08:00
// 实现接口
export const statsApi: StatsApi = {
getTotal: async () => {
try {
const res = await fetch(totalFetchUrl);
const data = await res.json();
return data.register;
} catch (e) {
return -1;
}
},
getOnline: async () => {
try {
const res = await fetch(onlineFetchUrl);
const data = await res.json();
return data.online;
} catch (e) {
return -1;
}
},
getGithubStats: async () => {
try {
const res = await fetch(`${githubAPIUrl}/repos/${OWNER}/${REPO}`);
const data = await res.json();
return {
stars: data.stargazers_count,
forks: data.forks_count,
watchers: data.watchers_count,
issues: data.open_issues_count,
prs: data.open_issues_count,
2024-09-01 21:16:45 +08:00
size: data.size,
2024-09-01 20:39:51 +08:00
};
} catch (e) {
return {
stars: -1,
forks: -1,
watchers: -1,
issues: -1,
prs: -1,
2024-09-01 21:16:45 +08:00
size: -1,
2024-09-01 20:39:51 +08:00
};
}
},
2024-09-01 21:16:45 +08:00
getPluginNum: async () => {
try {
2024-09-01 21:21:04 +08:00
const res = await fetch('/plugins.json');
2024-09-01 21:16:45 +08:00
const data = await res.json();
return data.length;
} catch (e) {
return -1;
}
},
getResourceNum: async () => {
try {
2024-09-01 21:21:04 +08:00
const res = await fetch('/resources.json');
2024-09-01 21:16:45 +08:00
const data = await res.json();
return data.length;
} catch (e) {
return -1;
}
2024-09-02 00:13:37 +08:00
},
getVisitCount: async () => {
try {
const res = await fetch(visitCountUrl);
const data = await res.json();
return data.count;
} catch (e) {
return -1;
}
2024-09-01 21:16:45 +08:00
}
2024-09-02 00:13:37 +08:00
};
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);
});
}