You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

397 lines
10 KiB

<template>
<div class="login-container">
<el-form
ref="loginForm" :model="loginForm" :rules="rules"
autocomplete="off"
class="login-form" label-position="left"
>
<div class="title-container">
<h3 class="title">平台登录</h3>
<!-- {{ $t('login.title') }} -->
<!-- <lang-select class="set-language" /> -->
</div>
<span v-if="login.type === &quot;up&quot;">
<el-form-item prop="account">
<el-input
ref="account"
v-model="loginForm.account"
:placeholder="$t(&quot;login.username&quot;)"
autocomplete="off"
name="account"
prefix-icon="el-icon-user"
type="text"
@keyup.enter.native="handleLogin"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
ref="password"
v-model="loginForm.password"
:placeholder="$t(&quot;login.password&quot;)"
:show-password="true"
autocomplete="off"
name="password"
prefix-icon="el-icon-key"
type="password"
@keyup.enter.native="handleLogin"
/>
</el-form-item>
<el-form-item class="code-input" prop="code">
<el-input
ref="code"
v-model="loginForm.code"
:placeholder="$t(&quot;login.code&quot;)"
autocomplete="off"
name="code"
prefix-icon="el-icon-lock"
style="width: 70%"
type="text"
@keyup.enter.native="handleLogin"
/>
</el-form-item>
<img :src="imageCode" alt="codeImage" class="code-image" @click="getCodeImage" />
<el-button :loading="loading" style="width:100%;margin-bottom:14px;" type="primary" @click.native.prevent="handleLogin">{{ $t('login.logIn') }}</el-button>
</span>
</el-form>
<span class="login-footer">
© 2019
cereshop
</span>
</div>
</template>
<script>
// import LangSelect from '@/components/LangSelect'
import db from '@/utils/localstorage'
import { randomNum } from '@/utils'
import loginApi from '@/api/Login.js'
export default {
name: 'Login',
// components: { LangSelect },
data () {
return {
login: {
type: 'up'
},
logo: [
{ img: 'gitee.png', name: 'gitee', radius: true },
{ img: 'github.png', name: 'github', radius: true },
{ img: 'tencent_cloud.png', name: 'tencent_cloud', radius: true },
{ img: 'qq.png', name: 'qq', radius: false },
{ img: 'dingtalk.png', name: 'dingtalk', radius: true },
{ img: 'microsoft.png', name: 'microsoft', radius: false }
],
loginForm: {
account: '',
password: '',
key: '',
code: '',
grantType: 'captcha',
bindAccount: '',
bindPassword: '',
signAccount: '',
signPassword: ''
},
rules: {
account: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
password: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
code: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
bindAccount: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
bindPassword: { required: true, message: this.$t('rules.require'), trigger: 'blur' },
signAccount: [
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
{ min: 4, max: 10, message: this.$t('rules.range4to10'), trigger: 'blur' }
],
signPassword: [
{ required: true, message: this.$t('rules.require'), trigger: 'blur' },
{ min: 6, max: 20, message: this.$t('rules.range6to20'), trigger: 'blur' }
]
},
authUser: null,
loading: false,
showDialog: false,
redirect: undefined,
otherQuery: {},
randomId: randomNum(24, 16),
imageCode: '',
page: {
width: window.screen.width * 0.5,
height: window.screen.height * 0.5
}
}
},
created () {
},
mounted () {
db.clear()
this.getCodeImage()
},
destroyed () {
window.removeEventListener('message', this.resolveSocialLogin)
},
methods: {
getCodeImage () {
loginApi.getCaptcha(this.randomId)
.then((response) => {
const res = response.data
if (res.byteLength <= 100) {
this.$message({
message: this.$t('tips.systemError'),
type: 'error'
})
}
return 'data:image/png;base64,' + btoa(
new Uint8Array(res)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
)
}).then((res) => {
console.log(res)
this.imageCode = res
}).catch((e) => {
if (e.toString().indexOf('429') !== -1) {
this.$message({
message: this.$t('tips.tooManyRequest'),
type: 'error'
})
} else {
this.$message({
message: this.$t('tips.getCodeImageFailed'),
type: 'error'
})
}
})
},
handleLogin () {
let account_c = false
let password_c = false
let code_c = false
this.$refs.loginForm.validateField('account', e => { if (!e) { account_c = true } })
this.$refs.loginForm.validateField('password', e => { if (!e) { password_c = true } })
this.$refs.loginForm.validateField('code', e => { if (!e) { code_c = true } })
if (account_c && password_c && code_c) {
this.loading = true
const that = this
that.loginForm['key'] = that.randomId
loginApi.login(this.loginForm)
.then((response) => {
const res = response.data
if (res.isSuccess) {
that.saveLoginData(res.data['token'], res.data['refreshToken'], res.data['expiration'])
that.saveUserInfo(res.data)
that.$message({
message: this.$t('tips.loginSuccess'),
type: 'success'
})
that.$router.push('/')
} else {
that.loading = false
that.getCodeImage()
}
}).finally(() => {
that.loading = false
return true
})
}
},
saveLoginData (token, refreshToken, expire) {
this.$store.commit('account/setToken', token)
this.$store.commit("account/setRefreshToken", refreshToken)
this.$store.commit('account/setExpireTime', expire)
},
saveUserInfo (user) {
this.$store.commit("account/setUser", {
id: user.userId,
account: user.account,
name: user.name,
avatar: user.avatar,
workDescribe: user.workDescribe
})
},
loginSuccessCallback (user) {
}
}
}
</script>
<style lang="scss">
$bg: #fff;
$light_gray: #fff;
$cursor: #555;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
/* reset element-ui css */
.login-container {
.el-input {
display: inline-block;
input {
background: transparent;
border: 0;
-webkit-appearance: none;
border-radius: 0;
color: #000000;
height: 28px;
caret-color: $cursor;
&:-webkit-autofill {
box-shadow: 0 0 0 1000px $bg inset !important;
-webkit-text-fill-color: $cursor !important;
}
}
}
.el-form-item {
border: 1px solid #dedede;
border-radius: 2px;
color: #454545;
transition: all 0.3s;
&:hover {
border-color: #57a3f3;
}
}
}
</style>
<style lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #aaa;
$light_gray: #eee;
.login-container {
background: url(../../assets/beijing.png) 50% no-repeat;
background-size: cover;
width: 100%;
height: 100vh;
.login-info {
position: absolute;
left: 15%;
top: 44%;
margin-top: -100px;
color: #fff;
.title {
font-size: 1.8rem;
font-weight: 600;
}
.sub-title {
font-size: 1.5rem;
margin: 0.3rem 0 0.7rem 1rem;
}
.desc {
font-size: 0.96rem;
line-height: 1.9rem;
}
}
.login-form {
position: absolute;
top: 50%;
left: 50%;
margin: -180px 0 0 -160px;
width: 350px;
height: 380px;
padding: 36px;
background: #fff;
border-radius: 3px;
.code-input {
width: 50%;
display: inline-block;
vertical-align: middle;
}
.code-image {
display: inline-block;
vertical-align: top;
cursor: pointer;
}
.login-type {
text-align: right;
display: inline-block;
width: 100%;
}
.logo-wrapper {
display: inline-block;
margin: 10px 0;
img {
width: 1.9rem;
display: inline-block;
margin: 0.8rem 0.8rem -0.8rem 0.8rem;
cursor: pointer;
&.radius {
border-radius: 50%;
}
}
}
}
.login-footer {
position: fixed;
bottom: 1rem;
width: 100%;
text-align: center;
color: white;
font-size: 0.85rem;
line-height: 1rem;
height: 1rem;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.title-container {
position: relative;
.title {
font-size: 20px;
color: rgba(0, 0, 0, 0.85);
margin: 0 auto 40px auto;
text-align: center;
font-weight: bold;
}
.set-language {
color: #aaa;
position: absolute;
top: 3px;
font-size: 18px;
right: 0;
cursor: pointer;
}
}
.thirdparty-button {
position: absolute;
right: 0;
bottom: 6px;
}
@media only screen and (max-width: 470px) {
.thirdparty-button {
display: none;
}
}
@media screen and (max-width: 1100px) {
.login-info {
left: 8%;
}
}
@media screen and (max-width: 970px) {
.login-form {
left: 50%;
}
.login-info {
display: none;
}
}
}
</style>