feat
This commit is contained in:
parent
dcd5444534
commit
52eccfa394
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" type="image/png" href="NIKO.png">
|
<link rel="icon" type="image/png" href="NIKO.png">
|
||||||
@ -6,120 +6,620 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>BAOGUTANG-MUSIC-LOGIN</title>
|
<title>BAOGUTANG-MUSIC-LOGIN</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
* {
|
||||||
font-family: 'Arial', sans-serif;
|
|
||||||
background-color: #f4f4f9;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 20px;
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
background: #fff;
|
min-height: 100vh;
|
||||||
padding: 20px;
|
max-height: 100vh;
|
||||||
border-radius: 8px;
|
overflow: hidden;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
display: grid;
|
||||||
width: 95%;
|
grid-template-columns: 1fr 1fr;
|
||||||
max-width: 400px;
|
|
||||||
margin: 50px auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
/* Left Section */
|
||||||
color: #62D2A1;
|
.left-section {
|
||||||
margin-bottom: 20px;
|
position: relative;
|
||||||
font-size: 1.8rem;
|
display: none;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
background: linear-gradient(135deg, #62D2A1 0%, #45a049 50%, #2d7a3e 100%);
|
||||||
|
padding: 40px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.left-section {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 600;
|
||||||
|
position: absolute;
|
||||||
|
top: 40px;
|
||||||
|
left: 40px;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animation-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 20;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animated Characters */
|
||||||
|
.character {
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-main {
|
||||||
|
width: 180px;
|
||||||
|
height: 280px;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
border-radius: 90px 90px 60px 60px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-face {
|
||||||
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 140px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group {
|
.character-eyes {
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
.eye {
|
||||||
font-size: 1rem;
|
width: 36px;
|
||||||
color: #555;
|
height: 36px;
|
||||||
margin-bottom: 8px;
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
box-shadow: inset 0 0 0 2px #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"], input[type="password"] {
|
.eye::before {
|
||||||
padding: 10px;
|
content: '';
|
||||||
font-size: 1rem;
|
position: absolute;
|
||||||
border: 1px solid #ccc;
|
width: 18px;
|
||||||
border-radius: 5px;
|
height: 18px;
|
||||||
background-color: #f9f9f9;
|
background: #333;
|
||||||
margin-top: 10px;
|
border-radius: 50%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(calc(-50% + var(--eye-move-x, 0px)), calc(-50% + var(--eye-move-y, 0px)));
|
||||||
|
transition: transform 0.08s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-btn, .register-btn {
|
.eye::after {
|
||||||
background-color: #62D2A1;
|
content: '';
|
||||||
color: white;
|
position: absolute;
|
||||||
border: none;
|
width: 6px;
|
||||||
padding: 10px 20px;
|
height: 6px;
|
||||||
font-size: 1rem;
|
background: white;
|
||||||
border-radius: 5px;
|
border-radius: 50%;
|
||||||
cursor: pointer;
|
top: calc(50% + var(--eye-move-y, 0px) - 6px);
|
||||||
transition: background-color 0.3s;
|
left: calc(50% + var(--eye-move-x, 0px) + 2px);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
transition: all 0.08s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-visible .eye {
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-visible .eye::before,
|
||||||
|
.password-visible .eye::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-mouth {
|
||||||
|
width: 40px;
|
||||||
|
height: 20px;
|
||||||
|
background: #ff6b6b;
|
||||||
|
border-radius: 0 0 20px 20px;
|
||||||
|
margin: 0 auto;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-visible .character-mouth {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-arms {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 80px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-btn:hover, .register-btn:hover {
|
.arm {
|
||||||
background-color: #45a049;
|
position: absolute;
|
||||||
|
width: 25px;
|
||||||
|
height: 80px;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
border-radius: 15px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arm-left {
|
||||||
|
left: -15px;
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arm-right {
|
||||||
|
right: -15px;
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyboard {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 200px;
|
||||||
|
height: 20px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating elements */
|
||||||
|
.floating-notes {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 2rem;
|
||||||
|
opacity: 0.6;
|
||||||
|
animation: float 6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note:nth-child(1) { left: 10%; top: 20%; animation-delay: 0s; }
|
||||||
|
.note:nth-child(2) { right: 15%; top: 30%; animation-delay: 1s; }
|
||||||
|
.note:nth-child(3) { left: 20%; bottom: 30%; animation-delay: 2s; }
|
||||||
|
.note:nth-child(4) { right: 20%; bottom: 25%; animation-delay: 3s; }
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translateY(0) rotate(0deg); }
|
||||||
|
50% { transform: translateY(-20px) rotate(10deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Decorative elements */
|
||||||
|
.grid-bg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-image: radial-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px);
|
||||||
|
background-size: 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glow-1 {
|
||||||
|
position: absolute;
|
||||||
|
top: 25%;
|
||||||
|
right: 25%;
|
||||||
|
width: 250px;
|
||||||
|
height: 250px;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(60px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.glow-2 {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 25%;
|
||||||
|
left: 25%;
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
border-radius: 50%;
|
||||||
|
filter: blur(80px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right Section */
|
||||||
|
.right-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 40px 20px;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
color: #62D2A1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.mobile-logo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-header h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1a1a1a;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
letter-spacing: -0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-header p {
|
||||||
|
color: #666;
|
||||||
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-msg {
|
.error-msg {
|
||||||
color: #ff0000;
|
background: #fee2e2;
|
||||||
font-size: 0.95rem;
|
color: #dc2626;
|
||||||
margin-bottom: 10px;
|
padding: 12px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input {
|
||||||
|
width: 100%;
|
||||||
|
height: 52px;
|
||||||
|
padding: 0 16px;
|
||||||
|
font-size: 1rem;
|
||||||
|
border: 1.5px solid #e5e5e5;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: white;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:focus {
|
||||||
|
border-color: #62D2A1;
|
||||||
|
box-shadow: 0 0 0 3px rgba(98, 210, 161, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input::placeholder {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-toggle {
|
||||||
|
position: absolute;
|
||||||
|
right: 16px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #888;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
padding: 4px;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.password-toggle:hover {
|
||||||
|
color: #62D2A1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 52px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: linear-gradient(135deg, #62D2A1 0%, #45a049 100%);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 4px 15px rgba(98, 210, 161, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 20px rgba(98, 210, 161, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background: white;
|
||||||
|
color: #62D2A1;
|
||||||
|
border: 2px solid #62D2A1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background: rgba(98, 210, 161, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 24px 0;
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider::before,
|
||||||
|
.divider::after {
|
||||||
|
content: '';
|
||||||
|
flex: 1;
|
||||||
|
height: 1px;
|
||||||
|
background: #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider span {
|
||||||
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
font-size: 0.9rem;
|
|
||||||
color: #666;
|
|
||||||
margin-top: 10px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
margin-top: 24px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips a {
|
||||||
|
color: #62D2A1;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading::after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-top-color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 8px;
|
||||||
|
animation: spin 0.8s linear infinite;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>登录BAOGUTANG-MUSIC</h1>
|
<!-- Left Section -->
|
||||||
<div class="error-msg" id="error-msg" style="display:none;"></div>
|
<div class="left-section">
|
||||||
<div class="form-group">
|
<div class="grid-bg"></div>
|
||||||
<label>用户名</label>
|
<div class="glow-1"></div>
|
||||||
<input type="text" id="username" placeholder="请输入用户名 (字母数字组合)"/>
|
<div class="glow-2"></div>
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="logo">
|
||||||
<label>密码</label>
|
<div class="logo-icon">🎵</div>
|
||||||
<input type="password" id="password" placeholder="请输入密码 (字母数字组合)"/>
|
<span>BAOGUTANG-MUSIC</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="animation-container">
|
||||||
|
<div class="floating-notes">
|
||||||
|
<div class="note">♪</div>
|
||||||
|
<div class="note">♫</div>
|
||||||
|
<div class="note">♬</div>
|
||||||
|
<div class="note">♩</div>
|
||||||
|
</div>
|
||||||
|
<div class="character" id="character">
|
||||||
|
<div class="character-main">
|
||||||
|
<div class="character-face">
|
||||||
|
<div class="character-eyes">
|
||||||
|
<div class="eye"></div>
|
||||||
|
<div class="eye"></div>
|
||||||
|
</div>
|
||||||
|
<div class="character-mouth"></div>
|
||||||
|
</div>
|
||||||
|
<div class="character-arms">
|
||||||
|
<div class="arm arm-left"></div>
|
||||||
|
<div class="arm arm-right"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="keyboard"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="login-btn" id="login-btn">登录</button>
|
<!-- Right Section -->
|
||||||
<button class="register-btn" id="register-btn">注册</button>
|
<div class="right-section">
|
||||||
|
<div class="form-container">
|
||||||
|
<div class="mobile-logo">
|
||||||
|
<div class="logo-icon">🎵</div>
|
||||||
|
<span>BAOGUTANG-MUSIC</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="tips">没有账号?请点击注册按钮进行注册。</div>
|
<div class="form-header">
|
||||||
|
<h1>欢迎回来!</h1>
|
||||||
|
<p>请输入您的登录信息</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="error-msg" id="error-msg"></div>
|
||||||
|
|
||||||
|
<form id="login-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">用户名</label>
|
||||||
|
<input type="text" id="username" placeholder="请输入用户名 (字母数字组合)" autocomplete="off"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">密码</label>
|
||||||
|
<div class="input-wrapper">
|
||||||
|
<input type="password" id="password" placeholder="请输入密码 (字母数字组合)"/>
|
||||||
|
<button type="button" class="password-toggle" id="toggle-password">👁️</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary" id="login-btn">登录</button>
|
||||||
|
<button type="button" class="btn btn-secondary" id="register-btn">注册新账号</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="divider"><span>或</span></div>
|
||||||
|
|
||||||
|
<div class="tips">
|
||||||
|
没有账号?<a href="#" id="register-link">点击注册</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 登录接口URL及注册接口URL稍后提供,这里先占位
|
// 接口配置
|
||||||
const loginUrl = '/api/v1/user/login'; // 后端登录接口地址(示例)
|
const loginUrl = '/api/v1/user/login';
|
||||||
const registerUrl = '/api/v1/user/register'; // 后端注册接口地址(示例)
|
const registerUrl = '/api/v1/user/register';
|
||||||
const musicPageUrl = '/music.html'; // 登录后跳转的音乐搜索下载页面地址
|
const musicPageUrl = '/music.html';
|
||||||
|
|
||||||
|
// DOM 元素
|
||||||
const usernameInput = document.getElementById('username');
|
const usernameInput = document.getElementById('username');
|
||||||
const passwordInput = document.getElementById('password');
|
const passwordInput = document.getElementById('password');
|
||||||
|
const loginForm = document.getElementById('login-form');
|
||||||
const loginBtn = document.getElementById('login-btn');
|
const loginBtn = document.getElementById('login-btn');
|
||||||
const registerBtn = document.getElementById('register-btn');
|
const registerBtn = document.getElementById('register-btn');
|
||||||
|
const registerLink = document.getElementById('register-link');
|
||||||
const errorMsg = document.getElementById('error-msg');
|
const errorMsg = document.getElementById('error-msg');
|
||||||
|
const togglePassword = document.getElementById('toggle-password');
|
||||||
|
const character = document.getElementById('character');
|
||||||
|
|
||||||
loginBtn.addEventListener('click', () => {
|
// 密码显示/隐藏
|
||||||
|
let showPassword = false;
|
||||||
|
togglePassword.addEventListener('click', () => {
|
||||||
|
showPassword = !showPassword;
|
||||||
|
passwordInput.type = showPassword ? 'text' : 'password';
|
||||||
|
togglePassword.textContent = showPassword ? '🙈' : '👁️';
|
||||||
|
updateCharacterState();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 眼睛跟随鼠标移动
|
||||||
|
document.addEventListener('mousemove', (e) => {
|
||||||
|
if (showPassword) return; // 闭眼时不跟随
|
||||||
|
|
||||||
|
const eyes = document.querySelectorAll('.eye');
|
||||||
|
eyes.forEach(eye => {
|
||||||
|
const rect = eye.getBoundingClientRect();
|
||||||
|
const eyeCenterX = rect.left + rect.width / 2;
|
||||||
|
const eyeCenterY = rect.top + rect.height / 2;
|
||||||
|
|
||||||
|
const angle = Math.atan2(e.clientY - eyeCenterY, e.clientX - eyeCenterX);
|
||||||
|
const distance = 8; // 眼珠移动距离
|
||||||
|
|
||||||
|
const moveX = Math.cos(angle) * distance;
|
||||||
|
const moveY = Math.sin(angle) * distance;
|
||||||
|
|
||||||
|
eye.style.setProperty('--eye-move-x', moveX + 'px');
|
||||||
|
eye.style.setProperty('--eye-move-y', moveY + 'px');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 输入框焦点状态 - 不再需要闭眼
|
||||||
|
// function updateCharacterState() 仅用于密码显示状态
|
||||||
|
|
||||||
|
function updateCharacterState() {
|
||||||
|
character.classList.remove('typing', 'password-visible');
|
||||||
|
if (showPassword) {
|
||||||
|
character.classList.add('password-visible');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单提交 - 登录
|
||||||
|
loginForm.addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
if (!validateInputs()) return;
|
if (!validateInputs()) return;
|
||||||
const username = usernameInput.value.trim();
|
const username = usernameInput.value.trim();
|
||||||
const password = passwordInput.value.trim();
|
const password = passwordInput.value.trim();
|
||||||
doLogin(username, password);
|
doLogin(username, password);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 注册按钮
|
||||||
registerBtn.addEventListener('click', () => {
|
registerBtn.addEventListener('click', () => {
|
||||||
if (!validateInputs()) return;
|
if (!validateInputs()) return;
|
||||||
const username = usernameInput.value.trim();
|
const username = usernameInput.value.trim();
|
||||||
@ -127,11 +627,17 @@
|
|||||||
doRegister(username, password);
|
doRegister(username, password);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 注册链接
|
||||||
|
registerLink.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
registerBtn.click();
|
||||||
|
});
|
||||||
|
|
||||||
function validateInputs() {
|
function validateInputs() {
|
||||||
errorMsg.style.display = 'none';
|
hideError();
|
||||||
const username = usernameInput.value.trim();
|
const username = usernameInput.value.trim();
|
||||||
const password = passwordInput.value.trim();
|
const password = passwordInput.value.trim();
|
||||||
const reg = /^[A-Za-z0-9]+$/; // 用户名和密码必须是字母和数字组合
|
const reg = /^[A-Za-z0-9]+$/;
|
||||||
|
|
||||||
if (!username || !password) {
|
if (!username || !password) {
|
||||||
showError("用户名和密码不能为空");
|
showError("用户名和密码不能为空");
|
||||||
@ -167,6 +673,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doLogin(username, password) {
|
function doLogin(username, password) {
|
||||||
|
loginBtn.classList.add('loading');
|
||||||
|
loginBtn.disabled = true;
|
||||||
|
|
||||||
fetch(loginUrl, {
|
fetch(loginUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -178,30 +687,30 @@
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
console.log('登录响应:', data);
|
console.log('登录响应:', data);
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
// 登陆成功,data.data中有token和用户名
|
|
||||||
const token = data.data.token;
|
const token = data.data.token;
|
||||||
const name = data.data.username;
|
const name = data.data.username;
|
||||||
setCookie('token', token, 1); // 有效期1天,可自行调整
|
setCookie('token', token, 1);
|
||||||
setCookie('username', name, 1);
|
setCookie('username', name, 1);
|
||||||
// 跳转到音乐搜索下载页面
|
|
||||||
window.location.href = musicPageUrl;
|
window.location.href = musicPageUrl;
|
||||||
} else {
|
} else {
|
||||||
// 登录失败
|
showError(data.msg || "登录失败,请重试");
|
||||||
if (data.code === -200) {
|
|
||||||
showError(data.msg || "登录失败,请重试");
|
|
||||||
} else {
|
|
||||||
showError(data.msg || "登录失败,请重试");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error('登录接口调用错误', err);
|
console.error('登录接口调用错误', err);
|
||||||
showError("登录接口调用失败,请稍后重试");
|
showError("登录接口调用失败,请稍后重试");
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loginBtn.classList.remove('loading');
|
||||||
|
loginBtn.disabled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doRegister(username, password) {
|
function doRegister(username, password) {
|
||||||
fetch('/api/v1/user/register', {
|
registerBtn.classList.add('loading');
|
||||||
|
registerBtn.disabled = true;
|
||||||
|
|
||||||
|
fetch(registerUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -211,7 +720,6 @@
|
|||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
// 注册成功,刷新当前页面等待用户登录
|
|
||||||
alert("注册成功,请使用新账号登录");
|
alert("注册成功,请使用新账号登录");
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
} else {
|
} else {
|
||||||
@ -221,6 +729,10 @@
|
|||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error('注册接口调用错误', err);
|
console.error('注册接口调用错误', err);
|
||||||
showError("注册接口调用失败,请稍后重试");
|
showError("注册接口调用失败,请稍后重试");
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
registerBtn.classList.remove('loading');
|
||||||
|
registerBtn.disabled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,6 +741,10 @@
|
|||||||
errorMsg.style.display = 'block';
|
errorMsg.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hideError() {
|
||||||
|
errorMsg.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
function setCookie(name, value, days) {
|
function setCookie(name, value, days) {
|
||||||
const d = new Date();
|
const d = new Date();
|
||||||
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user