| | |
| | | <template> |
| | | <template> |
| | | <div class="login-container"> |
| | | <el-card class="login-card"> |
| | | <h2>交通统计报表审核系统</h2> |
| | |
| | | <el-input v-model="form.password" type="password" placeholder="密码" @keyup.enter.native="login"></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="login" style="width:100%">登 录</el-button> |
| | | <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) { |
| | | this.$router.push('/dashboard') |
| | | 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: 400px; } |
| | | .login-card h2 { text-align: center; margin-bottom: 30px; } |
| | | </style> |
| | | .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> |