feat: update random-api-go service and UI with stats display

This commit is contained in:
wood chen 2024-10-26 14:28:04 +08:00
parent fe18d6c828
commit ff2163b207
4 changed files with 119 additions and 10 deletions

View File

@ -1,11 +1,13 @@
services:
random-api:
random-api-go:
container_name: random-api-go
image: woodchen/random-api-go:latest
ports:
- "5003:5003"
volumes:
- ./public:/root/public
- ./logs:/var/log/random-api
- ./data:/root/data
environment:
- TZ=Asia/Shanghai
restart: unless-stopped

16
main.go
View File

@ -180,11 +180,11 @@ func getCSVContent(path string) (*URLSelector, error) {
}
fullPath := filepath.Join("public", path)
log.Printf("Attempting to read file: %s", fullPath)
log.Printf("尝试读取文件: %s", fullPath)
fileContent, err := os.ReadFile(fullPath)
if err != nil {
return nil, fmt.Errorf("error reading CSV content: %w", err)
return nil, fmt.Errorf("读取 CSV 内容时出错: %w", err)
}
lines := strings.Split(string(fileContent), "\n")
@ -225,8 +225,8 @@ func handleAPIRequest(w http.ResponseWriter, r *http.Request) {
if time.Since(lastFetchTime) > cacheDuration {
if err := loadCSVPaths(); err != nil {
http.Error(w, "Failed to load CSV paths", http.StatusInternalServerError)
log.Printf("Error loading CSV paths: %v", err)
http.Error(w, "无法加载 CSV 路径", http.StatusInternalServerError)
log.Printf("加载 CSV 路径时出错: %v", err)
return
}
}
@ -253,13 +253,13 @@ func handleAPIRequest(w http.ResponseWriter, r *http.Request) {
selector, err := getCSVContent(csvPath)
if err != nil {
http.Error(w, "Failed to fetch CSV content", http.StatusInternalServerError)
log.Printf("Error fetching CSV content: %v", err)
http.Error(w, "无法获取 CSV 内容", http.StatusInternalServerError)
log.Printf("获取 CSV 内容时出错: %v", err)
return
}
if len(selector.URLs) == 0 {
http.Error(w, "No content available", http.StatusNotFound)
http.Error(w, "无可用内容", http.StatusNotFound)
return
}
@ -270,7 +270,7 @@ func handleAPIRequest(w http.ResponseWriter, r *http.Request) {
statsManager.IncrementCalls(endpoint)
duration := time.Since(start)
log.Printf("Request: %s %s from %s - Source: %s - Duration: %v - Redirecting to: %s",
log.Printf("请求:%s %s来自 %s -来源:%s -持续时间:%v -重定向至:%s",
r.Method, r.URL.Path, realIP, sourceDomain, duration, randomURL)
http.Redirect(w, r, randomURL, http.StatusFound)

View File

@ -54,6 +54,32 @@
max-width: 100%;
height: auto;
}
.stats-summary {
background-color: #f5f5f5;
padding: 15px;
border-radius: 8px;
margin: 20px 0;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
/* 两列布局 */
gap: 10px;
/* 项目之间的间距 */
}
.stats-item {
padding: 5px;
}
/* 确保在小屏幕上切换为单列 */
@media (max-width: 600px) {
.stats-grid {
grid-template-columns: 1fr;
}
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.2/markdown-it.min.js"></script>
</head>
@ -72,6 +98,81 @@
html: true
});
// 加载统计数据
async function loadStats() {
try {
const response = await fetch('/stats');
const stats = await response.json();
updateStats(stats);
} catch (error) {
console.error('Error loading stats:', error);
}
}
// 处理统计数据
function updateStats(stats) {
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.values(stats).forEach(stat => {
totalCalls += stat.total_calls;
todayCalls += stat.today_calls;
});
const avgCallsPerDay = Math.round(totalCalls / daysSinceStart);
// 更新总体统计
const summaryHtml = `
<div class="stats-summary">
<p>📊 <strong>接口调用统计</strong></p>
<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>
`;
// 更新详细统计
let detailHtml = `
<div class="prose">
<table>
<thead>
<tr>
<th>接口</th>
<th>今日调用</th>
<th>总调用</th>
</tr>
</thead>
<tbody>
`;
Object.entries(stats).forEach(([endpoint, stat]) => {
detailHtml += `
<tr>
<td>${endpoint}</td>
<td>${stat.today_calls}</td>
<td>${stat.total_calls}</td>
</tr>
`;
});
detailHtml += `
</tbody>
</table>
</div>
`;
// 插入统计数据
document.getElementById('stats-summary').innerHTML = summaryHtml;
document.getElementById('stats-detail').innerHTML = detailHtml;
}
// 异步加载 index.md 文件内容
fetch('./index.md')
.then(response => response.text())
@ -83,4 +184,4 @@
</script>
</body>
</html>
</html>

View File

@ -1,5 +1,11 @@
# Random-Api 随机文件API
## 接口统计
<div id="stats-summary"></div>
## 详细统计
<div id="stats-detail"></div>
## 图片接口
| 种类 | 请求地址 |