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