<template>
<div class="loginLayout">
<div class="vidbg-container"
style="z-index: -1;inset: 0px;overflow: hidden;background-size: cover;background-repeat: no-repeat;background-position: 50% 50%;background-image: none;">
<video id="video" muted="muted" class="video" :src="videoUrl" type="video/mp4" autoplay="autoplay"
controls="controls" loop="-1">
</video>
<div class="vidbg-overlay" style="position: absolute; inset: 0px; background: rgba(0, 0, 0, 0.1);"></div>
</div>
<center style="width:100vw;height:100vh;">
<div style="width:100%;position: absolute;bottom:30px;z-index:99;text-align: center;color: #fff;">
<div>
{{ $t("globalLang.Copyright") }}
</div>
</div>
<div class="" style="width: 1024px;height:100%;">
<div style="position: absolute;top:30px;z-index:99">
<!-- logo -->
<!-- <img src="../assets/logo/logo.png" style="width:100px;object-fit: contain;"> -->
</div>
<div class="div_center" style="height:100%;width:100%;flex-direction: row;justify-content: flex-start;">
<div style="width:50%;display: flex;justify-content: flex-start;">
<!-- 左边的图片背景 -->
<img src="/static/loginRes/wz.png" style="width:400px;object-fit: contain;">
</div>
<div style="width:50%;position:relative;top:-85px;">
<div id="main"
style="float: right; display: flex; flex-direction: column; justify-content: center; width: 350px; background-color: rgb(255, 255, 255); border-radius: 2px; opacity: 0.9;">
<div style="display: block; padding: 20px 30px;">
<div style="height:10px;"></div>
<div class="layout">
<div class="top">
<!-- <div class="header">
<span class="title">{{ $t("globalLang.AppName") }}</span>
</div>
<div class="desc">{{ $t("globalLang.AppDesc") }}</div> -->
<div class="header">
<span class="title">{{ $t("globalLang.LoginTitle") }}</span>
</div>
</div>
<div style="height:10px;"></div>
<div class="login">
<a-form @submit="onSubmit" :form="form">
<a-tabs v-model="curTab" size="large" :tabBarStyle="{ textAlign: 'center' }" style="padding: 0 2px">
<a-tab-pane :tab="this.$t('globalLang.UserLogin')" key="AccountLogin">
<a-form-item>
<a-input autocomplete="off" size="large" :placeholder="this.$t('globalLang.UserAccount')"
v-decorator="[
'name',
{
rules: [
{
required: true,
message: this.$t('globalLang.PleaseEnterUserAccount'),
whitespace: true,
},
],
},
]">
<a-icon slot="prefix" type="user" />
</a-input>
</a-form-item>
<a-form-item>
<a-input size="large" :placeholder="this.$t('globalLang.UserPassword')" autocomplete="off"
type="password" v-decorator="[
'password',
{
rules: [
{
required: true,
message: this.$t('globalLang.PleaseEnterUserPassword'),
whitespace: true,
},
],
},
]">
<a-icon slot="prefix" type="lock" />
</a-input>
</a-form-item>
</a-tab-pane>
<!-- <a-tab-pane :tab="this.$t('globalLang.MobileLogin')" key="MobileLogin" :forceRender="true">
<a-form-item>
<a-input size="large" :placeholder="this.$t('globalLang.PhoneNumber')" autocomplete="off" v-decorator="[
'phoneNumber',
{
rules: [
{
required: true,
message: this.$t('globalLang.PleaseEnterPhoneNumber'),
whitespace: true,
},
],
},
]">
<a-icon slot="prefix" type="mobile" />
</a-input>
</a-form-item>
<a-form-item>
<a-row :gutter="8" style="margin: 0 -4px">
<a-col :span="16">
<a-input size="large" autocomplete="off" v-decorator="[
'verificationCode',
{
rules: [
{
required: true,
message: this.$t(
'globalLang.PleaseEnterVerificationCode'
),
whitespace: true,
},
],
},
]" :placeholder="this.$t('globalLang.VerificationCode')">
<a-icon slot="prefix" type="mail" />
</a-input>
</a-col>
<a-col :span="8" style="padding-left: 4px">
<a-button style="width: 100%" class="captcha-button" size="large">{{ $t("globalLang.GetVerificationCode") }}</a-button>
</a-col>
</a-row>
</a-form-item>
</a-tab-pane> -->
</a-tabs>
<a-form-item style="margin-bottom: 0px;margin-left: 5px; text-align:left;">
<a-checkbox v-decorator="[
'isSavePassword',
{
valuePropName: 'checked',
initialValue: false,
},
]">{{ $t("globalLang.SavePassword") }}</a-checkbox>
<!-- <a style="float: right">{{ $t("globalLang.ForgetPassword") }}</a> -->
</a-form-item>
<a-form-item>
<a-button :loading="logging" style="width: 100%; margin-top: 16px;background-color:#4093F8;"
size="large" htmlType="submit" type="primary">{{ $t("globalLang.Login") }}</a-button>
</a-form-item>
<!-- <div>
{{ $t("globalLang.OtherLogin") }}
<a-icon class="icon" type="alipay-circle" />
<a-icon class="icon" type="taobao-circle" />
<a-icon class="icon" type="weibo-circle" />
<router-link style="float: right" to="/login">{{
$t("globalLang.Register")
}}</router-link>
</div> -->
<div style="padding-top: 0px; text-align: center;">
<a v-for="item in Langs" :key="item.Key" @click="changeLang(item.Key)" :style="AntVue.$store.state.setting.lang == item.Key
? ''
: 'color:#545456'
">
{{ item.Name }}
</a>
</div>
</a-form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</center>
</div>
</template>
<script>
import ThemeUtil from "@/theme/js/util";
import MenuUtil from "@/layouts/menu/util";
import { login } from "@/api/login";
import { getUserMenuList } from "@/api/system/sys_menu";
import { setAuthorization, removeAuthorization } from "@/utils/request";
import { setLoginUser } from "@/utils/util";
import langs from "@/lang/i18n.js";
export default {
name: "Login",
created() {
//初始化样式
ThemeUtil.initTheme();
},
mounted() {
//初始化菜单数据
MenuUtil.clearData();
//清除登录信息
removeAuthorization();
this.loadFormData();
},
data() {
var videos = ["beach.mp4", "Finland.mp4", "hohy.mp4", "hua.mp4", "leaf.mp4", "lotus.mp4", "mountains.mp4", "palm.mp4", "sky2.mp4", "turtle.mp4"];
return {
videoUrl: "/static/loginRes/" + videos[Math.floor(Math.random() * videos.length)],
form: this.$form.createForm(this),
//登录按钮处理中
logging: false,
//当前的登录方式
curTab: "AccountLogin",
//登陆中,提示消息的Key
loadingKey: "LoadingKey",
//记住密码的localstroeKey
loginKey: "LoginKey",
Langs: langs.getLangs(),
AntVue: this,
};
},
methods: {
changeLang(lang) {
this.$store.commit("setting/setLanguage", lang);
},
//加载本地我记住的密码
loadFormData() {
var formData = localStorage.getItem(this.loginKey);
if (formData != null) {
this.form.setFieldsValue(JSON.parse(formData));
}
},
//记录表单值
saveFormData(formData) {
if (formData.isSavePassword == false) {
localStorage.removeItem(this.loginKey);
} else {
localStorage.setItem(this.loginKey, JSON.stringify(formData));
}
},
//获取登录用户的菜单
getMenuList() {
this.logging = true;
//数据获取中
var hide = this.$message.loading({
content: this.$t("globalLang.DataLoading"),
key: this.loadingKey,
duration: 0,
});
this.NProgress.start();
getUserMenuList()
.then((data) => {
if (data.code != 200) {
this.$message.warning({
content: this.$t("globalLang.Messages.M000009"), //接口异常,请稍后再试
duration: 2,
});
return;
}
//初始化菜单数据
MenuUtil.clearData();
//验证菜单数据是否正常
var checkMenuData = false;
//菜单数据
var menuList = [];
for (var menu of data.data) {
//菜单的PID需要有=0的数据,否则会报错
if (menu.parent_id == 1) {
menu.parent_id = 0;
}
if (menu.parent_id == 0) {
checkMenuData = true;
}
//console.log(JSON.stringify(menu));
menuList.push({
title_en: menu.menu_name_en,
title: menu.menu_name,
component_name: menu.component_name,
component_path: menu.component_path,
key: menu.menu_id,
pkey: menu.parent_id,
icon: menu.icon,
url: menu.url,
params: menu.url_params == null ? "" : menu.url_params,
});
}
if (checkMenuData == false) {
this.$notification["error"]({
message: this.$t("globalLang.Messages.M000012"),
description: this.$t("globalLang.Messages.M000013"),
}); //后台菜单数据格式不对
return;
}
this.$message.success({
content: this.$t("globalLang.Messages.M000001"), //您好,欢迎回来
duration: 2,
});
//设置菜单显示的状态
MenuUtil.initMenus(menuList);
//绑定动态路由
this.$router.initRouter(menuList);
//默认跳转首页
this.$router.push(MenuUtil.getHomeUrl());
})
.finally(() => {
this.NProgress.done();
this.logging = false;
hide();
});
},
//登录
onSubmit(e) {
e.preventDefault();
this.form.validateFields((err, values) => {
//一般账号登录
if (this.curTab == "AccountLogin") {
if (err == null || (!err.name && !err.password)) {
this.logging = true;
//系统登录中
var hide = this.$message.loading({
content: this.$t("globalLang.LoginLoading"),
key: this.loadingKey,
duration: 0,
});
this.saveFormData(values);
removeAuthorization();
this.NProgress.start();
login(values.name, values.password)
.then((data) => {
if (data.code != 200) {
this.$message.warning({
content: this.$t("globalLang.Messages.M000002"), //登录失败,账号或密码不正确
duration: 2,
});
return;
}
//当前登录人的信息
setLoginUser(data.data.principal);
//设置登录信息
setAuthorization(data.data.token);
//获取登录用户的菜单
this.getMenuList();
})
.finally(() => {
this.NProgress.done();
this.logging = false;
hide();
});
}
}
//手机号登录
if (this.curTab == "MobileLogin") {
if (err == null || (!err.phoneNumber && !err.verificationCode)) {
this.logging = true;
this.$message.loading({
content: this.$t("globalLang.LoginLoading"),
key: this.loadingKey,
duration: 0,
});
this.saveFormData(values);
//values.phoneNumber values.verificationCode values.isSavePassword
//login(name, password).then(this.afterLogin)
setTimeout(() => {
this.logging = false;
this.$message.error({
content: this.$t("globalLang.Messages.M000003"),
key: this.loadingKey,
duration: 2,
});
}, 1000);
}
}
});
},
},
};
</script>
<style lang="less" scoped>
.animation-fade {
-webkit-animation-name: fade;
animation-name: fade;
-webkit-animation-duration: 0.8s;
animation-duration: 0.8s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
}
.active {
color: #3c91fc;
border-bottom: 2px solid #3c91fc;
}
.alert-warning {
color: #eb6709;
background-color: #ffffff;
border-color: #ffffff;
}
.alert {
padding-left: 10px;
padding: 0px 10px;
}
.checkbox-primary input[type="radio"]:checked+input[type="hidden"]+label::before,
.checkbox-primary input[type="radio"]:checked+label::before,
.checkbox-primary input[type="checkbox"]:checked+input[type="hidden"]+label::before,
.checkbox-primary input[type="checkbox"]:checked+label::before {
background-color: #3c91fc;
border-color: #3c91fc;
}
.page-login .page-copyright {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
}
.checkbox-custom label::after,
.checkbox-custom label::before {
position: absolute;
margin-left: -20px;
width: 18px;
height: 18px;
display: inline-block;
left: 0;
}
.checkbox-custom label {
position: relative;
display: inline-block;
padding-left: 5px;
vertical-align: middle;
}
.opacity {
opacity: 0.1;
}
.div_center {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.form-control {
border: 1px solid #cccccc;
}
body {
margin: 0;
}
video {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -9999;
opacity: 1;
object-fit: fill;
visibility: visible;
}
.img-size {
width: 220px;
}
.remarks_cell {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
}
.app-download {
/*width: 110px;
height: 110px;*/
border: 1px solid #f5f5f6;
cursor: pointer;
}
/deep/ .ant-tabs-nav-wrap {
display: none;
}
.loginLayout {
/deep/ .ant-form-item-control {
line-height: 30px;
}
/deep/ .ant-tabs-bar {
border: none;
}
padding-top: 5%;
.ant-tabs-tabpane {
padding-top: 10px;
}
.title {
font-size: 17px;
color: rgba(0, 0, 0, 0.85);
font-family: "Myriad Pro", "Helvetica Neue", Arial, Helvetica, sans-serif;
font-weight: 600;
position: relative;
}
.top {
text-align: left;
.header {
display: flex;
align-items: flex-end;
height: 44px;
line-height: 44px;
a {
text-decoration: none;
}
}
.desc {
font-size: 14px;
color: rgba(0, 0, 0, 0.45);
margin-top: 12px;
margin-bottom: 12px;
}
}
.login {
margin: 0 auto;
@media screen and (max-width: 576px) {
width: 95%;
}
@media screen and (max-width: 320px) {
.captcha-button {
font-size: 14px;
}
}
.icon {
font-size: 24px;
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color 0.3s;
}
}
}</style>