2024-08-20 12:11:33 +00:00
|
|
|
<template>
|
|
|
|
<div
|
|
|
|
class="login-container"
|
|
|
|
:style="{
|
2024-08-21 01:17:14 +00:00
|
|
|
backgroundImage: `url(${configs.loginBg || '/web-common-resource/img/bg_login.png'})`
|
2024-08-20 12:11:33 +00:00
|
|
|
}"
|
|
|
|
>
|
|
|
|
<div class="login-logo">
|
|
|
|
<img :src="configs.loginLogo" />
|
|
|
|
</div>
|
|
|
|
<div class="login-center">
|
|
|
|
<div class="desc-content">
|
|
|
|
<span class="desc-title">{{ configs.promotionalTitle }}</span>
|
|
|
|
<span class="desc-remark">{{ configs.promotionalContent }}</span>
|
|
|
|
</div>
|
2024-08-29 06:31:43 +00:00
|
|
|
<el-form :model="loginForm" ref="loginFormRef" label-position="left" label-width="0px" class="card-box login-form" @keyup.enter="handleUkeyLogin" @submit.prevent>
|
2024-08-22 08:50:27 +00:00
|
|
|
<el-tabs v-model="activeName">
|
|
|
|
<el-tab-pane label="云管登录" name="normal">
|
2024-08-27 09:53:57 +00:00
|
|
|
<div v-if="activeName === 'normal'">
|
|
|
|
<div class="login-title">账号登录</div>
|
|
|
|
<el-form-item class="login-form-item" prop="account" :rules="[{ ...required, message: '请输入用户名' }]">
|
|
|
|
<el-input v-model="loginForm.account" autocomplete="off" placeholder="登录账户">
|
2024-08-22 08:50:27 +00:00
|
|
|
<template #prefix>
|
2024-08-27 09:53:57 +00:00
|
|
|
<el-icon>
|
|
|
|
<icon-ep-user />
|
|
|
|
</el-icon>
|
2024-08-22 08:50:27 +00:00
|
|
|
</template>
|
|
|
|
</el-input>
|
|
|
|
</el-form-item>
|
2024-08-27 09:53:57 +00:00
|
|
|
<el-tooltip :visible="capsTooltip" content="大写锁定已打开" placement="right" :manual="true">
|
|
|
|
<el-form-item class="login-form-item" prop="password" :rules="[{ ...required, message: '请输入密码' }]">
|
|
|
|
<el-input show-password v-model="loginForm.password" placeholder="密码" @blur="capsTooltip = false" @keyup="checkCapslock">
|
|
|
|
<template #prefix>
|
|
|
|
<el-icon><icon-ep-lock /></el-icon>
|
|
|
|
</template>
|
|
|
|
</el-input>
|
|
|
|
</el-form-item>
|
|
|
|
</el-tooltip>
|
|
|
|
<el-form-item class="login-form-item">
|
|
|
|
<div class="operate-region">
|
|
|
|
<span class="remember">
|
|
|
|
<el-switch v-model="remember"></el-switch>
|
|
|
|
<span class="m-l-xs">记住密码</span>
|
|
|
|
</span>
|
|
|
|
<a :href="`mailto:${configs.helpInformationLink}`" type="text" class="text-info help-info" :title="configs.helpInformationContent">{{ configs.helpInformationContent }}</a>
|
|
|
|
</div>
|
|
|
|
</el-form-item>
|
|
|
|
<el-button class="login-btn" type="primary" :loading="loading" @click="handleLogin">登录</el-button>
|
|
|
|
</div>
|
2024-08-22 08:50:27 +00:00
|
|
|
</el-tab-pane>
|
2024-08-30 01:23:56 +00:00
|
|
|
<el-tab-pane label="UKEY登录" name="UKEY">
|
2024-08-27 09:53:57 +00:00
|
|
|
<div v-if="activeName === 'UKEY'">
|
|
|
|
<el-tooltip :visible="capsTooltip" content="大写锁定已打开" placement="right" :manual="true">
|
|
|
|
<el-form-item class="login-form-item" prop="ukeyPassword" :rules="[{ ...required, message: '请输入UKEY密码' }]">
|
2024-08-29 06:31:43 +00:00
|
|
|
<el-input show-password v-model="loginForm.ukeyPassword" placeholder="UKEY密码" @blur="capsTooltip = false" @keyup="checkCapslock" ref="ukeyPasswordInputRef">
|
2024-08-27 09:53:57 +00:00
|
|
|
<template #prefix>
|
|
|
|
<el-icon><icon-ep-lock /></el-icon>
|
|
|
|
</template>
|
|
|
|
</el-input>
|
|
|
|
</el-form-item>
|
|
|
|
</el-tooltip>
|
|
|
|
<el-button class="login-btn" type="primary" :loading="loading" @click="handleUkeyLogin">登录</el-button>
|
|
|
|
</div>
|
2024-08-22 08:50:27 +00:00
|
|
|
</el-tab-pane>
|
2024-10-31 03:45:22 +00:00
|
|
|
<el-tab-pane label="软KEY登录" name="SKEY">
|
|
|
|
<div v-if="activeName === 'SKEY'">
|
|
|
|
<div class="login-title">账号登录</div>
|
|
|
|
<el-form-item class="login-form-item" prop="account" :rules="[{ ...required, message: '请输入用户名' }]">
|
|
|
|
<el-input v-model="loginForm.saccount" autocomplete="off" placeholder="登录账户">
|
|
|
|
<template #prefix>
|
|
|
|
<el-icon>
|
|
|
|
<icon-ep-user />
|
|
|
|
</el-icon>
|
|
|
|
</template>
|
|
|
|
</el-input>
|
|
|
|
</el-form-item>
|
|
|
|
<el-tooltip :visible="capsTooltip" content="大写锁定已打开" placement="right" :manual="true">
|
|
|
|
<el-form-item class="login-form-item" prop="password" :rules="[{ ...required, message: '请输入密码' }]">
|
|
|
|
<el-input show-password v-model="loginForm.spassword" placeholder="密码" @blur="capsTooltip = false" @keyup="checkCapslock">
|
|
|
|
<template #prefix>
|
|
|
|
<el-icon><icon-ep-lock /></el-icon>
|
|
|
|
</template>
|
|
|
|
</el-input>
|
|
|
|
</el-form-item>
|
|
|
|
</el-tooltip>
|
|
|
|
<el-form-item class="login-form-item">
|
|
|
|
<div class="operate-region">
|
|
|
|
<span class="remember">
|
|
|
|
<el-switch v-model="remember"></el-switch>
|
|
|
|
<span class="m-l-xs">记住密码</span>
|
|
|
|
</span>
|
|
|
|
<a :href="`mailto:${configs.helpInformationLink}`" type="text" class="text-info help-info" :title="configs.helpInformationContent">{{ configs.helpInformationContent }}</a>
|
|
|
|
</div>
|
|
|
|
</el-form-item>
|
|
|
|
<el-button class="login-btn" type="primary" :loading="loading" @click="handleLogin4sKey">登录</el-button>
|
|
|
|
</div>
|
|
|
|
</el-tab-pane>
|
2024-08-22 08:50:27 +00:00
|
|
|
</el-tabs>
|
2024-08-20 12:11:33 +00:00
|
|
|
</el-form>
|
|
|
|
</div>
|
|
|
|
<div class="copyright-info">{{ configs.copyrightInformation }}</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2024-08-21 01:17:14 +00:00
|
|
|
import { decrypt, encrypt } from 'utils/crypto'
|
|
|
|
import { login } from 'services'
|
|
|
|
import { useStore } from 'vuex'
|
|
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
|
|
import setLoginData from './tools'
|
|
|
|
import { required } from '@/validate'
|
2024-08-22 08:50:27 +00:00
|
|
|
import { setUkeyPassword } from 'utils/auth'
|
2024-08-21 01:17:14 +00:00
|
|
|
import type { FormInstance } from 'element-plus'
|
2024-08-20 12:11:33 +00:00
|
|
|
|
2024-08-29 06:31:43 +00:00
|
|
|
const ukeyPasswordInputRef = ref()
|
|
|
|
onMounted(() => {
|
|
|
|
if (typeof ukeyPasswordInputRef.value.focus === 'function') ukeyPasswordInputRef.value.focus()
|
|
|
|
})
|
|
|
|
const activeName = ref('UKEY')
|
2024-08-20 12:11:33 +00:00
|
|
|
const loginForm = reactive({
|
2024-08-21 01:17:14 +00:00
|
|
|
account: '',
|
2024-08-22 08:50:27 +00:00
|
|
|
password: '',
|
|
|
|
ukeyPassword: ''
|
2024-08-21 01:17:14 +00:00
|
|
|
})
|
|
|
|
const remember = ref(false)
|
|
|
|
const loading = ref(false)
|
|
|
|
const capsTooltip = ref(false)
|
2024-08-20 12:11:33 +00:00
|
|
|
|
2024-08-21 01:17:14 +00:00
|
|
|
const store = useStore()
|
|
|
|
const configs = computed(() => store.getters.pageConfig)
|
|
|
|
const appConfigs = computed(() => store.getters.appConfigs)
|
|
|
|
const loginFormRef = ref<FormInstance>()
|
2024-08-20 12:11:33 +00:00
|
|
|
const init = () => {
|
2024-08-21 01:17:14 +00:00
|
|
|
const local = localStorage.getItem('cmcLoginData')
|
2024-08-20 12:11:33 +00:00
|
|
|
if (local) {
|
2024-08-21 01:17:14 +00:00
|
|
|
const obj = JSON.parse(local)
|
|
|
|
loginForm.account = obj.account
|
|
|
|
loginForm.password = decrypt(obj.password)
|
|
|
|
remember.value = true
|
2024-08-20 12:11:33 +00:00
|
|
|
}
|
2024-08-21 01:17:14 +00:00
|
|
|
}
|
|
|
|
init()
|
|
|
|
const router = useRouter()
|
|
|
|
const route = useRoute()
|
2024-08-20 12:11:33 +00:00
|
|
|
function goLogin(data: any) {
|
2024-08-21 01:17:14 +00:00
|
|
|
setLoginData(data)
|
2024-08-20 12:11:33 +00:00
|
|
|
if (unref(remember)) {
|
|
|
|
const obj = {
|
|
|
|
account: loginForm.account,
|
|
|
|
password: encrypt(loginForm.password)
|
2024-08-21 01:17:14 +00:00
|
|
|
}
|
|
|
|
localStorage.setItem('cmcLoginData', JSON.stringify(obj))
|
2024-08-20 12:11:33 +00:00
|
|
|
} else {
|
2024-08-21 01:17:14 +00:00
|
|
|
localStorage.removeItem('cmcLoginData')
|
2024-08-20 12:11:33 +00:00
|
|
|
}
|
2024-08-21 01:17:14 +00:00
|
|
|
const { redirect } = route.query
|
|
|
|
const path = redirect ? (redirect as string).split('/#')[1] : appConfigs.value.homePath
|
|
|
|
router.replace(path)
|
|
|
|
localStorage.removeItem('lockData')
|
2024-08-20 12:11:33 +00:00
|
|
|
}
|
|
|
|
function handleLogin() {
|
2024-08-21 01:17:14 +00:00
|
|
|
if (!loginFormRef.value) return
|
|
|
|
loginFormRef.value.validate(async valid => {
|
2024-08-20 12:11:33 +00:00
|
|
|
if (valid) {
|
2024-08-21 01:17:14 +00:00
|
|
|
loading.value = true
|
|
|
|
const { account, password } = loginForm
|
2024-08-20 12:11:33 +00:00
|
|
|
const res = await login({
|
|
|
|
account,
|
|
|
|
password: encrypt(password),
|
|
|
|
isManager: true
|
2024-08-26 02:38:22 +00:00
|
|
|
}).finally(() => {
|
|
|
|
loading.value = false
|
2024-08-21 01:17:14 +00:00
|
|
|
})
|
2024-08-20 12:11:33 +00:00
|
|
|
if (res.success) {
|
2024-08-21 01:17:14 +00:00
|
|
|
goLogin(res.data)
|
2024-08-20 12:11:33 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-21 01:17:14 +00:00
|
|
|
})
|
2024-08-20 12:11:33 +00:00
|
|
|
}
|
2024-10-31 03:45:22 +00:00
|
|
|
// 软key 登录
|
|
|
|
function handleLogin4sKey() {
|
|
|
|
if (!loginFormRef.value) return
|
|
|
|
loginFormRef.value.validate(async valid => {
|
|
|
|
if (valid) {
|
|
|
|
loading.value = true
|
|
|
|
const { saccount, spassword } = loginForm
|
|
|
|
const res = await store
|
|
|
|
.dispatch('skey/Login', {account: saccount, password: spassword})
|
|
|
|
.finally(() => (loading.value = false))
|
|
|
|
.catch(() => (loading.value = false))
|
|
|
|
if (res && res.success) {
|
|
|
|
console.log('SKEY: 登录成功,云管融合登录接口返回', res)
|
|
|
|
goLogin(res.data)
|
|
|
|
} else {
|
|
|
|
console.log('SKEY: 登录失败,云管融合登录接口返回', res)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
|
2024-08-22 08:50:27 +00:00
|
|
|
// ukey 登录
|
|
|
|
async function handleUkeyLogin() {
|
|
|
|
if (!loginFormRef.value) return
|
|
|
|
loginFormRef.value.validate(async valid => {
|
|
|
|
if (valid) {
|
2024-08-28 07:28:51 +00:00
|
|
|
console.log('UKEY: 密码校验通过')
|
2024-08-22 08:50:27 +00:00
|
|
|
loading.value = true
|
2024-08-28 07:30:28 +00:00
|
|
|
const res = await store
|
|
|
|
.dispatch('ukey/Login', loginForm.ukeyPassword)
|
|
|
|
.finally(() => (loading.value = false))
|
|
|
|
.catch(() => (loading.value = false))
|
2024-08-26 08:42:26 +00:00
|
|
|
if (res && res.success) {
|
2024-08-28 07:28:51 +00:00
|
|
|
console.log('UKEY: 登录成功,云管融合登录接口返回', res)
|
2024-08-22 08:50:27 +00:00
|
|
|
// 用于保活与监测 ukey 是否拔出
|
|
|
|
setUkeyPassword(loginForm.ukeyPassword)
|
|
|
|
goLogin(res.data)
|
2024-08-28 07:28:51 +00:00
|
|
|
} else {
|
|
|
|
console.log('UKEY: 登录失败,云管融合登录接口返回', res)
|
2024-08-22 08:50:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2024-08-21 01:17:14 +00:00
|
|
|
function checkCapslock({ shiftKey, key }: { shiftKey: boolean; key: string }) {
|
2024-08-20 12:11:33 +00:00
|
|
|
if (key && key.length === 1) {
|
2024-08-21 01:17:14 +00:00
|
|
|
if ((shiftKey && key >= 'a' && key <= 'z') || (!shiftKey && key >= 'A' && key <= 'Z')) {
|
|
|
|
capsTooltip.value = true
|
2024-08-20 12:11:33 +00:00
|
|
|
} else {
|
2024-08-21 01:17:14 +00:00
|
|
|
capsTooltip.value = false
|
2024-08-20 12:11:33 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-21 01:17:14 +00:00
|
|
|
if (key === 'CapsLock' && unref(capsTooltip) === true) {
|
|
|
|
capsTooltip.value = false
|
2024-08-20 12:11:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.login-container {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
height: 100vh;
|
2024-08-21 01:17:14 +00:00
|
|
|
background: url('/web-common-resource/img/bg_login.png') #2d3a4b no-repeat;
|
2024-08-20 12:11:33 +00:00
|
|
|
background-size: cover;
|
|
|
|
.login-logo {
|
|
|
|
padding: 5px 40px;
|
|
|
|
img {
|
|
|
|
height: 40px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.login-center {
|
|
|
|
display: flex;
|
|
|
|
flex: 1;
|
|
|
|
justify-content: space-around;
|
|
|
|
align-items: center;
|
|
|
|
.desc-content {
|
|
|
|
color: #fff;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
margin-top: -150x;
|
|
|
|
width: 600px;
|
|
|
|
.desc-title {
|
|
|
|
font-weight: 700;
|
|
|
|
font-style: normal;
|
|
|
|
font-size: 38px;
|
|
|
|
color: #ffffff;
|
|
|
|
margin-bottom: 56px;
|
|
|
|
}
|
|
|
|
.desc-remark {
|
|
|
|
line-height: 40px;
|
|
|
|
font-weight: 400;
|
|
|
|
font-style: normal;
|
|
|
|
font-size: 22px;
|
|
|
|
color: #ffffff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.login-form {
|
|
|
|
box-sizing: border-box;
|
|
|
|
width: 462px;
|
|
|
|
padding: 50px 30px;
|
|
|
|
background: #fff;
|
|
|
|
font-size: 17px;
|
|
|
|
.login-title {
|
|
|
|
font-size: 32px;
|
|
|
|
text-align: center;
|
|
|
|
color: #333;
|
|
|
|
margin-bottom: 50px;
|
|
|
|
}
|
|
|
|
.operate-region {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
width: 100%;
|
|
|
|
.remember {
|
|
|
|
flex: 1;
|
|
|
|
text-align: left;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.login-btn {
|
|
|
|
margin-top: 20px;
|
|
|
|
height: 60px;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
.help-info {
|
|
|
|
max-width: 130px;
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
white-space: nowrap;
|
|
|
|
}
|
|
|
|
.login-form-item {
|
|
|
|
:deep(.#{$namespace}-input__wrapper) {
|
|
|
|
height: 60px;
|
|
|
|
line-height: 60px;
|
|
|
|
}
|
|
|
|
:deep(.#{$namespace}-input__prefix) {
|
|
|
|
font-size: 20px;
|
|
|
|
color: #000;
|
|
|
|
padding: 0 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.copyright-info {
|
|
|
|
padding: 10px 0;
|
|
|
|
text-align: center;
|
|
|
|
background: rgba(10, 37, 68, 0.6);
|
|
|
|
color: #bbbbbb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|