3 changed files with 221 additions and 0 deletions
@ -0,0 +1,76 @@ |
|||
@import url('../index.less'); |
|||
|
|||
/* Make clicks pass-through */ |
|||
#nprogress { |
|||
pointer-events: none; |
|||
} |
|||
|
|||
#nprogress .bar { |
|||
background: @primary-color; |
|||
|
|||
position: fixed; |
|||
z-index: 1031; |
|||
top: 0; |
|||
left: 0; |
|||
|
|||
width: 100%; |
|||
height: 2px; |
|||
} |
|||
|
|||
/* Fancy blur effect */ |
|||
#nprogress .peg { |
|||
display: block; |
|||
position: absolute; |
|||
right: 0px; |
|||
width: 100px; |
|||
height: 100%; |
|||
box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color; |
|||
opacity: 1.0; |
|||
|
|||
-webkit-transform: rotate(3deg) translate(0px, -4px); |
|||
-ms-transform: rotate(3deg) translate(0px, -4px); |
|||
transform: rotate(3deg) translate(0px, -4px); |
|||
} |
|||
|
|||
/* Remove these to get rid of the spinner */ |
|||
#nprogress .spinner { |
|||
display: block; |
|||
position: fixed; |
|||
z-index: 1031; |
|||
top: 15px; |
|||
right: 15px; |
|||
} |
|||
|
|||
#nprogress .spinner-icon { |
|||
width: 18px; |
|||
height: 18px; |
|||
box-sizing: border-box; |
|||
|
|||
border: solid 2px transparent; |
|||
border-top-color: @primary-color; |
|||
border-left-color: @primary-color; |
|||
border-radius: 50%; |
|||
|
|||
-webkit-animation: nprogress-spinner 400ms linear infinite; |
|||
animation: nprogress-spinner 400ms linear infinite; |
|||
} |
|||
|
|||
.nprogress-custom-parent { |
|||
overflow: hidden; |
|||
position: relative; |
|||
} |
|||
|
|||
.nprogress-custom-parent #nprogress .spinner, |
|||
.nprogress-custom-parent #nprogress .bar { |
|||
position: absolute; |
|||
} |
|||
|
|||
@-webkit-keyframes nprogress-spinner { |
|||
0% { -webkit-transform: rotate(0deg); } |
|||
100% { -webkit-transform: rotate(360deg); } |
|||
} |
|||
@keyframes nprogress-spinner { |
|||
0% { transform: rotate(0deg); } |
|||
100% { transform: rotate(360deg); } |
|||
} |
|||
|
|||
@ -0,0 +1,145 @@ |
|||
<template> |
|||
<div class="login-container"> |
|||
<div class="login-form"> |
|||
<h2>系统登录</h2> |
|||
<div class="form-group"> |
|||
<label for="username">用户名</label> |
|||
<input type="text" id="username" v-model="username" placeholder="请输入用户名" /> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="password">密码</label> |
|||
<input type="password" id="password" v-model="password" placeholder="请输入密码" /> |
|||
</div> |
|||
<button class="login-button" @click="handleLogin" :disabled="loading"> |
|||
{{ loading ? '登录中...' : '登录' }} |
|||
</button> |
|||
<div v-if="error" class="error-message">{{ error }}</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { login } from '@/api/scinfo' |
|||
import storage from 'store' |
|||
import router from '@/router' |
|||
|
|||
export default { |
|||
name: 'Login', |
|||
data() { |
|||
return { |
|||
username: '', |
|||
password: '', |
|||
loading: false, |
|||
error: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
async handleLogin() { |
|||
if (!this.username || !this.password) { |
|||
this.error = '请输入用户名和密码' |
|||
return |
|||
} |
|||
|
|||
this.loading = true |
|||
this.error = '' |
|||
|
|||
try { |
|||
// 调用登录API |
|||
const res = await login({ |
|||
username: this.username, |
|||
password: this.password |
|||
}) |
|||
|
|||
if (res && res.data && res.data.token) { |
|||
// 保存token到localStorage |
|||
storage.set('token', res.data.token) |
|||
// 跳转到首页 |
|||
router.push('/') |
|||
} else { |
|||
this.error = '登录失败,请检查用户名和密码' |
|||
} |
|||
} catch (err) { |
|||
console.error('Login error:', err) |
|||
this.error = '登录失败,请稍后重试' |
|||
} finally { |
|||
this.loading = false |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.login-container { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
height: 100vh; |
|||
background-color: #f5f5f5; |
|||
} |
|||
|
|||
.login-form { |
|||
background: white; |
|||
padding: 40px; |
|||
border-radius: 8px; |
|||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); |
|||
width: 350px; |
|||
} |
|||
|
|||
.login-form h2 { |
|||
text-align: center; |
|||
margin-bottom: 30px; |
|||
color: #333; |
|||
} |
|||
|
|||
.form-group { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.form-group label { |
|||
display: block; |
|||
margin-bottom: 8px; |
|||
color: #666; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.form-group input { |
|||
width: 100%; |
|||
padding: 10px; |
|||
border: 1px solid #ddd; |
|||
border-radius: 4px; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.form-group input:focus { |
|||
outline: none; |
|||
border-color: #42b983; |
|||
} |
|||
|
|||
.login-button { |
|||
width: 100%; |
|||
padding: 12px; |
|||
background-color: #42b983; |
|||
color: white; |
|||
border: none; |
|||
border-radius: 4px; |
|||
font-size: 16px; |
|||
cursor: pointer; |
|||
margin-bottom: 15px; |
|||
} |
|||
|
|||
.login-button:hover:not(:disabled) { |
|||
background-color: #359c6d; |
|||
} |
|||
|
|||
.login-button:disabled { |
|||
background-color: #ccc; |
|||
cursor: not-allowed; |
|||
} |
|||
|
|||
.error-message { |
|||
color: #ff4d4f; |
|||
font-size: 14px; |
|||
text-align: center; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue