Files
iot_web/src/views/login.vue
Gjm 281c6d71b2 fix(login): 切换回生产环境的统一身份认证地址
- 在 login.vue 中将认证地址从本地开发地址切换回生产地址
- 在 Navbar.vue 中将登出跳转地址从本地开发地址切换回生产地址
- 移除本地测试配置,启用正确的认证服务器地址
- 确保单点登录功能在生产环境中正常工作
2026-03-30 11:13:17 +08:00

1302 lines
34 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 路由跳转 Loading 遮罩解决闪屏 -->
<div class="login">
<div class="main">
<div v-if="acountLogin" class="container a-container" :class="{ 'is-txl': isATxl }">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="form" id="a-form">
<h2 class="form_title title">{{ $t('login.989807-1') }}</h2>
<!-- <span class="form__span">{{ $t('login.989807-33') }}</span> -->
<el-form-item v-if="loginForm.bindId != null">
<div class="alert-box-wrap">
<div v-if="loginForm.bindId != null" class="alert-message-wrap">
<i class="el-icon-warning"/>
{{ $t('login.989807-10') }}
</div>
<el-row>
<el-col :span="10.5">
<div v-if="loginForm.bindId != null" class="alert-message-wrap">
{{ $t('login.989807-11') }}
</div>
</el-col>
<router-link
v-if="loginForm.bindId != null"
:to="{ path: '/register', query: this.$route.query }"
style="margin-left: 10px; font-size: 14px; font-family: '微软雅黑'; color: rgba(41, 96, 197, 0.856)"
>
{{ $t('login.989807-12') }}
</router-link>
</el-row>
</div>
</el-form-item>
<el-form-item prop="username">
<div class="username">
<i class="el-icon-user icon"></i>
<input class="form__input" v-model="loginForm.username" auto-complete="off" type="text"
:placeholder="$t('login.989807-4')"/>
</div>
</el-form-item>
<el-form-item prop="password" :class="{ 'is-null': isacount }">
<div class="password">
<svg-icon icon-class="password" class="icon left"/>
<input class="form__input" v-model="loginForm.password" auto-complete="off" :type="pwdtype"
:placeholder="$t('login.989807-5')" @keyup.enter="handleLogin"/>
<span class="el-icon-view icon right" @click="changetype()"></span>
</div>
</el-form-item>
<el-form-item v-if="captchaOnOff" prop="code" :class="{ 'is-null': ispwd }">
<div style="width: 350px" class="check">
<svg-icon icon-class="auth-code" class="icon"/>
<input v-model="loginForm.code" auto-complete="off" class="form__input__code" type="text"
:placeholder="$t('login.989807-6')"/>
<div class="login-code">
<img :src="codeUrl" @click="getCode" style="float: right"/>
</div>
</div>
</el-form-item>
<el-form-item :class="{ 'is-null': iscode }">
<div class="remember">
<el-checkbox v-model="loginForm.rememberMe" style="margin: 0; color: #000">
{{ $t('login.989807-7') }}
</el-checkbox>
</div>
</el-form-item>
<!-- <button class="form__button button submit">登录</button> -->
<el-button class="form__button button submit" v-if="!bindAccount" :loading="loading" type="primary"
@click.native.prevent="handleLogin">
<span v-if="!loading">{{ $t('login.989807-3') }}</span>
<span v-else>{{ $t('login.989807-13') }}</span>
</el-button>
<el-button v-else :loading="loading" class="form__button button" @click.native.prevent="handleBind">
<span v-if="!loading">{{ $t('login.989807-15') }}</span>
<span v-else>{{ $t('login.989807-16') }}</span>
</el-button>
<p class="form__link" @click="changesmsForm">{{ $t('login.989807-2') }}</p>
</el-form>
</div>
<div v-if="phoneLogin" class="container b-container" :class="{ 'is-txl': isBTxl, 'is-z200': isBZ200 }">
<el-form ref="smsLoginForm" :model="smsLoginForm" :rules="smsRules" class="form" id="b-form">
<h2 class="form_title title">{{ $t('login.989807-2') }}</h2>
<!-- <span class="form__span">没有账号立即注册</span> -->
<el-form-item prop="phonenumber">
<div class="telphone" style="width: 350px">
<svg-icon icon-class="phone" class="icon"/>
<input v-model="smsLoginForm.phonenumber" class="form__input__code" type="text" auto-complete="off"
:placeholder="$t('login.989807-8')" @input="validatePhoneNumber"/>
<div class="sendcode">
<el-button
slot="append"
type="primary"
:disabled="this.smsLoginForm.phonenumber == '' || isDisabled"
@click.prevent="getSmsCode()"
style="float: right; height: 40px; width: 90%; background-color: #0f73ee"
size="medium"
>
{{ buttonText }}
</el-button>
</div>
</div>
</el-form-item>
<el-form-item prop="smsCode">
<div class="smscode" :class="{ 'is-null': isphone }">
<svg-icon icon-class="password" class="icon"/>
<input class="form__input" type="password" v-model="smsLoginForm.smsCode" auto-complete="off"
:placeholder="$t('login.989807-9')"/>
</div>
</el-form-item>
<div class="other_login">
<div class="wechat-login">
<el-button v-if="loginForm.bindId == null" type="text" :wxloading="loading"
@click.native.prevent="weChatLogin">
<svg-icon icon-class="wechat" style="color: #07c160"/>
{{ $t('login.989807-34') }}
</el-button>
</div>
<div class="other-opt">
<router-link v-if="!bindAccount" style="font-size: 14px"
:to="{ path: '/register', query: this.$route.query }">{{ $t('login.989807-35') }}
</router-link>
<router-link v-else style="font-size: 14px" :to="{ path: '/register', query: this.$route.query }">
{{ $t('login.989807-36') }}
</router-link>
<langSelect style="margin-left: 12px"></langSelect>
</div>
</div>
<el-button class="form__button button submit" type="primary" :smsLoading="loading"
@click.native.prevent="handleSmsLogin">
<span v-if="!loading">{{ $t('login.989807-3') }}</span>
<span v-else>{{ $t('login.989807-13') }}</span>
</el-button>
<p class="form__link" @click="changesmsForm">{{ $t('login.989807-1') }}</p>
</el-form>
</div>
<div class="switch" id="switch-cnt" :class="{ 'is-gx': isGx, 'is-txr': isTxr }">
<div :class="{ switch__circle: true, 'is-txr': isTxr }"></div>
<div class="switch__container" id="switch-c1" :class="{ 'is-hidden': isC1Hidden }">
<div style="display: flex; align-items: center">
<h2 class="switch__title title" style="margin-left: 10px">{{ $t('login.989807-37') }}</h2>
</div>
<p class="switch__description description">{{ $t('login.989807-38') }}</p>
<img src="../assets/images/login3.jpeg" alt="logo" style="width: 220px; height: 220px"/>
</div>
</div>
</div>
</div>
</template>
<script>
import 'element-ui/lib/theme-chalk/display.css';
import logo from '@/assets/logo/logo.gif';
import {
getCodeImg,
checkBindId,
getErrorMsg,
socialLogin,
bindLogin,
getSmsLoginCaptcha,
smsLogin,
logincas
} from '@/api/login';
import Cookies from 'js-cookie';
import {encrypt, decrypt} from '@/utils/jsencrypt';
import {setToken, getToken, setAccessUser} from '@/utils/auth';
import langSelect from '@/layout/components/langSelect';
export default {
name: 'Login',
components: {langSelect},
data() {
return {
windowWidth: window.innerWidth,
acountLogin: true,
phoneLogin: false,
//控制密码可见
pwdtype: 'password',
isGx: false,
isTxr: false,
isATxl: false,
isBTxl: false,
isBZ200: false,
isC1Hidden: false,
isC2Hidden: true,
isacount: false,
ispwd: false,
isphone: false,
iscode: false,
logo,
codeUrl: '',
loginForm: {
username: '',
password: '',
rememberMe: false,
code: '',
uuid: '',
bindId: '',
},
smsLoginForm: {
phonenumber: '',
smsCode: '',
sourceType: 1,
},
smsLoading: false,
activeName: 'first',
isPhoneValid: true, // 标记手机号码是否有效
isDisabled: false, // 控制按钮状态
countdownTimer: null, // 倒计时器对象
buttonText: this.$t('login.989807-27'), // 按钮文本
remainingSeconds: 60, // 剩余秒数
waitTime: 61, // 获取验证码按钮失效时间
loginRules: {
username: [
{
required: true,
trigger: 'blur',
message: this.$t('login.989807-20'),
},
],
password: [
{required: true, message: this.$t('login.989807-21'), trigger: 'blur'},
],
code: [
{
required: true,
trigger: 'change',
message: this.$t('login.989807-22'),
},
],
},
smsRules: {
phonenumber: [
{required: true, message: this.$t('login.989807-23'), trigger: 'blur'},
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: this.$t('login.989807-24'),
trigger: 'blur',
},
],
smsCode: [
{
required: true,
trigger: 'change',
message: this.$t('login.989807-25'),
},
],
},
// 验证码开关
captchaOnOff: true,
bindAccount: false,
// 注册开关
register: true,
redirect: undefined,
rememberPsw: false,
otherQuery: {},
loading: false, // 控制系统loading框
};
},
watch: {
$route: {
handler: function (route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true,
},
},
created() {
const loginId = this.$route.query.loginId;
if (loginId === undefined || loginId === null) {
// 延迟执行这些方法确保loading先显示
this.checkBind();
this.getCode();
this.checkErrorMsg();
this.getCookie();
} else {
this.redirectSocialLogin(loginId);
}
},
mounted() {
// 优化:延迟执行登录相关逻辑,避免阻塞页面渲染
this.handleLoginFocus();
this.handleCASLogin();
this.checkDevice(); // 组件加载时检查设备
window.addEventListener('resize', this.checkDevice); // 添加resize事件监听
},
beforeDestroy() {
window.removeEventListener('resize', this.checkDevice); // 清除事件监听
},
methods: {
// 优化提取CAS登录逻辑到单独方法
handleCASLogin() {
const ticket = this.$route.query.ticket;
const isLoggingOut = localStorage.getItem('is_logging_out') === 'true';
const token = getToken();
if (!ticket && !token) {
// 如果是登出后返回,清除标记并停止
if (isLoggingOut) {
localStorage.removeItem('is_logging_out');
return;
}
// 没有ticket且没有token跳转统一身份认证
const isTs = true;
if (isTs) {
window.location.href = 'http://192.168.1.241/login?redirect=/lig/oauth2/oauth2/application&appid=330b4ecb60c9a6802b957fe1e5a5ecd3&url=http%3A%2F%2F192.168.1.241%3A9000%2Flogin'+(this.redirect?'&ssUrl='+this.redirect:'');
// window.location.href = 'http://localhost:81/login?redirect=/lig/oauth2/oauth2/application&appid=330b4ecb60c9a6802b957fe1e5a5ecd3&url=http%3A%2F%2Flocalhost%3A80%2Flogin' + (this.redirect ? '&ssUrl=' + this.redirect : '');
}
} else if (ticket && !token) {
// 有ticket但没有token请求登录
this.logincasapi();
} else {
}
},
handleLoginFocus() {
if (this.loginForm.loginName === "") {
if (this.$refs.loginName) {
this.$refs.loginName.focus();
}
} else if (this.loginForm.password === "") {
if (this.$refs.password) {
this.$refs.password.focus();
}
}
},
// 优化CAS登录方法
async logincasapi() {
const ticket = this.$route.query.ticket;
if (!ticket) {
return;
}
const obj = {
loginName: ticket,
password: "demo",
verifyCode: "",
};
try {
const {code, data, token} = await logincas(obj);
if (code !== 200) {
this.$message.error('CAS登录失败: ' + (data?.msg || '未知错误'));
// 清除ticket参数避免循环跳转
this.$router.push({
path: '/login',
query: {redirect: this.redirect}
});
return;
}
setToken(token || data.token);
setAccessUser(data);
// 跳转到目标页面清除ticket参数
const targetPath = this.redirect || "/";
this.$router.push({
path: targetPath,
query: this.otherQuery,
});
} catch (error) {
// 优化移除不必要的console.error
/* console.error('CAS登录错误:', error);
console.error('错误详情:', error.response || error.message); */
this.$message.error('CAS登录失败请检查后端CAS配置');
// 清除ticket参数避免循环跳转
this.$router.push({
path: '/login',
query: {redirect: this.redirect}
});
}
},
changesmsForm() {
this.acountLogin = !this.acountLogin;
this.phoneLogin = !this.phoneLogin;
},
checkDevice() {
this.windowWidth = window.innerWidth;
// 检查窗口宽度并设置登录方式
if (this.windowWidth <= 800) {
this.acountLogin = true;
this.phoneLogin = false;
}
},
changetype() {
this.pwdtype == 'password' ? (this.pwdtype = 'text') : (this.pwdtype = 'password');
},
getButtons(e) {
e.preventDefault();
},
changeForm() {
this.isGx = true;
setTimeout(() => {
this.isGx = false;
}, 1500);
this.isTxr = !this.isTxr;
this.isC1Hidden = !this.isC1Hidden;
this.isC2Hidden = !this.isC2Hidden;
this.isATxl = !this.isATxl;
this.isBTxl = !this.isBTxl;
this.isBZ200 = !this.isBZ200;
},
mainF() {
const allButtons = document.querySelectorAll('.submit');
for (var i = 0; i < allButtons.length; i++) {
allButtons[i].addEventListener('click', this.getButtons);
}
const switchBtn = document.querySelectorAll('.switch-btn');
for (var i = 0; i < switchBtn.length; i++) {
switchBtn[i].addEventListener('click', this.changeForm);
}
},
redirectSocialLogin() {
const query = this.$route.query;
const loginId = query.loginId;
socialLogin(loginId).then((res) => {
// 保存token
this.loading = true;
setToken(res.token);
this.$router
.push({
path: this.redirect || '/',
})
.catch(() => {
});
if (this.captchaOnOff) {
this.getCode();
this.loading = false;
}
});
},
checkBind() {
const query = this.$route.query;
const bindId = query.bindId;
if (bindId === undefined || bindId === null) {
this.bindAccount = false;
} else {
this.bindAccount = true;
checkBindId(bindId).then((res) => {
this.bindAccount = res.bindAccount === undefined ? true : res.bindAccount;
if (this.bindAccount) {
this.loginForm.bindId = bindId;
} else {
this.loginForm.bindId = '';
this.$router.push({
query: {},
});
}
});
}
},
checkErrorMsg() {
const errorId = this.$route.query.errorId;
if (errorId !== undefined && errorId !== null) {
getErrorMsg(errorId)
.then((res) => {
})
.catch((err) => {
this.$router.push({query: {}});
console.log(err);
});
}
},
getCode() {
getCodeImg().then((res) => {
// this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
this.captchaOnOff = res.captchaEnabled;
if (this.captchaOnOff) {
this.codeUrl = 'data:image/gif;base64,' + res.img;
this.loginForm.uuid = res.uuid;
}
});
},
getCookie() {
const username = Cookies.get('username');
const password = Cookies.get('password');
const rememberMe = Cookies.get('rememberMe');
const loginId = Cookies.get('loginId');
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
loginId: loginId === undefined ? this.loginForm.loginId : loginId,
};
},
qqLogin() {
window.location.href = 'http://localhost:8080/auth/render/qq';
},
weChatLogin() {
const baseURL = process.env.VUE_APP_BASE_API;
window.location.href = baseURL + '/auth/render/wechat_open_web';
},
//验证电话号码
validatePhoneNumber(number) {
const regExp = /^1[3456789]\d{9}$/; // 使用正则表达式进行校验
return regExp.test(number);
},
//获取短信验证码
getSmsCode() {
if (this.validatePhoneNumber(this.smsLoginForm.phonenumber)) {
getSmsLoginCaptcha(this.smsLoginForm.phonenumber).then((res) => {
if (res.code == 200) {
this.$message({
type: 'success',
message: this.$t('login.989807-26'),
});
this.countdownTimer = setInterval(() => {
if (this.remainingSeconds > 0) {
this.remainingSeconds--;
this.buttonText = `${this.remainingSeconds}秒后获取`;
} else {
clearInterval(this.countdownTimer);
this.buttonText = this.$t('login.989807-27');
this.isDisabled = false;
}
}, 1000);
this.isDisabled = true;
} else {
this.$message({
type: 'warning',
message: this.$t('login.989807-28'),
});
}
});
} else {
this.$message({
type: 'warning',
message: this.$t('login.989807-29'),
});
}
},
//短信登录操作
handleSmsLogin() {
if (!this.validatePhoneNumber(this.smsLoginForm.phonenumber)) {
this.isphone = true;
} else {
this.isphone = false;
}
this.$refs.smsLoginForm.validate((valid) => {
if (valid) {
this.smsLoading = true;
smsLogin(this.smsLoginForm).then((res) => {
setToken(res.data);
this.$router
.push({
path: '/',
})
.catch(() => {
});
});
}
});
},
handleBind() {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set('username', this.loginForm.username, {
expires: 30,
});
Cookies.set('password', encrypt(this.loginForm.password), {
expires: 30,
});
Cookies.set('rememberMe', this.loginForm.rememberMe, {
expires: 30,
});
} else {
Cookies.remove('username');
Cookies.remove('password');
Cookies.remove('rememberMe');
}
this.loginForm.bindId = this.$route.query.bindId;
bindLogin(this.loginForm)
.then((res) => {
// 保存token
setToken(res.token);
this.$router
.push({
path: '/',
})
.catch(() => {
});
})
.catch(() => {
this.loading = false;
if (this.captchaOnOff) {
this.loading = false;
this.getCode();
}
});
}
});
},
handleLogin() {
if (!this.loginForm.code) {
this.iscode = true;
} else {
this.iscode = false;
}
if (!this.loginForm.username) {
console.log('账号为空');
this.isacount = true;
} else {
this.isacount = false;
}
if (!this.loginForm.password) {
console.log('密码为空');
this.ispwd = true;
} else {
this.ispwd = false;
}
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set('username', this.loginForm.username, {
expires: 30,
});
Cookies.set('password', encrypt(this.loginForm.password), {
expires: 30,
});
Cookies.set('rememberMe', this.loginForm.rememberMe, {
expires: 30,
});
} else {
Cookies.remove('username');
Cookies.remove('password');
Cookies.remove('rememberMe');
}
this.$store
.dispatch('Login', this.loginForm)
.then(() => {
this.$router
.push({
path: this.redirect || '/',
})
.catch(() => {
});
})
.catch(() => {
this.loading = false;
if (this.captchaOnOff) {
this.getCode();
}
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
.login {
height: 100%;
overflow: auto;
width: 100%;
// height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Montserrat', sans-serif;
font-size: 12px;
//background: url('../assets/images/bg.png');
//background: linear-gradient(to right, #0f73ee 40%, #ffffffc6 40%), url('../assets/images/bg.png');
background: repeating-linear-gradient(to bottom right, #cee3fc 20%, #a8c7ed87 50%, #ffffffe7 50%, #ffffffc2 80%), url('../assets/images/bg.png');
color: #a0a5a8;
.main {
position: relative;
width: 1100px;
// min-width: 1100px;
// min-height: 600px;
height: 600px;
padding: 25px;
background-color: #fff;
box-shadow: 10px 0 10px #d0d5dd;
border-radius: 12px;
overflow: hidden;
}
.container {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
width: 600px;
height: 100%;
padding: 25px;
background-color: #fff;
transition: 1.25s;
}
.form {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 100%;
}
.username {
position: relative;
// margin-bottom: 1.5rem;
.icon {
position: absolute;
top: 50%;
left: 0.5rem;
transform: translateY(-50%);
color: #888;
}
.form__input {
padding-left: 2rem;
/* 确保输入框内文本不会被图标遮挡 */
}
}
.is-null {
margin-top: 20px;
}
.password {
position: relative;
.icon {
position: absolute;
top: 50%;
color: #888;
}
.icon.left {
left: 0.5rem;
transform: translateY(-50%);
}
.icon.right {
right: 0.5rem;
transform: translateY(-50%);
}
.form__input {
padding-left: 2rem;
/* 确保输入框内文本不会被左侧图标遮挡 */
padding-right: 2.5rem;
/* 确保输入框内文本不会被右侧图标遮挡 */
}
}
.check {
position: relative;
display: flex;
text-align: center;
justify-content: center;
align-items: center;
// margin-bottom: 1.5rem;
.icon {
position: absolute;
top: 50%;
left: 0.5rem;
transform: translateY(-50%);
color: #888;
}
.form__input__code {
padding-left: 2rem;
/* 确保输入框内文本不会被图标遮挡 */
}
}
.remember {
width: 350px;
display: flex;
justify-content: space-between;
align-items: center;
}
.other_login {
width: 350px;
margin-top: 20px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.other-opt {
flex: 1;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
}
.telphone {
display: flex;
text-align: center;
justify-content: center;
align-items: center;
position: relative;
// margin-bottom: 1.5rem;
.icon {
position: absolute;
top: 50%;
left: 0.5rem;
transform: translateY(-50%);
color: #888;
}
.form__input__code {
padding-left: 2rem;
/* 确保输入框内文本不会被图标遮挡 */
}
}
.smscode {
position: relative;
// margin-bottom: 1.5rem;
.icon {
position: absolute;
top: 50%;
left: 0.5rem;
transform: translateY(-50%);
color: #888;
}
.form__input {
padding-left: 2rem;
/* 确保输入框内文本不会被图标遮挡 */
}
}
.sendcode {
width: 34%;
float: right;
}
.form__icon {
object-fit: contain;
width: 30px;
margin: 0 5px;
opacity: 0.5;
transition: 0.15s;
}
.form__icon:hover {
opacity: 1;
transition: 0.15s;
cursor: pointer;
}
.form__input {
width: 350px;
height: 40px;
margin: 4px 0;
padding-left: 25px;
font-size: 13px;
letter-spacing: 0.15px;
border: none;
outline: none;
font-family: 'Montserrat', sans-serif;
background-color: #fff;
transition: 0.25s ease;
border-radius: 8px;
box-shadow: inset 2px 2px 4px #d1d9e6, inset -2px -2px 4px #f9f9f9;
}
.form__input__code {
width: 66%;
height: 40px;
margin: 4px 0;
padding-left: 25px;
font-size: 13px;
letter-spacing: 0.15px;
border: none;
outline: none;
font-family: 'Montserrat', sans-serif;
background-color: #fff;
transition: 0.25s ease;
border-radius: 8px;
box-shadow: inset 2px 2px 4px #d1d9e6, inset -2px -2px 4px #f9f9f9;
}
.form__input:focus {
box-shadow: inset 4px 4px 4px #d1d9e6, inset -4px -4px 4px #f9f9f9;
}
.form__input__code:focus {
box-shadow: inset 4px 4px 4px #d1d9e6, inset -4px -4px 4px #f9f9f9;
}
.form__span {
font-size: 15px;
margin-top: 5px;
margin-bottom: 12px;
color: #0f73ee9e;
}
.form__link {
display: none;
color: #181818;
font-size: 15px;
margin-top: 25px;
border-bottom: 1px solid #a0a5a8;
line-height: 2;
}
.title {
font-size: 34px;
font-weight: 700;
line-height: 3;
color: #181818;
}
.description {
font-size: 14px;
letter-spacing: 0.25px;
text-align: center;
line-height: 1.6;
}
.button {
width: 180px;
height: 50px;
border-radius: 25px;
margin-top: 45px;
font-weight: 700;
font-size: 14px;
letter-spacing: 1.15px;
background-color: #0f73ee;
color: #f9f9f9;
box-shadow: 8px 8px 16px #d1d9e6, -8px -8px 16px #f9f9f9;
border: none;
outline: none;
}
/**/
.a-container {
z-index: 100;
left: calc(100% - 600px);
}
.b-container {
left: calc(100% - 600px);
z-index: 0;
}
.switch {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 500px;
padding: 50px;
z-index: 200;
transition: 1.25s;
background-color: #fff;
overflow: hidden;
}
.switch__circle {
position: absolute;
width: 450px;
height: 450px;
border-radius: 50%;
background-color: #fff;
box-shadow: inset 8px 8px 12px #dde6f4, inset -8px -8px 12px #f9f9f9;
bottom: -60%;
left: -60%;
transition: 1.25s;
}
.switch__circle--t {
top: -30%;
left: 60%;
width: 300px;
height: 300px;
}
.switch__container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: absolute;
width: 400px;
padding: 50px 55px;
transition: 1.25s;
}
.switch__button {
cursor: pointer;
}
.switch__button:hover {
box-shadow: 6px 6px 10px #d1d9e6, -6px -6px 10px #f9f9f9;
transform: scale(0.985);
transition: 0.25s;
}
.switch__button:active,
.switch__button:focus {
box-shadow: 2px 2px 6px #d1d9e6, -2px -2px 6px #f9f9f9;
transform: scale(0.97);
transition: 0.25s;
}
/**/
.is-txr {
left: calc(100% - 500px);
transition: 1.3s;
transform-origin: left;
}
.is-txl {
left: 0;
transition: 1.25s;
transform-origin: right;
}
.is-z200 {
z-index: 200;
transition: 1.25s;
}
.is-hidden {
visibility: hidden;
opacity: 0;
position: absolute;
transition: 1.25s;
}
.is-gx {
animation: is-gx 1.25s;
}
@keyframes is-gx {
0%,
10%,
100% {
width: 500px;
}
30%,
50% {
width: 550px;
}
}
.tabs {
width: 400px;
border-bottom: none;
// border: solid white 1px;
box-shadow: none !important;
}
.tabs ::v-deep .el-tabs__nav {
background-color: white;
box-shadow: none !important;
text-decoration: none;
/* 设置导航栏背景颜色 */
}
/*去掉切换时el-tab-pane底部的蓝色下划线*/
::v-deep .el-tabs__active-bar {
background-color: transparent !important;
}
/*去掉tabs底部的下划线*/
::v-deep .el-tabs__nav-wrap::after {
position: static !important;
}
.tabs ::v-deep .el-tabs__item {
font-size: 20px;
/* 设置字体大小 */
border: none;
/* 去除默认边框 */
}
.bindAccountTitle {
margin: 0px auto 30px auto;
text-align: center;
color: #333;
font-size: 24px;
}
.tabs-login {
margin: 20px auto 0 auto;
z-index: 1000;
max-width: 350px;
}
.login-form {
margin: 10px 0 0 0;
z-index: 1000;
max-width: 350px;
input {
height: 38px;
background-color: #f1f1f1;
color: #666;
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-code {
width: 34%;
float: right;
img {
cursor: pointer;
vertical-align: middle;
border-radius: 3px;
height: 38px;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #333;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.alert-box-wrap {
border: 1px solid #f78e21;
.alert-message-wrap {
font-size: 14px;
font-family: '微软雅黑';
color: rgba(197, 41, 41, 0.856);
margin-left: 10px;
}
}
}
@media (max-width: 1200px) {
.main {
transform: scale(0.9);
.switch {
width: 40%;
}
.container {
width: 60%;
}
}
}
@media (max-width: 1000px) {
.main {
transform: scale(0.8);
.switch {
width: 40%;
}
.container {
width: 60%;
}
}
}
@media (max-width: 800px) {
.main {
transform: scale(0.9);
display: flex;
justify-content: center;
/* 水平居中 */
align-items: center;
/* 垂直居中 */
height: 100vh;
/* 设置容器高度为视口高度,实现垂直居中 */
width: 600px;
.a-container {
position: absolute;
z-index: 100;
left: 50%;
/* 将元素的左边缘移动到父容器的水平中心 */
transform: translateX(-50%);
/* 通过向左平移自身宽度的一半来实现水平居中 */
}
.b-container {
position: absolute;
z-index: 100;
left: 50%;
/* 将元素的左边缘移动到父容器的水平中心 */
transform: translateX(-50%);
/* 通过向左平移自身宽度的一半来实现水平居中 */
}
.switch {
display: none;
}
.form__link {
display: block;
color: #181818;
font-size: 15px;
margin-top: 25px;
border-bottom: 1px solid #a0a5a8;
line-height: 2;
}
}
}
@media (max-width: 600px) {
.login {
background: repeating-linear-gradient(to bottom right, #cee3fc 20%, #a8c7ed87 50%, #ffffffe7 50%, #ffffffc2 80%), url('../assets/images/login.png');
.main {
transform: scale(0.9);
display: flex;
justify-content: center;
/* 水平居中 */
align-items: center;
/* 垂直居中 */
height: 75vh;
width: 100vh;
box-shadow: 10px 0 10px #5c7aaa;
.a-container {
//background: linear-gradient(to bottom, #0f73ee 25%, #ffffff 25%);
position: absolute;
width: 100%;
z-index: 100;
left: 50%;
/* 将元素的左边缘移动到父容器的水平中心 */
transform: translateX(-50%);
/* 通过向左平移自身宽度的一半来实现水平居中 */
}
.switch {
display: none;
}
.b-container {
position: absolute;
z-index: 100;
left: 50%;
/* 将元素的左边缘移动到父容器的水平中心 */
transform: translateX(-50%);
/* 通过向左平移自身宽度的一半来实现水平居中 */
}
.form__link {
display: block;
color: #181818;
font-size: 15px;
margin-top: 25px;
border-bottom: 1px solid #a0a5a8;
line-height: 2;
}
}
}
}
/* 路由跳转 Loading 样式 */
</style>