22 lines
1.9 KiB
Vue
22 lines
1.9 KiB
Vue
<template>
|
|
<main class="login-page">
|
|
<el-card class="login-card">
|
|
<template #header><div><p class="eyebrow">BELL</p><h1>登录预警中心</h1><p>使用 Bell 独立账户。Sense 账户不能登录此系统。</p></div></template>
|
|
<el-alert v-if="error" :title="error" type="error" show-icon :closable="false" />
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-position="top" @submit.prevent="submit">
|
|
<el-form-item label="用户名" prop="username"><el-input v-model.trim="form.username" autocomplete="username" autofocus /></el-form-item>
|
|
<el-form-item label="密码" prop="password"><el-input v-model="form.password" type="password" show-password autocomplete="current-password" @keyup.enter="submit" /></el-form-item>
|
|
<el-button type="primary" native-type="submit" :loading="loading" class="full-button">登录 Bell</el-button>
|
|
</el-form>
|
|
</el-card>
|
|
</main>
|
|
</template>
|
|
<script setup>
|
|
import { reactive, ref } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { useStore } from 'vuex'
|
|
const store=useStore();const route=useRoute();const router=useRouter();const formRef=ref();const loading=ref(false);const error=ref('');const form=reactive({username:'',password:''});const rules={username:[{required:true,message:'请输入用户名',trigger:'blur'}],password:[{required:true,message:'请输入密码',trigger:'blur'}]}
|
|
async function submit(){if(loading.value)return;try{await formRef.value.validate();loading.value=true;error.value='';await store.dispatch('identity/login',form);await router.replace(String(route.query.redirect||'/'))}catch(e){if(e?.error)error.value=e.error}finally{loading.value=false}}
|
|
</script>
|
|
<style scoped>.login-page{min-height:100vh;display:grid;place-items:center;padding:20px;background:#f3f4f7}.login-card{width:min(420px,100%)}h1{margin:0 0 8px}.full-button{width:100%;min-height:44px}</style>
|