From 361999a8b18361df9485513c6ab89b7586b14ea0 Mon Sep 17 00:00:00 2001 From: RhenCloud Date: Sun, 7 Dec 2025 14:27:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20Umami=20=E5=88=86?= =?UTF-8?q?=E6=9E=90=E6=94=AF=E6=8C=81=EF=BC=8C=E6=9B=B4=E6=96=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 4 ++ README.md | 27 +++++++++--- package.json | 1 + pnpm-workspace.yaml | 2 + src/App.vue | 1 + src/components/FooterSection.vue | 68 +++++++++++++++++++++++++++++- src/config/siteConfig.ts | 72 ++++++-------------------------- src/main.ts | 11 ++++- src/views/About.vue | 2 - 9 files changed, 118 insertions(+), 70 deletions(-) create mode 100644 pnpm-workspace.yaml diff --git a/.env.example b/.env.example index facb12f..049df13 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,9 @@ +# Github Token VITE_GITHUB_TOKEN=your-github-token +# UMAMI API KEY +VITE_UMAMI_API_KEY=your-umami-api-key + # SMTP 服务器地址 SMTP_HOST=smtp.example.com diff --git a/README.md b/README.md index b3d1e14..86a9e60 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ const siteConfig: SiteConfig = { title: "I'm a software developer.", // 你的简介,可为空 avatar: "avatar.webp", // 你的头像,可为public目录下的文件或外部链接 bio: "Hello World", // 你的喜欢的一句话,可为空 + birthday: "xxxx-xx-xx", // 你的生日,可为空 + gender: "", // 你的性别,可为空 + pronouns: "", // 你希望别人如何称呼你,可为空 + location: "", // 你的居住地,可为空 }, // 社交链接,预定义的社交链接可在 `src/components/SocialLink.vue` 中查阅 @@ -52,8 +56,16 @@ const siteConfig: SiteConfig = { ], siteMeta: { - title: "RhenCloud", // 网站标题 + title: "Example Title", // 网站标题 icon: "favicon.ico", // 网站图标,可为public目录下的文件或外部链接 + startDate:"xxxx-xx-xx", // 网站创建日期 + }, + + umami: { + enable: true, // 是否启用 Umami 分析 + url: "https://cloud.umami.is/script.js", // Umami 分析脚本 URL,一般无需修改 + websiteId: "YOUR_WEBSITE_ID", // Umami 网站 ID + apiBase: "https://api.umami.is", // Umami API 地址,一般无需修改 }, // 技能图标展示,详见https://github.com/tandpfun/skill-icons#icons-list @@ -100,9 +112,11 @@ const siteConfig: SiteConfig = { footer: { beian: "备案号", // 备案号,留空则不显示 beianLink: "https://beian.miit.gov.cn/", // 备案号链接,一般无需修改 - showHitokoto: true, // 是否显示一言 - hitokotoType: "a&b&c&d&j", // 一言类型,详见 https://developer.hitokoto.cn/sentence/#%E5%8F%A5%E5%AD%90%E7%B1%BB%E5%9E%8B-%E5%8F%82%E6%95%B0 customHtml: '', // 自定义 HTML 代码,如统计代码等 + hitokoto: { + enable: true, // 是否启用一言 + type: "a&b&c&d&j", // 一言类型,详见 https://developer.hitokoto.cn/sentence/#%E5%8F%A5%E5%AD%90%E7%B1%BB%E5%9E%8B-%E5%8F%82%E6%95%B0 + }, }, }; ``` @@ -112,11 +126,12 @@ const siteConfig: SiteConfig = { - **404 页面**:修改 `public/404.html` 来自定义 404 错误页面的样式与内容。 - **友链展示逻辑**:`FriendsSection.vue` 默认使用随机顺序渲染 `siteConfig.friends`,如需固定顺序请修改该组件。 -## 环境变量(邮件发送) +## 环境变量 在 Vercel 控制台或本地 `.env` 配置: -- `VITE_GITHUB_TOKEN`: 具有仓库读取权限的 GitHub Token,用于绕过 GitHub API 速率限制。 +- `VITE_GITHUB_TOKEN`: 具有仓库读取权限的 GitHub Token,用于绕过 GitHub API 速率限制。(可选) +- `UMAMI_API_KEY`: Umami 分析的 API Key。 - `SMTP_HOST`: 邮件服务器主机名 - `SMTP_PORT`: 端口(如 465 或 587) - `SMTP_USER`: 发件人邮箱账号 @@ -140,7 +155,7 @@ pnpm dev pnpm build ``` -产物输出到 `dist/`。 +产物输出到 ## 部署到 Vercel diff --git a/package.json b/package.json index b6f91af..f54fba9 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "preview": "vite preview" }, "dependencies": { + "@jaseeey/vue-umami-plugin": "^1.4.0", "@vercel/node": "^5.5.15", "express": "^5.2.1", "he": "^1.2.0", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..efc037a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +onlyBuiltDependencies: + - esbuild diff --git a/src/App.vue b/src/App.vue index 0358a03..40be79b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -9,6 +9,7 @@ @@ -54,14 +107,17 @@ onMounted(() => { text-align: center; margin-top: 8px; } + .from { margin-left: 6px; } + .beian { font-size: 12px; margin: 6px 0; letter-spacing: 0.2px; } + .beian a { color: inherit; opacity: 0.85; @@ -69,12 +125,20 @@ onMounted(() => { border-radius: 8px; transition: color 0.2s ease, background 0.2s ease, opacity 0.2s ease; } + .beian a:hover { color: var(--accent, #7cc1ff); background: rgba(124, 193, 255, 0.1); opacity: 1; } + .custom-html { margin-top: 6px; } + +.stats { + font-size: 12px; + margin: 6px 0; + letter-spacing: 0.2px; +} diff --git a/src/config/siteConfig.ts b/src/config/siteConfig.ts index cc6d1be..47ae771 100644 --- a/src/config/siteConfig.ts +++ b/src/config/siteConfig.ts @@ -1,60 +1,4 @@ -interface SiteConfig { - profile: { - name: string; - title: string; - avatar: string; - bio: string; - birthday?: string; - gender?: string; - pronouns?: string; - location?: string; - }; - socialLinks: Array<{ - name: string; - url: string; - }>; - github: { - username: string; - }; - about: Array<{ - title: string; - desc: string; - icon: string; - }>; - siteMeta: { - title: string; - icon: string; - }; - skills: Array<{ - title: string; - items: string[]; - }>; - sites: Array<{ - name: string; - desc: string; - url: string; - }>; - projects: Array<{ - name: string; - url: string; - desc: string; - }>; - friends: Array<{ - name: string; - desc: string; - url: string; - avatar: string; - }>; - footer: { - beian: string; - beianLink: string; - showHitokoto: boolean; - hitokotoType: string; - customHtml: string; - }; -} - -const siteConfig: SiteConfig = { +const siteConfig = { profile: { name: "RhenCloud", title: "I'm RhenCloud.", @@ -88,6 +32,14 @@ const siteConfig: SiteConfig = { siteMeta: { title: "RhenCloud", icon: "favicon.ico", // public/favicon.ico + startDate: "2025-12-06", + }, + + umami: { + enable: true, + url: "https://cloud.umami.is/script.js", + websiteId: "ddcd51c3-ccc7-45e4-81e6-11567027f69b", + apiBase: "https://api.umami.is", }, skills: [ @@ -143,9 +95,11 @@ const siteConfig: SiteConfig = { footer: { beian: "津ICP备2025039003号-1", beianLink: "https://beian.miit.gov.cn/", - showHitokoto: true, - hitokotoType: "a&b&c&d&j", customHtml: '© 2025 RhenCloud', + hitokoto: { + enable: true, + type: "a&b&c&d&j", + }, }, }; diff --git a/src/main.ts b/src/main.ts index c8c4d1e..0811677 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,15 @@ import { createApp } from "vue"; +import { VueUmamiPlugin } from "@jaseeey/vue-umami-plugin"; import App from "./App.vue"; import router from "./router"; import "./styles.css"; +import siteConfig from "./config/siteConfig"; -createApp(App).use(router).mount("#app"); +const app = createApp(App); + +if (process.env.NODE_ENV !== "development") { + if (siteConfig.umami?.enable) { + app.use(VueUmamiPlugin({ websiteID: siteConfig.umami.websiteId, scriptSrc: siteConfig.umami.url, router })); + } +} +app.use(router).mount("#app"); diff --git a/src/views/About.vue b/src/views/About.vue index 99df128..589a0ab 100644 --- a/src/views/About.vue +++ b/src/views/About.vue @@ -25,8 +25,6 @@ const github = reactive({ // 修改此处:使用 VITE_ 前缀 const githubToken = import.meta.env.VITE_GITHUB_TOKEN ?? ""; -console.log(githubToken); - onMounted(() => { document.title = siteMeta.title; const link = document.querySelector("link[rel~='icon']") || document.createElement("link");