mirror of
https://github.com/Ad-closeNN/blog-fuwari.git
synced 2026-05-31 01:00:04 -04:00
5fbc350af2
commit54078a69f8Author: Ad-closeNN <1709301095@qq.com> Date: Thu Aug 7 23:33:17 2025 +0800 2025/8/7 commitf65632b1e8Author: Ad-closeNN <1709301095@qq.com> Date: Thu Aug 7 18:45:38 2025 +0800 Finish commit7986271c89Author: Ad-closeNN <1709301095@qq.com> Date: Thu Aug 7 17:41:57 2025 +0800 Delete umami.md commitfc0208cf4fAuthor: Ad-closeNN <1709301095@qq.com> Date: Thu Aug 7 17:38:53 2025 +0800 测试第一篇文章 commit690d1290e4Author: Ad-closeNN <1709301095@qq.com> Date: Thu Aug 7 11:56:58 2025 +0800 feat: 博客访问量测试 commit135830db3cAuthor: Ad-closeNN <1709301095@qq.com> Date: Thu Aug 7 00:30:57 2025 +0800 25/8/6
155 lines
5.9 KiB
Plaintext
155 lines
5.9 KiB
Plaintext
---
|
|
import path from "node:path";
|
|
import { Icon } from "astro-icon/components";
|
|
import I18nKey from "../i18n/i18nKey";
|
|
import { i18n } from "../i18n/translation";
|
|
import { formatDateToYYYYMMDD } from "../utils/date-utils";
|
|
import { getCategoryUrl, getTagUrl, getDir, url } from "../utils/url-utils";
|
|
import { umamiConfig } from "../config";
|
|
|
|
interface Props {
|
|
class: string;
|
|
published: Date;
|
|
updated?: Date;
|
|
tags: string[];
|
|
category: string | null;
|
|
hideTagsForMobile?: boolean;
|
|
hideUpdateDate?: boolean;
|
|
slug?: string;
|
|
}
|
|
const {
|
|
published,
|
|
updated,
|
|
tags,
|
|
category,
|
|
hideTagsForMobile = false,
|
|
hideUpdateDate = false,
|
|
slug,
|
|
} = Astro.props;
|
|
const className = Astro.props.class;
|
|
---
|
|
|
|
<div class:list={["flex flex-wrap text-neutral-500 dark:text-neutral-400 items-center gap-4 gap-x-4 gap-y-2", className]}>
|
|
<!-- publish date -->
|
|
<div class="flex items-center">
|
|
<div class="meta-icon"
|
|
>
|
|
<Icon name="material-symbols:calendar-today-outline-rounded" class="text-xl"></Icon>
|
|
</div>
|
|
<span class="text-50 text-sm font-medium">{formatDateToYYYYMMDD(published)}</span>
|
|
</div>
|
|
|
|
<!-- update date
|
|
{!hideUpdateDate && updated && updated.getTime() !== published.getTime() && (
|
|
<div class="flex items-center">
|
|
<div class="meta-icon"
|
|
>
|
|
<Icon name="material-symbols:edit-calendar-outline-rounded" class="text-xl"></Icon>
|
|
</div>
|
|
<span class="text-50 text-sm font-medium">{formatDateToYYYYMMDD(updated)}</span>
|
|
</div>
|
|
)}
|
|
-->
|
|
|
|
<!-- categories -->
|
|
<div class="flex items-center">
|
|
<div class="meta-icon"
|
|
>
|
|
<Icon name="material-symbols:book-2-outline-rounded" class="text-xl"></Icon>
|
|
</div>
|
|
<div class="flex flex-row flex-nowrap items-center">
|
|
<a href={getCategoryUrl(category)} aria-label={`View all posts in the ${category} category`}
|
|
class="link-lg transition text-50 text-sm font-medium
|
|
hover:text-[var(--primary)] dark:hover:text-[var(--primary)] whitespace-nowrap">
|
|
{category || i18n(I18nKey.uncategorized)}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- tags -->
|
|
<div class:list={["items-center", {"flex": !hideTagsForMobile, "hidden md:flex": hideTagsForMobile}]}>
|
|
<div class="meta-icon"
|
|
>
|
|
<Icon name="material-symbols:tag-rounded" class="text-xl"></Icon>
|
|
</div>
|
|
<div class="flex flex-row flex-nowrap items-center">
|
|
{(tags && tags.length > 0) && tags.map((tag, i) => (
|
|
<div class:list={[{"hidden": i == 0}, "mx-1.5 text-[var(--meta-divider)] text-sm"]}>/</div>
|
|
<a href={getTagUrl(tag)} aria-label={`View all posts with the ${tag.trim()} tag`}
|
|
class="link-lg transition text-50 text-sm font-medium
|
|
hover:text-[var(--primary)] dark:hover:text-[var(--primary)] whitespace-nowrap">
|
|
{tag.trim()}
|
|
</a>
|
|
))}
|
|
{!(tags && tags.length > 0) && <div class="transition text-50 text-sm font-medium">{i18n(I18nKey.noTags)}</div>}
|
|
</div>
|
|
</div>
|
|
|
|
{slug && (
|
|
<div class="flex items-center">
|
|
<div class="meta-icon">
|
|
<Icon name="material-symbols:visibility-outline-rounded" class="text-xl"></Icon>
|
|
</div>
|
|
<span class="text-50 text-sm font-medium" id="page-views-display">加载中...</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<!-- https://github.com/afoim/fuwari/blob/81f22decb17ff7ee1dd480c10773f7ba8f4df296/src/components/PostMeta.astro -->
|
|
|
|
{slug && (
|
|
<script define:vars={{ slug, umamiConfig }}>
|
|
// 获取访问量统计
|
|
async function fetchPageViews() {
|
|
if (!umamiConfig.enable) {
|
|
return;
|
|
}
|
|
|
|
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
|
|
}
|
|
});
|
|
|
|
if (!statsResponse.ok) {
|
|
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-display');
|
|
if (displayElement) {
|
|
displayElement.textContent = `浏览量 ${pageViews} · 访问数 ${visits}`;
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching page views:', error);
|
|
const displayElement = document.getElementById('page-views-display');
|
|
if (displayElement) {
|
|
displayElement.textContent = '统计不可用';
|
|
}
|
|
}
|
|
}
|
|
|
|
// 页面加载完成后获取统计数据
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', fetchPageViews);
|
|
} else {
|
|
fetchPageViews();
|
|
}
|
|
</script>
|
|
)} |