django-vue-admin/web/src/views/system/login/page.vue

492 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="page-login">
<div class="page-login--layer page-login--layer-area">
<ul class="circles">
<li v-for="n in 10" :key="n"></li>
</ul>
</div>
<div class="page-login--layer page-login--layer-time" flex="main:center cross:center">{{ time }}</div>
<div class="page-login--layer">
<div class="page-login--content" flex="dir:top main:justify cross:stretch box:justify">
<div class="page-login--content-header">
<p class="page-login--content-header-motto">时间是一切财富中最宝贵的财富</p>
</div>
<div class="page-login--content-main" flex="dir:top main:center cross:center">
<!-- logo -->
<img class="page-login--logo" src="./image/dvadmin.png" />
<!-- form -->
<div class="page-login--form">
<el-card shadow="never">
<el-form
ref="loginForm"
label-position="top"
:rules="rules"
:model="formLogin"
size="default"
>
<el-form-item prop="username">
<el-input type="text" v-model="formLogin.username" placeholder="用户名">
<i slot="prepend" class="fa fa-user-circle-o"></i>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
v-model="formLogin.password"
show-password
placeholder="密码"
>
<i slot="prepend" class="fa fa-keyboard-o"></i>
</el-input>
</el-form-item>
<el-form-item prop="captcha" v-if="captchaVisible">
<el-input type="text" v-model="formLogin.captcha" placeholder="验证码">
<template slot="append">
<img class="login-code" :src="image_base" @click="getCaptcha" />
</template>
</el-input>
</el-form-item>
<el-button size="default" @click="submit" type="primary" class="button-login">登录</el-button>
</el-form>
</el-card>
<!-- <p class="page-login--options" flex="main:justify cross:center">
<span><d2-icon name="question-circle" /> 忘记密码</span>
<span>注册用户</span>
</p>-->
<!-- quick login -->
<el-button
class="page-login--quick"
size="default"
type="info"
v-if="$env === 'development'"
@click="dialogVisible = true"
>
快速选择用户限dev环境
</el-button>
</div>
</div>
<div class="page-login--content-footer">
<p class="page-login--content-footer-locales">
<a
v-for="language in $languages"
:key="language.value"
@click="onChangeLocale(language.value)"
>
{{ language.label }}
</a>
</p>
<p class="page-login--content-footer-copyright">
Copyright
<d2-icon name="copyright" />Copyright © 2018-2021 pro.django-vue-admin.com All Rights Reserved.
|
<a href="https://beian.miit.gov.cn" target="_blank">晋ICP备18005113号-3</a>
</p>
<p class="page-login--content-footer-options">
<a href="#">帮助</a>
<a href="#">隐私</a>
<a href="#">条款</a>
</p>
</div>
</div>
</div>
<el-dialog title="快速选择用户" :visible.sync="dialogVisible" width="400px">
<el-row :gutter="10" style="margin: -20px 0px -10px 0px">
<el-col v-for="(user, index) in users" :key="index" :span="8">
<div class="page-login--quick-user" @click="handleUserBtnClick(user)">
<d2-icon name="user-circle-o" />
<span>{{ user.name }}</span>
</div>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import dayjs from 'dayjs'
import { mapActions } from 'vuex'
import localeMixin from '@/locales/mixin.js'
import * as api from './api'
export default {
mixins: [localeMixin],
data () {
return {
timeInterval: null,
time: dayjs().format('HH:mm:ss'),
// 快速选择用户
dialogVisible: false,
captchaVisible: false,
users: [
{
name: '超管',
username: 'superadmin',
password: 'admin123456'
},
{
name: '管理员',
username: 'admin',
password: 'admin123456'
}
],
// 表单
formLogin: {
username: '',
password: '',
captcha: ''
},
// 表单校验
rules: {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur'
}
],
password: [
{
required: true,
message: '请输入密码',
trigger: 'blur'
}
],
captcha: [
{
required: true,
message: '请输入验证码',
trigger: 'blur'
}
]
},
captchaKey: null,
image_base: null
}
},
created () {
this.$store.dispatch('d2admin/db/databaseClear')
this.getCaptcha()
},
mounted () {
this.timeInterval = setInterval(() => {
this.refreshTime()
}, 1000)
},
beforeDestroy () {
clearInterval(this.timeInterval)
},
methods: {
...mapActions('d2admin/account', ['login']),
refreshTime () {
this.time = dayjs().format('HH:mm:ss')
},
/**
* @description 接收选择一个用户快速登录的事件
* @param {Object} user 用户信息
*/
handleUserBtnClick (user) {
this.formLogin.username = user.username
this.formLogin.password = user.password
this.dialogVisible = !this.dialogVisible
if (!this.captchaVisible) {
this.submit()
}
},
/**
* @description 提交表单
*/
// 提交登录信息
submit () {
const that = this
this.$refs.loginForm.validate((valid) => {
if (valid) {
// 登录
// 注意 这里的演示没有传验证码
// 具体需要传递的数据请自行修改代码
this.login({
username: that.formLogin.username,
password: that.$md5(that.formLogin.password),
captcha: that.formLogin.captcha,
captchaKey: that.captchaKey
})
.then(() => {
// 重定向对象不存在则返回顶层路径
this.$router.replace(this.$route.query.redirect || '/')
})
.catch(() => {
this.getCaptcha()
})
} else {
// 登录表单校验失败
this.$message.error('表单校验失败,请检查')
}
})
},
/**
* 获取验证码
*/
getCaptcha () {
api.getCaptchaStatus().then((ret) => {
this.captchaVisible = ret.data.status
if (this.captchaVisible) {
api.getCaptcha().then((ret) => {
this.formLogin.captcha = null
if (ret.data) {
this.captchaKey = ret.data.key
this.image_base = ret.data.image_base
}
})
}
})
}
}
}
</script>
<style lang="scss">
.page-login {
@extend %unable-select;
$backgroundColor: #f0f2f5;
// ---
background-color: $backgroundColor;
height: 100%;
position: relative;
// 层
.page-login--layer {
@extend %full;
overflow: auto;
}
.page-login--layer-area {
overflow: hidden;
}
// 时间
.page-login--layer-time {
font-size: 24em;
font-weight: bold;
color: rgba(0, 0, 0, 0.03);
overflow: hidden;
}
// 登陆页面控件的容器
.page-login--content {
height: 100%;
min-height: 500px;
}
// header
.page-login--content-header {
padding: 1em 0;
.page-login--content-header-motto {
margin: 0px;
padding: 0px;
color: $color-text-normal;
text-align: center;
font-size: 12px;
}
}
// main
.page-login--logo {
width: 240px;
margin-bottom: 2em;
margin-top: -2em;
}
// 登录表单
.page-login--form {
width: 280px;
// 卡片
.el-card {
margin-bottom: 15px;
}
// 登录按钮
.button-login {
width: 100%;
}
// 输入框左边的图表区域缩窄
.el-input-group__prepend {
padding: 0px 14px;
}
.login-code {
height: 40px - 2px;
display: block;
margin: 0px -20px;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
// 登陆选项
.page-login--options {
margin: 0px;
padding: 0px;
font-size: 14px;
color: $color-primary;
margin-bottom: 15px;
font-weight: bold;
}
.page-login--quick {
width: 100%;
}
}
// 快速选择用户面板
.page-login--quick-user {
@extend %flex-center-col;
padding: 10px 0px;
border-radius: 4px;
&:hover {
background-color: $color-bg;
i {
color: $color-text-normal;
}
span {
color: $color-text-normal;
}
}
i {
font-size: 36px;
color: $color-text-sub;
}
span {
font-size: 12px;
margin-top: 10px;
color: $color-text-sub;
}
}
// footer
.page-login--content-footer {
padding: 1em 0;
.page-login--content-footer-locales {
padding: 0px;
margin: 0px;
margin-bottom: 15px;
font-size: 12px;
line-height: 12px;
text-align: center;
color: $color-text-normal;
a {
color: $color-text-normal;
margin: 0 0.5em;
&:hover {
color: $color-text-main;
}
}
}
.page-login--content-footer-copyright {
padding: 0px;
margin: 0px;
font-size: 12px;
line-height: 12px;
text-align: center;
color: $color-text-normal;
a {
color: $color-text-normal;
}
}
.page-login--content-footer-options {
padding: 0px;
margin: 0px;
margin-bottom: 10px;
font-size: 12px;
line-height: 12px;
text-align: center;
a {
color: $color-text-normal;
margin: 0 1em;
}
}
}
// 背景
.circles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
margin: 0px;
padding: 0px;
li {
position: absolute;
display: block;
list-style: none;
width: 20px;
height: 20px;
background: #fff;
animation: animate 25s linear infinite;
bottom: -200px;
@keyframes animate {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
border-radius: 0;
}
100% {
transform: translateY(-1000px) rotate(720deg);
opacity: 0;
border-radius: 50%;
}
}
&:nth-child(1) {
left: 15%;
width: 80px;
height: 80px;
animation-delay: 0s;
}
&:nth-child(2) {
left: 5%;
width: 20px;
height: 20px;
animation-delay: 2s;
animation-duration: 12s;
}
&:nth-child(3) {
left: 70%;
width: 20px;
height: 20px;
animation-delay: 4s;
}
&:nth-child(4) {
left: 40%;
width: 60px;
height: 60px;
animation-delay: 0s;
animation-duration: 18s;
}
&:nth-child(5) {
left: 65%;
width: 20px;
height: 20px;
animation-delay: 0s;
}
&:nth-child(6) {
left: 75%;
width: 150px;
height: 150px;
animation-delay: 3s;
}
&:nth-child(7) {
left: 35%;
width: 200px;
height: 200px;
animation-delay: 7s;
}
&:nth-child(8) {
left: 50%;
width: 25px;
height: 25px;
animation-delay: 15s;
animation-duration: 45s;
}
&:nth-child(9) {
left: 20%;
width: 15px;
height: 15px;
animation-delay: 2s;
animation-duration: 35s;
}
&:nth-child(10) {
left: 85%;
width: 150px;
height: 150px;
animation-delay: 0s;
animation-duration: 11s;
}
}
}
}
</style>