first commit

This commit is contained in:
2025-09-24 13:31:30 +08:00
commit b1ac9b9c08
26 changed files with 8239 additions and 0 deletions

30
.gitignore vendored Normal file
View File

@@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo

6
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"recommendations": [
"Vue.volar",
"vitest.explorer"
]
}

35
README.md Normal file
View File

@@ -0,0 +1,35 @@
# MyfronyProject
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
## Customize configuration
See [Vite Configuration Reference](https://vite.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Compile and Minify for Production
```sh
npm run build
```
### Run Unit Tests with [Vitest](https://vitest.dev/)
```sh
npm run test:unit
```

13
index.html Normal file
View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清疯不颠</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

8
jsconfig.json Normal file
View File

@@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

6656
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

33
package.json Normal file
View File

@@ -0,0 +1,33 @@
{
"name": "myfronyproject",
"version": "0.0.0",
"private": true,
"type": "module",
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test:unit": "vitest"
},
"dependencies": {
"ant-design-vue": "^4.2.6",
"antd": "^5.27.3",
"axios": "^1.11.0",
"element-plus": "^2.11.2",
"vue": "^3.5.18",
"vue-router": "^4.5.1"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.1",
"@vue/test-utils": "^2.4.6",
"jsdom": "^26.1.0",
"unplugin-auto-import": "^20.1.0",
"unplugin-vue-components": "^29.0.0",
"vite": "^7.0.6",
"vite-plugin-vue-devtools": "^8.0.0",
"vitest": "^3.2.4"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

9
src/App.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<Index/>
</template>
<script setup>
import Index from './index.vue';
</script>
<style scoped>
</style>

BIN
src/img/8.21.1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

333
src/index.vue Normal file
View File

@@ -0,0 +1,333 @@
<template>
<div class="elrow-top" :class="elrowtop">
<el-row justify="center">
<el-col :span="4">
<div class="grid-content ep-bg-purple-dark">
<!-- <div><img src="../public/favicon.ico" alt=""></div> -->
<div>清疯不颠</div>
</div>
</el-col>
<el-col :span="14">
<div class="grid-content ep-bg-purple-dark">
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="/:type">
首页
</el-menu-item>
<el-menu-item index="/aericle">
文章
</el-menu-item>
<el-menu-item index="/nonsense">
疯言疯语
</el-menu-item>
<el-menu-item index="/about">
关于
</el-menu-item>
<el-menu-item index="/message">
留言板
</el-menu-item>
</el-menu>
</div>
</el-col>
<el-col :span="2" class="search-container">
</el-col>
</el-row>
</div>
<div class="hero" :class="{ 'newhero': classhero }">
<h1>如果感到累了撸一管就好了</h1>
</div>
<div id="content-section" :class="{ 'visible': isconts }">
<div class="nonsensetitle" v-if="classnonsenset">
<div class="nonsensetitleconst">
<h1>发癫中QAQ</h1>
</div>
</div>
<!-- 状态模块 -->
<leftmodlue class="leftmodluepage" :class="{ 'nonsensetmargintop': classnonsenset }" />
<!-- 内容模块 -->
<RouterView class="RouterViewpage" :class="{ 'nonsensetmargintop': classnonsenset }" />
</div>
<!-- 分页 -->
<div class="Pagination">
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router'
import leftmodlue from '@/views/leftmodlue.vue'
// hero 的高度更新
const classhero = ref(false);
const isconts = ref(false); // 内容
const isScrollingleftmodlue = ref(false);
const elrowtop = ref(); // 导航
const classnonsenset = ref(false) // 疯言疯语
// 路由
const router = useRouter()
const handleSelect = (key: string) => {
router.push({
path: key
})
}
// 是否在某页面
const isclass = (url: any) => {
classhero.value = url != '/:type';
classnonsenset.value = url == '/nonsense'
}
// url监听
// 使用router.beforeEach或router.afterEach全局守卫
router.beforeEach((to, from) => {
// console.log("从", from.path, "到", to.path);
isclass(to.path)
// 回到顶部
window.scrollTo({
top: 0,
behavior: 'smooth' // 平滑滚动
});
if (to.path == '/:type') {
isconts.value = false;
} else {
isconts.value = false;
isconts.value = true;
}
});
// 滚动事件
const handleScroll = () => {
const scrollYmo = window.scrollY;
// 只有首页才会执行页面内容滚动效果
if (location.pathname == '/:type') {
isconts.value = window.scrollY > 200;
isScrollingleftmodlue.value = window.scrollY > 600;
}
// 导航
if (scrollYmo > 1200) {
elrowtop.value = 'hide'
} else {
elrowtop.value = window.scrollY > 100 ? 'solid' : 'transparent';
}
};
window.addEventListener('scroll', handleScroll);
// 页面加载完成后执行
const activeIndex = ref('/:type')
const isactiveindex = () => {
// 获取当前路径
const currentPath = window.location.pathname;
// 判断路径并设置hero值
activeIndex.value = currentPath;
}
window.addEventListener('DOMContentLoaded', isactiveindex);
// 输入框
</script>
<style>
body {
/* background-image: url(./img/8.21.1.jpg); */
background-size: 120% 120%;
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;
}
body ul {
border-bottom: 0px;
}
.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: inherit;
font-weight: 400;
line-height: 1.5;
margin-bottom: .5rem;
color: #32325d;
}
p {
font-size: 1rem;
font-weight: 300;
line-height: 1.7;
}
.cont {
margin-top: 5%;
}
/* 导航 */
.elrow-top {
position: fixed;
top: 0;
left: 0;
width: 100%;
padding: 20px 40px;
justify-content: space-between;
align-items: center;
z-index: 1000;
transition: all 0.4s ease;
font-size: inherit;
}
.elrow-top.transparent {
background-color: transparent;
}
.elrow-top.solid {
background-color: rgba(145, 196, 238, 0.85);
padding: 15px 40px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
}
.elrow-top.hide {
background-color: rgba(145, 196, 238, 0);
box-shadow: 0 5px 20px rgba(0, 0, 0, 0);
top: -100px;
transition: all 0.8s ease;
}
.elrow-top .el-row .el-col .grid-content .el-menu--horizontal {
border-bottom: 0px;
}
.el-menu--horizontal {
background: rgb(0, 0, 0, 0);
}
.el-menu-demo {
font-weight: bold;
font-size: 20px;
left: 10%;
}
.el-menu-demo .el-menu-item {
margin-left: 10px;
}
.el-menu.el-menu--horizontal.el-menu-demo .el-menu-item {
font-size: inherit;
}
.el-menu.el-menu--horizontal.el-menu-demo .el-menu-item:hover,
.el-menu.el-menu--horizontal.el-menu-demo .el-menu-item.is-active {
background-color: rgb(0, 0, 0, 0);
}
/* 内容 */
#content-section {
min-height: 100vh;
padding: 100px 10%;
opacity: 0;
transform: translateY(50px);
transition: all 0.8s ease-out;
/* margin: 20px 0; */
border-radius: 10px;
display: flex;
}
#content-section.visible {
opacity: 1;
transform: translateY(0);
}
.search {
margin-top: 12px;
}
.grid-content {
text-align: center;
}
.RouterViewpage {
width: 80%;
margin-left: 5%;
margin-right: 5%;
}
/* 分页 */
.Pagination {
align-self: center;
background-color: aqua;
}
#search {
display: flex;
}
.el-button {
background-color: rgb(0, 0, 0, 0);
border: 0px;
}
/* 状态栏 */
.leftmodluepage {
width: 20%;
}
/* 开头标题样式*/
.hero {
height: 600px;
margin-top: 5%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
color: white;
}
.hero.newhero {
height: 200px;
transition: all 0.3s ease;
}
.hero h1 {
font-size: 3.5rem;
margin-bottom: 20px;
}
.hero p {
font-size: 1.5rem;
max-width: 700px;
margin: 0 auto 30px;
}
/* 疯言疯语标题 */
.nonsensetitle {
text-align: center;
position: absolute;
top: 0;
width: 76.5%;
padding: 20px;
margin-bottom: 50px;
background: rgba(255, 255, 255, 0.1) !important;
backdrop-filter: blur(10px);
border-radius: 20px;
}
.nonsensetitle .nonsensetitleconst {
padding: 1.5rem;
flex: 1 1 auto;
box-sizing: border-box;
}
.nonsensetitle .nonsensetitleconst p {
font-size: 1rem;
}
/* 调整样式 */
.nonsensetmargintop {
margin-top: 130px;
}
/* 输入框 */
</style>

