添加部分页面

This commit is contained in:
2025-12-12 21:35:24 +08:00
parent 52bfe51aa4
commit 9d27ed1484
5699 changed files with 289 additions and 408385 deletions

View File

@@ -1,44 +0,0 @@
<script setup>
defineProps({
msg: {
type: String,
required: true,
},
})
</script>
<template>
<div class="greetings">
<h1 class="green">{{ msg }}</h1>
<h3>
Youve successfully created a project with
<a href="https://vite.dev/" target="_blank" rel="noopener">Vite</a> +
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
</h3>
</div>
</template>
<style scoped>
h1 {
font-weight: 500;
font-size: 2.6rem;
position: relative;
top: -10px;
}
h3 {
font-size: 1.2rem;
}
.greetings h1,
.greetings h3 {
text-align: center;
}
@media (min-width: 1024px) {
.greetings h1,
.greetings h3 {
text-align: left;
}
}
</style>

View File

@@ -1,87 +0,0 @@
<script setup>
import WelcomeItem from './WelcomeItem.vue'
const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
</script>
<template>
<WelcomeItem>
<template #icon>
<DocumentationIcon />
</template>
<template #heading>Documentation</template>
Vues
<a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a>
provides you with all information you need to get started.
</WelcomeItem>
<WelcomeItem>
<template #heading>Tooling</template>
This project is served and bundled with
<a href="https://vite.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The
recommended IDE setup is
<a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a>
+
<a href="https://github.com/vuejs/language-tools" target="_blank" rel="noopener"
>Vue - Official</a
>. If you need to test your components and web pages, check out
<a href="https://vitest.dev/" target="_blank" rel="noopener">Vitest</a>
and
<a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a>
/
<a href="https://playwright.dev/" target="_blank" rel="noopener">Playwright</a>.
<br />
More instructions are available in
<a href="javascript:void(0)" @click="openReadmeInEditor"><code>README.md</code></a
>.
</WelcomeItem>
<WelcomeItem>
<template #icon>
<EcosystemIcon />
</template>
<template #heading>Ecosystem</template>
Get official tools and libraries for your project:
<a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
<a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>,
<a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and
<a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If
you need more resources, we suggest paying
<a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a>
a visit.
</WelcomeItem>
<WelcomeItem>
<template #icon>
<CommunityIcon />
</template>
<template #heading>Community</template>
Got stuck? Ask your question on
<a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>
(our official Discord server), or
<a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener"
>StackOverflow</a
>. You should also follow the official
<a href="https://bsky.app/profile/vuejs.org" target="_blank" rel="noopener">@vuejs.org</a>
Bluesky account or the
<a href="https://x.com/vuejs" target="_blank" rel="noopener">@vuejs</a>
X account for latest news in the Vue world.
</WelcomeItem>
<WelcomeItem>
<template #icon>
<SupportIcon />
</template>
<template #heading>Support Vue</template>
As an independent project, Vue relies on community backing for its sustainability. You can help
us by
<a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>.
</WelcomeItem>
</template>

View File

@@ -1,86 +0,0 @@
<template>
<div class="item">
<i>
<slot name="icon"></slot>
</i>
<div class="details">
<h3>
<slot name="heading"></slot>
</h3>
<slot></slot>
</div>
</div>
</template>
<style scoped>
.item {
margin-top: 2rem;
display: flex;
position: relative;
}
.details {
flex: 1;
margin-left: 1rem;
}
i {
display: flex;
place-items: center;
place-content: center;
width: 32px;
height: 32px;
color: var(--color-text);
}
h3 {
font-size: 1.2rem;
font-weight: 500;
margin-bottom: 0.4rem;
color: var(--color-heading);
}
@media (min-width: 1024px) {
.item {
margin-top: 0;
padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
}
i {
top: calc(50% - 25px);
left: -26px;
position: absolute;
border: 1px solid var(--color-border);
background: var(--color-background);
border-radius: 8px;
width: 50px;
height: 50px;
}
.item:before {
content: ' ';
border-left: 1px solid var(--color-border);
position: absolute;
left: 0;
bottom: calc(50% + 25px);
height: calc(50% - 25px);
}
.item:after {
content: ' ';
border-left: 1px solid var(--color-border);
position: absolute;
left: 0;
top: calc(50% + 25px);
height: calc(50% - 25px);
}
.item:first-of-type:before {
display: none;
}
.item:last-of-type:after {
display: none;
}
}
</style>

