map/ui/dasadmin/src/views/backend/login.vue

341 lines
11 KiB
Vue
Raw Normal View History

2024-06-13 11:30:23 +08:00
<template>
2024-06-19 16:32:11 +08:00
<div class="login-div">
<!-- <div class="switch-language">
2024-06-13 11:30:23 +08:00
<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>
2024-06-19 16:32:11 +08:00
</div> -->
2024-06-13 11:30:23 +08:00
<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">
2024-06-19 16:32:11 +08:00
<div class="title">
<div class="title1">欢迎使用润阳风电场系统</div>
<div class="title2">一站式数据采集平台</div>
</div>
2024-06-13 11:30:23 +08:00
<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>
2024-06-19 10:56:57 +08:00
<el-form-item v-if="state.showCaptcha" prop="captcha">
<el-space>
2024-06-19 18:05:52 +08:00
<el-input ref="captchaRef" v-model="form.code" type="text" :placeholder="t('login.Please input a captcha')">
2024-06-19 10:56:57 +08:00
<template #prefix>
<Icon name="fa fa-unlock-alt" class="form-item-icon" size="16" color="var(--el-input-icon-color)" />
</template>
</el-input>
2024-06-19 18:05:52 +08:00
<img @click.prevent="load()" :src="state.captcha" />
2024-06-19 10:56:57 +08:00
</el-space>
</el-form-item>
<!-- <el-checkbox v-model="form.keep" :label="t('login.Hold session')" size="default"></el-checkbox> -->
2024-06-13 11:30:23 +08:00
<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'
2024-06-19 10:56:57 +08:00
import { getCaptchaData } from '/@/api/common'
2024-06-13 11:30:23 +08:00
import * as pageBubble from '/@/utils/pageBubble'
import type { FormInstance, InputInstance } from 'element-plus'
2024-06-19 18:05:52 +08:00
import { ElNotification } from 'element-plus'
2024-06-13 11:30:23 +08:00
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'
2024-06-19 10:56:57 +08:00
// import clickCaptcha from '/@/components/clickCaptcha'
2024-06-13 11:30:23 +08:00
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>()
2024-06-19 10:56:57 +08:00
const captchaRef = ref<InputInstance>()
2024-06-13 11:30:23 +08:00
const state = reactive({
2024-06-19 10:56:57 +08:00
showCaptcha: true,
2024-06-13 11:30:23 +08:00
submitLoading: false,
2024-06-19 10:56:57 +08:00
captcha: '',
2024-06-13 11:30:23 +08:00
})
const form = reactive({
username: '',
password: '',
keep: false,
2024-06-19 10:56:57 +08:00
uuid: '',
code: '',
2024-06-13 11:30:23 +08:00
})
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' })],
2024-06-19 18:05:52 +08:00
code: [buildValidatorData({ name: 'required', message: t('login.Please input a captcha') })],
2024-06-13 11:30:23 +08:00
})
const focusInput = () => {
if (form.username === '') {
usernameRef.value!.focus()
} else if (form.password === '') {
passwordRef.value!.focus()
2024-06-19 10:56:57 +08:00
} else if (form.code === '') {
captchaRef.value!.focus()
2024-06-13 11:30:23 +08:00
}
}
onMounted(() => {
timer = window.setTimeout(() => {
pageBubble.init()
}, 1000)
2024-06-19 10:56:57 +08:00
load()
2024-06-13 11:30:23 +08:00
// 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) {
2024-06-19 10:56:57 +08:00
// if (state.showCaptcha) {
// clickCaptcha(form.uuid, (captchaInfo: string) => onSubmit(captchaInfo))
// } else {
onSubmit()
// }
2024-06-13 11:30:23 +08:00
}
})
}
2024-06-19 10:56:57 +08:00
const load = () => {
getCaptchaData().then((res) => {
2024-06-19 11:41:29 +08:00
form.uuid = res.data.key
2024-06-19 10:56:57 +08:00
state.captcha = 'data:image\/png;base64,' + res.data.img
})
}
2024-06-19 11:41:29 +08:00
const onSubmit = () => {
2024-06-13 11:30:23 +08:00
state.submitLoading = true
2024-06-19 10:56:57 +08:00
login(form)
2024-06-13 11:30:23 +08:00
.then((res) => {
2024-06-19 18:05:52 +08:00
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()
}
2024-06-13 11:30:23 +08:00
})
.finally(() => {
state.submitLoading = false
2024-06-19 16:32:11 +08:00
// load()
2024-06-13 11:30:23 +08:00
})
}
</script>
<style scoped lang="scss">
2024-06-19 16:32:11 +08:00
.login-div {
}
2024-06-13 11:30:23 +08:00
.switch-language {
position: fixed;
top: 20px;
right: 20px;
z-index: 1;
}
.bubble {
overflow: hidden;
2024-06-19 16:32:11 +08:00
width: 64%;
background: url(/@/assets/bg.png) no-repeat;
background-size: 100% 100%;
2024-06-13 11:30:23 +08:00
}
.form-item-icon {
height: auto;
}
.login {
position: absolute;
top: 0;
2024-06-19 16:32:11 +08:00
right: 0;
2024-06-13 11:30:23 +08:00
display: flex;
2024-06-19 16:32:11 +08:00
width: 36%;
height: 100%;
2024-06-13 11:30:23 +08:00
align-items: center;
justify-content: center;
.login-box {
overflow: hidden;
2024-06-19 16:32:11 +08:00
width: 100%;
height: 100%;
2024-06-13 11:30:23 +08:00
background: var(--ba-bg-color-overlay);
2024-06-19 16:32:11 +08:00
display: flex;
align-items: center;
justify-content: center;
2024-06-13 11:30:23 +08:00
}
2024-06-19 16:32:11 +08:00
.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;
2024-06-13 11:30:23 +08:00
}
}
.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 {
2024-06-19 16:32:11 +08:00
padding: 100px 0;
2024-06-13 11:30:23 +08:00
}
.submit-button {
width: 100%;
letter-spacing: 2px;
font-weight: 300;
margin-top: 15px;
2024-06-19 16:32:11 +08:00
// --el-button-bg-color: var(--el-color-primary);
2024-06-13 11:30:23 +08:00
}
}
}
2024-06-19 16:32:11 +08:00
@media screen and (max-width: 1370px) {
.title {
.title1 {
font-size: 30px !important;
}
.title2 {
font-size: 20px !important;
2024-06-13 11:30:23 +08:00
}
}
}
.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>