7
src/main.js Normal file
View File

@@ -0,0 +1,7 @@
import { createApp } from 'vue'
import App from './App.vue'
import Router from './router/Router'
const app = createApp(App)
app.use(Router)
app.mount('#app')

50
src/router/Router.js Normal file
View File

@@ -0,0 +1,50 @@
import { createWebHistory, createRouter } from 'vue-router'
import Aericle from '../views/aericle.vue'
import home from '../views/home.vue'
import nonsense from '../views/nonsense.vue'
import messageboard from '../views/messageboard.vue'
import about from '../views/aboutme.vue'
import articlecontents from '../views/articlecontents.vue'
const routes = [
{
path: '/:type',
// 如果type为空则是所有不为空查询相对应属性的文章
name: '/home',
component: home
},
{
path: '/aericle',
name: 'Aericle',
component: Aericle
},
{
path: '/nonsense',
name: 'nonsense',
component: nonsense
},
{
path: '/message',
name: 'messageboard',
component: messageboard
},
{
path: '/about',
name: 'about',
component: about
},
{
path: '/articlecontents/:url',
name: 'articlecontents',
component: articlecontents
}
]
const router = createRouter({
history: createWebHistory(),
routes,
})
export default router;

11
src/views/aboutme.vue Normal file
View File

@@ -0,0 +1,11 @@
<template>
<div id="allstyle">
<div class="header">
<h1>关于</h1>
</div>
</div>
</template>
<script>
</script>
<style></style>

