<template>
|
<div class="login-container">
|
<el-card class="login-card">
|
<h2>交通统计报表审核系统</h2>
|
<el-form ref="form" :model="form" :rules="rules">
|
<el-form-item prop="username">
|
<el-input v-model="form.username" placeholder="用户名" @keyup.enter.native="login"></el-input>
|
</el-form-item>
|
<el-form-item prop="password">
|
<el-input v-model="form.password" type="password" placeholder="密码" @keyup.enter.native="login"></el-input>
|
</el-form-item>
|
<el-form-item>
|
<div class="captcha-wrap" v-loading="captchaLoading">
|
<shape-captcha v-if="captcha.shapes.length"
|
:shapes="captcha.shapes"
|
:instruction="captcha.instruction"
|
@complete="onCaptchaComplete"
|
@refresh="loadCaptcha"
|
@reset="onCaptchaReset"></shape-captcha>
|
<div v-else class="captcha-empty">正在加载验证码…</div>
|
</div>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="login" :loading="loading" style="width:100%">登 录</el-button>
|
</el-form-item>
|
</el-form>
|
</el-card>
|
</div>
|
</template>
|
<script>
|
import api from '@/api'
|
import ShapeCaptcha from '@/components/ShapeCaptcha.vue'
|
export default {
|
name: 'Login',
|
components: { ShapeCaptcha },
|
data() {
|
return {
|
form: { username: '', password: '' },
|
loading: false,
|
captchaLoading: false,
|
captcha: { captchaId: '', shapes: [], instruction: '' },
|
seq: [],
|
rules: {
|
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
}
|
}
|
},
|
created() { this.loadCaptcha() },
|
methods: {
|
loadCaptcha() {
|
this.captchaLoading = true
|
this.seq = []
|
this.captcha = { captchaId: '', shapes: [], instruction: '' }
|
api.get('/captcha/shape')
|
.then(res => {
|
const d = res && res.data
|
if (!d || !d.captchaId) { this.$message.error((res && res.message) || '验证码加载失败'); return }
|
this.captcha = d
|
})
|
.catch(err => {
|
const d = err && err.response && err.response.data
|
this.$message.error((d && d.message) || '验证码加载失败,请稍后重试')
|
})
|
.finally(() => { this.captchaLoading = false })
|
},
|
onCaptchaComplete(sequence) { this.seq = sequence || [] },
|
onCaptchaReset() { this.seq = [] },
|
login() {
|
this.$refs.form.validate(valid => {
|
if (!valid) return
|
if (!this.captcha.captchaId) { this.$message.warning('验证码加载中,请稍候'); return }
|
if (!this.seq || this.seq.length < this.captcha.total) {
|
this.$message.warning('请先按提示顺序点击验证码图形')
|
return
|
}
|
this.loading = true
|
api.post('/captcha/verify', { captchaId: this.captcha.captchaId, sequence: this.seq })
|
.then(res => {
|
if (!res || res.code !== 200) {
|
this.$message.error((res && res.message) || '验证码校验失败')
|
this.loadCaptcha()
|
return
|
}
|
return api.post('/auth/login', this.form)
|
})
|
.then(res => {
|
if (!res) return
|
const d = res.data
|
if (!d || !d.token) { this.$message.error((res && res.message) || '登录失败'); return }
|
localStorage.setItem('token', d.token)
|
localStorage.setItem('username', d.username || '')
|
localStorage.setItem('realName', d.realName || '')
|
localStorage.setItem('modules', d.modules || '')
|
this.$message.success('欢迎,' + (d.realName || d.username))
|
this.$router.push('/dashboard')
|
})
|
.catch(err => {
|
const d = err && err.response && err.response.data
|
this.$message.error((d && d.message) || '登录失败:请检查用户名或密码')
|
this.loadCaptcha()
|
})
|
.finally(() => { this.loading = false })
|
})
|
}
|
}
|
}
|
</script>
|
<style scoped>
|
.login-container { display: flex; justify-content: center; align-items: center; height: 100vh; background: #f0f2f5; }
|
.login-card { width: 420px; }
|
.login-card h2 { text-align: center; margin-bottom: 20px; }
|
.captcha-wrap { min-height: 168px; }
|
.captcha-empty { display: flex; justify-content: center; align-items: center; height: 168px; color: #909399; font-size: 13px; }
|
</style>
|