fix: 登录与首页修改

This commit is contained in:
Shu Guang 2025-05-17 00:58:31 +08:00
parent 2cbcb14ff7
commit cd8148f65a
2 changed files with 247 additions and 197 deletions

View File

@ -29,17 +29,10 @@
<span>联系我们</span> <span>联系我们</span>
<div class="link-hover-effect"></div> <div class="link-hover-effect"></div>
</a> </a>
<button class="cyber-button" onclick="window.location.href='/login'"> <button class="cyber-button" @click="goToLogin">
<span class="btn-text">登录</span> <span class="btn-text">登录</span>
<span class="btn-glitch"></span> <span class="btn-glitch"></span>
</button> </button>
<button
class="cyber-button outline"
onclick="window.location.href='/register'"
>
<span class="btn-text">注册</span>
<span class="btn-glitch"></span>
</button>
</div> </div>
<div class="menu-toggle"> <div class="menu-toggle">
<div class="hamburger"> <div class="hamburger">
@ -68,18 +61,12 @@
<span class="typing-cursor">|</span> <span class="typing-cursor">|</span>
</p> </p>
<div class="index-cta-buttons animate-slide-up-delay-2"> <div class="index-cta-buttons animate-slide-up-delay-2">
<button <button class="cyber-btn glow-button" @click="goToLogin">
class="cyber-btn glow-button"
onclick="window.location.href='/login'"
>
<span class="cyber-btn-text">开始使用</span> <span class="cyber-btn-text">开始使用</span>
<span class="cyber-btn-glitch"></span> <span class="cyber-btn-glitch"></span>
<span class="cyber-btn-glow"></span> <span class="cyber-btn-glow"></span>
</button> </button>
<button <button class="cyber-btn outline-button" @click="goToLogin">
class="cyber-btn outline-button"
onclick="window.scrollTo({top: document.querySelector('#features').offsetTop, behavior: 'smooth'})"
>
<span class="cyber-btn-text">了解更多</span> <span class="cyber-btn-text">了解更多</span>
<span class="cyber-arrow"></span> <span class="cyber-arrow"></span>
</button> </button>
@ -1618,169 +1605,13 @@ h6 {
} }
} }
</style> </style>
<script>
<script setup> export default {
import { onMounted, ref } from "vue"; name: "Index",
methods: {
// goToLogin() {
const menuOpen = ref(false); this.$router.push("/login");
},
const toggleMenu = () => { },
menuOpen.value = !menuOpen.value;
const navLinks = document.querySelector(".index-nav-links");
if (navLinks) {
if (menuOpen.value) {
navLinks.classList.add("active");
} else {
navLinks.classList.remove("active");
}
}
}; };
onMounted(() => {
//
const menuToggle = document.querySelector(".menu-toggle");
if (menuToggle) {
menuToggle.addEventListener("click", toggleMenu);
}
//
const addMatrixElements = () => {
const grid = document.createElement("div");
grid.classList.add("matrix-bg");
document.body.appendChild(grid);
for (let i = 0; i < 50; i++) {
const digit = document.createElement("div");
digit.classList.add("matrix-digit");
digit.style.left = `${Math.random() * 100}%`;
digit.style.top = `${Math.random() * 100}%`;
digit.style.animationDelay = `${Math.random() * 5}s`;
digit.textContent = Math.floor(Math.random() * 10);
grid.appendChild(digit);
}
};
// particles.js
if (typeof particlesJS !== "undefined") {
particlesJS("particles-js", {
particles: {
number: { value: 80, density: { enable: true, value_area: 800 } },
color: { value: "#4e54c8" },
shape: { type: "circle" },
opacity: { value: 0.5, random: true },
size: { value: 3, random: true },
line_linked: {
enable: true,
distance: 150,
color: "#4e54c8",
opacity: 0.2,
width: 1,
},
move: {
enable: true,
speed: 1.5,
direction: "none",
random: true,
straight: false,
out_mode: "out",
bounce: false,
},
},
interactivity: {
detect_on: "canvas",
events: {
onhover: { enable: true, mode: "grab" },
onclick: { enable: true, mode: "push" },
resize: true,
},
modes: {
grab: { distance: 140, line_linked: { opacity: 0.5 } },
push: { particles_nb: 3 },
},
},
retina_detect: true,
});
} else {
// particlesJS
addMatrixElements();
}
//
const subtitleElement = document.querySelector(".index-subtitle");
if (subtitleElement) {
const text = subtitleElement.textContent.trim().replace("|", "");
subtitleElement.textContent = "";
const typeText = async () => {
for (let i = 0; i < text.length; i++) {
await new Promise((resolve) => setTimeout(resolve, 100));
subtitleElement.textContent = text.substring(0, i + 1);
if (i === text.length - 1) {
subtitleElement.innerHTML += '<span class="typing-cursor">|</span>';
}
}
};
setTimeout(typeText, 1000);
}
//
const scrollElements = document.querySelectorAll(
".index-feature-card, .index-stat-item"
);
const isElementInView = (el) => {
const rect = el.getBoundingClientRect();
return (
rect.top <=
(window.innerHeight || document.documentElement.clientHeight) * 0.8
);
};
const displayScrollElement = (element) => {
element.classList.add("scrolled");
};
const hideScrollElement = (element) => {
element.classList.remove("scrolled");
};
const handleScrollAnimation = () => {
scrollElements.forEach((el) => {
if (isElementInView(el)) {
displayScrollElement(el);
} else {
hideScrollElement(el);
}
});
};
//
const styleSheet = document.styleSheets[0];
styleSheet.insertRule(
`
.index-feature-card, .index-stat-item {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
`,
styleSheet.cssRules.length
);
styleSheet.insertRule(
`
.index-feature-card.scrolled, .index-stat-item.scrolled {
opacity: 1;
transform: translateY(0);
}
`,
styleSheet.cssRules.length
);
//
setTimeout(handleScrollAnimation, 100);
window.addEventListener("scroll", handleScrollAnimation);
});
</script> </script>