178
src/views/aericle.vue Normal file
View File

@@ -0,0 +1,178 @@
<template>
<div id="allstyle">
<div class="header">
<h1>目录</h1>
</div>
<div class="post_content">
<div v-for="(items, index) in datas" style=" padding: 20px;">
<h2>{{ items[index].title }}</h2>
<span class="badge badge-primary">{{ contentsum(items) }}</span>
<ul class="pcont_ul">
<li class="pcont_li" v-for="item in items">
<a class="btn" @click="btnonclick(item.contentid)"><kbd>{{ item.content }}</kbd></a> ({{ item.sum }})
</li>
</ul>
</div>
</div>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const btnonclick = (contentid) => {
router.push({
path: '/:type',
query: {
type: contentid
}
})
}
const contentsum = (items) => {
let nums = 0
for (let i = 0; i < items.length; i++) {
nums += items[i].sum
}
return nums
}
const datas = [
// 学习模块
[
{
title: '学习',
contentid: '1',
content: '算法',
sum: 1,
},
{
title: '学习',
contentid: '2',
content: '前端',
sum: 1,
},
{
title: '学习',
contentid: '3',
content: '后端',
sum: 1,
},
{
title: '学习',
contentid: '4',
content: 'Java',
sum: 1,
},
],
// 生活模块
[
{
title: '生活',
contentid: '1',
content: '生活',
sum: 1,
},
{
title: '生活',
contentid: '2',
content: '书',
sum: 1,
},
{
title: '生活',
contentid: '2',
content: '书',
sum: 1,
}
]
]
</script>
<style>
#allstyle {
background-color: rgba(255, 255, 255, 0.85);
border-radius: 10px;
}
.header {
text-align: center;
padding: 20px;
}
.post_content {
padding: 20px;
}
.pcont_ul {
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 15px;
margin-top: 20px;
}
.pcont_li {
display: flex;
align-items: center;
padding: 10px 15px;
border-radius: 12px;
transition: transform 0.3s ease;
}
.btn {
position: relative;
text-decoration: none;
color: black;
padding: 10px 15px;
border-radius: 8px;
transition: all 0.3s ease;
display: inline-block;
z-index: 1;
overflow: hidden;
}
/* 透明方块效果 */
.btn::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 8px;
z-index: -1;
transition: all 0.3s ease;
transform: scale(0.95);
opacity: 0.8;
}
/* 悬浮效果 */
.btn:hover::before {
transform: scale(1.1);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
background: rgba(145, 196, 238, 0.85);
transform: translateY(-3px);
}
/* spa */
.badge {
text-transform: uppercase;
}
.badge-primary {
color: #2643e9;
background-color: rgba(203, 210, 246, .5);
}
.badge {
font-size: 66%;
font-weight: 600;
line-height: 1;
display: inline-block;
padding: .35rem .375rem;
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
text-align: center;
vertical-align: baseline;
white-space: nowrap;
border-radius: .25rem;
}
</style>

