seaislee1209 bc06725ed1
All checks were successful
Build and Deploy Backend / build-and-deploy (push) Successful in 1m22s
Build and Deploy Web / build-and-deploy (push) Successful in 51s
style: UI鍏ㄩ潰鍗囩骇涓洪涔﹂鏍?- 鐧藉簳钃濊壊涓昏壊璋?娓呯埥涓撲笟
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 15:07:54 +08:00

134 lines
3.6 KiB
Vue

<template>
<div class="login-page">
<div class="login-left">
<div class="brand">
<div class="brand-icon">A</div>
<h1>AirLabs Project</h1>
<p>内容组 · 项目管理系统</p>
</div>
<div class="brand-features">
<div class="feature"><span class="dot blue"></span>项目进度实时追踪</div>
<div class="feature"><span class="dot green"></span>成本自动核算分摊</div>
<div class="feature"><span class="dot orange"></span>损耗与效率分析</div>
</div>
</div>
<div class="login-right">
<div class="login-card">
<h2>登录</h2>
<p class="login-desc">使用你的账号登录系统</p>
<el-form :model="form" @submit.prevent="handleLogin" class="login-form">
<el-form-item>
<el-input v-model="form.username" placeholder="用户名" size="large" />
</el-form-item>
<el-form-item>
<el-input v-model="form.password" placeholder="密码" type="password" size="large" show-password />
</el-form-item>
<el-button type="primary" size="large" :loading="loading" @click="handleLogin" class="login-btn">
</el-button>
</el-form>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '../stores/auth'
import { ElMessage } from 'element-plus'
const router = useRouter()
const authStore = useAuthStore()
const loading = ref(false)
const form = reactive({ username: '', password: '' })
async function handleLogin() {
if (!form.username || !form.password) {
ElMessage.warning('请输入用户名和密码')
return
}
loading.value = true
try {
await authStore.login(form.username, form.password)
ElMessage.success(`欢迎回来,${authStore.user?.name || ''}`)
router.push('/')
} catch {
// 错误已在拦截器处理
} finally {
loading.value = false
}
}
</script>
<style scoped>
.login-page {
min-height: 100vh;
display: flex;
}
/* 左侧品牌区 */
.login-left {
flex: 1;
background: linear-gradient(135deg, #3370FF 0%, #2451B8 100%);
display: flex;
flex-direction: column;
justify-content: center;
padding: 80px;
color: #fff;
}
.brand { margin-bottom: 48px; }
.brand-icon {
width: 48px; height: 48px;
border-radius: 12px;
background: rgba(255,255,255,0.2);
display: flex; align-items: center; justify-content: center;
font-size: 22px; font-weight: 700;
margin-bottom: 24px;
backdrop-filter: blur(10px);
}
.brand h1 { font-size: 32px; font-weight: 700; margin-bottom: 8px; }
.brand p { font-size: 16px; opacity: 0.8; }
.brand-features { display: flex; flex-direction: column; gap: 16px; }
.feature {
display: flex; align-items: center; gap: 12px;
font-size: 15px; opacity: 0.9;
}
.dot {
width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.dot.blue { background: #7EB8FF; }
.dot.green { background: #7DECA2; }
.dot.orange { background: #FFB967; }
/* 右侧登录区 */
.login-right {
width: 480px;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-page);
}
.login-card {
width: 360px;
}
.login-card h2 {
font-size: 24px;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 8px;
}
.login-desc {
font-size: 14px;
color: var(--text-secondary);
margin-bottom: 32px;
}
.login-form .el-form-item { margin-bottom: 20px; }
.login-btn {
width: 100%;
height: 44px !important;
font-size: 15px !important;
border-radius: var(--radius-sm) !important;
}
</style>