3 changed files with 485 additions and 19 deletions
|
After Width: 1920 | Height: 1080 | Size: 899 KiB |
@ -0,0 +1,472 @@ |
|||
<template> |
|||
<div class="login" v-loading="autoLoading" element-loading-text="自动登陆中..."> |
|||
<div id="login-bg-container" ref="loginBgContainerRef"></div> |
|||
<div class="screen-adapter"> |
|||
<screen-adapter> |
|||
<div class="container"> |
|||
<div id="login-animate"></div> |
|||
<div class="form theme-bg"> |
|||
<div class="title" v-html="title"></div> |
|||
<el-form @keyup.enter="dataFormSubmitHandle" :model="dataForm" :rules="dataRule" ref="dataFormRef"> |
|||
<el-form-item prop="username"> |
|||
<el-input placeholder="请输入用户账号" v-model="dataForm.username"> |
|||
<template #prefix> |
|||
<!-- <svg-icon name="userName" class="name-svg"></svg-icon>--> |
|||
<el-icon color="#20a3f5" size="18"> |
|||
<User /> |
|||
</el-icon> |
|||
</template> |
|||
</el-input> |
|||
</el-form-item> |
|||
<el-form-item prop="password"> |
|||
<el-input :type="type" placeholder="请输入密码" v-model="dataForm.password"> |
|||
<template #prefix> |
|||
<!-- <svg-icon name="password" class="pass-svg"></svg-icon>--> |
|||
<el-icon color="#20a3f5" size="18"> |
|||
<Lock /> |
|||
</el-icon> |
|||
</template> |
|||
<template #suffix> |
|||
<div style="cursor: pointer"> |
|||
<el-icon @click="flag = !flag"> |
|||
<View v-if="flag" /> |
|||
<Lock v-else /> |
|||
</el-icon> |
|||
</div> |
|||
</template> |
|||
</el-input> |
|||
</el-form-item> |
|||
|
|||
<el-button type="primary" size="small" @click="dataFormSubmitHandle" :loading="loading" class="submit-btn"> |
|||
<!-- <svg-icon v-if="loading" name="loading" className="loading-svg"></svg-icon>--> |
|||
登录 |
|||
</el-button> |
|||
</el-form> |
|||
</div> |
|||
<!-- 备案号 --> |
|||
<div class="website-records" v-if="!!support" v-html="support"></div> |
|||
<!-- <div class="record">--> |
|||
<!-- <a>技术支持:苏州琅润达检测科技有限公司</a>--> |
|||
<!-- <!– <a href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=32059002004367">苏公网安备--> |
|||
<!-- 32059002004367号</a> –>--> |
|||
<!-- </div>--> |
|||
<!-- <div class="record">|</div>--> |
|||
<!-- <div class="record">--> |
|||
<!-- <a href="https://beian.miit.gov.cn">联系电话:400 869 6981</a>--> |
|||
<!-- </div>--> |
|||
</div> |
|||
</screen-adapter> |
|||
</div> |
|||
<!-- <div class="left-title">浙江省工业碳效<br />评价与改革创新中心</div>--> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import ScreenAdapter from '@/components/screen-adapter.vue'; |
|||
import { defineComponent, onMounted, nextTick, reactive, toRefs, onActivated, onBeforeUnmount, computed, watch } from 'vue'; |
|||
import { CacheToken, CacheCompanyId, CacheTenantCode, CacheTenantType, CacheUserId } from '@/constants/cacheKey'; |
|||
import { setCache } from '@/utils/cache'; |
|||
import debounce from 'lodash/debounce'; |
|||
import { supportLangs } from '@/i18n'; |
|||
import { getUuid } from '@/utils/utils'; |
|||
import baseService from '@/service/baseService'; |
|||
import { prefechScada } from './prefechScada.js'; |
|||
import utilService from '@/service/utilService'; |
|||
import toolHooks from '@/hooks/tool'; |
|||
import { useFetch } from '@/hooks/fetch'; |
|||
import { useStore } from 'vuex'; |
|||
import { ElForm, ElMessage } from 'element-plus'; |
|||
import { useRouter } from 'vue-router'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'login', |
|||
components: { |
|||
ScreenAdapter, |
|||
//SvgIcon |
|||
}, |
|||
setup() { |
|||
const store = useStore(); |
|||
const router = useRouter(); |
|||
const { t } = useI18n(); |
|||
const state = reactive({ |
|||
dataForm: { |
|||
username: '', |
|||
password: '', |
|||
uuid: '', |
|||
captcha: 'any', |
|||
}, |
|||
loading: false, |
|||
autoLoading: false, |
|||
loginBgContainerRef: null, |
|||
support: '', |
|||
dataFormRef: null, |
|||
title: store.state.title || '物管理平台', |
|||
}); |
|||
|
|||
const getHref = () => { |
|||
let url = window.location.href; |
|||
if (url.includes('loading')) { |
|||
//const channel = new BroadcastChannel('myChannel'); |
|||
window.opener && window.opener.postMessage('*', import.meta.env.VITE_APP_NEW_OPEN_WINDOW); |
|||
|
|||
window.addEventListener('message', autoLogin); |
|||
} |
|||
}; |
|||
|
|||
getHref(); |
|||
|
|||
const autoLogin = (ret) => { |
|||
try { |
|||
// console.log('messagemessage', e) |
|||
state.autoLoading = true; |
|||
login(ret.data); |
|||
} catch (e) { |
|||
console.warn(e); |
|||
state.autoLoading = false; |
|||
} |
|||
}; |
|||
|
|||
const setDefaultTitle = () => { |
|||
state.title = '物管理平台'; |
|||
}; |
|||
|
|||
useFetch('/title', { |
|||
noErrorMsg: true, |
|||
err_cb: setDefaultTitle, |
|||
cb: (res) => { |
|||
if (res && typeof res === 'string' && res.length) { |
|||
state.title = res; |
|||
} else { |
|||
setDefaultTitle(); |
|||
} |
|||
}, |
|||
}); |
|||
|
|||
watch( |
|||
() => state.title, |
|||
() => { |
|||
nextTick(() => { |
|||
const title = document.querySelector('.title'); |
|||
if (title) { |
|||
const text = title.innerText; |
|||
store.state.title = text; |
|||
} |
|||
}); |
|||
}, |
|||
); |
|||
|
|||
useFetch('/support', { |
|||
noErrorMsg: true, |
|||
cb: (res) => { |
|||
if (res && typeof res === 'string' && res.length) { |
|||
state.support = res; |
|||
} |
|||
}, |
|||
}); |
|||
|
|||
const mainObserver = new ResizeObserver((entries) => { |
|||
const [first] = entries; |
|||
if (first) { |
|||
init(); |
|||
} |
|||
}); |
|||
|
|||
const { generateSvg2Dom, setSvgLayout } = toolHooks(); |
|||
const init = () => { |
|||
const target = document.getElementById('login-bg-container'); |
|||
if (target) { |
|||
const width = state.loginBgContainerRef.clientWidth; |
|||
const height = state.loginBgContainerRef.clientHeight; |
|||
const cb = () => { |
|||
setSvgLayout(target, { width, height, layoutIndex: 1 }); |
|||
}; |
|||
if (!target.innerHTML) { |
|||
generateSvg2Dom('cdn/login-bg.svg', target, cb); |
|||
} else { |
|||
cb(); |
|||
} |
|||
} |
|||
|
|||
{ |
|||
const target = document.getElementById('login-animate'); |
|||
if (target && !target.innerHTML) { |
|||
generateSvg2Dom('cdn/login-animate.svg', target); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
const login = (data) => { |
|||
state.loading = true; |
|||
baseService |
|||
.post('/login/noCaptcha', { |
|||
...state.dataForm, |
|||
...data, |
|||
}) |
|||
.then(async (res) => { |
|||
if (res.code !== 0) { |
|||
state.loading = false; |
|||
//this.getCaptcha(); |
|||
return ElMessage.error(res.msg || '登录失败!'); |
|||
|
|||
//return this.$notify({ title: "警告", message: res.msg || "操作失败", type: "warning" }); |
|||
} |
|||
|
|||
setCache(CacheToken, res.data); |
|||
setCache(CacheTenantCode, res.data?.tenantCode || ''); |
|||
|
|||
state.loading = false; |
|||
ElMessage.success(t('ui.login.loginOk')); |
|||
router.replace('/home'); |
|||
|
|||
setTimeout(() => { |
|||
prefechScada(); |
|||
}, 1000); |
|||
}) |
|||
.catch(() => { |
|||
state.loading = false; |
|||
}) |
|||
.finally(() => { |
|||
state.autoLoading = false; |
|||
state.loading = false; |
|||
}); |
|||
}; |
|||
|
|||
const dataFormSubmitHandle = debounce( |
|||
function () { |
|||
state.dataFormRef.validate((valid: boolean) => { |
|||
if (!valid) { |
|||
return false; |
|||
} |
|||
|
|||
login(state.dataForm); |
|||
}); |
|||
// const { username, password } = state.dataForm; |
|||
// if (!username) { |
|||
// ElMessage.warning("请输入账号"); |
|||
// return; |
|||
// } |
|||
// if (!password) { |
|||
// ElMessage.warning("请输入密码"); |
|||
// return; |
|||
// } |
|||
}, |
|||
1000, |
|||
{ leading: true, trailing: false }, |
|||
); |
|||
|
|||
onMounted(() => { |
|||
nextTick(() => { |
|||
mainObserver.observe(state.loginBgContainerRef); |
|||
}); |
|||
}); |
|||
onBeforeUnmount(() => { |
|||
mainObserver.unobserve(state.loginBgContainerRef); |
|||
}); |
|||
return { |
|||
dataFormSubmitHandle, |
|||
...toRefs(state), |
|||
}; |
|||
}, |
|||
data() { |
|||
return { |
|||
flag: false, |
|||
i18nMessages: supportLangs, |
|||
|
|||
svgContent: '', |
|||
}; |
|||
}, |
|||
computed: { |
|||
type() { |
|||
return this.flag ? 'text' : 'password'; |
|||
}, |
|||
dataRule() { |
|||
return { |
|||
username: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }], |
|||
password: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }], |
|||
//captcha: [{ required: true, message: this.$t("validate.required"), trigger: "blur" }] |
|||
}; |
|||
}, |
|||
}, |
|||
created() { |
|||
this.$store.dispatch({ type: 'logout' }); |
|||
this.getCaptcha(); |
|||
|
|||
setCache(CacheCompanyId, ''); |
|||
setCache(CacheTenantCode, ''); |
|||
setCache(CacheTenantType, ''); |
|||
setCache(CacheUserId, ''); |
|||
|
|||
//router内部重新获取home组件时,路由守卫中的to对象还是上一个租户的&&router对象不能重置?所以重新刷新一下 todo |
|||
if (this.$route.query?.reload) { |
|||
this.$router.replace('/login'); |
|||
setTimeout(() => { |
|||
history.go(0); |
|||
}); |
|||
} |
|||
}, |
|||
methods: { |
|||
// 获取验证码 |
|||
getCaptcha() { |
|||
this.dataForm.uuid = getUuid(); |
|||
}, |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped lang="less"> |
|||
.login { |
|||
position: fixed; |
|||
width: 100%; |
|||
height: 100%; |
|||
overflow: hidden; |
|||
left: 0; |
|||
top: 0; |
|||
background: #2d85be; |
|||
|
|||
#login-bg-container { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
.left-title { |
|||
position: absolute; |
|||
top: 24px; |
|||
left: 24px; |
|||
color: #fff; |
|||
font-size: 2vw; |
|||
font-style: italic; |
|||
font-family: SimSun; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.screen-adapter { |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 100%; |
|||
left: 0; |
|||
top: 0; |
|||
|
|||
.container { |
|||
position: relative; |
|||
width: 100%; |
|||
height: 100%; |
|||
|
|||
#login-animate { |
|||
width: 100%; |
|||
position: absolute; |
|||
top: 50%; |
|||
transform: translate(-8%, -50%) scale(0.78); |
|||
} |
|||
|
|||
.form { |
|||
position: absolute; |
|||
top: 50%; |
|||
transform: translateY(-50%); |
|||
right: 160px; |
|||
width: 585px; |
|||
height: 700px; |
|||
border-radius: 12px; |
|||
box-shadow: -2px 1px 30px 1px rgb(0 119 253 / 10%); |
|||
background: url('@/assets/images/login_frame.png') no-repeat center; |
|||
background-size: cover; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
padding-top: 200px; |
|||
z-index: 2; |
|||
|
|||
> .title { |
|||
text-align: center; |
|||
font-size: 28px; |
|||
font-weight: bold; |
|||
color: #222; |
|||
margin-bottom: 40px; |
|||
} |
|||
|
|||
::v-deep .el-form { |
|||
padding: 0 100px; |
|||
width: 100%; |
|||
|
|||
.el-form-item { |
|||
&:first-child { |
|||
margin-bottom: 40px; |
|||
} |
|||
} |
|||
|
|||
.el-input { |
|||
height: 56px; |
|||
font-size: 18px; |
|||
|
|||
.el-input__prefix-inner { |
|||
z-index: 2; |
|||
} |
|||
|
|||
.el-input__inner { |
|||
color: #222; |
|||
padding-left: 16px; |
|||
} |
|||
|
|||
.el-input__wrapper { |
|||
background: transparent !important; |
|||
box-shadow: 0 0 0 1px #dcdfe6 inset; |
|||
} |
|||
|
|||
input:-webkit-autofill, |
|||
input:-webkit-autofill:hover, |
|||
input:-webkit-autofill:focus, |
|||
input:-webkit-autofill:active { |
|||
-webkit-transition-delay: 111111s; |
|||
-webkit-transition: color 11111s ease-out, background-color 111111s ease-out; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.submit-btn { |
|||
margin-top: 30px; |
|||
width: 100%; |
|||
height: 56px; |
|||
font-size: 18px; |
|||
background-color: #20a3f5 !important; |
|||
box-shadow: 0 15px 10px -15px #333333; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.website-records { |
|||
height: 24px; |
|||
line-height: 20px; |
|||
text-align: center; |
|||
position: fixed; |
|||
bottom: 10px; |
|||
left: 0; |
|||
right: 0; |
|||
z-index: 100; |
|||
font-size: 12px; |
|||
color: #fff; |
|||
|
|||
.record { |
|||
display: inline-block; |
|||
vertical-align: middle; |
|||
color: #fff; |
|||
letter-spacing: 1px; |
|||
|
|||
&:nth-child(1) { |
|||
// background-image: url("@/assets/images/records/website-icon.png"); |
|||
background-position: left -2px; |
|||
background-repeat: no-repeat; |
|||
padding-left: 24px; |
|||
} |
|||
|
|||
&:nth-child(2) { |
|||
margin: -1px 6px 0; |
|||
} |
|||
} |
|||
|
|||
a { |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue