mirror of
https://github.com/RhenCloud/Cloud-Home.git
synced 2026-01-22 17:39:07 +08:00
chore:一些修复
This commit is contained in:
@@ -79,15 +79,9 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from "vue";
|
import { ref, onMounted, computed } from "vue";
|
||||||
|
import siteConfig from "~/config/siteConfig";
|
||||||
|
|
||||||
const props = defineProps({
|
const wakapi = siteConfig.wakapi;
|
||||||
wakatime: {
|
|
||||||
type: Object,
|
|
||||||
required: false,
|
|
||||||
default: () => ({ languages: [] }),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const wakatime = props.wakatime;
|
|
||||||
|
|
||||||
const weeklyData = ref(null);
|
const weeklyData = ref(null);
|
||||||
const allTimeData = ref(null);
|
const allTimeData = ref(null);
|
||||||
@@ -123,65 +117,45 @@ const formatTime = (seconds) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchWakatimeData = async () => {
|
const fetchWakatimeData = async () => {
|
||||||
if (!wakatime.enable) return;
|
if (!wakapi.enable) {
|
||||||
|
console.warn("Wakatime is disabled in siteConfig.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiUrl = wakapi.apiUrl || "https://wakatime.com/api/v1";
|
||||||
|
const username = wakapi.username;
|
||||||
|
|
||||||
|
if (!username) {
|
||||||
|
console.error("Wakatime username is not configured.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams();
|
const [weeklyStatsResponse, allTimeStatsResponse, statusResponse] = await Promise.all([
|
||||||
if (wakatime.apiUrl && wakatime.apiUrl !== "https://wakatime.com/api/v1") {
|
fetch(`${apiUrl}/users/${username}/stats/last_7_days`),
|
||||||
params.append("apiUrl", wakatime.apiUrl);
|
fetch(`${apiUrl}/users/${username}/stats`),
|
||||||
}
|
fetch(`${apiUrl}/users/${username}/status`),
|
||||||
const url = `/api/wakatime${params.toString() ? `?${params.toString()}` : ""}`;
|
]);
|
||||||
console.log("Fetching Wakatime data from:", url);
|
|
||||||
const response = await fetch(url);
|
|
||||||
console.log("Response status:", response.status);
|
|
||||||
console.log("Response headers:", Object.fromEntries(response.headers.entries()));
|
|
||||||
|
|
||||||
if (response.ok) {
|
if (weeklyStatsResponse.ok) {
|
||||||
const data = await response.json();
|
weeklyData.value = await weeklyStatsResponse.json();
|
||||||
console.log("Wakatime data:", data);
|
|
||||||
weeklyData.value = data.weekly;
|
|
||||||
allTimeData.value = data.allTime;
|
|
||||||
statusData.value = data.status;
|
|
||||||
} else {
|
} else {
|
||||||
const errorText = await response.text();
|
console.error("Failed to fetch weekly stats:", weeklyStatsResponse.status);
|
||||||
console.error("API Error:", response.status, errorText);
|
}
|
||||||
if (response.status === 500 && errorText.includes("Wakatime API Key not configured")) {
|
|
||||||
console.warn("Wakatime API Key not configured - hiding component");
|
if (allTimeStatsResponse.ok) {
|
||||||
showComponent.value = false;
|
allTimeData.value = await allTimeStatsResponse.json();
|
||||||
return;
|
} else {
|
||||||
}
|
console.warn("All-time stats not available:", allTimeStatsResponse.status);
|
||||||
throw new Error(`API returned ${response.status}: ${errorText}`);
|
}
|
||||||
|
|
||||||
|
if (statusResponse.ok) {
|
||||||
|
statusData.value = await statusResponse.json();
|
||||||
|
} else {
|
||||||
|
console.warn("Status data not available:", statusResponse.status);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch Wakatime data:", error);
|
console.error("Error fetching Wakatime data:", error);
|
||||||
// 在开发环境中,如果 API 不可用,设置一些示例数据
|
|
||||||
if (import.meta.env.DEV) {
|
|
||||||
console.log("Using mock data for development");
|
|
||||||
weeklyData.value = {
|
|
||||||
total_seconds: 36000,
|
|
||||||
daily_average: 5142,
|
|
||||||
days_including_holidays: 7,
|
|
||||||
languages: [
|
|
||||||
{ name: "TypeScript", percent: 45.2, total_seconds: 16272 },
|
|
||||||
{ name: "Vue", percent: 30.1, total_seconds: 10836 },
|
|
||||||
{ name: "JavaScript", percent: 15.3, total_seconds: 5508 },
|
|
||||||
{ name: "Python", percent: 9.4, total_seconds: 3384 },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
allTimeData.value = {
|
|
||||||
total_seconds: 864000,
|
|
||||||
daily_average: 2800,
|
|
||||||
days_including_holidays: 308,
|
|
||||||
languages: [
|
|
||||||
{ name: "JavaScript", percent: 35.2, total_seconds: 304128 },
|
|
||||||
{ name: "TypeScript", percent: 28.1, total_seconds: 242688 },
|
|
||||||
{ name: "Python", percent: 20.3, total_seconds: 175392 },
|
|
||||||
{ name: "Vue", percent: 10.1, total_seconds: 87296 },
|
|
||||||
{ name: "CSS", percent: 6.3, total_seconds: 54432 },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
statusData.value = { is_coding: false };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const siteConfig = {
|
|||||||
profile: {
|
profile: {
|
||||||
name: "RhenCloud",
|
name: "RhenCloud",
|
||||||
title: "I'm RhenCloud.",
|
title: "I'm RhenCloud.",
|
||||||
avatar: "/avatar.webp", // public/avatar.webp
|
avatar: "/avatar-1.webp", // public/avatar.webp
|
||||||
bio: "趁世界还未重启之前 约一次爱恋",
|
bio: "趁世界还未重启之前 约一次爱恋",
|
||||||
email: "i@rhen.cloud",
|
email: "i@rhen.cloud",
|
||||||
birthday: "2010-03-28",
|
birthday: "2010-03-28",
|
||||||
@@ -32,9 +32,13 @@ const siteConfig = {
|
|||||||
|
|
||||||
siteMeta: {
|
siteMeta: {
|
||||||
title: "RhenCloud",
|
title: "RhenCloud",
|
||||||
|
description: "RhenCloud的个人主页,分享技术、生活、兴趣。",
|
||||||
|
keywords: ["Technology", "Blog", "Development", "Programming"],
|
||||||
|
author: "RhenCloud",
|
||||||
url: "https://rhen.cloud",
|
url: "https://rhen.cloud",
|
||||||
icon: "/favicon.svg", // public/favicon.svg
|
favicon: "/favicon.svg", // public/favicon.svg
|
||||||
startDate: "2025-12-06",
|
startDate: "2025-12-06",
|
||||||
|
lang: "zh-CN",
|
||||||
},
|
},
|
||||||
|
|
||||||
appearance: {
|
appearance: {
|
||||||
@@ -80,9 +84,10 @@ const siteConfig = {
|
|||||||
apiBase: "https://api.umami.is",
|
apiBase: "https://api.umami.is",
|
||||||
},
|
},
|
||||||
|
|
||||||
wakatime: {
|
wakapi: {
|
||||||
enable: true,
|
enable: false,
|
||||||
apiUrl: "https://wakapi.rhen.cloud/api/v1",
|
apiUrl: "https://wakapi.rhen.cloud/api/v1",
|
||||||
|
username: "RhenCloud",
|
||||||
},
|
},
|
||||||
|
|
||||||
skills: [
|
skills: [
|
||||||
|
|||||||
@@ -5,18 +5,7 @@ import tailwindcss from "@tailwindcss/vite";
|
|||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
compatibilityDate: "2025-12-12",
|
compatibilityDate: "2025-12-12",
|
||||||
srcDir: "app/",
|
srcDir: "app/",
|
||||||
modules: ["@nuxt/image", "@nuxt/eslint", "@nuxtjs/sitemap"],
|
modules: ["@nuxt/image", "@nuxt/eslint", "@nuxtjs/sitemap", "@nuxtjs/seo"],
|
||||||
|
|
||||||
// eslint: {
|
|
||||||
// config: {
|
|
||||||
// extends: ["plugin:nuxt/recommended", "prettier"],
|
|
||||||
// plugins: ["prettier"],
|
|
||||||
// rules: {
|
|
||||||
// "prettier/prettier": "error",
|
|
||||||
// },
|
|
||||||
// stylistic: true
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
|
|
||||||
// 禁用 Vue Router 的非关键警告
|
// 禁用 Vue Router 的非关键警告
|
||||||
vue: {
|
vue: {
|
||||||
@@ -32,11 +21,6 @@ export default defineNuxtConfig({
|
|||||||
plugins: [tailwindcss()],
|
plugins: [tailwindcss()],
|
||||||
},
|
},
|
||||||
|
|
||||||
site: {
|
|
||||||
url: siteConfig.siteMeta.url,
|
|
||||||
title: siteConfig.siteMeta.title,
|
|
||||||
},
|
|
||||||
|
|
||||||
routeRules: {
|
routeRules: {
|
||||||
"/": { prerender: true },
|
"/": { prerender: true },
|
||||||
"/about": { isr: 3600 },
|
"/about": { isr: 3600 },
|
||||||
@@ -47,9 +31,22 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
app: {
|
app: {
|
||||||
head: {
|
head: {
|
||||||
|
charset: "utf-8",
|
||||||
|
viewport: "width=device-width,initial-scale=1,maximum-scale=5",
|
||||||
title: siteConfig.siteMeta.title,
|
title: siteConfig.siteMeta.title,
|
||||||
|
titleTemplate: `%s - ${siteConfig.siteMeta.title}`,
|
||||||
|
meta: [
|
||||||
|
{ name: "author", content: siteConfig.siteMeta.author },
|
||||||
|
{ name: "language", content: "zh-CN" },
|
||||||
|
{ name: "description", content: siteConfig.siteMeta.description },
|
||||||
|
],
|
||||||
link: [
|
link: [
|
||||||
{ rel: "icon", href: siteConfig.siteMeta.icon },
|
{ rel: "icon", href: siteConfig.siteMeta.favicon, type: "image/svg+xml" },
|
||||||
|
{ rel: "canonical", href: siteConfig.siteMeta.url },
|
||||||
|
{ rel: "alternate", hreflang: siteConfig.siteMeta.lang, href: siteConfig.siteMeta.url },
|
||||||
|
{ rel: "dns-prefetch", href: siteConfig.siteMeta.url },
|
||||||
|
{ rel: "preconnect", href: siteConfig.siteMeta.url },
|
||||||
|
{ rel: "icon", href: siteConfig.siteMeta.favicon },
|
||||||
// Font Awesome CDN 预加载和优化
|
// Font Awesome CDN 预加载和优化
|
||||||
{
|
{
|
||||||
rel: "preload",
|
rel: "preload",
|
||||||
@@ -73,6 +70,8 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
pageTransition: { name: "page", mode: "out-in" },
|
||||||
|
layoutTransition: { name: "layout", mode: "out-in" },
|
||||||
},
|
},
|
||||||
|
|
||||||
nitro: {
|
nitro: {
|
||||||
@@ -91,9 +90,11 @@ export default defineNuxtConfig({
|
|||||||
senderEmail: process.env.SENDER_EMAIL ?? "",
|
senderEmail: process.env.SENDER_EMAIL ?? "",
|
||||||
adminEmail: process.env.ADMIN_EMAIL ?? "",
|
adminEmail: process.env.ADMIN_EMAIL ?? "",
|
||||||
smtpSecure: process.env.SMTP_SECURE ? process.env.SMTP_SECURE === "true" : undefined,
|
smtpSecure: process.env.SMTP_SECURE ? process.env.SMTP_SECURE === "true" : undefined,
|
||||||
wakatimeApiKey: process.env.WAKATIME_API_KEY ?? "",
|
|
||||||
wakatimeApiUrl: process.env.WAKATIME_API_URL ?? "https://wakatime.com/api/v1",
|
|
||||||
githubToken: process.env.NUXT_PUBLIC_GITHUB_TOKEN ?? "",
|
githubToken: process.env.NUXT_PUBLIC_GITHUB_TOKEN ?? "",
|
||||||
umamiApiKey: process.env.UMAMI_API_KEY ?? "",
|
umamiApiKey: process.env.UMAMI_API_KEY ?? "",
|
||||||
|
public: {
|
||||||
|
wakatimeApiKey: process.env.WAKATIME_API_KEY ?? "",
|
||||||
|
wakatimeApiUrl: process.env.WAKATIME_API_URL ?? "https://wakatime.com/api/v1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"@giscus/vue": "^3.1.1",
|
"@giscus/vue": "^3.1.1",
|
||||||
"@jaseeey/vue-umami-plugin": "^1.4.0",
|
"@jaseeey/vue-umami-plugin": "^1.4.0",
|
||||||
"@nuxt/image": "2.0.0",
|
"@nuxt/image": "2.0.0",
|
||||||
|
"@nuxtjs/seo": "3.3.0",
|
||||||
"@nuxtjs/sitemap": "^7.5.0",
|
"@nuxtjs/sitemap": "^7.5.0",
|
||||||
"nodemailer": "^7.0.11",
|
"nodemailer": "^7.0.11",
|
||||||
"nuxt": "^4.2.2",
|
"nuxt": "^4.2.2",
|
||||||
|
|||||||
785
pnpm-lock.yaml
generated
785
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
BIN
public/avatar-1.webp
Normal file
BIN
public/avatar-1.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 587 KiB |
Reference in New Issue
Block a user