View File

@@ -0,0 +1,13 @@
<template>
<div id="allstyle">
<div class="header">
<h1>文章内容页面</h1>
</div>
<p>通过传来的{{ urls }}向服务器发送请求获取相关文章的链接</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router';
const urls = useRoute().query
</script>
<style></style>

162
src/views/home.vue Normal file
View File

@@ -0,0 +1,162 @@
<!-- 文章模板 -->
<template>
<div>
<div class="button-example" @click="aericleClick(items.aur) " v-for="items in datas">
<div v-if="items.mg == ''">
<h2>{{ items.title }}</h2>
<el-text class="mx-1">{{ items.author }}</el-text>
<p>{{ items.publishedAt }}</p>
</div>
<div v-else="items.mg != ''">
<h2>{{ items.title }}</h2>
<el-text class="mx-1">{{ items.author }}</el-text>
<div>mg</div>
<p>{{ items.publishedAt }}</p>
</div>
</div>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const aericleClick = (aur) => {
router.push({
path:'/articlecontents/:url',
query:{
url:aur
}
})
}
const datas = [
{
title: '测试1',
author: '这是文章模块测试',
aur: '链接',
mg: '11',
publishedAt: '2016-04-10'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
]
</script>
<style scoped>
.button-example {
border-radius: 10px;
display: flex;
flex-direction: column;
gap: 1rem;
background-color: rgba(255, 255, 255, 0.85);
padding: 15px;
margin-bottom: 30px;
}
.button-example {
transition: all 0.4s ease;
position: relative;
overflow: hidden;
}
.button-example::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg,
rgba(255,255,255,0.6) 0%,
rgba(255,255,255,0.2) 50%,
rgba(255,255,255,0.05) 100%);
pointer-events: none;
opacity: 0;
transition: opacity 0.4s ease;
}
.button-example:hover {
transform: translateY(-5px) perspective(2000px) rotateX(0);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.25),
0 0 50px rgba(255, 255, 255, 0.3);
}
.button-example:hover::before {
opacity: 1;
}
</style>

176
src/views/leftmodlue.vue Normal file
View File

@@ -0,0 +1,176 @@
<template>
<div id="alld">
<div id="top">
<div class="top1">
<h3>小颠公告栏</h3>
</div>
<div class="top2">
<p>站主发癫中请勿靠近</p>
</div>
</div>
<div id="cont">
<div class="cont1">
<h2>小颠片刻</h2>
<p>左眼右右眼左四十五度成就美</p>
</div>
<div class="cont2">
<el-menu class="el-menu-vertical-demo" @select="handleSelect">
<el-menu-item index="/:type">
<el-icon>
</el-icon>
<span>首页</span>
</el-menu-item>
<el-menu-item index="/aericle">
<el-icon>
</el-icon>
<span>文章</span>
</el-menu-item>
<el-menu-item index="/nonsense">
<el-icon>
</el-icon>
<span>疯言疯语</span>
</el-menu-item>
</el-menu>
</div>
</div>
<div id="bot" :class="{ 'botrelative': scrollY }">
<el-tabs v-model="activeName" class="demo-tabs">
<el-tab-pane label="个人简介" name="first">
<div class="mylogo">
<el-avatar :src="state" />
</div>
<p>清疯不颠</p>
<p>···重度精神失常患者···</p>
</el-tab-pane>
<el-tab-pane label="功能" name="second">
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const activeName = ref('first')
const state = reactive({
circleUrl:
'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
squareUrl:
'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
sizeList: ['small', '', 'large'] as const,
})
const handleSelect = (key: string, keyPath: string[]) => {
router.push({
path: key
})
}
// 滚动事件
const scrollY = ref(false);
const handleScroll = () => {
const scrollYmo = window.scrollY;
scrollY.value = scrollYmo > 1100;
};
window.addEventListener('scroll', handleScroll);
</script>
<style>
#alld div {
margin-bottom: 15px;
}
#top {
height: 100px;
border-radius: 10px;
background-color: rgb(102, 161, 216, 0.9);
text-align: left;
padding: 15px;
}
#top .top2 p {
font-size: 15px;
}
#cont {
padding: 15px;
height: 350px;
border-radius: 10px;
padding: 0;
}
/* */
#cont .cont1 {
border-radius:10px 10px 0 0;
padding: 15px;
text-align: center;
margin-bottom: 0;
background-color: rgb(102, 161, 216, 0.9);
}
#cont .cont2{
padding: 10px 0;
border-radius:0 0 10px 10px;
background-color: rgba(215, 224, 218, 0.9);
}
.el-menu-vertical-demo {
background-color: rgb(0, 0, 0, 0);
border-right: 0px;
}
#cont div,
#bot div {
margin-bottom: 0%;
}
/* */
#bot {
padding: 15px;
border-radius: 10px;
background-color: rgb(0, 233, 70, 0.7);
transition: all 0.4s ease;
}
#bot.botrelative {
transition: all 0.4s ease;
position: sticky;
top: 20px;
}
.demo-tabs {
text-align: center;
color: #6b778c;
}
.el-tabs__nav-scroll {
height: 45px;
margin-bottom: 5px;
}
.el-tabs__nav {
width: 100%;
}
.el-tabs__item {
width: 50%;
}
.el-tabs__nav-wrap:after {
height: 0px;
}
.mylogo {
height: 80px;
display: flex;
justify-content: center;
align-items: center;
}
.el-avatar:hover {
transform: scale(2);
z-index: 2;
transition: all 0.4s ease;
}
</style>

