map/ui/dasadmin/src/views/backend/login.vue
2024-06-19 18:05:52 +08:00

341 lines
11 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-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>