friends(new): 雪诺的小博客

2. feat(analytics): 加入 Google Analytics
3. fix(style): 修复 Umami 请求重复多次请求的问题
This commit is contained in:
Ad-closeNN
2026-03-22 14:03:18 +08:00
parent c4940140b5
commit 175df8b814
8 changed files with 148 additions and 116 deletions
+19 -37
View File
@@ -7,7 +7,6 @@ import { i18n } from "../i18n/translation";
import { getDir } from "../utils/url-utils";
import ImageWrapper from "./misc/ImageWrapper.astro";
import PostMetadata from "./PostMeta.astro";
import { umamiConfig } from "../config";
interface Props {
class?: string;
@@ -43,7 +42,7 @@ const coverWidth = "28%";
const { remarkPluginFrontmatter } = await entry.render();
---
<div class:list={["card-base flex flex-col-reverse md:flex-col w-full rounded-[var(--radius-large)] overflow-hidden relative hover:scale-[1.02] hover:shadow-xl transition-all duration-[300ms]", className]} style={style}>
<div class:list={["card-base flex flex-col-reverse md:flex-col w-full rounded-[var(--radius-large)] overflow-hidden relative border border-black/20 dark:border-white/20 hover:scale-[1.02] hover:shadow-xl transition-all duration-[300ms]", className]} style={style}>
<div class:list={["pl-6 md:pl-9 pr-6 md:pr-2 pt-6 md:pt-7 pb-6 relative", {"w-full md:w-[calc(100%_-_52px_-_12px)]": !hasCover, "w-full md:w-[calc(100%_-_var(--coverWidth)_-_12px)]": hasCover}]}>
<a href={url}
class="transition group w-full block font-bold mb-3 text-3xl text-90
@@ -111,56 +110,39 @@ const { remarkPluginFrontmatter } = await entry.render();
<!-- https://github.com/afoim/fuwari/blob/81f22decb17ff7ee1dd480c10773f7ba8f4df296/src/components/PostCard.astro -->
<script define:vars={{ entry, umamiConfig }}>
<script define:vars={{ slug: entry.slug }}>
// 获取文章浏览量统计
async function fetchPostCardViews(slug) {
if (!umamiConfig.enable) {
const displayElement = document.getElementById(`page-views-${slug}`);
if (!displayElement || displayElement.dataset.umamiState === 'loading' || displayElement.dataset.umamiState === 'loaded') {
return;
}
displayElement.dataset.umamiState = 'loading';
try {
// 第一步:获取网站ID和token
const shareResponse = await fetch(`${umamiConfig.baseUrl}/api/share/${umamiConfig.shareId}`);
if (!shareResponse.ok) {
throw new Error('获取分享信息失败');
}
const shareData = await shareResponse.json();
const { websiteId, token } = shareData;
// 第二步:获取统计数据
const currentTimestamp = Date.now();
const statsUrl = `${umamiConfig.baseUrl}/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent(umamiConfig.timezone)}&url=%2Fposts%2F${slug}%2F&compare=false`;
const statsResponse = await fetch(statsUrl, {
headers: {
'x-umami-share-token': token
}
const umamiStore = window['__blogUmami'];
const statsData = await umamiStore?.getStats(`post:${slug}`, (websiteId) => {
const currentTimestamp = Date.now();
return `https://umami.adclosenn.top/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent('Asia/Shanghai')}&url=%2Fposts%2F${slug}%2F&compare=false`;
});
if (!statsResponse.ok) {
throw new Error('获取统计数据失败');
if (!statsData) {
throw new Error('统计功能未启用');
}
const statsData = await statsResponse.json();
const pageViews = statsData.pageviews?.value || 0;
// const visits = statsData.visits?.value || 0;
const displayElement = document.getElementById(`page-views-${slug}`);
if (displayElement) {
displayElement.textContent = `浏览量 ${pageViews}`;
}
displayElement.textContent = `浏览量 ${pageViews}`;
displayElement.dataset.umamiState = 'loaded';
} catch (error) {
console.error('Error fetching page views for', slug, ':', error);
const displayElement = document.getElementById(`page-views-${slug}`);
if (displayElement) {
displayElement.textContent = '统计不可用';
}
displayElement.textContent = '统计不可用';
displayElement.dataset.umamiState = 'error';
}
}
// 页面加载完成后获取统计数据
function initPostCardStats() {
const slug = entry.slug;
if (slug) {
fetchPostCardViews(slug);
}