Files
ndm-web-platform/src/pages/login/login-page.vue
2026-01-13 13:27:25 +08:00

115 lines
3.1 KiB
Vue

<script setup lang="ts">
import { userClient, type LoginParams } from '@/apis';
import { ThemeSwitch } from '@/components';
import { useUserStore } from '@/stores';
import { parseErrorFeedback, randomNum } from '@/utils';
import { useMutation } from '@tanstack/vue-query';
import { NButton, NCard, NFlex, NForm, NFormItem, NInput, NLayout } from 'naive-ui';
import { reactive } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const loginParams = reactive<LoginParams>({
username: '',
password: '',
code: '',
key: randomNum(24, 16),
grantType: 'PASSWORD',
});
const { mutate: login, isPending: loading } = useMutation({
mutationFn: async (params: LoginParams) => {
const userStore = useUserStore();
await userStore.userLogin(params);
const [err] = await userClient.post<void>(`/api/ndm/ndmKeepAlive/verify`, {}, { timeout: 5000 });
if (err) throw err;
},
onSuccess: () => {
window.$message.success('登录成功');
router.push({ path: '/' });
},
onError: (error) => {
console.error(error);
const errorFeedback = parseErrorFeedback(error);
window.$dialog.destroyAll();
window.$dialog.error({
closable: false,
maskClosable: false,
title: '错误提示',
content: errorFeedback,
positiveText: '确认',
onPositiveClick: () => {
window.$message.destroyAll();
},
});
},
});
</script>
<template>
<NLayout class="login-page" position="absolute">
<div class="login-card-wrapper" @keyup.enter="() => login(loginParams)">
<NCard class="login-card">
<ThemeSwitch class="theme-switch" />
<NFlex vertical justify="center" align="center">
<span class="platform-title">网络设备管理平台</span>
<span class="login-title">登录</span>
<NForm class="login-form" :model="loginParams" label-placement="top">
<NFormItem label="用户名" path="username">
<NInput v-model:value="loginParams.username" placeholder="请输入用户名" />
</NFormItem>
<NFormItem label="密码" path="password">
<NInput v-model:value="loginParams.password" type="password" show-password-on="click" placeholder="请输入密码" />
</NFormItem>
</NForm>
<NButton type="primary" block strong :loading="loading" @click="() => login(loginParams)">登录</NButton>
</NFlex>
</NCard>
</div>
</NLayout>
</template>
<style scoped lang="scss">
.login-page {
.login-card-wrapper {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.login-card {
width: 400px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 32px;
position: relative;
}
.theme-switch {
position: absolute;
bottom: 16px;
right: 16px;
}
.platform-title {
font-size: 28px;
font-weight: 500;
margin-bottom: 8px;
}
.login-title {
font-size: 16px;
color: #999;
margin-bottom: 24px;
}
.login-form {
width: 100%;
margin-bottom: 16px;
}
}
</style>