pangu-user-platform/pangu-ui/src/views/login/index.vue

218 lines
4.7 KiB
Vue
Raw Normal View History

<template>
<div class="login-container">
<div class="login-card">
<!-- 标题 -->
<div class="login-header">
<h2>盘古用户平台</h2>
<p>统一用户管理系统</p>
</div>
<!-- 登录表单 -->
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form">
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
placeholder="请输入用户名"
:prefix-icon="User"
size="large"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
placeholder="请输入密码"
:prefix-icon="Lock"
size="large"
show-password
@keyup.enter="handleLogin"
/>
</el-form-item>
<el-form-item prop="code">
<div class="captcha-row">
<el-input
v-model="loginForm.code"
placeholder="请输入验证码"
:prefix-icon="Picture"
size="large"
style="flex: 1"
@keyup.enter="handleLogin"
/>
<img
:src="captchaImg"
class="captcha-img"
@click="getCaptcha"
title="点击刷新验证码"
/>
</div>
</el-form-item>
<el-form-item>
<el-checkbox v-model="loginForm.rememberMe">记住密码</el-checkbox>
</el-form-item>
<el-form-item>
<el-button
type="primary"
size="large"
style="width: 100%"
:loading="loading"
@click="handleLogin"
>
登录
</el-button>
</el-form-item>
</el-form>
<!-- 提示 -->
<div class="login-tip">
默认账号: admin / admin123
</div>
</div>
</div>
</template>
<script setup>
/**
* 登录页面占位Agent-2会完善
* @author pangu
*/
import { useUserStore } from '@/store/user'
import request from '@/utils/request'
import { Lock, Picture, User } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const userStore = useUserStore()
const loginFormRef = ref()
const loading = ref(false)
const captchaImg = ref('')
const uuid = ref('')
const loginForm = ref({
username: 'admin',
password: 'admin123',
code: '',
rememberMe: false
})
const loginRules = {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
}
// 获取验证码
const getCaptcha = async () => {
try {
const res = await request.get('/api/captchaImage')
if (res.code === 200) {
captchaImg.value = res.img
uuid.value = res.uuid
}
} catch (error) {
console.error('获取验证码失败:', error)
}
}
// 登录
const handleLogin = () => {
loginFormRef.value?.validate(async (valid) => {
if (!valid) return
loading.value = true
try {
const res = await request.post('/api/login', {
username: loginForm.value.username,
password: loginForm.value.password,
code: loginForm.value.code,
uuid: uuid.value
})
if (res.code === 200) {
userStore.setToken(res.token)
ElMessage.success('登录成功')
router.push('/')
}
} catch (error) {
// 登录失败刷新验证码
getCaptcha()
} finally {
loading.value = false
}
})
}
onMounted(() => {
getCaptcha()
})
</script>
<style scoped>
.login-container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
}
.login-card {
width: 100%;
max-width: 400px;
padding: 40px;
background: #fff;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.login-header {
text-align: center;
margin-bottom: 32px;
}
.login-header h2 {
margin: 0;
font-size: 28px;
color: #303133;
}
.login-header p {
margin: 8px 0 0;
font-size: 14px;
color: #909399;
}
.login-form {
margin-top: 20px;
}
.captcha-row {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
}
.captcha-img {
width: 100px;
height: 40px;
cursor: pointer;
border: 1px solid #dcdfe6;
border-radius: 4px;
}
.login-tip {
text-align: center;
font-size: 12px;
color: #909399;
margin-top: 16px;
}
</style>