<template> <div class="login-container"> <div class="login-logo"> <img :src="imgUrl" alt=""> </div> <div class="outside-shadow"> <div class="inside-shadow"> <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left"> <div class="title-container"> <h3 class="title">企业用户登录</h3> </div> <el-form-item prop="username"> <span class="svg-container"> <svg-icon icon-class="user"/> </span> <el-input ref="username" v-model="loginForm.username" placeholder="用户名" type="text" tabindex="1" autocomplete="on"/> </el-form-item> <el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual> <el-form-item prop="password"> <span class="svg-container"> <svg-icon icon-class="password"/> </span> <el-input ref="password" :key="passwordType" v-model="loginForm.password" :type="passwordType" auto-complete="off" placeholder="密码" tabindex="2" autocomplete="on" @keyup.native="checkCapslock" @blur="capsTooltip = false"/> </el-form-item> </el-tooltip> <div v-show="loginCount >= 3"> <el-form-item> <span class="svg-container"> <svg-icon icon-class="s-code"/> </span> <el-input v-model="code" placeholder="验证码" type="text" tabindex="3" autocomplete="on"/> </el-form-item> <div class="login-code" style="display: flex;margin-top: -15px;margin-bottom: 10px;" @click="refreshCode"> <!--验证码组件--> <s-identify :identify-code="identifyCode"/> <el-button type="text" style="margin-left: 50px" @click="refreshCode">看不清,换一张</el-button> </div> </div> <validation ref="validation"/> <el-button :loading="loading" :disabled="flag" type="primary" size="medium" style="width:100%;margin:30px 0;" @click.native.prevent="handleLogin">登录 </el-button> <div v-if="false" style="margin-top: -25px; margin-bottom: 30px; color: red">{{ failMsg }}</div> <div style="position:relative"> <div class="tips"> <span @click="goqrcode">秦港-双基双控APP下载</span> </div> </div> </el-form> </div> </div> <el-dialog :visible.sync="dialogFormQrcode" title="秦港-双基双控APP下载" width="340px"> <el-form ref="form" label-width="110px" style="width: 300px;"> <vue-qr :text="qrcodeStr" :margin="0" :size="300" color-dark="#000" color-light="#fff"/> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormQrcode = false">取 消</el-button> </div> </el-dialog> <div class="login-foot"> 秦皇岛港股份有限公司 版权所有 BETA1.0 Copy right 2013-2022 技术支持:河北秦安 Version 1.0.18 </div> </div> </template> <script> import { requestFN } from '@/utils/request' import SIdentify from './components/sidentify' import JSEncrypt from '../../../static/js/jsencrypt.min.js' // eslint-disable-next-line no-unused-vars import { validUsername } from '@/utils/validate' import validation from './components/validation' import vueQr from 'vue-qr' // eslint-disable-next-line no-unused-vars import axios from 'axios' export default { name: 'Login', components: { vueQr, validation, SIdentify }, data() { const validateUsername = (rule, value, callback) => { if (value.length < 1) { callback(new Error('用户名不能为空')) } else { callback() } } const validatePassword = (rule, value, callback) => { if (value.length < 1) { callback(new Error('密码不能为空')) } else { callback() } } return { config: config, dialogFormQrcode: false, qrcodeStr: '', imgUrl: require('@/assets/images/logonew.png'), loginForm: { username: '', password: '' }, loginRules: { username: [{ required: true, trigger: 'blur', validator: validateUsername }], password: [{ required: true, trigger: 'blur', validator: validatePassword }] }, passwordType: 'password', capsTooltip: false, loading: false, showDialog: false, redirect: undefined, otherQuery: {}, rangeStatus: false, flag: false, loginCount: 0, code: '', // text框输入的验证码 identifyCodes: '1234567890', identifyCode: '', isLock: '0', failMsg: '' } }, watch: { $route: { // eslint-disable-next-line handler: function (route) { const query = route.query if (query) { this.redirect = query.redirect this.otherQuery = this.getOtherQuery(query) } }, immediate: true } }, created() { const loginCount = this.validStr(sessionStorage.getItem('loginCount')) ? sessionStorage.getItem('loginCount') : 0 sessionStorage.clear() sessionStorage.setItem('loginCount', loginCount) this.refreshCode() // window.addEventListener('storage', this.afterQRScan) }, mounted() { if (this.loginForm.username === '') { this.$refs.username.focus() } else if (this.loginForm.password === '') { this.$refs.password.focus() } this.identifyCode = '' this.makeCode(this.identifyCodes, 4) }, destroyed() { // window.removeEventListener('storage', this.afterQRScan) }, methods: { // 验证码 randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min) }, refreshCode() { this.identifyCode = '' this.makeCode(this.identifyCodes, 4) }, makeCode(o, l) { for (let i = 0; i < l; i++) { this.identifyCode += this.identifyCodes[ this.randomNum(0, this.identifyCodes.length) ] } // console.log(this.identifyCode) }, checkCapslock(e) { const { key } = e this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z') }, showPwd() { if (this.passwordType === 'password') { this.passwordType = '' } else { this.passwordType = 'password' } this.$nextTick(() => { this.$refs.password.focus() }) }, handleLogin() { const loginCount = this.validStr(sessionStorage.getItem('loginCount')) ? sessionStorage.getItem('loginCount') : 0 if (this.loginCount >= 3) { // 登录次数超过3次,需要填写验证码 if (this.code === '') { this.$message({ message: '请输入验证码', type: 'error' }) this.flag = false return false } } if (loginCount >= 5) { // 登录次数超过3次,需要填写验证码 this.$message({ message: '发现异常登录,系统拒绝访问', type: 'error' }) this.code = '' this.refreshCode() return false } this.$refs.loginForm.validate(valid => { if (this.$refs.validation.rangeStatus) { if (valid) { this.flag = true if (this.loginCount >= 3) { // 登录次数超过3次,需要填写验证码 if (this.code === '') { this.$message({ message: '请输入验证码', type: 'error' }) this.flag = false return false } if (this.identifyCode !== this.code) { this.code = '' this.refreshCode() this.$message({ message: '请输入正确的验证码', type: 'error' }) this.flag = false return false } } var jsencrypt = new JSEncrypt() jsencrypt.setPublicKey(config.publicKey) const loginData = jsencrypt.encrypt('qdkjchina' + this.loginForm.username + ',qd,' + this.loginForm.password) this.loading = true requestFN( '/admin/check', { KEYDATA: loginData } ).then((data) => { if (data.result === 'success') { sessionStorage.setItem('user', JSON.stringify(data)) sessionStorage.setItem('loginCount', '0') this.$router.push({ path: '/index' }) this.loading = false this.flag = false this.getWorkTask(data.USER_ID) } else { if (data.msg) { this.$message.error(data.msg) } this.flag = false this.loading = false this.code = '' this.refreshCode() sessionStorage.setItem('loginCount', Number(this.loginCount) + 1) this.loginCount++ } }) .catch((e) => { this.loading = false this.flag = false this.code = '' this.refreshCode() sessionStorage.setItem('loginCount', Number(this.loginCount) + 1) this.loginCount++ }) } else { return false } } else { this.flag = false this.$message({ message: '请进行登录验证', type: 'error' }) } }) }, getWorkTask(id) { requestFN( '/xgf/user/getWorkTask', { USER_ID: id } ).then((data) => { if (data.list && data.list.length > 0) { setTimeout(() => { this.$notify.info({ title: '消息', message: '您有【' + data.list.length + '】条相关方人员数据待审核', onClick: () => { this.$router.push('/xgf/flow') } }) }, 3000) } }).catch((e) => { console.log(e) }) }, getOtherQuery(query) { return Object.keys(query).reduce((acc, cur) => { if (cur !== 'redirect') { acc[cur] = query[cur] } return acc }, {}) }, goqrcode() { requestFN( '/app/versionmanager/getVersion', { FILETYPE: '1' } ).then((data) => { // this.qrcodeStr = 'http://192.168.192.201:8991/file/uploadFiles/gwjapp/app.apk' this.qrcodeStr = config.fileUrlWaiwang + data.pd.FILEURL this.dialogFormQrcode = true }).catch((e) => { }) } // afterQRScan() { // if (e.key === 'x-admin-oauth-code') { // const code = getQueryObject(e.newValue) // const codeMap = { // wechat: 'code', // tencent: 'code' // } // const type = codeMap[this.auth_type] // const codeName = code[type] // if (codeName) { // this.$store.dispatch('LoginByThirdparty', codeName).then(() => { // this.$router.push({ path: this.redirect || '/' }) // }) // } else { // alert('第三方登录失败') // } // } // } } } </script> <style> /* 修复input 背景不协调 和光标变色 */ /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ @supports (-webkit-mask: none) and (not (cater-color: #fff)) { .login-container .el-input input { color: #fff; } } /* reset element-ui css */ .login-container .el-input { display: inline-block; height: 42px; width: 85%; } .login-container .el-input input { background: transparent; border: 0px; border-radius: 0px; font-size: 16px; color: #000; height: 42px; line-height: 42px; /* caret-color: #fff; */ } .login-container .el-input input:-webkit-autofill { box-shadow: 0 0 0px 1000px #fff inset !important; -webkit-text-fill-color: #000 !important; } .login-container .el-form-item { border: 1px solid #aad5ff; /* background: rgba(0, 0, 0, 0.1); */ border-radius: 5px; color: #454545; } </style> <style> .login-logo { position: absolute; top: 50px; left: 50px; pointer-events: none; } .login-logo img { width: 836px; height: 93px; } .login-container { height: 100vh; width: 100%; background-color: #2d3a4b; overflow: hidden; position: relative; background-image: url(../../assets/images/bg-f.jpg); background-repeat: no-repeat; background-size: 100% 100%; } .login-foot { font-size: 14px; color: rgba(255, 255, 255, 0.5); text-align: center; position: absolute; bottom: 60px; left: 50%; transform: translateX(-50%); z-index: 99; } .outside-shadow { position: absolute; right: 10%; top: 24%; width: 460px; height: 400px; border-radius: 10px; background-color: rgba(255, 255, 255, 0.3); z-index: 97; } .inside-shadow { position: absolute; top: -22.5px; left: 15px; width: 430px; height: 445px; border-radius: 10px; background-color: rgba(255, 255, 255, 0.5); z-index: 98; } .login-container .login-form { position: absolute; width: 400px; max-width: 100%; height: 490px; padding: 40px 50px; margin: 0 auto; overflow: hidden; background-color: #fff; border-radius: 5px; top: -22.5px; left: 15px; z-index: 99; } .login-name { position: absolute; right: 9.5%; top: 15%; } .login-name img { width: 422px; height: 53px; } .login-container .tips { font-size: 14px; color: #464646; margin-bottom: 60px; text-align: right; cursor: pointer; } .login-container .svg-container { padding: 2px 5px 6px 15px; color: #889aa4; vertical-align: middle; width: 30px; display: inline-block; } .login-container .title-container { position: relative; } .login-container .title-container .title { font-size: 20px; color: #000; font-weight: normal; font-family: "微软雅黑", "宋体", "Arial Narrow", Helvetica, sans-serif; } .login-container .show-pwd { position: absolute; right: 10px; top: 7px; font-size: 16px; color: #889aa4; cursor: pointer; user-select: none; } .login-container .thirdparty-button { position: absolute; right: 0; bottom: 6px; } @media only screen and (max-width: 470px) { .login-container .thirdparty-button { display: none; } } </style>