mirror of
https://github.com/RhenCloud/Cloud-Home.git
synced 2026-01-22 17:39:07 +08:00
chore: 格式化代码
This commit is contained in:
@@ -1,84 +1,87 @@
|
||||
<template>
|
||||
<main class="page">
|
||||
<HeroSection :profile="profile" />
|
||||
<SkillsSection :skills="skills" />
|
||||
<Suspense>
|
||||
<template #default>
|
||||
<StatsSection :github="github" :wakatime="wakatime" />
|
||||
</template>
|
||||
<template #fallback>
|
||||
<div class="card" style="text-align: center; padding: 40px">
|
||||
<p>加载统计数据中...</p>
|
||||
</div>
|
||||
</template>
|
||||
</Suspense>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { useRuntimeConfig, definePageMeta } from "#imports";
|
||||
import HeroSection from "~/components/HeroSection.vue";
|
||||
import SkillsSection from "~/components/SkillsSection.vue";
|
||||
import StatsSection from "~/components/StatsSection.vue";
|
||||
import siteConfig from "@/config/siteConfig";
|
||||
|
||||
const profile = siteConfig.profile;
|
||||
const skills = siteConfig.skills;
|
||||
const wakatime = siteConfig.wakatime;
|
||||
const config = useRuntimeConfig();
|
||||
const githubToken = config.public.githubToken ?? "";
|
||||
|
||||
type GithubHeatmap = {
|
||||
username: string;
|
||||
heatmapUrl: string;
|
||||
languages?: { name: string; percent: number }[];
|
||||
};
|
||||
|
||||
const github = reactive<GithubHeatmap>({
|
||||
...siteConfig.github,
|
||||
heatmapUrl: `https://ghchart.rshah.org/${siteConfig.github.username}`,
|
||||
languages: [],
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
order: 1,
|
||||
label: "关于",
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
fetchGithubMeta();
|
||||
});
|
||||
|
||||
async function fetchGithubMeta() {
|
||||
try {
|
||||
const headers: HeadersInit = {};
|
||||
if (githubToken) {
|
||||
headers.Authorization = `Bearer ${githubToken}`;
|
||||
}
|
||||
const resp = await fetch(`https://api.github.com/users/${github.username}/repos?per_page=100&sort=updated`, {
|
||||
headers,
|
||||
});
|
||||
const data = await resp.json();
|
||||
if (!Array.isArray(data)) return;
|
||||
type GithubRepo = { language?: string };
|
||||
const repos = data as GithubRepo[];
|
||||
const counts: Record<string, number> = {};
|
||||
repos.forEach((repo) => {
|
||||
if (!repo.language) return;
|
||||
counts[repo.language] = (counts[repo.language] || 0) + 1;
|
||||
});
|
||||
const total = Object.values(counts).reduce((sum, value) => sum + value, 0) || 1;
|
||||
const parsed = Object.entries(counts)
|
||||
.map(([name, count]) => ({ name, count }))
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.slice(0, 5);
|
||||
github.languages = parsed.map((item) => ({
|
||||
name: item.name,
|
||||
percent: Math.round((item.count / total) * 100),
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch GitHub metadata:", error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<main class="page">
|
||||
<HeroSection :profile="profile" />
|
||||
<SkillsSection :skills="skills" />
|
||||
<Suspense>
|
||||
<template #default>
|
||||
<StatsSection :github="github" :wakatime="wakatime" />
|
||||
</template>
|
||||
<template #fallback>
|
||||
<div class="card" style="text-align: center; padding: 40px">
|
||||
<p>加载统计数据中...</p>
|
||||
</div>
|
||||
</template>
|
||||
</Suspense>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { useRuntimeConfig, definePageMeta } from "#imports";
|
||||
import HeroSection from "~/components/HeroSection.vue";
|
||||
import SkillsSection from "~/components/SkillsSection.vue";
|
||||
import StatsSection from "~/components/StatsSection.vue";
|
||||
import siteConfig from "@/config/siteConfig";
|
||||
|
||||
const profile = siteConfig.profile;
|
||||
const skills = siteConfig.skills;
|
||||
const wakatime = siteConfig.wakatime;
|
||||
const config = useRuntimeConfig();
|
||||
const githubToken = config.public.githubToken ?? "";
|
||||
|
||||
type GithubHeatmap = {
|
||||
username: string;
|
||||
heatmapUrl: string;
|
||||
languages?: { name: string; percent: number }[];
|
||||
};
|
||||
|
||||
const github = reactive<GithubHeatmap>({
|
||||
...siteConfig.github,
|
||||
heatmapUrl: `https://ghchart.rshah.org/${siteConfig.github.username}`,
|
||||
languages: [],
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
order: 1,
|
||||
label: "关于",
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
fetchGithubMeta();
|
||||
});
|
||||
|
||||
async function fetchGithubMeta() {
|
||||
try {
|
||||
const headers: HeadersInit = {};
|
||||
if (githubToken) {
|
||||
headers.Authorization = `Bearer ${githubToken}`;
|
||||
}
|
||||
const resp = await fetch(
|
||||
`https://api.github.com/users/${github.username}/repos?per_page=100&sort=updated`,
|
||||
{
|
||||
headers,
|
||||
}
|
||||
);
|
||||
const data = await resp.json();
|
||||
if (!Array.isArray(data)) return;
|
||||
type GithubRepo = { language?: string };
|
||||
const repos = data as GithubRepo[];
|
||||
const counts: Record<string, number> = {};
|
||||
repos.forEach((repo) => {
|
||||
if (!repo.language) return;
|
||||
counts[repo.language] = (counts[repo.language] || 0) + 1;
|
||||
});
|
||||
const total = Object.values(counts).reduce((sum, value) => sum + value, 0) || 1;
|
||||
const parsed = Object.entries(counts)
|
||||
.map(([name, count]) => ({ name, count }))
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.slice(0, 5);
|
||||
github.languages = parsed.map((item) => ({
|
||||
name: item.name,
|
||||
percent: Math.round((item.count / total) * 100),
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch GitHub metadata:", error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
<template>
|
||||
<section class="container mx-auto py-8">
|
||||
<p v-if="!giscus || !giscus.repo" class="text-sm text-red-500 mb-4">Giscus 未配置。</p>
|
||||
<ClientOnly>
|
||||
<section class="card panel flex flex-col gap-2.5">
|
||||
<h2 class="m-0 mb-1 text-lg font-semibold">留言板</h2>
|
||||
<p class="text-sm text-white/60 mb-3">在这里留下想说的话吧 · Comments</p>
|
||||
<div class="giscus-wrapper">
|
||||
<component
|
||||
:is="GiscusComponent"
|
||||
v-if="GiscusComponent"
|
||||
:repo="giscus.repo"
|
||||
:repo-id="giscus.repoId"
|
||||
:category="giscus.category"
|
||||
:category-id="giscus.categoryId"
|
||||
:mapping="giscus.mapping"
|
||||
:strict="giscus.strict"
|
||||
:reactions-enabled="giscus.reactionsEnabled"
|
||||
:emit-metadata="giscus.emitMetadata"
|
||||
:input-position="giscus.inputPosition"
|
||||
:theme="'/css/giscus.css'"
|
||||
lang="zh-CN"
|
||||
class="giscus"
|
||||
/>
|
||||
<div v-else id="giscus-container" class="giscus" />
|
||||
</div>
|
||||
</section>
|
||||
</ClientOnly>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { definePageMeta } from "#imports";
|
||||
import { onMounted, shallowRef, markRaw } from "vue";
|
||||
import type { Component } from "vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const giscus = siteConfig.comments.giscus || {};
|
||||
const GiscusComponent = shallowRef<Component | null>(null);
|
||||
|
||||
async function tryUseOfficialComponent() {
|
||||
try {
|
||||
const mod = await import("@giscus/vue");
|
||||
const comp = mod.default ?? mod;
|
||||
if (comp) GiscusComponent.value = markRaw(comp);
|
||||
return !!comp;
|
||||
} catch (e) {
|
||||
console.error("Failed to import Giscus component:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 如果没有配置 giscus,显示提示(由模板处理)
|
||||
if (!siteConfig.comments.enable) return;
|
||||
if (!giscus || !giscus.repo) return;
|
||||
const ok = await tryUseOfficialComponent();
|
||||
if (!ok) {
|
||||
console.error("Failed to load Giscus component.");
|
||||
}
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
order: 5,
|
||||
label: "留言",
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
max-width: 880px;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #e6eef8;
|
||||
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- <style src="../styles/giscus.css"></style> -->
|
||||
<template>
|
||||
<section class="container mx-auto py-8">
|
||||
<p v-if="!giscus || !giscus.repo" class="text-sm text-red-500 mb-4">Giscus 未配置。</p>
|
||||
<ClientOnly>
|
||||
<section class="card panel flex flex-col gap-2.5">
|
||||
<h2 class="m-0 mb-1 text-lg font-semibold">留言板</h2>
|
||||
<p class="text-sm text-white/60 mb-3">在这里留下想说的话吧 · Comments</p>
|
||||
<div class="giscus-wrapper">
|
||||
<component
|
||||
:is="GiscusComponent"
|
||||
v-if="GiscusComponent"
|
||||
:repo="giscus.repo"
|
||||
:repo-id="giscus.repoId"
|
||||
:category="giscus.category"
|
||||
:category-id="giscus.categoryId"
|
||||
:mapping="giscus.mapping"
|
||||
:strict="giscus.strict"
|
||||
:reactions-enabled="giscus.reactionsEnabled"
|
||||
:emit-metadata="giscus.emitMetadata"
|
||||
:input-position="giscus.inputPosition"
|
||||
:theme="'/css/giscus.css'"
|
||||
lang="zh-CN"
|
||||
class="giscus"
|
||||
/>
|
||||
<div v-else id="giscus-container" class="giscus" />
|
||||
</div>
|
||||
</section>
|
||||
</ClientOnly>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { definePageMeta } from "#imports";
|
||||
import { onMounted, shallowRef, markRaw } from "vue";
|
||||
import type { Component } from "vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const giscus = siteConfig.comments.giscus || {};
|
||||
const GiscusComponent = shallowRef<Component | null>(null);
|
||||
|
||||
async function tryUseOfficialComponent() {
|
||||
try {
|
||||
const mod = await import("@giscus/vue");
|
||||
const comp = mod.default ?? mod;
|
||||
if (comp) GiscusComponent.value = markRaw(comp);
|
||||
return !!comp;
|
||||
} catch (e) {
|
||||
console.error("Failed to import Giscus component:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 如果没有配置 giscus,显示提示(由模板处理)
|
||||
if (!siteConfig.comments.enable) return;
|
||||
if (!giscus || !giscus.repo) return;
|
||||
const ok = await tryUseOfficialComponent();
|
||||
if (!ok) {
|
||||
console.error("Failed to load Giscus component.");
|
||||
}
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
order: 5,
|
||||
label: "留言",
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
max-width: 880px;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #e6eef8;
|
||||
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- <style src="../styles/giscus.css"></style> -->
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<main class="page">
|
||||
<FriendsSection :friends="friends" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import FriendsSection from "~/components/FriendsSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const friends = siteConfig.friends;
|
||||
|
||||
definePageMeta({
|
||||
order: 4,
|
||||
label: "友链",
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<main class="page">
|
||||
<FriendsSection :friends="friends" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import FriendsSection from "~/components/FriendsSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const friends = siteConfig.friends;
|
||||
|
||||
definePageMeta({
|
||||
order: 4,
|
||||
label: "友链",
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<template>
|
||||
<main class="page">
|
||||
<HeroSection :profile="profile" />
|
||||
<SocialLinks :links="socialLinks" />
|
||||
<AboutSection :items="about" :profile="profile" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import HeroSection from "~/components/HeroSection.vue";
|
||||
import SocialLinks from "~/components/SocialLinks.vue";
|
||||
import AboutSection from "~/components/AboutSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const profile = siteConfig.profile;
|
||||
const socialLinks = siteConfig.socialLinks;
|
||||
const about = siteConfig.about;
|
||||
|
||||
definePageMeta({
|
||||
order: 0,
|
||||
label: "首页",
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<main class="page">
|
||||
<HeroSection :profile="profile" />
|
||||
<SocialLinks :links="socialLinks" />
|
||||
<AboutSection :items="about" :profile="profile" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import HeroSection from "~/components/HeroSection.vue";
|
||||
import SocialLinks from "~/components/SocialLinks.vue";
|
||||
import AboutSection from "~/components/AboutSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const profile = siteConfig.profile;
|
||||
const socialLinks = siteConfig.socialLinks;
|
||||
const about = siteConfig.about;
|
||||
|
||||
definePageMeta({
|
||||
order: 0,
|
||||
label: "首页",
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<main class="page">
|
||||
<ProjectsSection :projects="projects" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ProjectsSection from "~/components/ProjectsSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const projects = siteConfig.projects;
|
||||
|
||||
definePageMeta({
|
||||
order: 3,
|
||||
label: "项目",
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<main class="page">
|
||||
<ProjectsSection :projects="projects" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ProjectsSection from "~/components/ProjectsSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const projects = siteConfig.projects;
|
||||
|
||||
definePageMeta({
|
||||
order: 3,
|
||||
label: "项目",
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<main class="page">
|
||||
<SitesSection :sites="sites" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import SitesSection from "~/components/SitesSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const sites = siteConfig.sites;
|
||||
|
||||
definePageMeta({
|
||||
order: 2,
|
||||
label: "网站",
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<main class="page">
|
||||
<SitesSection :sites="sites" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import SitesSection from "~/components/SitesSection.vue";
|
||||
import siteConfig from "~/config/siteConfig";
|
||||
|
||||
const sites = siteConfig.sites;
|
||||
|
||||
definePageMeta({
|
||||
order: 2,
|
||||
label: "网站",
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user