web/src/views/LoginView.vue
2025-05-06 16:37:57 +08:00

183 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { authApi } from '@/services/api'
const router = useRouter()
const email = ref('')
const password = ref('')
const loading = ref(false)
const error = ref('')
const handleLogin = async () => {
if (!email.value || !password.value) {
error.value = '请填写邮箱和密码'
return
}
try {
loading.value = true
error.value = ''
await authApi.login({
mail: email.value,
password: password.value,
})
// 登录成功,跳转到首页
router.push('/')
} catch (err) {
error.value = err instanceof Error ? err.message : '登录失败,请重试'
console.error('登录失败:', err)
} finally {
loading.value = false
}
}
</script>
<template>
<div class="login-view">
<div class="auth-container">
<h1 class="auth-title">登录</h1>
<form @submit.prevent="handleLogin" class="auth-form">
<div class="form-group">
<label for="email">邮箱</label>
<input
type="email"
id="email"
v-model="email"
placeholder="请输入邮箱"
required
autocomplete="email"
/>
</div>
<div class="form-group">
<label for="password">密码</label>
<input
type="password"
id="password"
v-model="password"
placeholder="请输入密码"
required
autocomplete="current-password"
/>
</div>
<div v-if="error" class="error-message">{{ error }}</div>
<button type="submit" class="auth-button" :disabled="loading">
{{ loading ? '登录中...' : '登录' }}
</button>
</form>
<div class="auth-links">
<router-link to="/register">没有账号立即注册</router-link>
</div>
</div>
</div>
</template>
<style scoped>
.login-view {
display: flex;
justify-content: center;
align-items: center;
min-height: calc(100vh - var(--header-height) - 100px);
padding: 2rem 1rem;
}
.auth-container {
width: 100%;
max-width: 400px;
background-color: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
padding: 2rem;
}
.auth-title {
font-size: 1.8rem;
font-weight: 700;
margin-bottom: 1.5rem;
text-align: center;
}
.auth-form {
display: flex;
flex-direction: column;
gap: 1.2rem;
}
.form-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.form-group label {
font-size: 0.9rem;
color: var(--color-text-secondary);
}
.form-group input {
padding: 0.8rem 1rem;
border-radius: var(--border-radius);
background-color: var(--color-bg-primary);
border: 1px solid var(--color-border);
color: var(--color-text-primary);
font-size: 1rem;
transition: all 0.2s ease;
}
.form-group input:focus {
outline: none;
border-color: #3355ff;
box-shadow: 0 0 0 2px rgba(51, 85, 255, 0.2);
}
.error-message {
color: #ff4d4d;
font-size: 0.9rem;
margin-top: 0.5rem;
}
.auth-button {
margin-top: 1rem;
padding: 0.8rem;
border-radius: var(--border-radius);
background-color: #3355ff;
color: white;
font-weight: 600;
border: none;
cursor: pointer;
transition: all 0.2s ease;
}
.auth-button:hover:not(:disabled) {
background-color: #2244ee;
}
.auth-button:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.auth-links {
margin-top: 1.5rem;
text-align: center;
}
.auth-links a {
color: #3355ff;
text-decoration: none;
font-size: 0.9rem;
}
.auth-links a:hover {
text-decoration: underline;
}
</style>