View File

@@ -0,0 +1 @@
<template></template>

View File

@@ -0,0 +1,59 @@
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
document.title = 'Loading...'
})
</script>
<template>
<div class="loading">
<div class="title">DataBuddy</div>
<div class="loading-bar">
<div class="loading-line"></div>
</div>
</div>
</template>
<style>
.loading {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
background-color: #fff;
}
.title {
position: fixed;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 48px;
font-weight: bold;
}
.loading-bar {
position: fixed;
top: 55%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 4px;
background-color: #e0e0e0;
border-radius: 2px;
overflow: hidden;
}
.loading-line {
height: 100%;
width: 100%;
background: linear-gradient(90deg, transparent, #f472b6, transparent);
background-size: 200% 100%;
animation: loading 1.5s infinite linear;
}
@keyframes loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -100% 0;
}
}
</style>

View File

@@ -0,0 +1,32 @@
<script setup>
import getConfig from '@/utils/config'
const config = getConfig()
</script>
<template>
<div class="topbar">
<div class="logo" @click="router.push('/')">
<img src="@/assets/logo.svg" alt="logo" />
</div>
</div>
</template>
<style>
.topbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 32px;
background-color: rgba(255,255,255,0.2);
backdrop-filter: blur(3px);
}
.logo {
position: fixed;
top: 6px;
left: 10px;
}
.logo img {
width: 20px;
height: 20px;
}
</style>

View File

@@ -1,4 +1,5 @@
import { createRouter, createWebHistory } from 'vue-router'
import { createApp, h } from 'vue'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
@@ -14,26 +15,27 @@ const style = document.createElement('style')
style.innerHTML = `
#nprogress .bar {
background: #f472b6 !important;
height: 2px !important;
height: 3px !important;
box-shadow: 0 0 5px rgba(244, 114, 182, 0.7) !important;
}
#nprogress .peg {
box-shadow: 0 0 15px #f472b6, 0 0 10px #f472b6 !important;
opacity: 1 !important;
}
#nprogress .spinner {
display: none !important;
}
`
document.head.appendChild(style)
let loadingApp = null;
let loadingNode = null;
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
path: '/' || '/index.html',
name: 'index',
component: () => import('./views/Index.vue'),
meta: { requiresIndexLoading: true },
},
{
path: '/:pathMatch(.*)*',
@@ -43,13 +45,55 @@ const router = createRouter({
],
})
router.beforeEach((to, from, next) => {
NProgress.start()
next()
})
router.beforeEach(async (to, from, next) => {
if (!to.meta.requiresIndexLoading) {
NProgress.start()
}
router.afterEach(() => {
NProgress.done()
})
if (to.meta.requiresIndexLoading) {
NProgress.done()
NProgress.remove()
loadingNode = document.createElement('div');
loadingNode.id = 'custom-loading';
document.body.appendChild(loadingNode);
try {
const LoadingComponent = (await import('@/components/index/Loading.vue')).default;
loadingApp = createApp({
render: () => h(LoadingComponent)
});
loadingApp.mount(loadingNode);
} catch (error) {
console.error('Failed to load custom loading component:', error);
NProgress.start();
document.body.removeChild(loadingNode);
loadingNode = null;
}
}
next();
});
router.afterEach((to) => {
if (to.meta.requiresIndexLoading && loadingApp) {
setTimeout(() => {
if (loadingApp) {
loadingApp.unmount();
loadingApp = null;
}
if (loadingNode && document.body.contains(loadingNode)) {
document.body.removeChild(loadingNode);
loadingNode = null;
}
}, 300);
}
if (!to.meta.requiresIndexLoading && NProgress.isStarted()) {
NProgress.done();
}
});
export default router

