Initial commit

This commit is contained in:
wfz
2026-05-13 16:24:00 +08:00
commit 5728d3cbda
55 changed files with 37267 additions and 0 deletions

View File

@@ -0,0 +1,311 @@
<script setup lang="ts">
import { onMounted, onUnmounted, computed } from 'vue'
import { useData } from 'vitepress'
import { useSettingsStore } from './stores/settings'
import { isMobileDevice } from './utils'
import VideoBackground from './components/VideoBackground.vue'
import Dock from './components/Dock.vue'
import DraggableWidget from './components/DraggableWidget.vue'
import Window from './components/Window.vue'
import Calendar from './components/Calendar.vue'
import TaoXin from './components/TaoXin.vue'
import Cafe from './components/Cafe.vue'
import Settings from './components/Settings.vue'
import DocSidebar from './components/DocSidebar.vue'
import sidebarData from './data/sidebar.json'
const { frontmatter } = useData()
const settingsStore = useSettingsStore()
settingsStore.initWidgets(['calendar', 'taoxin', 'cafe'])
const isHome = computed(() => frontmatter.value.home === true)
const blurAmount = computed(() => settingsStore.theme.blurAmount ?? 20)
const backgroundColor = computed(() => settingsStore.theme.backgroundColor ?? 'rgba(30, 30, 30, 0.7)')
const navItems = computed(() => {
return sidebarData.map(group => ({
text: group.title,
link: group.path
}))
})
const handleResize = () => {
settingsStore.setMobile(isMobileDevice())
}
onMounted(() => {
handleResize()
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
})
</script>
<template>
<div class="app-container">
<VideoBackground />
<template v-if="isHome">
<div class="home-container" :class="{ 'home-mobile': settingsStore.isMobile }">
<DraggableWidget id="calendar" :width="320" :height="400">
<Calendar />
</DraggableWidget>
<DraggableWidget id="taoxin" :width="300" :height="280">
<TaoXin />
</DraggableWidget>
<DraggableWidget id="cafe" :width="300" :height="300">
<Cafe />
</DraggableWidget>
</div>
<Dock />
<Window id="settings" title="设置中心" :default-width="800" :default-height="600">
<Settings />
</Window>
</template>
<template v-else>
<div class="doc-page">
<header class="doc-header">
<a href="/" class="logo">乌仿镇</a>
<nav class="doc-nav">
<a href="/" class="nav-link">首页</a>
<a
v-for="item in navItems"
:key="item.link"
:href="item.link"
class="nav-link"
>
{{ item.text }}
</a>
</nav>
</header>
<div class="doc-layout" :style="{
background: backgroundColor,
backdropFilter: 'blur(' + blurAmount + 'px)',
WebkitBackdropFilter: 'blur(' + blurAmount + 'px)'
}">
<aside class="doc-sidebar">
<DocSidebar />
</aside>
<main class="doc-main">
<Content />
</main>
</div>
</div>
<Dock />
<Window id="settings" title="设置中心" :default-width="800" :default-height="600">
<Settings />
</Window>
</template>
</div>
</template>
<style scoped>
.app-container {
min-height: 100vh;
position: relative;
}
.home-container {
position: relative;
min-height: 100vh;
padding-bottom: 100px;
}
.home-mobile {
display: flex;
flex-direction: column;
padding: 10px;
padding-bottom: 120px;
}
.doc-page {
min-height: 100vh;
}
.doc-header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
background: rgba(30, 30, 30, 0.9);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
z-index: 50;
}
.logo {
font-size: 20px;
font-weight: 700;
color: white;
text-decoration: none;
}
.doc-nav {
display: flex;
gap: 24px;
}
.nav-link {
color: rgba(255, 255, 255, 0.8);
text-decoration: none;
font-size: 14px;
transition: color 0.2s ease;
}
.nav-link:hover {
color: white;
}
.doc-layout {
position: fixed;
top: 60px;
left: 0;
right: 0;
bottom: 0;
display: flex;
overflow: hidden;
}
.doc-sidebar {
width: 280px;
padding: 20px;
height: 100%;
overflow-y: auto;
border-right: 1px solid rgba(255, 255, 255, 0.1);
flex-shrink: 0;
}
.doc-main {
flex: 1;
padding: 20px 40px;
padding-bottom: 120px;
overflow-y: auto;
height: 100%;
}
.doc-main :deep(*) {
color: white;
}
.doc-main :deep(a) {
color: #007AFF;
}
.doc-main :deep(h1),
.doc-main :deep(h2),
.doc-main :deep(h3) {
color: white;
border-bottom-color: rgba(255, 255, 255, 0.1);
padding-bottom: 8px;
margin-top: 24px;
}
.doc-main :deep(h1) {
font-size: 28px;
}
.doc-main :deep(h2) {
font-size: 22px;
}
.doc-main :deep(h3) {
font-size: 18px;
}
.doc-main :deep(p) {
line-height: 1.8;
margin: 16px 0;
}
.doc-main :deep(code) {
background: rgba(255, 255, 255, 0.1);
padding: 2px 6px;
border-radius: 4px;
font-family: 'Fira Code', monospace;
}
.doc-main :deep(pre) {
background: rgba(0, 0, 0, 0.4);
border-radius: 8px;
padding: 16px;
overflow-x: auto;
margin: 16px 0;
}
.doc-main :deep(pre code) {
background: transparent;
padding: 0;
}
.doc-main :deep(blockquote) {
border-left: 4px solid #007AFF;
background: rgba(255, 255, 255, 0.05);
padding: 12px 16px;
margin: 16px 0;
border-radius: 0 8px 8px 0;
}
.doc-main :deep(table) {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
}
.doc-main :deep(th),
.doc-main :deep(td) {
border: 1px solid rgba(255, 255, 255, 0.1);
padding: 12px;
text-align: left;
}
.doc-main :deep(th) {
background: rgba(255, 255, 255, 0.1);
}
.doc-main :deep(ul),
.doc-main :deep(ol) {
padding-left: 24px;
margin: 16px 0;
}
.doc-main :deep(li) {
margin: 8px 0;
}
@media (max-width: 768px) {
.doc-sidebar {
display: none;
}
.doc-main {
padding: 16px;
padding-bottom: 120px;
}
.doc-header {
padding: 0 16px;
}
.doc-nav {
gap: 16px;
}
}
</style>