View File

@ -1,26 +1,245 @@
<template> <template>
<div class="container"> <div class="container">
<UserLogin class="login" /> <div class="background-shapes">
<p style="position: fixed;bottom: 0;text-align: center;left: 0;right: 0;font-family: '宋体';">@ 2024-青创先锋</p> <div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="shape shape-3"></div>
</div>
<div class="content-wrapper">
<div class="left-section">
<h1 class="welcome-text">欢迎使用</h1>
<div class="brand">
<div class="logo-container">
<!-- <img src="@/assets/logo.png" alt="Logo" class="logo" /> -->
<!-- <h2 class="gradient-text">CodeMaster</h2> -->
</div>
<div class="brand-description">
<p class="main-slogan">基于ChatGLM大模型的高校竞赛管理系统</p>
<p class="sub-slogan">智能辅助 · 高效管理 · 实时评测</p>
</div>
</div>
<div class="features">
<div class="feature-item">
<i class="el-icon-trophy"></i>
<span>竞赛管理</span>
</div>
<div class="feature-item">
<i class="el-icon-monitor"></i>
<span>实时评测</span>
</div>
<div class="feature-item">
<i class="el-icon-data-line"></i>
<span>数据分析</span>
</div>
</div>
</div>
<div class="login-wrapper">
<UserLogin class="login" />
</div>
</div>
<p class="copyright">@ 2025-基于ChatGLM大模型的高校竞赛管理系统</p>
</div> </div>
</template> </template>
<script>
import UserLogin from '@/components/common/UserLogin.vue';
export default {
name: 'Login',
components: { UserLogin },
metaInfo: {
title: '登录',
},
};
</script>
<style scoped lang="stylus"> <style scoped lang="stylus">
.container .container
height 100vh height 100vh
background #f0f2f5 url('~@/assets/bg.svg') repeat
.login background-image url('https://www.sxhju.cn/images/weixintupian_20240717112809.jpg')
center() position relative
display flex
justify-content center
align-items center
overflow hidden
.content-wrapper
display flex
background rgba(255, 255, 255, 0.8)
backdrop-filter blur(10px)
border-radius 20px
box-shadow 0 10px 30px rgba(0, 0, 0, 0.1)
width 900px
height 560px
position relative
z-index 2
animation fadeIn 0.8s ease-out
.left-section
flex 1
padding 60px
background linear-gradient(135deg, #2196f3 0%, #00bcd4 100%)
border-radius 20px 0 0 20px
color white
display flex
flex-direction column
justify-content space-between
.welcome-text
font-size 32px
margin-bottom 20px
font-weight 300
.brand
margin-bottom 40px
.logo-container
display flex
align-items center
gap 15px
margin-bottom 15px
.logo
width 48px
height 48px
object-fit contain
.gradient-text
font-size 36px
background linear-gradient(45deg, #ffffff, #e0f7fa)
-webkit-background-clip text
color transparent
margin 0
font-weight 700
letter-spacing 1px
.brand-description
margin-top 20px
.main-slogan
font-size 20px
font-weight 500
margin-bottom 8px
color #ffffff
letter-spacing 0.5px
.sub-slogan
font-size 16px
color rgba(255, 255, 255, 0.8)
font-weight 300
letter-spacing 0.5px
display flex
align-items center
gap 15px
&::before, &::after
content ''
height 1px
flex 1
background linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent)
.slogan
font-size 18px
opacity 0.9
margin-top 10px
.features
display flex
flex-direction column
gap 20px
.feature-item
display flex
align-items center
gap 15px
font-size 18px
opacity 0.9
transition transform 0.3s ease
&:hover
transform translateX(10px)
i
font-size 24px
.login-wrapper
flex 1
padding 40px
display flex
align-items center
justify-content center
.shape
position absolute
border-radius 50%
opacity 0.1
animation float 20s infinite
.shape-1
width 300px
height 300px
top -150px
right -150px
background white
animation-delay -5s
.shape-2
width 200px
height 200px
bottom -100px
left -100px
background white
animation-delay -10s
.shape-3
width 150px
height 150px
top 50%
right -75px
background white
animation-delay -15s
.copyright
position fixed
bottom 20px
left 0
right 0
text-align center
color #666
font-size 14px
z-index 2
@keyframes float
0%, 100%
transform translate(0, 0)
50%
transform translate(20px, -20px)
@keyframes fadeIn
from
opacity 0
transform translateY(20px)
to
opacity 1
transform translateY(0)
@media (max-width: 992px)
.content-wrapper
width 95%
flex-direction column
height auto
.left-section
border-radius 20px 20px 0 0
padding 40px
.login-wrapper
padding 30px
.main-slogan
font-size 20px
font-weight 500
margin-bottom 8px
color #ffffff
letter-spacing 0.5px
</style> </style>
<script>
import UserLogin from "@/components/common/UserLogin.vue";
export default {
name: "Login",
components: { UserLogin },
metaInfo: {
title: "登录",
},
};
</script>