341 lines
11 KiB
Vue
341 lines
11 KiB
Vue
<template>
|
||
<div class="login-div">
|
||
<!-- <div class="switch-language">
|
||
<el-dropdown size="large" :hide-timeout="50" placement="bottom-end" :hide-on-click="true">
|
||
<Icon name="fa fa-globe" color="var(--el-text-color-secondary)" size="28" />
|
||
<template #dropdown>
|
||
<el-dropdown-menu class="chang-lang">
|
||
<el-dropdown-item v-for="item in config.lang.langArray" :key="item.name" @click="editDefaultLang(item.name)">
|
||
{{ item.value }}
|
||
</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
</template>
|
||
</el-dropdown>
|
||
</div> -->
|
||
<div @contextmenu.stop="" id="bubble" class="bubble">
|
||
<canvas id="bubble-canvas" class="bubble-canvas"></canvas>
|
||
</div>
|
||
<div class="login">
|
||
<div class="login-box">
|
||
<div class="form">
|
||
<div class="title">
|
||
<div class="title1">欢迎使用润阳风电场系统</div>
|
||
<div class="title2">一站式数据采集平台</div>
|
||
</div>
|
||
<div class="content">
|
||
<el-form @keyup.enter="onSubmitPre()" ref="formRef" :rules="rules" size="large" :model="form">
|
||
<el-form-item prop="username">
|
||
<el-input
|
||
ref="usernameRef"
|
||
type="text"
|
||
clearable
|
||
v-model="form.username"
|
||
:placeholder="t('login.Please enter an account')"
|
||
>
|
||
<template #prefix>
|
||
<Icon name="fa fa-user" class="form-item-icon" size="16" color="var(--el-input-icon-color)" />
|
||
</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item prop="password">
|
||
<el-input
|
||
ref="passwordRef"
|
||
v-model="form.password"
|
||
type="password"
|
||
:placeholder="t('login.Please input a password')"
|
||
show-password
|
||
>
|
||
<template #prefix>
|
||
<Icon name="fa fa-unlock-alt" class="form-item-icon" size="16" color="var(--el-input-icon-color)" />
|
||
</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item v-if="state.showCaptcha" prop="captcha">
|
||
<el-space>
|
||
<el-input ref="captchaRef" v-model="form.code" type="text" :placeholder="t('login.Please input a captcha')">
|
||
<template #prefix>
|
||
<Icon name="fa fa-unlock-alt" class="form-item-icon" size="16" color="var(--el-input-icon-color)" />
|
||
</template>
|
||
</el-input>
|
||
<img @click.prevent="load()" :src="state.captcha" />
|
||
</el-space>
|
||
</el-form-item>
|
||
<!-- <el-checkbox v-model="form.keep" :label="t('login.Hold session')" size="default"></el-checkbox> -->
|
||
<el-form-item>
|
||
<el-button
|
||
:loading="state.submitLoading"
|
||
class="submit-button"
|
||
round
|
||
type="primary"
|
||
size="large"
|
||
@click="onSubmitPre()"
|
||
>
|
||
{{ t('login.Sign in') }}
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { onMounted, onBeforeUnmount, reactive, ref, nextTick } from 'vue'
|
||
import { getCaptchaData } from '/@/api/common'
|
||
import * as pageBubble from '/@/utils/pageBubble'
|
||
import type { FormInstance, InputInstance } from 'element-plus'
|
||
import { ElNotification } from 'element-plus'
|
||
import { useI18n } from 'vue-i18n'
|
||
import { editDefaultLang } from '/@/lang/index'
|
||
import { useConfig } from '/@/stores/config'
|
||
import { useAdminInfo } from '/@/stores/adminInfo'
|
||
import { login } from '/@/api/backend'
|
||
import { buildValidatorData } from '/@/utils/validate'
|
||
import router from '/@/router'
|
||
// import clickCaptcha from '/@/components/clickCaptcha'
|
||
import toggleDark from '/@/utils/useDark'
|
||
import { fullUrl } from '/@/utils/common'
|
||
import { adminBaseRoutePath } from '/@/router/static/adminBase'
|
||
import JSEncrypt from 'jsencrypt'
|
||
let timer: number
|
||
|
||
const config = useConfig()
|
||
const adminInfo = useAdminInfo()
|
||
toggleDark(config.layout.isDark)
|
||
|
||
const formRef = ref<FormInstance>()
|
||
const usernameRef = ref<InputInstance>()
|
||
const passwordRef = ref<InputInstance>()
|
||
const captchaRef = ref<InputInstance>()
|
||
const state = reactive({
|
||
showCaptcha: true,
|
||
submitLoading: false,
|
||
captcha: '',
|
||
})
|
||
const form = reactive({
|
||
username: '',
|
||
password: '',
|
||
keep: false,
|
||
uuid: '',
|
||
code: '',
|
||
})
|
||
|
||
const { t } = useI18n()
|
||
|
||
// 表单验证规则
|
||
const rules = reactive({
|
||
username: [buildValidatorData({ name: 'required', message: t('login.Please enter an account') }), buildValidatorData({ name: 'account' })],
|
||
password: [buildValidatorData({ name: 'required', message: t('login.Please input a password') }), buildValidatorData({ name: 'password' })],
|
||
code: [buildValidatorData({ name: 'required', message: t('login.Please input a captcha') })],
|
||
})
|
||
|
||
const focusInput = () => {
|
||
if (form.username === '') {
|
||
usernameRef.value!.focus()
|
||
} else if (form.password === '') {
|
||
passwordRef.value!.focus()
|
||
} else if (form.code === '') {
|
||
captchaRef.value!.focus()
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
timer = window.setTimeout(() => {
|
||
pageBubble.init()
|
||
}, 1000)
|
||
load()
|
||
// login('get')
|
||
// .then((res) => {
|
||
// state.showCaptcha = res.data.captcha
|
||
// nextTick(() => focusInput())
|
||
// })
|
||
// .catch((err) => {
|
||
// console.log(err)
|
||
// })
|
||
})
|
||
|
||
onBeforeUnmount(() => {
|
||
clearTimeout(timer)
|
||
pageBubble.removeListeners()
|
||
})
|
||
|
||
const onSubmitPre = () => {
|
||
formRef.value?.validate((valid) => {
|
||
if (valid) {
|
||
// if (state.showCaptcha) {
|
||
// clickCaptcha(form.uuid, (captchaInfo: string) => onSubmit(captchaInfo))
|
||
// } else {
|
||
onSubmit()
|
||
// }
|
||
}
|
||
})
|
||
}
|
||
|
||
const load = () => {
|
||
getCaptchaData().then((res) => {
|
||
form.uuid = res.data.key
|
||
state.captcha = 'data:image\/png;base64,' + res.data.img
|
||
})
|
||
}
|
||
|
||
const onSubmit = () => {
|
||
state.submitLoading = true
|
||
login(form)
|
||
.then((res) => {
|
||
if (res.code == 200) {
|
||
adminInfo.dataFill({
|
||
id: res.data.sysUser.id,
|
||
username: res.data.sysUser.account,
|
||
nickname: res.data.sysUser.userName,
|
||
avatar: '',
|
||
last_login_time: '',
|
||
token: res.data.token,
|
||
refresh_token: '',
|
||
// 是否是superAdmin,用于判定是否显示终端按钮等,不做任何权限判断
|
||
super: false,
|
||
})
|
||
router.push({ path: adminBaseRoutePath })
|
||
} else {
|
||
ElNotification({
|
||
message: res.msg,
|
||
type: 'error',
|
||
})
|
||
load()
|
||
}
|
||
})
|
||
.finally(() => {
|
||
state.submitLoading = false
|
||
// load()
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.login-div {
|
||
}
|
||
.switch-language {
|
||
position: fixed;
|
||
top: 20px;
|
||
right: 20px;
|
||
z-index: 1;
|
||
}
|
||
.bubble {
|
||
overflow: hidden;
|
||
width: 64%;
|
||
background: url(/@/assets/bg.png) no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
.form-item-icon {
|
||
height: auto;
|
||
}
|
||
.login {
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
display: flex;
|
||
width: 36%;
|
||
height: 100%;
|
||
align-items: center;
|
||
justify-content: center;
|
||
.login-box {
|
||
overflow: hidden;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: var(--ba-bg-color-overlay);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.title {
|
||
.title1 {
|
||
font-size: 36px;
|
||
color: #333333;
|
||
letter-spacing: 0;
|
||
line-height: 36px;
|
||
font-weight: 600;
|
||
}
|
||
.title2 {
|
||
padding-top: 20px;
|
||
font-size: 24px;
|
||
color: #666666;
|
||
letter-spacing: 0;
|
||
line-height: 24px;
|
||
font-weight: 400;
|
||
}
|
||
}
|
||
.form {
|
||
position: relative;
|
||
.profile-avatar {
|
||
display: block;
|
||
position: absolute;
|
||
height: 100px;
|
||
width: 100px;
|
||
border-radius: 50%;
|
||
border: 4px solid var(--ba-bg-color-overlay);
|
||
top: -50px;
|
||
right: calc(50% - 50px);
|
||
z-index: 2;
|
||
user-select: none;
|
||
}
|
||
.content {
|
||
padding: 100px 0;
|
||
}
|
||
.submit-button {
|
||
width: 100%;
|
||
letter-spacing: 2px;
|
||
font-weight: 300;
|
||
margin-top: 15px;
|
||
// --el-button-bg-color: var(--el-color-primary);
|
||
}
|
||
}
|
||
}
|
||
|
||
@media screen and (max-width: 1370px) {
|
||
.title {
|
||
.title1 {
|
||
font-size: 30px !important;
|
||
}
|
||
.title2 {
|
||
font-size: 20px !important;
|
||
}
|
||
}
|
||
}
|
||
.chang-lang :deep(.el-dropdown-menu__item) {
|
||
justify-content: center;
|
||
}
|
||
.content :deep(.el-input__prefix) {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
// 暗黑样式
|
||
@at-root .dark {
|
||
.bubble {
|
||
background: url(/@/assets/bg-dark.jpg) repeat;
|
||
}
|
||
.login {
|
||
.login-box {
|
||
background: #161b22;
|
||
}
|
||
.head {
|
||
img {
|
||
filter: brightness(61%);
|
||
}
|
||
}
|
||
.form {
|
||
.submit-button {
|
||
--el-button-bg-color: var(--el-color-primary-light-5);
|
||
--el-button-border-color: rgba(240, 252, 241, 0.1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
@media screen and (max-height: 800px) {
|
||
.login .login-box {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
</style>
|