View File

@@ -0,0 +1,73 @@
<template>
<div id="messahe_all">
<div id="allstyle">
<div class="header">
<h1>留言板</h1>
</div>
</div>
<div id="allstyle" class="botom">
<h1>发送评论(请正确填写邮箱地址否则将会当成垃圾评论处理)</h1>
<el-form :model="form">
<!-- 输入框 -->
<el-form-item >
<el-input v-model="form" placeholder="评论内容" type="textarea" />
</el-form-item>
<div class="botom_form_input">
<el-form-item >
<el-input v-model="form" placeholder="昵称" clearable />
</el-form-item>
<el-form-item >
<el-input v-model="form" placeholder="邮箱/QQ号" clearable />
</el-form-item>
<el-form-item >
<el-input v-model="form" placeholder="验证码" clearable />
</el-form-item>
</div>
<!-- 按钮 -->
<el-form-item>
<el-button type="primary" @click="onSubmit">发送</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import { reactive } from 'vue'
// do not use same name with ref
const form = reactive({
name: '',
region: '',
type: [],
resource: '',
desc: '',
})
const onSubmit = () => {
console.log('submit!')
}
</script>
<style>
.botom{
padding: 20px;
}
#allstyle.botom{
margin-top: 10px;
}
.botom_form_input{
display: flex;
}
.botom_form_input .el-form-item{
width: 30%;
display: block;
}
.botom_form_input .el-form-item:nth-child(2){
margin: 0 2.5%;
}
.botom_form_input .el-form-item .el-input__inner {
height: 45px;
}
</style>

7
src/views/nonsense.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="allstyle">
<div class="header">
<h1>疯言疯语</h1>
</div>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<template>
<div style="max-width: 600px">
<el-alert title="Primary alert" type="primary" />
<el-alert title="Success alert" type="success" />
<el-alert title="Info alert" type="info" />
<el-alert title="Warning alert" type="warning" />
<el-alert title="Error alert" type="error" />
</div>
</template>
<style scoped>
.el-alert {
margin: 20px 0 0;
}
.el-alert:first-child {
margin: 0;
}
</style>

336
src/views/viewsDemo.vue Normal file
View File

