random-api-go/public/index.html

235 lines
8.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<title>随机文件api</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" size="32x32" href="https://cdn-r2.czl.net/2023/06/20/649168ebc2b5d.png">
<link rel="stylesheet" href="https://cdn-r2.czl.net/frame/czlfonts/slice/font.css" media="all">
<link rel="stylesheet" href="https://cdn-r2.czl.net/frame/prose.css" media="all">
<link rel="stylesheet" href="./css/main.css" media="all">
<style>
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.2/markdown-it.min.js"></script>
</head>
<body>
<div class="overlay">
<main>
<div id="markdown-content" class="prose prose-dark">
</div>
</main>
</div>
<!-- 渲染markdown -->
<script>
// 创建带有配置的 markdown-it 实例
var md = window.markdownit({
html: true
});
// 用于存储配置的全局变量
let cachedEndpointConfig = null;
// 加载配置的函数
async function loadEndpointConfig() {
// 如果已经有缓存的配置,直接返回
if (cachedEndpointConfig) {
return cachedEndpointConfig;
}
try {
const response = await fetch('/config/endpoint.json');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 保存配置到缓存
cachedEndpointConfig = await response.json();
return cachedEndpointConfig;
} catch (error) {
console.error('加载endpoint配置失败:', error);
return {}; // 返回空对象作为默认值
}
}
// 加载统计数据
async function loadStats() {
try {
// 添加刷新动画
const refreshIcon = document.querySelector('.refresh-icon');
const summaryElement = document.getElementById('stats-summary');
const detailElement = document.getElementById('stats-detail');
if (refreshIcon) {
refreshIcon.classList.add('spinning');
}
if (summaryElement) summaryElement.classList.add('fade');
if (detailElement) detailElement.classList.add('fade');
// 获取数据
const response = await fetch('/stats');
const stats = await response.json();
// 更新统计
await updateStats(stats);
// 移除动画
setTimeout(() => {
if (refreshIcon) {
refreshIcon.classList.remove('spinning');
}
if (summaryElement) summaryElement.classList.remove('fade');
if (detailElement) detailElement.classList.remove('fade');
}, 300);
} catch (error) {
console.error('Error loading stats:', error);
}
}
// 处理统计数据
async function updateStats(stats) {
const endpointConfig = await loadEndpointConfig();
const startDate = new Date('2024-10-26');
const today = new Date();
const daysSinceStart = Math.ceil((today - startDate) / (1000 * 60 * 60 * 24));
let totalCalls = 0;
let todayCalls = 0;
Object.entries(stats).forEach(([endpoint, stat]) => {
if (endpointConfig[endpoint]) {
totalCalls += stat.total_calls;
todayCalls += stat.today_calls;
}
});
const avgCallsPerDay = Math.round(totalCalls / daysSinceStart);
const summaryHtml = `
<div class="stats-summary">
<div class="stats-header">
<h2>📊 接口调用次数 <span class="refresh-icon">🔄</span></h2>
</div>
<div class="stats-grid">
<div class="stats-item">今日总调用:${todayCalls} 次</div>
<div class="stats-item">平均每天调用:${avgCallsPerDay} 次</div>
<div class="stats-item">总调用次数:${totalCalls} 次</div>
<div class="stats-item">统计开始日期2024-10-26</div>
</div>
</div>
`;
const sortedEndpoints = Object.entries(stats)
.filter(([endpoint]) => endpointConfig[endpoint])
.sort(([endpointA], [endpointB]) => {
const orderA = endpointConfig[endpointA].order;
const orderB = endpointConfig[endpointB].order;
return orderA - orderB;
});
let detailHtml = `
<table>
<thead>
<tr>
<th>接口</th>
<th>今日调用</th>
<th>总调用</th>
<th>查看</th>
</tr>
</thead>
<tbody>
`;
sortedEndpoints.forEach(([endpoint, stat]) => {
detailHtml += `
<tr>
<td>
<a href="javascript:void(0)"
onclick="copyToClipboard('${endpoint}')"
class="endpoint-link"
title="点击复制链接">
${getDisplayName(endpoint, endpointConfig)}
</a>
</td>
<td>${stat.today_calls}</td>
<td>${stat.total_calls}</td>
<td><a href="${endpoint}" target="_blank" rel="noopener noreferrer">👀</a></td>
</tr>
`;
});
detailHtml += `
</tbody>
</table>
`;
const summaryElement = document.getElementById('stats-summary');
const detailElement = document.getElementById('stats-detail');
if (summaryElement) summaryElement.innerHTML = summaryHtml;
if (detailElement) detailElement.innerHTML = detailHtml;
}
// 获取显示名称的函数
function getDisplayName(endpoint, endpointConfig) {
return endpointConfig[endpoint]?.name || endpoint;
}
// 修改事件处理函数来处理异步更新
async function refreshStats() {
try {
// 如果配置还没有加载,先加载配置
if (!cachedEndpointConfig) {
await loadEndpointConfig();
}
// 然后获取统计数据
const response = await fetch('/stats');
const stats = await response.json();
await updateStats(stats);
} catch (error) {
console.error('Error:', error);
}
}
// 初始加载
document.addEventListener('DOMContentLoaded', refreshStats);
// 添加复制功能
function copyToClipboard(endpoint) {
const url = `https://random-api.czl.net/${endpoint}`;
navigator.clipboard.writeText(url).then(() => {
// 显示提示
const toast = document.createElement('div');
toast.className = 'toast';
toast.textContent = '链接已复制到剪贴板!';
document.body.appendChild(toast);
// 2秒后移除提示
setTimeout(() => {
toast.remove();
}, 2000);
}).catch(err => {
console.error('复制失败:', err);
});
}
// 先加载 markdown 内容
fetch('./index.md')
.then(response => response.text())
.then(markdownText => {
document.getElementById('markdown-content').innerHTML = md.render(markdownText);
// markdown 加载完成后等待一小段时间再加载统计数据
setTimeout(loadStats, 100);
})
.catch(error => console.error('Error loading index.md:', error));
// 定期更新统计数据
setInterval(loadStats, 5 * 1000);
</script>
</body>
</html>