Files
RCZN-bs-program/rc_autoplc_front/src/views/Login.vue
2026-01-19 16:15:02 +08:00

318 lines
7.8 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.
<template>
<div class="login-container">
<div class="login-box">
<div class="login-header">
<h2>北京融创智能仪器管理系统</h2>
<p>用户登录</p>
</div>
<el-form
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
class="login-form"
label-width="0"
@keyup.enter="handleLogin"
>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
placeholder="请输入用户名2-16位的字母、数字、下划线或减号"
size="large"
:prefix-icon="User"
clearable
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
placeholder="请输入密码"
size="large"
:prefix-icon="Lock"
show-password
clearable
@keyup.enter="handleLogin"
/>
</el-form-item>
<el-form-item>
<div class="button-row">
<el-button
type="primary"
size="large"
class="login-button"
:loading="loginLoading"
@click="handleLogin"
>
登录
</el-button>
<el-button
size="large"
class="register-button"
@click="showRegisterDialog = true"
>
注册
</el-button>
</div>
</el-form-item>
</el-form>
</div>
<!-- 注册弹窗 -->
<el-dialog
v-model="showRegisterDialog"
title="用户注册"
width="500px"
:close-on-click-modal="false"
>
<el-form
ref="registerFormRef"
:model="registerForm"
:rules="registerRules"
label-width="100px"
>
<el-form-item label="用户名" prop="username">
<el-input
v-model="registerForm.username"
placeholder="2-16位的字母、数字、下划线或减号"
clearable
/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="registerForm.password"
type="password"
placeholder="请输入密码"
show-password
clearable
/>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input
v-model="registerForm.confirmPassword"
type="password"
placeholder="请再次输入密码"
show-password
clearable
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showRegisterDialog = false">取消</el-button>
<el-button
type="primary"
:loading="registerLoading"
@click="handleRegister"
>
注册
</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import { User, Lock } from '@element-plus/icons-vue'
import { userlogin, userregister } from '@/api/system/user'
import { useAuthStore } from '@/stores/auth'
const router = useRouter()
const authStore = useAuthStore()
// 登录表单
const loginFormRef = ref<FormInstance>()
const loginForm = reactive({
username: '',
password: '',
})
const loginLoading = ref(false)
// 注册表单
const registerFormRef = ref<FormInstance>()
const registerForm = reactive({
username: '',
password: '',
confirmPassword: '',
})
const registerLoading = ref(false)
const showRegisterDialog = ref(false)
// 登录表单验证规则
const loginRules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9_-]{2,16}$/,
message: '用户名必须是2-16位的字母、数字、下划线或减号',
trigger: 'blur',
},
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
],
}
// 注册表单验证规则
const validateConfirmPassword = (rule: any, value: string, callback: Function) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== registerForm.password) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
const registerRules: FormRules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9_-]{2,16}$/,
message: '用户名必须是2-16位的字母、数字、下划线或减号',
trigger: 'blur',
},
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
],
confirmPassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ validator: validateConfirmPassword, trigger: 'blur' },
],
}
// 处理登录
const handleLogin = async () => {
if (!loginFormRef.value) return
await loginFormRef.value.validate(async (valid) => {
if (valid) {
loginLoading.value = true
try {
const response: any = await userlogin(loginForm.username, loginForm.password)
// 根据图片返回的data字段直接是token字符串
if (response.code === 0 && response.data) {
const token = response.data
// 存储token
authStore.setToken(token)
// 存储用户名
localStorage.setItem('username', loginForm.username)
ElMessage.success('登录成功')
// 跳转到首页
router.push('/')
}
} catch (error: any) {
// 错误提示已在全局响应拦截中处理,这里不重复弹出
console.warn('login error:', error)
} finally {
loginLoading.value = false
}
}
})
}
// 处理注册
const handleRegister = async () => {
if (!registerFormRef.value) return
await registerFormRef.value.validate(async (valid) => {
if (valid) {
registerLoading.value = true
try {
const response: any = await userregister(registerForm.username, registerForm.password)
if (response.code === 0) {
ElMessage.success('注册成功,请登录')
// 关闭注册弹窗
showRegisterDialog.value = false
// 清空注册表单
if (registerFormRef.value) {
registerFormRef.value.resetFields()
}
// 自动填充登录表单的用户名
loginForm.username = registerForm.username
} else {
ElMessage.error(response.message || '注册失败')
}
} catch (error: any) {
ElMessage.error(error.message || '注册失败')
} finally {
registerLoading.value = false
}
}
})
}
</script>
<style scoped>
.login-container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.login-box {
width: 450px;
padding: 40px;
background: #fff;
border-radius: 10px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
}
.login-header {
text-align: center;
margin-bottom: 30px;
}
.login-header h2 {
margin: 0 0 10px 0;
font-size: 24px;
color: #333;
font-weight: 500;
}
.login-header p {
margin: 0;
font-size: 14px;
color: #999;
}
.login-form {
margin-top: 30px;
}
.login-form :deep(.el-form-item) {
margin-bottom: 20px;
}
.button-row {
width: 100%;
display: flex;
gap: 12px;
}
.login-button,
.register-button {
flex: 1 1 0;
width: auto;
display: block;
}
.login-button {
margin: 0;
}
</style>