@@ -0,0 +1,336 @@
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
display: flex;
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
color: #e6e6e6;
overflow: hidden;
}
/* 进度条样式 */
.progress-container {
width: 50px;
background: rgba(0, 0, 0, 0.2);
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 0;
position: relative;
z-index: 100;
}
.progress-bar {
width: 20px;
height: 70vh;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
overflow: hidden;
position: relative;
}
.progress-fill {
position: absolute;
bottom: 0;
width: 100%;
background: linear-gradient(to top, #ff416c, #ff4b2b);
height: 0%;
transition: height 0.3s ease;
border-radius: 10px;
}
.progress-text {
writing-mode: vertical-rl;
text-orientation: mixed;
margin-top: 20px;
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
letter-spacing: 1px;
}
/* 内容区域样式 */
.content {
flex: 1;
padding: 40px;
position: relative;
}
h1 {
font-size: 2.5rem;
margin-bottom: 20px;
color: #ff4b2b;
}
p {
font-size: 1.1rem;
line-height: 1.6;
margin-bottom: 15px;
max-width: 800px;
}
.warning {
color: #ff416c;
font-weight: bold;
}
/* 崩坏效果 */
.corruption-effect {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 50;
}
.glitch-text {
animation: glitch 1s infinite;
}
@keyframes glitch {
0% {
text-shadow: 2px 2px #ff416c, -2px -2px #2bffc2;
}
25% {
text-shadow: -2px 2px #2bffc2, 2px -2px #ff416c;
}
50% {
text-shadow: 2px -2px #2bffc2, -2px 2px #ff416c;
}
75% {
text-shadow: -2px -2px #ff416c, 2px 2px #2bffc2;
}
100% {
text-shadow: 2px 2px #2bffc2, -2px -2px #ff416c;
}
}
/*内容消融 */
.dissolve {
animation: dissolve 3s forwards;
}
@keyframes dissolve {
to {
opacity: 0;
transform: translateY(20px) rotate(5deg);
}
}
/* 模态框样式 */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
padding: 30px;
border-radius: 10px;
text-align: center;
max-width: 500px;
width: 90%;
border: 2px solid #ff416c;
box-shadow: 0 0 25px #ff416c;
}
.modal h2 {
color: #ff4b2b;
margin-bottom: 20px;
font-size: 2rem;
}
.modal p {
margin-bottom: 25px;
font-size: 1.2rem;
}
.btn {
background: linear-gradient(to right, #ff416c, #ff4b2b);
color: white;
border: none;
padding: 12px 30px;
border-radius: 30px;
font-size: 1rem;
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(255, 75, 43, 0.4);
}
</style>
<template>
<!-- 进度条 -->
<div class="progress-container">
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<div class="progress-text">系统稳定性进度</div>
</div>
<!-- 内容区域 -->
<div class="content">
<h1>系统稳定性控制面板</h1>
<p>欢迎访问系统控制中心本面板用于监控和维持系统稳定性</p>
<p class="warning">警告系统目前处于高度不稳定状态请勿进行任何关键操作</p>
<p>当前状态<span id="statusText">监控中...</span></p>
<p>系统完整性<span id="integrityText">98%</span></p>
<p>如果系统开始出现异常请立即保存您的工作并准备撤离</p>
<p>倒计时直到可能的不稳定事件<span id="countdown">00:30</span></p>
</div>
<!-- 崩坏效果层 -->
<div class="corruption-effect" id="corruptionEffect"></div>
<!-- 模态框 -->
<div class="modal" id="modal">
<div class="modal-content">
<h2>系统崩溃</h2>
<p>系统稳定性已降至临界水平为防止数据丢失系统将自动关闭</p>
<p>请返回主页并重新登录</p>
<button class="btn" id="homeBtn">返回主页</button>
</div>
</div>
</template>
<script>
document.addEventListener('DOMContentLoaded', function () {
const progressFill = document.getElementById('progressFill');
const statusText = document.getElementById('statusText');
const integrityText = document.getElementById('integrityText');
const countdown = document.getElementById('countdown');
const corruptionEffect = document.getElementById('corruptionEffect');
const modal = document.getElementById('modal');
const homeBtn = document.getElementById('homeBtn');
const content = document.querySelector('.content');
let progress = 0;
let countdownTime = 30;
let corruptionActive = false;
// 更新倒计时显示
function updateCountdown() {
const minutes = Math.floor(countdownTime / 60);
const seconds = countdownTime % 60;
countdown.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
if (countdownTime > 0) {
countdownTime--;
}
}
// 初始化倒计时
setInterval(updateCountdown, 1000);
// 更新进度条
const progressInterval = setInterval(() => {
progress += 1;
progressFill.style.height = `${progress}%`;
if (progress >= 70) {
statusText.textContent = "稳定性下降";
statusText.classList.add('warning');
}
if (progress >= 85) {
integrityText.textContent = "75%";
}
if (progress >= 100) {
clearInterval(progressInterval);
startCorruption();
}
}, 100);
// 开始崩坏效果
function startCorruption() {
corruptionActive = true;
statusText.textContent = "系统崩溃中!";
integrityText.textContent = "23%";
// 添加崩坏效果
document.body.classList.add('glitch-text');
// 文字颜色随机变化
const textElements = document.querySelectorAll('p, h1, span');
const colorInterval = setInterval(() => {
textElements.forEach(el => {
el.style.color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
});
}, 200);
// 内容逐渐消融
content.classList.add('dissolve');
// 显示模态框
setTimeout(() => {
modal.style.display = 'flex';
clearInterval(colorInterval);
}, 3000);
}
// 返回主页按钮事件
homeBtn.addEventListener('click', function () {
alert('返回主页');
// 实际应用中这里可能是 window.location.href = '/';
});
// 添加一些随机崩坏效果
function addCorruptionEffects() {
if (!corruptionActive) return;
// 创建随机闪烁元素
const effect = document.createElement('div');
effect.style.position = 'absolute';
effect.style.left = Math.random() * 100 + 'vw';
effect.style.top = Math.random() * 100 + 'vh';
effect.style.width = Math.random() * 100 + 50 + 'px';
effect.style.height = Math.random() * 10 + 2 + 'px';
effect.style.background = `linear-gradient(90deg,
rgba(255, 75, 43, ${Math.random() * 0.7}),
rgba(255, 65, 108, ${Math.random() * 0.5}))`;
effect.style.boxShadow = '0 0 10px rgba(255, 65, 108, 0.7)';
effect.style.opacity = Math.random() * 0.7;
effect.style.transform = `rotate(${Math.random() * 360}deg)`;
effect.style.pointerEvents = 'none';
corruptionEffect.appendChild(effect);
// 移除元素
setTimeout(() => {
if (effect.parentNode) {
effect.parentNode.removeChild(effect);
}
}, 2000);
}
// 当崩坏激活时,定期添加效果
setInterval(() => {
if (corruptionActive) {
for (let i = 0; i < 3; i++) {
addCorruptionEffects();
}
}
}, 300);
});
</script>

32
vite.config.js Normal file
View File

@@ -0,0 +1,32 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueDevTools(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
server: {
host: '0.0.0.0'
},
})

