319 lines
8.0 KiB
Vue
319 lines
8.0 KiB
Vue
|
|
<template>
|
||
|
|
<div :class="prefixCls" class="login-box relative w-full h-full" v-if="!isSingleLogin">
|
||
|
|
<div class="center-box">
|
||
|
|
<div class="login-left-title">
|
||
|
|
<div class="sub-title">{{ sysName }}</div>
|
||
|
|
</div>
|
||
|
|
<div :class="`${prefixCls}-form`">
|
||
|
|
<LoginForm />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div style="width: 100%; height: 300px; display: flex;justify-content: center;align-items: center;" v-else>
|
||
|
|
<a-spin />
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
<script lang="ts" setup>
|
||
|
|
import LoginForm from './LoginForm.vue';
|
||
|
|
import { getAppEnvConfig } from '/@/utils/env';
|
||
|
|
import { useUserStore } from '/@/store/modules/user';
|
||
|
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||
|
|
import { useAppStore } from '/@/store/modules/app';
|
||
|
|
import { getLogoInfo } from '/@/api/system/login';
|
||
|
|
import { onMounted } from 'vue';
|
||
|
|
import { ref } from 'vue';
|
||
|
|
import { LogoConfig } from '/#/config';
|
||
|
|
import { useRouter } from 'vue-router';
|
||
|
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||
|
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||
|
|
|
||
|
|
const { currentRoute } = useRouter();
|
||
|
|
const userStore = useUserStore();
|
||
|
|
const isSingleLogin = ref(false)
|
||
|
|
|
||
|
|
const { notification } = useMessage();
|
||
|
|
const { t } = useI18n();
|
||
|
|
|
||
|
|
onMounted(async () => {
|
||
|
|
const fullPath = currentRoute.value.fullPath;
|
||
|
|
if (currentRoute.value.query?.ltpasToken) {
|
||
|
|
isSingleLogin.value = true
|
||
|
|
let targetURL = ''
|
||
|
|
let redirect = ''
|
||
|
|
if (fullPath.includes('targetURL')) {
|
||
|
|
const list = fullPath.split('targetURL=');
|
||
|
|
targetURL = list[1];
|
||
|
|
} else {
|
||
|
|
const list = fullPath.split('redirect=');
|
||
|
|
redirect = list[1];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
let tenantCode='';
|
||
|
|
if(getAppEnvConfig().VITE_GLOB_TENANT_ENABLED=='true'){
|
||
|
|
let url='';
|
||
|
|
if(targetURL){
|
||
|
|
url=targetURL;
|
||
|
|
}else{
|
||
|
|
url=redirect;
|
||
|
|
}
|
||
|
|
if(url.includes('tenantCode')){
|
||
|
|
const fullString = decodeURIComponent(url);
|
||
|
|
const queryString = fullString.split('?')[1];
|
||
|
|
tenantCode = (queryString.match(/tenantCode=([^&]+)/) || [])[1]
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tenantCode){
|
||
|
|
notification.error({
|
||
|
|
message: t('提示'),
|
||
|
|
description: t('租户码不能为空!'),
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
let params = {...currentRoute.value.query, targetURL: targetURL,redirect: redirect, mode: 'none',tenantCode:tenantCode }; //不要默认的错误提示
|
||
|
|
await userStore.singleLogin(params);
|
||
|
|
}
|
||
|
|
|
||
|
|
});
|
||
|
|
|
||
|
|
const appStore = useAppStore();
|
||
|
|
defineProps({
|
||
|
|
sessionTimeout: {
|
||
|
|
type: Boolean
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
const { prefixCls } = useDesign('login');
|
||
|
|
const sysName = ref(import.meta.env.VITE_SYSTEM_NAME);
|
||
|
|
|
||
|
|
let logoConfig = ref<LogoConfig>({});
|
||
|
|
let show = ref(false);
|
||
|
|
getLogoInfo().then((res) => {
|
||
|
|
show.value = true;
|
||
|
|
logoConfig.value = {
|
||
|
|
companyName: res.companyName,
|
||
|
|
shortName: res.shortName,
|
||
|
|
refreshLogoUrl: res.refreshLogoUrl,
|
||
|
|
backgroundLogoUrl: res.backgroundLogoUrl,
|
||
|
|
designerLogoUrl: res.designerLogoUrl,
|
||
|
|
loginLogoUrl: res.loginLogoUrl,
|
||
|
|
menuLogoUrl: res.menuLogoUrl
|
||
|
|
};
|
||
|
|
appStore.setLogoConfig(logoConfig.value);
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
<style lang="less">
|
||
|
|
@prefix-cls: ~'@{namespace}-login';
|
||
|
|
@logo-prefix-cls: ~'@{namespace}-app-logo';
|
||
|
|
@countdown-prefix-cls: ~'@{namespace}-countdown-input';
|
||
|
|
@dark-bg: linear-gradient(to bottom, #364876, #112049);
|
||
|
|
|
||
|
|
.vben-login-form {
|
||
|
|
padding: 40px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-box {
|
||
|
|
display: flex;
|
||
|
|
background: linear-gradient(180deg, #00356d 0%, rgb(0 53 109 / 0%) 100%), linear-gradient(180deg, #0074d3 2%, #011853 100%);
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.logo-box {
|
||
|
|
position: fixed;
|
||
|
|
top: 50px;
|
||
|
|
left: 40px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.logo-box img {
|
||
|
|
width: 180px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.center-box {
|
||
|
|
background-color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-left-title {
|
||
|
|
position: relative;
|
||
|
|
top: 30px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-left-title .title {
|
||
|
|
font-size: 20px;
|
||
|
|
border: none;
|
||
|
|
margin-bottom: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-left-title .sub-title {
|
||
|
|
font-size: 36px;
|
||
|
|
font-weight: bold;
|
||
|
|
color: #5e95ff;
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-box .right-box {
|
||
|
|
position: absolute;
|
||
|
|
right: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.fixed-tool {
|
||
|
|
position: fixed;
|
||
|
|
right: 20px;
|
||
|
|
top: 40px;
|
||
|
|
display: flex;
|
||
|
|
z-index: 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
.right-top-box {
|
||
|
|
width: 400px;
|
||
|
|
position: fixed;
|
||
|
|
right: 0;
|
||
|
|
top: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
html[data-theme='dark'] {
|
||
|
|
.login-box {
|
||
|
|
background: @dark-bg;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-left-title {
|
||
|
|
border: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.login-left-title .title {
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.@{prefix-cls} {
|
||
|
|
background-color: @dark-bg;
|
||
|
|
|
||
|
|
// &::before {
|
||
|
|
// background-image: url(/@/assets/svg/login-bg-dark.svg);
|
||
|
|
// }
|
||
|
|
|
||
|
|
.ant-input,
|
||
|
|
.ant-input-password {
|
||
|
|
background-color: #232a3b;
|
||
|
|
}
|
||
|
|
|
||
|
|
.ant-input-affix-wrapper {
|
||
|
|
border-color: #525e7c;
|
||
|
|
background-color: #232a3b;
|
||
|
|
}
|
||
|
|
|
||
|
|
.ant-checkbox-inner {
|
||
|
|
border-color: #525e7c;
|
||
|
|
}
|
||
|
|
|
||
|
|
.ant-btn:not(.ant-btn-link, .ant-btn-primary) {
|
||
|
|
border: 1px solid #4a5569;
|
||
|
|
}
|
||
|
|
|
||
|
|
&-form {
|
||
|
|
background: transparent !important;
|
||
|
|
}
|
||
|
|
|
||
|
|
.app-iconify {
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
input.fix-auto-fill,
|
||
|
|
.fix-auto-fill input {
|
||
|
|
-webkit-text-fill-color: #c9d1d9 !important;
|
||
|
|
box-shadow: inherit !important;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.@{prefix-cls} {
|
||
|
|
min-height: 100%;
|
||
|
|
overflow: hidden;
|
||
|
|
@media (max-width: @screen-xl) {
|
||
|
|
background-color: @dark-bg;
|
||
|
|
|
||
|
|
.@{prefix-cls}-form {
|
||
|
|
background-color: #fff;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.@{logo-prefix-cls} {
|
||
|
|
position: absolute;
|
||
|
|
top: 12px;
|
||
|
|
height: 30px;
|
||
|
|
|
||
|
|
&__title {
|
||
|
|
font-size: 16px;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
img {
|
||
|
|
width: 32px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.container {
|
||
|
|
.@{logo-prefix-cls} {
|
||
|
|
display: flex;
|
||
|
|
width: 60%;
|
||
|
|
height: 80px;
|
||
|
|
|
||
|
|
&__title {
|
||
|
|
font-size: 24px;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
img {
|
||
|
|
width: 48px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
&-sign-in-way {
|
||
|
|
.anticon {
|
||
|
|
font-size: 22px;
|
||
|
|
color: #888;
|
||
|
|
cursor: pointer;
|
||
|
|
|
||
|
|
&:hover {
|
||
|
|
color: @primary-color;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
input:not([type='checkbox']) {
|
||
|
|
min-width: 320px;
|
||
|
|
|
||
|
|
@media (max-width: @screen-xl) {
|
||
|
|
min-width: 280px;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (max-width: @screen-lg) {
|
||
|
|
min-width: 260px;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (max-width: @screen-md) {
|
||
|
|
min-width: 240px;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (max-width: @screen-sm) {
|
||
|
|
min-width: 160px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.@{countdown-prefix-cls} input {
|
||
|
|
min-width: unset;
|
||
|
|
}
|
||
|
|
|
||
|
|
.ant-divider-inner-text {
|
||
|
|
font-size: 12px;
|
||
|
|
color: @text-color-secondary;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
<style scoped>
|
||
|
|
:deep(.center-box) {
|
||
|
|
width: 540px;
|
||
|
|
}
|
||
|
|
</style>
|