chore: 初始化项目仓库

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 21:27:39 +08:00
commit b7addb5c7a
50 changed files with 15964 additions and 0 deletions
+162
View File
@@ -0,0 +1,162 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import { siteConfig } from '~/config/site'
useHead({
script: [
{ src: '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js', async: true, defer: true },
],
})
// 网易云热评
const { data: hitokoto } = await useAsyncData('wyy-comment', () => $fetch<{ user: string; music: string; content: string }>('/api/wyy'))
onMounted(() => {
const el = document.getElementById('busuanzi_value_site_pv')
if (!el) return
el.textContent = '1'
const animate = (target: number) => {
if (target <= 1) return
const duration = 800
const start = performance.now()
const tick = (now: number) => {
const progress = Math.min((now - start) / duration, 1)
const eased = 1 - Math.pow(1 - progress, 3)
el.textContent = Math.floor(1 + (target - 1) * eased).toLocaleString()
if (progress < 1) requestAnimationFrame(tick)
}
requestAnimationFrame(tick)
}
const observer = new MutationObserver(() => {
const val = parseInt(el.textContent || '0', 10)
if (val > 1) {
observer.disconnect()
animate(val)
}
})
observer.observe(el, { childList: true, characterData: true, subtree: true })
setTimeout(() => observer.disconnect(), 10000)
})
</script>
<template>
<div class="flex flex-col items-center gap-8 px-4 pt-4 pb-12">
<!-- 公告卡片 -->
<div class="w-full max-w-2xl text-center anim-fade-in-up">
<div class="announcement-happy rounded-xl p-6">
<p class="announcement-text text-sm md:text-base">
<strong>欢迎来到{{ siteConfig.siteName }}~ 用代码创造快乐用热爱点亮生活 (゚ヮ゚)</strong>
</p>
<p class="announcement-text text-sm md:text-base mt-1">
遇到问题的话可以去 <a href="https://github.com/wishesl/SuBlog/issues" target="_blank" rel="noopener noreferrer">Issues</a> 提反馈哦会尽快修的
</p>
</div>
</div>
<!-- 头像 -->
<div class="anim-fade-in-up anim-delay-1">
<img
:src="siteConfig.avatar"
:alt="siteConfig.siteName"
class="h-32 w-32 rounded-full shadow-lg"
/>
</div>
<!-- 标题 + 口号 + 访客 -->
<div class="text-center anim-fade-in-up anim-delay-2">
<h1 class="text-4xl font-bold mb-2">{{ siteConfig.siteName }}</h1>
<p v-if="hitokoto" class="text-sm italic leading-relaxed mb-1" style="color: var(--color-text-secondary)">
"{{ hitokoto.content }}"
</p>
<p v-if="hitokoto" class="text-xs opacity-60 mb-1" style="color: var(--color-text-secondary)">
{{ hitokoto.user }} · {{ hitokoto.music }}
</p>
<p class="text-sm mt-6" style="color: var(--color-text-secondary)">
您是第 <span id="busuanzi_value_site_pv" class="font-medium" style="color: var(--color-primary)"></span> 个访客
</p>
</div>
<!-- 社交卡片 -->
<div class="w-full max-w-2xl mx-auto anim-fade-in-up anim-delay-3">
<div class="card relative overflow-hidden py-6">
<div class="absolute inset-0 flex items-center justify-center pointer-events-none select-none z-0">
<span class="text-5xl font-black tracking-widest" style="color: var(--color-text); opacity: 0.04;">社交</span>
</div>
<div class="relative z-10 px-6 flex flex-wrap gap-3 justify-center">
<a
v-for="link in siteConfig.socialLinks"
:key="link.name"
:href="link.url"
target="_blank"
rel="noopener noreferrer"
class="btn-pill"
>
<img
:src="`https://api.iconify.design/${link.icon}.svg?color=${encodeURIComponent(link.color || 'currentColor')}`"
:alt="link.name"
class="w-5 h-5"
/>
<span>{{ link.name }}</span>
</a>
</div>
</div>
</div>
<!-- 导航卡片 -->
<div class="w-full max-w-2xl mx-auto anim-fade-in-up anim-delay-4">
<div class="card relative overflow-hidden py-6">
<div class="absolute inset-0 flex items-center justify-center pointer-events-none select-none z-0">
<span class="text-5xl font-black tracking-widest" style="color: var(--color-text); opacity: 0.04;">导航</span>
</div>
<div class="relative z-10 px-6 flex flex-wrap gap-3 justify-center">
<NuxtLink
v-for="link in siteConfig.navLinks"
:key="link.href"
:to="link.href"
class="btn-pill"
>
<Icon :icon="link.icon" class="w-5 h-5" />
<span>{{ link.label }}</span>
</NuxtLink>
</div>
</div>
</div>
</div>
</template>
<style scoped>
@keyframes rainbow-flow {
0% { background-position: 0% 50%; }
100% { background-position: 200% 50%; }
}
.announcement-happy {
animation: rainbow-flow 3s linear infinite;
}
.announcement-text,
.announcement-text * {
background: linear-gradient(90deg,
oklch(0.78 0.18 0),
oklch(0.78 0.18 45),
oklch(0.78 0.18 90),
oklch(0.78 0.18 135),
oklch(0.78 0.18 180),
oklch(0.78 0.18 225),
oklch(0.78 0.18 270),
oklch(0.78 0.18 315),
oklch(0.78 0.18 360)
);
background-size: 200% 100%;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: rainbow-flow 3s linear infinite;
}
</style>