14
vitest.config.js Normal file
View File

@@ -0,0 +1,14 @@
import { fileURLToPath } from 'node:url'
import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
import viteConfig from './vite.config'
export default mergeConfig(
viteConfig,
defineConfig({
test: {
environment: 'jsdom',
exclude: [...configDefaults.exclude, 'e2e/**'],
root: fileURLToPath(new URL('./', import.meta.url)),
},
}),
)

38
Normal file
View File

@@ -0,0 +1,38 @@
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

1
.pub Normal file
View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQChFrYp8soAeeSu4wMSikfOTCfz9etz+kpB9/Q5t1jaDid/X5aVi57+0YFcxdE9IBpNn0MnSfEqPlebPJyRjFngIp7IkpSfqNie4EOuyUyG9m4ec3z+A3TMjArpRNt5sbF9rel3b3UTrmvJ0a0mGXRihSVIzEKHT6UtLikC2NAWMrE3y3I4wmS4CWBGQg8YpOt2pWSiNnwds/hpyXpbeRAU++2Wt3wVdtAHBkMBW8dnM0adrN9EorMlWqqJYnA6CF+HcdnSBi8zorrZs70QCjc6k0PF3udkrozs98IzuRPEL85WudJJbvR4eFGhzTBB1kzXNJ+g0v/6rT+b+5H9a5tXnwxB2sxV07fcwd1Xj+uosj1GtydUu8SJG/epZF8pZu/ent3gS1CtV2CCLqvJnsPgKSh2TzgTOipNjukbAnOGIVhW5olsSF2l41SQaXW/eZJH+JaLkfTFvre7y9OXZa2OLFXAzAX/1SzlmDKPGSMgDdS+lnCeYfbLGq19+q2rJgU= 3080373706@qq.com