SmartSubstationPlatform/riis-web/src/views/login/index.vue
2025-04-25 10:20:05 +08:00

737 lines
18 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>
<div class="login-container">
<img :src="loginImg" alt="" style="position: absolute;top: 0;width: 100vw !important;max-width:100vw!important;height:100vh">
<div class="login-container-center">
<div class="title-container">
<img src="@/assets/login/bt.png" alt="" style="margin: auto;">
</div>
<div class="login-container-right">
<el-form
ref="loginFormRef"
:model="loginData"
:rules="loginRules"
class="login-form"
auto-complete="on"
label-position="left"
>
<div style="text-align: center;
padding:0 40px;
padding-bottom: 20px;
color: rgb(181, 215, 255);
font-size: 24px;">欢迎登录</div>
<el-form-item prop="username" style="position: relative;">
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<el-input
ref="inputref"
v-model="loginData.username"
:placeholder="$t('login.username')"
name="username"
@focus="focusClick(1)"
type="text"
tabindex="1"
auto-complete="on"
/>
<div class="lineargradient" :class="{'activeline':activeline == 1}"></div>
</el-form-item>
<el-form-item prop="password" style="position: relative;">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input
ref="passwordRef"
clearable
:key="passwordType"
v-model="loginData.password"
:type="passwordType"
:placeholder="$t('login.password')"
name="password"
tabindex="2"
auto-complete="on"
@keyup="checkCapslock"
@focus="focusClick(2)"
@blur="capslockTooltipDisabled = true"
@keyup.enter="handleLogin"
/>
<span
style="color:rgb(181, 215, 255)"
class="show-pwd"
@click="showPwd"
>
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
</span>
<div class="lineargradient" :class="{'activeline':activeline == 2}"></div>
</el-form-item>
<el-form-item
prop="code"
class="login-code"
>
<span class="svg-container">
<svg-icon icon-class="valid_code" />
</span>
<el-input
style="width: 55%;"
clearable
v-model="loginData.code"
:placeholder="$t('login.code')"
name="username"
type="text"
tabindex="3"
auto-complete="on"
@keyup.enter="handleLogin"
@focus="focusClick(3)"
/>
<span class="svg-container svg-container-refresh flex items-center" @click="getCode">
<img :src="codeUrl" class="mr-[10px]">
<svg-icon icon-class="refresh" />
</span>
<div class="lineargradient" :class="{'activeline':activeline == 3}"></div>
</el-form-item>
<div class="loginButton">
<el-button type="text" @click.prevent="handleLogin"
:loading="loading" style="width: 341px;
height: 52px;
color: #ffffff;
text-align: center;
font-size: 18px;">{{ $t('login.login') }}</el-button>
<!-- {{ $t('login.login') }} -->
</div>
</el-form>
<div
v-if="showCopyright == true"
class="copyright"
>
<p>{{ $t('login.copyright') }}</p>
<p>{{ $t('login.icp') }}</p>
</div>
</div>
</div>
<Eldialog v-if="userStore.isExpire == true" :title="'修改密码'" :zIndex="2000" :width="'480px'"
@before-close="userStore.isExpire = false" >
<template v-slot:PopFrameContent>
<div class="passwordTisp">{{userStore.promptTitle}}</div>
<el-form ref="rulePass" :model="userInfo" label-width="92px" style="margin-top:10px">
<el-form-item label="登录账号" prop="password">
<el-input v-model="userInfo.username" style="width:97%" disabled></el-input>
</el-form-item>
<el-form-item label="原密码" prop="password">
<el-input v-model="userInfo.password" type="password" style="width:97%"></el-input>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="userInfo.newPassword" type="password" style="width:97%"></el-input>
</el-form-item>
<el-form-item label="确认新密码" prop="confirmPassword">
<el-input v-model="userInfo.confirmPassword" type="password" style="width:97%"></el-input>
</el-form-item>
</el-form>
<div style="width: 100%;height: 40px;line-height:40px;text-align: center;color: red;">{{tisp}}</div>
<div style="width: 100%;display: flex;justify-content: center;padding-top: 20px;">
<div class="details-button" @click="submitClick">确定</div>
</div>
</template>
</Eldialog>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, toRefs, watch, nextTick } from 'vue';
import loginImg from '@/assets/login/bj.jpg';
import { getCaptcha } from '@/api/auth';
import { updateEncryptPassword } from '@/api/user';
// 组件依赖
import { ElForm, ElInput,ElMessage } from 'element-plus';
import router from '@/router';
import SvgIcon from '@/components/SvgIcon/index.vue';
// API依赖
import { useRoute } from 'vue-router';
import { LoginData } from '@/api/auth/types';
//密码加密
import { encrypt } from '@/utils/sm4';
// 状态管理依赖
import { useUserStore } from '@/store/modules/user';
import Eldialog from '@/components/seccmsdialog/eldialog.vue';
// 国际化
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const userStore = useUserStore();
const route = useRoute();
// 图片验证码
const codeUrl = ref('');
const activeline = ref(1);
const loginFormRef = ref(ElForm);
const passwordRef = ref(ElInput);
const tisp = ref('')
const userInfo:any = ref({
username:"",
password:"",
newPassword:"",
confirmPassword:""
})
function submitClick(){ // 提交修改密码
tisp.value = ""
if(userInfo.value.username == ""){
tisp.value = "账号不能为空!"
return
}
if(userInfo.value.password == ""){
tisp.value = "原密码不能为空!"
return
}
if(userInfo.value.newPassword == ""){
tisp.value = "新密码不能为空!"
return
}
if(userInfo.value.newPassword == userInfo.value.password){
tisp.value = "新密码不能与原密码相同!"
return
}
if(userInfo.value.newPassword.length <8){
tisp.value = "新密码不能小于8位数"
return
}
const lettersmall = /([a-z])+/
const num= /([0-9])+/
const letterbig = /([A-Z])+/
const regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im
const regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im
if(!num.test(userInfo.value.newPassword)){
tisp.value = "新密码缺少数字!"
return
}
if(!lettersmall.test(userInfo.value.newPassword)){
tisp.value = "新密码缺少小写字母!"
return
}
if(!letterbig.test(userInfo.value.newPassword)){
tisp.value = "新密码缺少大写字母!"
return
}
if(!regEn.test(userInfo.value.newPassword)){
tisp.value = "新密码缺少特殊符号!"
return
}
if(userInfo.value.confirmPassword == ""){
tisp.value = "确认新密码不能为空!"
return
}
if(userInfo.value.newPassword != userInfo.value.confirmPassword){
tisp.value = "新密码与确认新密码不一致!"
return
}
const params = {
username: userInfo.value.username,
oldpassword: encrypt(userInfo.value.password).replace(/\s+/g,""),
newpassword: encrypt(userInfo.value.newPassword).replace(/\s+/g,""),
}
updateEncryptPassword(params).then((res:any) => {
if(res.code == "1"){
tisp.value = res.msg
}else{
ElMessage({
type: 'success',
message: '密码修改成功',
})
userStore.isExpire = false
}
})
}
// 记住密码
const state:any = reactive({
redirect: '',
loginData: {
uuid: '',
username: 'admin',
password: 'Jytl123qaz@@',
code: ''
} as LoginData,
loginRules: {
username: [{ required: true, trigger: 'blur', message: t('login.rulesUsername') }],
password: [{ required: true, trigger: 'blur', message: t('login.rulesPassword') }],
code: [{ required: true, trigger: 'blur', message: '请输入验证码' }],
},
loginImg: loginImg[0],
loading: false,
passwordType: 'password',
// 大写提示禁用
capslockTooltipDisabled: true,
otherQuery: {},
clientHeight: document.documentElement.clientHeight,
showCopyright: true,
showDialog: false,
cookiePass: ''
});
// function validatePassword(rule: any, value: any, callback: any) {
// if (value.length == 0) {
// callback(new Error(t('login.rulesPassword')));
// } else if (value.length < 6) {
// callback(new Error(t('login.rulesPasswordPlace')));
// } else {
// callback();
// }
// }
const {
loginData,
loginRules,
loading,
passwordType,
capslockTooltipDisabled,
showCopyright
} = toRefs(state);
function checkCapslock(e: any) {
const { key } = e;
state.capslockTooltipDisabled =
key && key.length === 1 && key >= 'A' && key <= 'Z';
}
function focusClick(type:any){
activeline.value = type
}
function showPwd() {
if (passwordType.value === 'password') {
passwordType.value = '';
} else {
passwordType.value = 'password';
}
nextTick(() => {
passwordRef.value.focus();
});
}
const loadType = ref(false)
/**
* 登录
*/
function handleLogin() {
tisp.value = ""
loginFormRef.value.validate((valid: boolean) => {
if (valid) {
userInfo.value = {
username:loginData.value.username,
password:"",
newPassword:"",
confirmPassword:""
}
const user = {
username: state.loginData.username,
password: state.loginData.password,
// rememberMe: state.loginData.rememberMe,
code: state.loginData.code,
uuid: state.loginData.uuid,
custom3:loadType.value == true?'1':'0'
};
if (user.password !== state.cookiePass) {
user.password = encrypt(user.password);
}
state.loading = true;
userStore
.login(user)
.then((ress:any) => {
if(ress.code == '0'){
// if(ress.data.goto == "admin"){
router.push({ path:'/' });
// }else{
// getUserInfo().then((res: any) => {
// if(res.data.codeList != undefined && res.data.codeList.length > 1){
// router.push({ path: '/areaboard' });
// }else{
// router.push({ path: '/stationboard' });
// }
// })
// }
state.loading = false;
}
})
.catch(() => {
getCode();
state.loading = false;
});
} else {
return false;
}
});
}
watch(
route,
() => {
const query = route.query;
if (query) {
state.redirect = query.redirect as string;
state.otherQuery = getOtherQuery(query);
}
},
{
immediate: true
}
);
function getOtherQuery(query: any) {
return Object.keys(query).reduce((acc: any, cur: any) => {
if (cur !== 'redirect') {
acc[cur] = query[cur];
}
return acc;
}, {});
}
function getCode() {
getCaptcha().then((result:any) => {
codeUrl.value = result.data.img
state.loginData.uuid = result.data.uuid;
})
}
const inputref = ref()
onMounted(() => {
getCode();
inputref.value.focus()
window.onresize = () => {
if (state.clientHeight > document.documentElement.clientHeight) {
state.showCopyright = false;
} else {
state.showCopyright = true;
}
};
});
</script>
<style lang="scss">
$bg: #283443;
$light_gray: #000000;
/* reset element-ui css */
.login-container-center {
.title-container {
position: relative;
.title {
font-size: 36px;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
color: #fff;
}
.set-language {
color: #000;
position: absolute;
top: 3px;
font-size: 18px;
right: 0px;
cursor: pointer;
}
}
.el-form-item__content {
width: 100%;
background: #ffffff;
border-radius: 5px;
flex-wrap: nowrap;
}
.el-input {
display: inline-block;
width: calc(100% - 80px);
height: 50px;
background: #ffffff;
.el-input__wrapper {
width: 100%;
padding: 0;
background: #ffffff;
box-shadow: none;
.el-input__inner {
background: #ffffff;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
color: $light_gray;
height: 50px;
}
}
}
.el-input__inner {
&:hover {
border-color: var(--el-input-hover-border, var(--el-border-color-hover));
box-shadow: none;
}
box-shadow: none;
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
.copyright {
width: 100%;
position: absolute;
bottom: 0;
font-size: 12px;
text-align: center;
color: #cccccc;
}
.login-code {
width: 100%;
.el-form-item__content {
width: 100%;
.el-input {
width: calc(100% - 100px);
}
}
}
}
</style>
<style lang="scss" scoped>
$bg: #fff;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container-center {
width: 530px;
height: 590px;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;
display: flex;
flex-wrap: wrap;
// align-items: center;
// justify-content: space-around;
// background-color: $bg;
// background: url(@/assets/);
.login-container-img {
.el-image {
width: 100%;
height: 100%;
position: absolute;
left: 0;
z-index: 99;
// min-height: 420px;
// height: calc(100vh - 200px) !important;
// min-width: 310px;
}
}
.login-container-left {
position: relative;
z-index: 100;
height: 656px;
}
.login-container-right {
width: 461px;
height: 420px;
background: url(@/assets/login/bk.png);
background-size:100% 100% ;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
// align-items: center;
// -webkit-align-items: center;
padding-top: 40px;
}
}
.login-container {
min-height: 100%;
width: 100%;
background-color: $bg;
overflow: hidden;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
.login-form {
width: 85%;
margin: 0 auto;
overflow: hidden;
}
.svg-container {
padding: 0 10px;
color: $dark_gray;
vertical-align: text-bottom;
font-size: 20px;
color: rgb(181, 215, 255);
}
.svg-container-refresh {
padding-right: 5px;
padding-left: 0;
font-size: 26px;
color: rgb(181, 215, 255);
cursor: pointer;
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
.captcha {
position: absolute;
right: 0;
top: 0;
img {
height: 42px;
cursor: pointer;
vertical-align: middle;
}
}
:deep(.el-form-item__content){
background-color: transparent !important;
border-radius: 0;
}
:deep(.el-form-item){
border-radius: 0;
background: transparent;
border: 0;
}
}
@media only screen and (max-width: 1366px) {
.title {
margin: 0px auto 20px auto !important;
}
.login-code {
margin-bottom: 0;
}
}
.loadTypeClass{
:deep(.el-checkbox__label){
color: #fff;
}
}
.loginButton{
width: 341px;
height: 52px;
line-height: 41px;
color: #ffffff;
// font-weight: bold;
text-align: center;
font-size: 18px;
background: url(@/assets/login/an.png);
margin: 40px auto 30px;
cursor: pointer;
}
.login-container-right{
:deep(.el-checkbox__inner::after) {
box-sizing: content-box;
content: "";
border: 1px solid transparent;
border-left: 0;
border-top: 0;
left: 2px;
position: absolute;
top: 2px;
width: 7px;
height: 7px;
background: rgb(0, 249, 160);
transition: transform .15s ease-in 50ms;
transform-origin: center;
}
:deep(.el-input){
background: transparent !important;
--el-input-icon-color: rgb(181, 215, 255)
}
:deep(.el-input .el-input__wrapper){
background: transparent !important;
}
:deep(.el-input .el-input__wrapper .el-input__inner){
color: #ffffff !important;
background: transparent !important;
}
:deep(.el-button.is-loading:before){
background: transparent;
}
}
.lineargradient{
position:absolute;
bottom:0;
width: 100%;
height: 1px;
background: linear-gradient(to left,transparent,rgba(64, 158, 255,0.2),transparent);
}
.activeline{
background: linear-gradient(to left,transparent,rgba(64, 158, 255,1),transparent);
}
.el-overlay {
position: fixed;
z-index: 2023;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2000;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
overflow: auto;
.examination {
width: 480px;
height: 430px;
position: absolute;
top: 0px;
right: 0px;
left: 0px;
bottom: 0px;
margin: auto;
background: url(@/assets/login/passimg.png);
background-size: 100% 100%;
padding:0 30px;
.examination-title {
text-align: center;
font-family: 'Arial Negreta', 'Arial Normal', 'Arial';
font-weight: 700;
font-style: normal;
font-size: 18px;
color: #FFFFFF;
height: 40px;
line-height: 38px;
}
}
}
.passwordTisp{
color: #fff;
text-align: center;
padding: 20px;
}
:deep(.el-form-item.is-error .el-input__wrapper.is-focus){
box-shadow: 0 0 0 1px rgba(0,0,0,0) !important;
}
</style>