-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdashboard.html
More file actions
146 lines (133 loc) · 8.02 KB
/
Copy pathdashboard.html
File metadata and controls
146 lines (133 loc) · 8.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="./favicon.ico"><link rel="apple-touch-icon" href="./apple-touch-icon.png"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数据看板 — ToolHero Analytics</title>
<meta name="robots" content="noindex, nofollow">
<link rel="stylesheet" href="css/style.css">
<style>
.db-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:20px;margin:24px 0}
.db-card{background:var(--surface);border-radius:var(--radius-lg);padding:28px 24px;box-shadow:var(--shadow);border-left:4px solid var(--primary)}
.db-card .val{font-size:2.4rem;font-weight:900;line-height:1.1;color:var(--text)}
.db-card .lbl{font-size:0.82rem;color:var(--text-light);margin-top:6px;text-transform:uppercase;letter-spacing:0.5px}
.db-card.green{border-left-color:var(--success)}.db-card.green .val{color:var(--success)}
.db-card.amber{border-left-color:var(--accent)}.db-card.amber .val{color:var(--accent)}
.db-card.purple{border-left-color:#8b5cf6}.db-card.purple .val{color:#8b5cf6}
.table-wrap{overflow-x:auto;margin:24px 0;background:var(--surface);border-radius:var(--radius-lg);box-shadow:var(--shadow);padding:20px}
table{width:100%;border-collapse:collapse}
th{text-align:left;padding:12px 16px;font-size:0.78rem;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-light);border-bottom:2px solid var(--border)}
td{padding:14px 16px;font-size:0.92rem;border-bottom:1px solid var(--border)}
tr:last-child td{border-bottom:none}
.bar{display:inline-block;height:8px;border-radius:4px;background:var(--primary);min-width:4px}
.updated{font-size:0.78rem;color:var(--text-light);text-align:right;margin-top:16px}
</style>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-NW92XRTC');</script>
<!-- End Google Tag Manager -->
</head>
<body>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NW92XRTC" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<header><nav class="navbar"><div class="container"><a href="./" class="logo"><span class="logo-icon">🦸</span><span class="logo-text">Tool<span class="highlight">Hero</span></span></a><ul class="nav-links"><li><a href="./">Home</a></li><li><a href="./#tools">Tools</a></li><li><a href="blog/">Blog</a></li></ul></div></nav></header>
<main style="padding:40px 0 80px">
<div class="container">
<h1 style="font-size:2rem;margin-bottom:8px">数据看板</h1>
<p style="color:var(--text-light);margin-bottom:32px">每3天自动刷新。数据来源:Google Analytics 4 + Search Console。</p>
<div class="db-grid">
<div class="db-card"><div class="val" id="visitors">--</div><div class="lbl">7日访客数</div></div>
<div class="db-card green"><div class="val" id="pageviews">--</div><div class="lbl">7日页面浏览量</div></div>
<div class="db-card amber"><div class="val" id="avgTime">--</div><div class="lbl">平均停留时长</div></div>
<div class="db-card purple"><div class="val" id="revenue">$0.00</div><div class="lbl">广告收入(等AdSense通过)</div></div>
</div>
<div class="table-wrap">
<h3 style="margin-bottom:16px">热门页面(近7天)</h3>
<table>
<thead><tr><th>页面</th><th>浏览量</th><th>占比</th></tr></thead>
<tbody id="topPages">
<tr><td colspan="3" style="text-align:center;color:var(--text-light)">Loading data...</td></tr>
</tbody>
</table>
</div>
<div class="db-grid">
<div class="db-card"><div class="val" id="searchClicks">--</div><div class="lbl">搜索点击量(7日)</div></div>
<div class="db-card green"><div class="val" id="searchImpressions">--</div><div class="lbl">搜索展示量(7日)</div></div>
<div class="db-card amber"><div class="val" id="avgPosition">--</div><div class="lbl">平均搜索排名</div></div>
<div class="db-card purple"><div class="val" id="indexedPages">--</div><div class="lbl">已收录页面</div></div>
</div>
<div class="table-wrap">
<h3 style="margin-bottom:16px">快捷入口</h3>
<table>
<tr><td>Google Analytics</td><td><a href="https://analytics.google.com" target="_blank">查看完整报告 →</a></td></tr>
<tr><td>Search Console</td><td><a href="https://search.google.com/search-console" target="_blank">查看搜索数据 →</a></td></tr>
<tr><td>Cloudflare</td><td><a href="https://dash.cloudflare.com" target="_blank">CDN & DNS →</a></td></tr>
<tr><td>GitHub</td><td><a href="https://github.com/Z1YiKK/usefultools" target="_blank">源码仓库 →</a></td></tr>
</table>
</div>
<p class="updated">Last updated: <span id="lastUpdate">Just now</span></p>
</div>
</main>
<footer><div class="container"><div class="footer-bottom"><p>© 2026 ToolHero.</p></div></div></footer>
<script>
var pageNames = {
'/': '首页 (Home)',
'/tools/pet-cost-calculator.html': '宠物花费计算器 (Pet Cost)',
'/tools/mortgage-calculator.html': '房贷计算器 (Mortgage)',
'/tools/bmi-calculator.html': 'BMI 计算器',
'/tools/savings-calculator.html': '储蓄目标计算器 (Savings)',
'/tools/subscription-calculator.html': '订阅费用分析 (Subscription)',
'/tools/tip-calculator.html': '小费计算器 (Tip)',
'/tools/moving-calculator.html': '搬家费用估算 (Moving)',
'/tools/fuel-calculator.html': '油费计算器 (Fuel)',
'/tools/calorie-calculator.html': '卡路里计算器 (Calorie)',
'/blog/': '博客首页 (Blog)',
'/privacy.html': '隐私政策 (Privacy)',
'/terms.html': '使用条款 (Terms)',
'/contact.html': '联系我们 (Contact)',
'/dashboard.html': '数据看板 (数据看板)'
};
fetch('data/dashboard-data.json?v=' + Date.now())
.then(function(r) { return r.json(); })
.then(function(d) {
document.getElementById('lastUpdate').textContent = 'Last updated: ' + new Date(d.updated).toLocaleString() + ' | GA4 + Search Console';
// GA4 data
if (d.ga4 && d.ga4.rows) {
var totalUsers = 0, totalViews = 0, totalTime = 0;
var pages = [];
d.ga4.rows.forEach(function(r) {
var page = r.dimensionValues[0].value;
var users = parseInt(r.metricValues[0].value) || 0;
var views = parseInt(r.metricValues[1].value) || 0;
var time = parseFloat(r.metricValues[2].value) || 0;
totalUsers += users; totalViews += views; totalTime += time * users;
pages.push({page: page, users: users, views: views});
});
var avgTime = totalUsers > 0 ? Math.round(totalTime / totalUsers) : 0;
document.getElementById('visitors').textContent = totalUsers;
document.getElementById('pageviews').textContent = totalViews;
document.getElementById('avgTime').textContent = avgTime + 's avg';
pages.sort(function(a,b) { return b.views - a.views; });
var topPagesHtml = '';
pages.slice(0, 10).forEach(function(p) {
var pct = totalViews > 0 ? Math.round(p.views / totalViews * 100) : 0;
var barWidth = Math.min(pct * 4, 300);
var label = pageNames[p.page] || p.page;
topPagesHtml += '<tr><td>' + label + '</td><td>' + p.views + '</td><td><span class="bar" style="width:' + barWidth + 'px;"></span> ' + pct + '%</td></tr>';
});
document.getElementById('topPages').innerHTML = topPagesHtml;
}
// Search Console data
if (d.searchTotals) {
document.getElementById('searchClicks').textContent = d.searchTotals.clicks || 0;
document.getElementById('searchImpressions').textContent = (d.searchTotals.impressions || 0).toLocaleString();
document.getElementById('avgPosition').textContent = d.searchTotals.avgPosition || '--';
document.getElementById('indexedPages').textContent = d.searchTotals.impressions > 0 ? 'Active' : 'Waiting';
}
})
.catch(function() {
document.getElementById('lastUpdate').textContent = 'Data loading... check back later';
});
</script>
</body>
</html>