158 lines
3.5 KiB
Vue
158 lines
3.5 KiB
Vue
<script setup lang="ts">
|
||
import { ref, computed } from 'vue'
|
||
import { ElMessage } from 'element-plus'
|
||
import { User } from '@element-plus/icons-vue'
|
||
import { authApi } from '../../api/auth'
|
||
import { deviceApi } from '../../api/device'
|
||
|
||
interface Props {
|
||
modelValue: boolean
|
||
}
|
||
|
||
interface Emits {
|
||
(e: 'update:modelValue', value: boolean): void
|
||
(e: 'loginSuccess', data: { token: string; user: any }): void
|
||
(e: 'showRegister'): void
|
||
}
|
||
|
||
const props = defineProps<Props>()
|
||
const emit = defineEmits<Emits>()
|
||
|
||
const authForm = ref({ username: '', password: '' })
|
||
const authLoading = ref(false)
|
||
|
||
const visible = computed({
|
||
get: () => props.modelValue,
|
||
set: (value) => emit('update:modelValue', value)
|
||
})
|
||
|
||
async function handleAuth() {
|
||
if (!authForm.value.username || !authForm.value.password) return
|
||
|
||
authLoading.value = true
|
||
try {
|
||
await deviceApi.register({ username: authForm.value.username })
|
||
const loginRes: any = await authApi.login(authForm.value)
|
||
const data = loginRes?.data || loginRes
|
||
|
||
emit('loginSuccess', {
|
||
token: data.token,
|
||
user: {
|
||
username: data.username,
|
||
permissions: data.permissions
|
||
}
|
||
})
|
||
ElMessage.success('登录成功')
|
||
resetForm()
|
||
} catch (err) {
|
||
ElMessage.error((err as Error).message)
|
||
} finally {
|
||
authLoading.value = false
|
||
}
|
||
}
|
||
|
||
function cancelAuth() {
|
||
visible.value = false
|
||
resetForm()
|
||
}
|
||
|
||
function resetForm() {
|
||
authForm.value = { username: '', password: '' }
|
||
}
|
||
|
||
function showRegister() {
|
||
emit('showRegister')
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<el-dialog
|
||
title=""
|
||
v-model="visible"
|
||
:close-on-click-modal="false"
|
||
width="360px"
|
||
center
|
||
class="auth-dialog">
|
||
<div style="padding: 20px 0;">
|
||
<div style="text-align: center; margin-bottom: 16px; color: #666;">
|
||
<img src="/icon/image.png" alt="logo" class="auth-logo" />
|
||
</div>
|
||
<div class="auth-title-wrap">
|
||
<h3 class="auth-title">账号登录</h3>
|
||
<p class="auth-subtitle">登录账户以获取完整服务体验</p>
|
||
</div>
|
||
|
||
<el-input
|
||
v-model="authForm.username"
|
||
placeholder="请输入用户名"
|
||
size="large"
|
||
style="margin-bottom: 15px;"
|
||
:disabled="authLoading"
|
||
@keyup.enter="handleAuth">
|
||
</el-input>
|
||
|
||
<el-input
|
||
v-model="authForm.password"
|
||
placeholder="请输入密码"
|
||
type="password"
|
||
size="large"
|
||
style="margin-bottom: 20px;"
|
||
:disabled="authLoading"
|
||
@keyup.enter="handleAuth">
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button
|
||
type="primary"
|
||
size="large"
|
||
:loading="authLoading"
|
||
:disabled="!authForm.username || !authForm.password || authLoading"
|
||
@click="handleAuth"
|
||
style="width: 100%;">
|
||
登录
|
||
</el-button>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; text-align: center;">
|
||
<el-button type="text" @click="showRegister" :disabled="authLoading">
|
||
还没有账号?点击注册
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.auth-logo {
|
||
width: 160px;
|
||
height: auto;
|
||
}
|
||
|
||
.auth-dialog {
|
||
--el-color-primary: #1677FF;
|
||
}
|
||
|
||
.auth-dialog :deep(.el-button--primary) {
|
||
background-color: #1677FF;
|
||
border-color: #1677FF;
|
||
}
|
||
|
||
.auth-title-wrap {
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.auth-title {
|
||
margin: 0;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #1f1f1f;
|
||
text-align: left;
|
||
}
|
||
|
||
.auth-subtitle {
|
||
margin: 6px 0 0;
|
||
font-size: 12px;
|
||
color: #8c8c8c;
|
||
text-align: left;
|
||
}
|
||
</style> |