From 1b6295a5f1961fb44e5283600a920b16c4c71b79 Mon Sep 17 00:00:00 2001 From: jacksen168 Date: Mon, 22 Jun 2026 23:27:04 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat(sidebar/widget):=20add=2051LA=20visito?= =?UTF-8?q?r=20statistics=20sidebar=20widget=20feat(=E4=BE=A7=E8=BE=B9?= =?UTF-8?q?=E6=A0=8F/=E7=BB=84=E4=BB=B6):=20=E6=96=B0=E5=A2=9E51LA?= =?UTF-8?q?=E8=AE=BF=E9=97=AE=E7=BB=9F=E8=AE=A1=E4=BE=A7=E8=BE=B9=E6=A0=8F?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fully implements the 51LA visitor statistics sidebar widget feature. New Features: - **LaStats widget**: Add new sidebar widget component for 51LA analytics, supports displaying online users, today UV/PV, yesterday UV/PV, monthly and total views - **Type definition**: Add `lastats` widget type in `src/types/sidebarConfig.ts` - **I18n support**: Add multi-language translation entries for 51LA stats across all supported languages - **Config preset**: Pre-configure the LaStats widget in default sidebar layout config 本提交完整实现了51LA访问统计侧边栏组件功能: 新增功能: - **LaStats组件**:新增51LA分析侧边栏组件,支持展示当前在线人数、今日访客/浏览量、昨日访客/浏览量、本月和总浏览量 - **类型定义**:在`src/types/sidebarConfig.ts`中新增`lastats`组件类型 - **国际化支持**:为所有支持语言添加51LA统计相关的多语言翻译条目 - **配置预设**:在默认侧边栏布局配置中预启用LaStats组件 --- src/components/layout/SideBar.astro | 2 + src/components/widget/LaStats.astro | 133 ++++++++++++++++++++++++++++ src/config/sidebarConfig.ts | 18 ++++ src/i18n/i18nKey.ts | 10 +++ src/i18n/languages/en.ts | 10 +++ src/i18n/languages/ja.ts | 10 +++ src/i18n/languages/ru.ts | 10 +++ src/i18n/languages/zh_CN.ts | 10 +++ src/i18n/languages/zh_TW.ts | 10 +++ src/types/sidebarConfig.ts | 1 + 10 files changed, 214 insertions(+) create mode 100644 src/components/widget/LaStats.astro diff --git a/src/components/layout/SideBar.astro b/src/components/layout/SideBar.astro index 57bb9e9413..589e303637 100644 --- a/src/components/layout/SideBar.astro +++ b/src/components/layout/SideBar.astro @@ -4,6 +4,7 @@ import Advertisement from "@/components/widget/Advertisement.astro"; import Announcement from "@/components/widget/Announcement.astro"; import Calendar from "@/components/widget/Calendar.astro"; import Categories from "@/components/widget/Categories.astro"; +import LaStats from "@/components/widget/LaStats.astro"; import Music from "@/components/widget/Music.astro"; import Profile from "@/components/widget/Profile.astro"; import SidebarTOC from "@/components/widget/SidebarTOC.astro"; @@ -47,6 +48,7 @@ const componentMap = { sidebarToc: SidebarTOC, advertisement: Advertisement, stats: SiteStats, + lastats: LaStats, calendar: Calendar, music: Music, siteInfo: SiteInfo, diff --git a/src/components/widget/LaStats.astro b/src/components/widget/LaStats.astro new file mode 100644 index 0000000000..744aee3e11 --- /dev/null +++ b/src/components/widget/LaStats.astro @@ -0,0 +1,133 @@ +--- +import { Icon } from "astro-icon/components"; +import WidgetLayout from "@/components/common/WidgetLayout.astro"; +import { analyticsConfig } from "@/config"; +import I18nKey from "@/i18n/i18nKey"; +import { i18n } from "@/i18n/translation"; +import type { WidgetComponentConfig } from "@/types/config"; + +interface Props { + class?: string; + style?: string; + widgetConfig?: WidgetComponentConfig; +} + +const { class: className, style, widgetConfig } = Astro.props; + +const showTitle = widgetConfig?.showTitle !== false; + +const la51Id = analyticsConfig?.la51Analytics?.Id || ""; + +// 51LA 统计指标定义 +const stats = [ + { + icon: "material-symbols:person-outline", + label: i18n(I18nKey.laStatsOnline), + id: "la-online", + }, + { + icon: "material-symbols:calendar-today-outline", + label: i18n(I18nKey.laStatsTodayUV), + id: "la-today-uv", + }, + { + icon: "material-symbols:visibility-outline", + label: i18n(I18nKey.laStatsTodayPV), + id: "la-today-pv", + }, + { + icon: "material-symbols:calendar-month-outline", + label: i18n(I18nKey.laStatsYesterdayUV), + id: "la-yesterday-uv", + }, + { + icon: "material-symbols:visibility-outline", + label: i18n(I18nKey.laStatsYesterdayPV), + id: "la-yesterday-pv", + }, + { + icon: "material-symbols:calendar-clock-outline", + label: i18n(I18nKey.laStatsMonthPV), + id: "la-month-pv", + }, + { + icon: "mingcute:chart-line-line", + label: i18n(I18nKey.laStatsTotalPV), + id: "la-total-pv", + }, +]; +--- + +{la51Id && ( + +
+ {stats.map((stat) => ( +
+
+
+ +
+ + {stat.label} + +
+ + - + +
+ ))} +
+
+ + +)} diff --git a/src/config/sidebarConfig.ts b/src/config/sidebarConfig.ts index b48fe24649..95966382bf 100644 --- a/src/config/sidebarConfig.ts +++ b/src/config/sidebarConfig.ts @@ -108,6 +108,16 @@ export const sidebarLayoutConfig: SidebarLayoutConfig = { // 是否在文章详情页显示 showOnPostPage: true, }, + { + // 组件类型:51LA访问统计组件 + type: "lastats", + // 是否启用该组件 + enable: true, + // 组件位置 + position: "top", + // 是否在文章详情页显示 + showOnPostPage: true, + }, { // 组件类型:站点信息组件 type: "siteInfo", @@ -275,6 +285,14 @@ export const sidebarLayoutConfig: SidebarLayoutConfig = { // 是否在文章详情页显示 showOnPostPage: true, }, + { + // 组件类型:51LA访问统计组件 + type: "lastats", + // 是否启用该组件 + enable: true, + // 是否在文章详情页显示 + showOnPostPage: true, + }, { // 组件类型:站点信息组件 type: "siteInfo", diff --git a/src/i18n/i18nKey.ts b/src/i18n/i18nKey.ts index be4d50a4f1..35c3a07885 100644 --- a/src/i18n/i18nKey.ts +++ b/src/i18n/i18nKey.ts @@ -269,6 +269,16 @@ enum I18nKey { siteStatsDays = "siteStatsDays", today = "today", + // 51LA 访问统计 + laStats = "laStats", + laStatsOnline = "laStatsOnline", + laStatsTodayUV = "laStatsTodayUV", + laStatsTodayPV = "laStatsTodayPV", + laStatsYesterdayUV = "laStatsYesterdayUV", + laStatsYesterdayPV = "laStatsYesterdayPV", + laStatsMonthPV = "laStatsMonthPV", + laStatsTotalPV = "laStatsTotalPV", + // 站点信息 siteInfo = "siteInfo", siteInfoBuildTime = "siteInfoBuildTime", diff --git a/src/i18n/languages/en.ts b/src/i18n/languages/en.ts index 32bbf47a74..cdb50c0467 100644 --- a/src/i18n/languages/en.ts +++ b/src/i18n/languages/en.ts @@ -281,6 +281,16 @@ export const en: Translation = { [Key.siteStatsDays]: "{days} days", [Key.today]: "Today", + // 51LA Visitor Statistics + [Key.laStats]: "Visitor Statistics", + [Key.laStatsOnline]: "Online Now", + [Key.laStatsTodayUV]: "Today Visitors", + [Key.laStatsTodayPV]: "Today Views", + [Key.laStatsYesterdayUV]: "Yesterday Visitors", + [Key.laStatsYesterdayPV]: "Yesterday Views", + [Key.laStatsMonthPV]: "This Month Views", + [Key.laStatsTotalPV]: "Total Views", + // Site Info [Key.siteInfo]: "Site Info", [Key.siteInfoBuildTime]: "Build Time", diff --git a/src/i18n/languages/ja.ts b/src/i18n/languages/ja.ts index 5ddcdcd7d3..ab1fe21149 100644 --- a/src/i18n/languages/ja.ts +++ b/src/i18n/languages/ja.ts @@ -280,6 +280,16 @@ export const ja: Translation = { [Key.siteStatsDays]: "{days} 日", [Key.today]: "今日", + // 51LA アクセス統計 + [Key.laStats]: "アクセス統計", + [Key.laStatsOnline]: "現在オンライン", + [Key.laStatsTodayUV]: "本日の訪問者", + [Key.laStatsTodayPV]: "本日の閲覧数", + [Key.laStatsYesterdayUV]: "昨日の訪問者", + [Key.laStatsYesterdayPV]: "昨日の閲覧数", + [Key.laStatsMonthPV]: "今月の閲覧数", + [Key.laStatsTotalPV]: "累計閲覧数", + // サイト情報 [Key.siteInfo]: "サイト情報", [Key.siteInfoBuildTime]: "ビルド日時", diff --git a/src/i18n/languages/ru.ts b/src/i18n/languages/ru.ts index 1394649bd4..9e48b2ed11 100644 --- a/src/i18n/languages/ru.ts +++ b/src/i18n/languages/ru.ts @@ -282,6 +282,16 @@ export const ru: Translation = { [Key.siteStatsDays]: "{days} дней", [Key.today]: "Сегодня", + // 51LA Статистика посещений + [Key.laStats]: "Статистика посещений", + [Key.laStatsOnline]: "Сейчас онлайн", + [Key.laStatsTodayUV]: "Посетители сегодня", + [Key.laStatsTodayPV]: "Просмотры сегодня", + [Key.laStatsYesterdayUV]: "Посетители вчера", + [Key.laStatsYesterdayPV]: "Просмотры вчера", + [Key.laStatsMonthPV]: "Просмотры за месяц", + [Key.laStatsTotalPV]: "Всего просмотров", + // Информация о сайте [Key.siteInfo]: "Информация о сайте", [Key.siteInfoBuildTime]: "Время сборки", diff --git a/src/i18n/languages/zh_CN.ts b/src/i18n/languages/zh_CN.ts index ac1bc27433..e4663c00bb 100644 --- a/src/i18n/languages/zh_CN.ts +++ b/src/i18n/languages/zh_CN.ts @@ -272,6 +272,16 @@ export const zh_CN: Translation = { [Key.siteStatsDays]: "{days} 天", [Key.today]: "今天", + // 51LA 访问统计 + [Key.laStats]: "访问统计", + [Key.laStatsOnline]: "当前在线", + [Key.laStatsTodayUV]: "今日访客", + [Key.laStatsTodayPV]: "今日浏览", + [Key.laStatsYesterdayUV]: "昨日访客", + [Key.laStatsYesterdayPV]: "昨日浏览", + [Key.laStatsMonthPV]: "本月浏览", + [Key.laStatsTotalPV]: "累计浏览", + // 站点信息 [Key.siteInfo]: "站点信息", [Key.siteInfoBuildTime]: "构建时间", diff --git a/src/i18n/languages/zh_TW.ts b/src/i18n/languages/zh_TW.ts index 08fa97124c..cac1f4bde6 100644 --- a/src/i18n/languages/zh_TW.ts +++ b/src/i18n/languages/zh_TW.ts @@ -274,6 +274,16 @@ export const zh_TW: Translation = { [Key.siteStatsDays]: "{days} 天", [Key.today]: "今天", + // 51LA 訪問統計 + [Key.laStats]: "訪問統計", + [Key.laStatsOnline]: "當前在線", + [Key.laStatsTodayUV]: "今日訪客", + [Key.laStatsTodayPV]: "今日瀏覽", + [Key.laStatsYesterdayUV]: "昨日訪客", + [Key.laStatsYesterdayPV]: "昨日瀏覽", + [Key.laStatsMonthPV]: "本月瀏覽", + [Key.laStatsTotalPV]: "累計瀏覽", + // 站點資訊 [Key.siteInfo]: "站點資訊", [Key.siteInfoBuildTime]: "構建時間", diff --git a/src/types/sidebarConfig.ts b/src/types/sidebarConfig.ts index 5a94dd7dfe..6b4595e854 100644 --- a/src/types/sidebarConfig.ts +++ b/src/types/sidebarConfig.ts @@ -7,6 +7,7 @@ export type WidgetComponentType = | "sidebarToc" | "advertisement" | "stats" + | "lastats" | "calendar" | "music" | "siteInfo"; From 14a997b7cd1a1604585200bc469ab257440cd0ea Mon Sep 17 00:00:00 2001 From: jacksen168 Date: Fri, 26 Jun 2026 22:34:45 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix(components/widget):=20correct=20syntax?= =?UTF-8?q?=20error=20from=20merge=20conflict=20in=20LaStats.astro=20fix(c?= =?UTF-8?q?omponents/widget):=20=E4=BF=AE=E5=A4=8D=E5=9B=A0=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=90=88=E5=B9=B6=E5=86=B2=E7=AA=81=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=20LaStats.astro=20=E7=BB=84=E4=BB=B6=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E8=AF=AD=E6=B3=95=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The automatic merge resolution introduced a misplaced closing curly brace in the LaStats.astro component template, resulting in invalid template syntax. This fix restores the correct structure and resolves the compilation error. 修复因自动合并冲突导致的 LaStats.astro 组件模板语法错误。 合并过程中引入了一个位置错误的闭合大括号,导致模板语法无效。 --- src/components/widget/LaStats.astro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/widget/LaStats.astro b/src/components/widget/LaStats.astro index 744aee3e11..69db01f587 100644 --- a/src/components/widget/LaStats.astro +++ b/src/components/widget/LaStats.astro @@ -80,6 +80,7 @@ const stats = [ ))} +)} -)} From 6037ca1fc0f055351e9d6d20d54ab8e102aa55f2 Mon Sep 17 00:00:00 2001 From: jacksen168 Date: Mon, 13 Jul 2026 23:41:53 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat(analytics/widget):=20add=20configurabl?= =?UTF-8?q?e=20data=20source=20for=20la=20stats=20widget=20feat(analytics/?= =?UTF-8?q?widget):=20=E4=B8=BA51LA=E7=BB=9F=E8=AE=A1=E6=8C=82=E4=BB=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8F=AF=E9=85=8D=E7=BD=AE=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for multiple data sources for the LA stats widget: - Add `statsDataSource` and `statsApiUrl` fields to AnalyticsConfig type - Set default config values for the new fields - Rework the widget logic to support both quote.js built-in source and custom API source 该提交为51LA统计挂件添加了多数据源支持: - 向AnalyticsConfig类型新增`statsDataSource`和`statsApiUrl`配置项 - 为新配置项设置默认值 - 重构挂件逻辑,同时支持官方quote.js数据源和自定义API数据源 --- src/components/widget/LaStats.astro | 76 +++++++++++++++++++---------- src/config/analyticsConfig.ts | 9 ++++ src/types/analyticsConfig.ts | 2 + 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/components/widget/LaStats.astro b/src/components/widget/LaStats.astro index 69db01f587..161f57fc3f 100644 --- a/src/components/widget/LaStats.astro +++ b/src/components/widget/LaStats.astro @@ -17,6 +17,9 @@ const { class: className, style, widgetConfig } = Astro.props; const showTitle = widgetConfig?.showTitle !== false; const la51Id = analyticsConfig?.la51Analytics?.Id || ""; +const la51StatsDataSource = + analyticsConfig?.la51Analytics?.statsDataSource || "quotejs"; +const la51StatsApiUrl = analyticsConfig?.la51Analytics?.statsApiUrl || ""; // 51LA 统计指标定义 const stats = [ @@ -82,50 +85,71 @@ const stats = [ )} -