cyber/src/pages/Login.vue
Guarp 04b2ec88e7 [v0.1.1] 新增功能
- 新增管理员日志上传
2025-02-21 19:52:33 +08:00

318 lines
7.6 KiB
Vue

<template>
<div class="auth-page">
<div class="auth-card">
<div class="auth-tabs">
<button :class="{ active: mode === 'login' }" @click="mode = 'login'">登录</button>
<button :class="{ active: mode === 'register' }" @click="mode = 'register'">注册</button>
</div>
<transition name="fade" mode="out-in">
<div key="login" v-if="mode === 'login'" class="auth-form">
<form @submit.prevent="handleLogin">
<h2>欢迎回来</h2>
<div class="form-group">
<input type="text" placeholder="用户名" v-model="loginInfo.user"/>
</div>
<div class="form-group">
<input :type="viewPSWD?'text':'password'" placeholder="密码" v-model="loginInfo.password"/>
</div>
<button type="submit">登录</button>
</form>
</div>
<div key="register" v-else class="auth-form">
<form @submit.prevent="handleRegister">
<h2>创建新账号</h2>
<div class="form-group">
<input type="text" placeholder="用户名" v-model="loginInfo.user"/>
</div>
<div class="form-group">
<input type="email" placeholder="邮箱" v-model="loginInfo.email"/>
</div>
<div class="form-group">
<input type="password" placeholder="密码" v-model="loginInfo.password"/>
</div>
<button type="submit">注册</button>
</form>
</div>
</transition>
</div>
</div>
</template>
<script setup>
import {ref} from 'vue'
import swal from "../utils/sweetalert.js";
import store from "../store/index.js";
import router from "../router/index.js";
import AuthService from "../../services/auth.js";
const mode = ref('login')
const viewPSWD = ref(false)
const loginInfo = ref({
user: '',
email: '',
password: ''
})
const handleLogin = async () => {
await (async function () {
if (
!(loginInfo.value.user && loginInfo.value.password)
) {
swal.tip('error', '用户名和密码不得为空!');
return;
}
store.commit('startLoading', "正在验证...");
const result = await AuthService.login(loginInfo.value.user, loginInfo.value.password);
if (result.code === 1) {
swal.tip('error', '用户名或密码错误!');
return;
}
if (result.code === 2) {
swal.tip('error', '服务端程序出错...');
return;
}
if (result.code === 3) {
swal.tip('error', '网络连接错误');
return;
}
store.commit('setToken', result.token);
store.commit('startLoading', '请稍后...');
await AuthService.setSelfInfo();
if (!store.state.token) {
swal.tip('error', '未知错误...');
return;
}
if (!store.state.userInfo.uid) {
swal.tip('info', '登录成功, 加载用户信息失败');
return;
}
store.commit('stopLoading');
swal.tip('success', '登录成功! 即将跳转');
loginInfo.value.isFinish = true;
setTimeout(() => {
if (router.currentRoute.value.path === '/login') {
router.push('/');
}
}, 2000);
}
)
();
store.commit('stopLoading');
}
const handleRegister = async () => {
if (!(loginInfo.value.user && loginInfo.value.password && loginInfo.value.email)) {
swal.tip('error', '用户名、邮箱及密码不得为空!');
store.commit('stopLoading');
return;
}
if (!(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(loginInfo.value.email))) {
swal.tip('error', '邮箱格式不正确');
store.commit('stopLoading');
return;
}
store.commit('startLoading', "请稍后...");
try {
const message = await AuthService.sendMessage(loginInfo.value.user, loginInfo.value.email, loginInfo.value.password);
if (message.code !== 0) {
swal.tip('error', '注册失败(已存在此用户)');
store.commit('stopLoading');
return;
}
} catch (e) {
console.warn(e);
swal.tip('error', '服务器连接错误...');
store.commit('stopLoading');
return;
}
store.commit('stopLoading');
swal.window('info', '邮箱验证链接发送成功!', '请前往邮箱查看', '好的', 'ok');
}
</script>
<style scoped>
/* =======================================
全局变量
========================================== */
:global(:root) {
--bg-color: #000;
--accent-color: #005757;
--text-color: #fff;
--card-bg: rgba(0, 0, 0, 0.8);
--input-bg: #222;
--input-text: #fff;
--border-color: #00ffff;
}
:global(.theme-light) {
--bg-color: #fff;
--accent-color: #eea2a2;
--text-color: #2f2f2f;
--card-bg: #f9f9f9;
--input-bg: #fff;
--input-text: #2f2f2f;
--border-color: #2f2f2f;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
/* =======================================
整体页面布局
========================================== */
.auth-page {
min-height: calc(100vh - 60px);
margin-top: 60px;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
background: linear-gradient(45deg, var(--bg-color), var(--accent-color));
background-size: 400% 400%;
animation: gradientAnimation 15s ease infinite, bgDisplay 0.5s forwards;
padding: 1rem;
}
@keyframes bgDisplay {
to {
opacity: 1;
}
}
@keyframes gradientAnimation {
0% {
background-position: 0 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}
/* =======================================
表单卡片
========================================== */
.auth-card {
background: var(--card-bg);
padding: 2rem;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
width: 320px;
text-align: center;
height: 400px;
transform: translateY(20px);
opacity: 0;
animation: cardFadeIn 0.5s forwards;
}
@keyframes cardFadeIn {
to {
transform: translateY(0);
opacity: 1;
}
}
/* =======================================
登册切换
========================================== */
.auth-tabs {
display: flex;
justify-content: center;
margin-bottom: 1rem;
}
.auth-tabs button {
flex: 1;
background: transparent;
border: none;
padding: 0.5rem;
cursor: pointer;
font-size: 1.1rem;
color: var(--text-color);
border-bottom: 2px solid transparent;
transition: border-color 0.3s;
}
.auth-tabs button.active {
border-color: var(--accent-color);
font-weight: bold;
}
/* =======================================
表单
========================================== */
.auth-form h2 {
margin-bottom: 1rem;
color: var(--text-color);
}
.form-group {
margin-bottom: 1rem;
text-align: left;
}
.form-group input {
width: 100%;
padding: 0.75rem;
border: 1px solid var(--border-color);
border-radius: 5px;
background: var(--input-bg);
color: var(--input-text);
transition: border-color 0.3s, box-shadow 0.3s;
}
.form-group input:focus {
outline: none;
border-color: var(--accent-color);
box-shadow: 0 0 5px var(--accent-color);
}
.auth-form button {
width: 100%;
padding: 0.75rem;
border: none;
border-radius: 5px;
background: var(--accent-color);
color: var(--bg-color);
font-size: 1rem;
cursor: pointer;
transition: background 0.3s, transform 0.2s;
}
.auth-form button:hover {
filter: brightness(0.9);
}
.auth-form button:active {
transform: scale(0.980);
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
}
</style>