View File

@@ -1,23 +0,0 @@
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView,
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue'),
},
],
})
export default router

View File

@@ -1,5 +1,22 @@
<script setup>
import { onMounted, defineAsyncComponent } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import getConfig from '@/utils/config'
const route = useRoute()
const router = useRouter()
const config = getConfig()
const Topbar = defineAsyncComponent(() => import('@/components/index/Topbar.vue'))
const Leftbar = defineAsyncComponent(() => import('@/components/index/Leftbar.vue'))
onMounted(() => {
document.title = config.title
document.body.style.background = "url('"+config.backgroundImg+"') no-repeat center center fixed"
document.body.style.backgroundSize = "cover"
})
</script>
<template>
<main>
<h1>Welcome to DataBuddy</h1>
</main>
</template>
<Topbar />
<Leftbar />
</template>

View File

@@ -1,15 +1,27 @@
<script setup>
import { onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import getConfig from '@/utils/config'
const route = useRoute()
const router = useRouter()
const config = getConfig()
onMounted(() => {
document.title = '页面未找到 - ' + config.title
document.body.style.backgroundColor = '#000'
document.body.style.color = '#fff'
document.body.style.background = "url('"+config.backgroundImg+"') no-repeat center center fixed"
document.body.style.backgroundSize = "cover"
const linkElement = document.createElement('link');
linkElement.rel = 'stylesheet';
if (config.cdnUrl && config.cdnUrl !== "") {
linkElement.href = `${config.cdnUrl}/assets/font-awesome/css/all.min.css`;
} else {
linkElement.href = '@/assets/font-awesome/css/all.min.css';
}
document.head.appendChild(linkElement);
if (window.gtag) {
window.gtag('event', 'page_view', {
@@ -20,5 +32,106 @@ onMounted(() => {
})
</script>
<template>
<h1>404 - Page Not Found</h1>
</template>
<div class="container">
<i class="fa-solid fa-ban"></i>
<div class="right-container">
<h1>页面未找到</h1>
<p>抱歉您正在寻找的页面不存在</p>
<button class="go-home-button" @click="router.push('/')">
<i class="fa-solid fa-arrow-left"></i>
<span class="go-home-button-text">返回首页</span>
</button>
</div>
</div>
</template>
<style>
.container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
height: 80%;
border-radius: 20px;
backdrop-filter: blur(3px);
background-color: rgba(255, 255, 255, 0.2);
box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.2);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container i {
position: absolute;
font-size: 256px;
color: #000;
left: 32px;
}
.right-container {
position: absolute;
width: calc(100% - 416px);
right: 32px;
text-align: center;
}
.right-container h1,
.right-container p {
padding: 8px;
}
.go-home-button {
height: 48px;
width: 210px;
align-items: center;
justify-content: center;
position: relative;
border: 0.1px solid rgba(255, 255, 255, 0.2);
border-radius: 16px;
backdrop-filter: blur(3px);
background-color: rgba(255, 255, 255, 0.2);
cursor: pointer;
}
.go-home-button i {
position: absolute;
font-size: 18px;
left: 12px;
bottom: 14px;
}
.go-home-button .go-home-button-text {
position: absolute;
right: 12px;
bottom: 11px;
font-size: 18px;
}
.go-home-button:hover {
background-color: rgba(255, 255, 255, 0.4);
}
.go-home-button:active {
background-color: rgba(255, 255, 255, 0.6);
}
@media (max-width: 768px) {
.container {
width: 90%;
height: 95%;
}
.container i {
font-size: 128px;
left: auto;
top: 64px;
}
.right-container {
width: 100%;
height: calc(100% - 256px);
right: 0;
bottom: 32px;
}
.go-home-button i {
font-size: 18px;
left: 12px;
top: 14px;
}
}
@media (max-width: 480px) {
.container-404 {
width: 95%;
}
}
</style>