refactor: 优化加载慢时国际化会有短暂闪烁

Signed-off-by: fit2-zhao <yong.zhao@fit2cloud.com>
This commit is contained in:
fit2-zhao 2024-08-26 18:00:39 +08:00 committed by Craftsman
parent b9df006022
commit a02673b154
7 changed files with 208 additions and 177 deletions

View File

@ -25,12 +25,11 @@ export const getLanguage = () => {
axios.get('/system/default-locale').then((response) => {
if (response.data && response.data.data) {
language = response.data.data.replace('_', '-');
i18n.locale = language;
}
return language;
});
} else {
return language;
}
return language;
};
const i18n = new VueI18n({

View File

@ -5,10 +5,10 @@
<div class="content">
<div class="title">
<div class="title-img">
<img :src="'/display/file/loginLogo'" alt="">
<img :src="'/display/file/loginLogo'" alt="" />
</div>
<div class="welcome">
<span>{{ loginTitle }}</span>
<span>{{ loginTitle || this.$t('commons.welcome') }}</span>
</div>
</div>
<div class="form">
@ -17,19 +17,27 @@
<el-radio-group v-model="form.authenticate" @change="redirectAuth(form.authenticate)">
<el-radio label="LDAP" size="mini" v-if="openLdap">LDAP</el-radio>
<el-radio label="LOCAL" size="mini" v-if="openLdap">{{ $t('login.normal_Login') }}</el-radio>
<el-radio :label="auth.id" size="mini" v-for="auth in authSources" :key="auth.id">{{ auth.type }}
<el-radio :label="auth.id" size="mini" v-for="auth in authSources" :key="auth.id"
>{{ auth.type }}
{{ auth.name }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="username">
<el-input v-model="form.username" :placeholder="$t('commons.login_username')" autofocus
autocomplete="off"/>
<el-input
v-model="form.username"
:placeholder="$t('commons.login_username')"
autofocus
autocomplete="off" />
</el-form-item>
<el-form-item prop="password">
<el-input v-model="form.password" :placeholder="$t('commons.password')" show-password
autocomplete="off"
maxlength="30" show-word-limit/>
<el-input
v-model="form.password"
:placeholder="$t('commons.password')"
show-password
autocomplete="off"
maxlength="30"
show-word-limit />
</el-form-item>
</el-form>
</div>
@ -44,23 +52,21 @@
</div>
</el-col>
<div class="divider"/>
<div class="divider" />
<el-col :span="12">
<div class="content">
<img class="login-image" :src="'/display/file/loginImage'" alt="">
<img class="login-image" :src="'/display/file/loginImage'" alt="" />
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import {getCurrentUserId, publicKeyEncrypt} from "../../utils/token";
import {DEFAULT_LANGUAGE, PRIMARY_COLOR} from "../../utils/constants";
import {hasLicense, hasPermissions, saveLicense} from "../../utils/permission";
import { getCurrentUserId, publicKeyEncrypt } from '../../utils/token';
import { DEFAULT_LANGUAGE, PRIMARY_COLOR } from '../../utils/constants';
import { hasLicense, hasPermissions, saveLicense } from '../../utils/permission';
import {
checkLdapOpen,
getAuthSource,
@ -68,39 +74,38 @@ import {
getDisplayInfo,
getLanguage,
getSystemTheme,
saveBaseUrl
} from "../../api/user";
import {useUserStore} from "@/store"
import {operationConfirm} from "../../utils";
import {getModuleList} from "../../api/module";
import {getLicense} from "../../api/license";
import {setLanguage} from "../../i18n";
saveBaseUrl,
} from '../../api/user';
import { useUserStore } from '@/store';
import { operationConfirm } from '../../utils';
import { getModuleList } from '../../api/module';
import { getLicense } from '../../api/license';
import { setLanguage } from '../../i18n';
const checkLicense = () => {
return getLicense()
.then(response => {
.then((response) => {
let data = response.data;
if (!data || !data.status || !data.license || !data.license.count) {
return;
}
saveLicense(data.status)
saveLicense(data.status);
if (data.status !== 'valid') {
localStorage.setItem('setShowLicenseCountWarning', "false");
localStorage.setItem('setShowLicenseCountWarning', 'false');
}
})
.catch(e => {
})
}
.catch((e) => {});
};
export default {
name: "Login",
name: 'Login',
data() {
return {
loading: false,
form: {
username: '',
password: '',
authenticate: 'LOCAL'
authenticate: 'LOCAL',
},
rules: this.getDefaultRules(),
msg: '',
@ -110,81 +115,73 @@ export default {
openLdap: false,
authSources: [],
lastUser: sessionStorage.getItem('lastUser'),
loginTitle: this.$t('commons.welcome')
}
loginTitle: undefined,
};
},
watch: {
$route: {
handler: function (route) {
const query = route.query
const query = route.query;
if (query) {
this.redirect = query.redirect
this.otherQuery = this.getOtherQuery(query)
this.redirect = query.redirect;
this.otherQuery = this.getOtherQuery(query);
}
},
immediate: true
}
immediate: true,
},
},
beforeCreate() {
const userStore = useUserStore()
getSystemTheme()
.then(res => {
this.color = res.data ? res.data : PRIMARY_COLOR;
document.body.style.setProperty('--primary_color', this.color);
});
const userStore = useUserStore();
getSystemTheme().then((res) => {
this.color = res.data ? res.data : PRIMARY_COLOR;
document.body.style.setProperty('--primary_color', this.color);
});
// url
saveBaseUrl()
.then(() => {
})
.catch(() => {
});
.then(() => {})
.catch(() => {});
// ldap open
checkLdapOpen("/ldap/open")
.then(response => {
this.openLdap = response.data;
});
getModuleList()
.then(response => {
let modules = {};
response.data.forEach(m => {
modules[m.key] = m.status;
});
localStorage.setItem('modules', JSON.stringify(modules));
checkLdapOpen('/ldap/open').then((response) => {
this.openLdap = response.data;
});
getModuleList().then((response) => {
let modules = {};
response.data.forEach((m) => {
modules[m.key] = m.status;
});
localStorage.setItem('modules', JSON.stringify(modules));
});
//
checkLicense()
.then(() => {
if (!hasLicense()) {
return;
checkLicense().then(() => {
if (!hasLicense()) {
return;
}
getAuthSources().then((response) => {
this.authSources = response.data;
});
getDisplayInfo().then((response) => {
if (response.data[3].paramValue) {
this.loginTitle = response.data[3].paramValue;
}
getAuthSources()
.then(response => {
this.authSources = response.data;
});
getDisplayInfo()
.then(response => {
if (response.data[3].paramValue) {
this.loginTitle = response.data[3].paramValue;
}
let title = response.data[4].paramValue;
if (title) {
document.title = title;
}
})
})
let title = response.data[4].paramValue;
if (title) {
document.title = title;
}
});
});
userStore.getIsLogin()
.then(res => {
userStore
.getIsLogin()
.then((res) => {
this.getLanguage(res.data.language);
window.location.href = "/";
window.location.href = '/';
})
.catch(data => {
.catch((data) => {
//
localStorage.setItem("publicKey", data.message);
let lang = localStorage.getItem("language");
localStorage.setItem('publicKey', data.message);
let lang = localStorage.getItem('language');
if (lang) {
setLanguage(lang);
this.rules = this.getDefaultRules();
@ -194,10 +191,9 @@ export default {
window.location.href = url;
}
});
},
created: function () {
document.addEventListener("keydown", this.watchEnter);
document.addEventListener('keydown', this.watchEnter);
let authenticate = localStorage.getItem('AuthenticateType');
if (authenticate === 'LOCAL' || authenticate === 'LDAP') {
this.form.authenticate = authenticate;
@ -205,7 +201,7 @@ export default {
},
destroyed() {
document.removeEventListener("keydown", this.watchEnter);
document.removeEventListener('keydown', this.watchEnter);
},
methods: {
watchEnter(e) {
@ -226,33 +222,62 @@ export default {
getOtherQuery(query) {
return Object.keys(query).reduce((acc, cur) => {
if (cur !== 'redirect') {
acc[cur] = query[cur]
acc[cur] = query[cur];
}
return acc
}, {})
return acc;
}, {});
},
getDefaultRules() { //
getDefaultRules() {
//
return {
username: [
{required: true, message: this.$t('commons.input_login_username'), trigger: 'blur'},
],
username: [{ required: true, message: this.$t('commons.input_login_username'), trigger: 'blur' }],
password: [
{required: true, message: this.$t('commons.input_password'), trigger: 'blur'},
{min: 6, max: 30, message: this.$t('commons.input_limit', [6, 30]), trigger: 'blur'}
]
{ required: true, message: this.$t('commons.input_password'), trigger: 'blur' },
{ min: 6, max: 30, message: this.$t('commons.input_limit', [6, 30]), trigger: 'blur' },
],
};
},
checkRedirectUrl() {
if (this.lastUser === getCurrentUserId()) {
this.$router.push({path: sessionStorage.getItem('redirectUrl') || '/'});
this.$router.push({ path: sessionStorage.getItem('redirectUrl') || '/' });
return;
}
let redirectUrl = '/';
if (hasPermissions('PROJECT_USER:READ', 'PROJECT_ENVIRONMENT:READ', 'PROJECT_OPERATING_LOG:READ', 'PROJECT_FILE:READ+JAR', 'PROJECT_FILE:READ+FILE', 'PROJECT_CUSTOM_CODE:READ', 'PROJECT_MESSAGE:READ', 'PROJECT_TEMPLATE:READ')) {
if (
hasPermissions(
'PROJECT_USER:READ',
'PROJECT_ENVIRONMENT:READ',
'PROJECT_OPERATING_LOG:READ',
'PROJECT_FILE:READ+JAR',
'PROJECT_FILE:READ+FILE',
'PROJECT_CUSTOM_CODE:READ',
'PROJECT_MESSAGE:READ',
'PROJECT_TEMPLATE:READ'
)
) {
redirectUrl = '/project/home';
} else if (hasPermissions('WORKSPACE_SERVICE:READ', 'WORKSPACE_USER:READ', 'WORKSPACE_PROJECT_MANAGER:READ', 'WORKSPACE_PROJECT_ENVIRONMENT:READ', 'WORKSPACE_OPERATING_LOG:READ')) {
} else if (
hasPermissions(
'WORKSPACE_SERVICE:READ',
'WORKSPACE_USER:READ',
'WORKSPACE_PROJECT_MANAGER:READ',
'WORKSPACE_PROJECT_ENVIRONMENT:READ',
'WORKSPACE_OPERATING_LOG:READ'
)
) {
redirectUrl = '/setting/project/:type';
} else if (hasPermissions('SYSTEM_USER:READ', 'SYSTEM_WORKSPACE:READ', 'SYSTEM_GROUP:READ', 'SYSTEM_TEST_POOL:READ', 'SYSTEM_SETTING:READ', 'SYSTEM_AUTH:READ', 'SYSTEM_QUOTA:READ', 'SYSTEM_OPERATING_LOG:READ')) {
} else if (
hasPermissions(
'SYSTEM_USER:READ',
'SYSTEM_WORKSPACE:READ',
'SYSTEM_GROUP:READ',
'SYSTEM_TEST_POOL:READ',
'SYSTEM_SETTING:READ',
'SYSTEM_AUTH:READ',
'SYSTEM_QUOTA:READ',
'SYSTEM_OPERATING_LOG:READ'
)
) {
redirectUrl = '/setting';
} else {
redirectUrl = '/';
@ -260,44 +285,42 @@ export default {
sessionStorage.setItem('redirectUrl', redirectUrl);
sessionStorage.setItem('lastUser', getCurrentUserId());
this.$router.push({name: "login_redirect", path: redirectUrl || '/', query: this.otherQuery});
this.$router.push({ name: 'login_redirect', path: redirectUrl || '/', query: this.otherQuery });
},
doLogin() {
const userStore = useUserStore()
const userStore = useUserStore();
//
sessionStorage.removeItem('changePassword');
let publicKey = localStorage.getItem("publicKey");
let publicKey = localStorage.getItem('publicKey');
let form = {
username: publicKeyEncrypt(this.form.username, publicKey),
password: publicKeyEncrypt(this.form.password, publicKey),
authenticate: this.form.authenticate
authenticate: this.form.authenticate,
};
userStore.userLogin(form)
.then(response => {
sessionStorage.setItem('loginSuccess', 'true');
sessionStorage.setItem('changePassword', response.message);
localStorage.setItem('AuthenticateType', this.form.authenticate);
this.getLanguage(response.data.language);
//
this.checkRedirectUrl();
});
userStore.userLogin(form).then((response) => {
sessionStorage.setItem('loginSuccess', 'true');
sessionStorage.setItem('changePassword', response.message);
localStorage.setItem('AuthenticateType', this.form.authenticate);
this.getLanguage(response.data.language);
//
this.checkRedirectUrl();
});
},
getLanguage(language) {
if (!language) {
getLanguage()
.then(response => {
language = response.data;
localStorage.setItem(DEFAULT_LANGUAGE, language);
});
getLanguage().then((response) => {
language = response.data;
localStorage.setItem(DEFAULT_LANGUAGE, language);
});
}
},
redirectAuth(authId) {
if (authId === 'LDAP' || authId === 'LOCAL') {
return;
}
getAuthSource(authId).then(res => {
getAuthSource(authId).then((res) => {
if (!res || !res.data) {
return;
}
@ -305,7 +328,7 @@ export default {
this.$message.error(this.$t('login.auth_not_enable'));
return;
}
let source = this.authSources.filter(auth => auth.id === authId)[0];
let source = this.authSources.filter((auth) => auth.id === authId)[0];
// cas
if (source.type === 'CAS') {
let config = JSON.parse(source.configuration);
@ -313,41 +336,56 @@ export default {
return;
}
}
operationConfirm(this, this.$t('commons.auth_redirect_tip'), () => {
let config = JSON.parse(source.configuration);
let redirectUrl = eval('`' + config.redirectUrl + '`');
let url;
if (source.type === 'CAS') {
url = config.loginUrl + "?service=" + encodeURIComponent(redirectUrl);
}
if (source.type === 'OIDC') {
url = config.authUrl + "?client_id=" + config.clientId + "&redirect_uri=" + redirectUrl +
"&response_type=code&scope=openid+profile+email&state=" + authId;
//
if (config.loginUrl) {
localStorage.setItem('oidcLoginUrl', config.loginUrl);
operationConfirm(
this,
this.$t('commons.auth_redirect_tip'),
() => {
let config = JSON.parse(source.configuration);
let redirectUrl = eval('`' + config.redirectUrl + '`');
let url;
if (source.type === 'CAS') {
url = config.loginUrl + '?service=' + encodeURIComponent(redirectUrl);
}
}
if (source.type === 'OAuth2') {
url = config.authUrl
+ "?client_id=" + config.clientId
+ "&response_type=code"
+ "&redirect_uri=" + redirectUrl
+ "&state=" + authId;
if (config.scope) {
url += "&scope=" + config.scope;
if (source.type === 'OIDC') {
url =
config.authUrl +
'?client_id=' +
config.clientId +
'&redirect_uri=' +
redirectUrl +
'&response_type=code&scope=openid+profile+email&state=' +
authId;
//
if (config.loginUrl) {
localStorage.setItem('oidcLoginUrl', config.loginUrl);
}
}
if (source.type === 'OAuth2') {
url =
config.authUrl +
'?client_id=' +
config.clientId +
'&response_type=code' +
'&redirect_uri=' +
redirectUrl +
'&state=' +
authId;
if (config.scope) {
url += '&scope=' + config.scope;
}
}
if (url) {
window.location.href = url;
}
},
() => {
this.form.authenticate = 'LOCAL';
}
if (url) {
window.location.href = url;
}
}, () => {
this.form.authenticate = 'LOCAL';
});
);
});
},
}
}
},
};
</script>
<style scoped>
@ -355,7 +393,7 @@ export default {
width: 1200px;
height: 730px;
margin: 0 auto;
background-color: #FFFFFF;
background-color: #ffffff;
}
.content {
@ -399,7 +437,8 @@ export default {
text-align: center;
}
.form, .btn {
.form,
.btn {
padding: 0;
width: 443px;
margin: auto;
@ -443,7 +482,8 @@ export default {
box-shadow: inset 0 0 0 1000px #f6f3f8 !important;
}
.el-input, .el-button {
.el-input,
.el-button {
width: 443px;
}
@ -456,6 +496,4 @@ export default {
height: 480px;
margin: 165px 0px;
}
</style>

View File

@ -17,18 +17,16 @@ const messages = LANG_FILES.keys().reduce((messages, path) => {
return messages;
}, {});
export const getLanguage = async () => {
export const getLanguage = () => {
let language = localStorage.getItem('language');
if (!language) {
language = navigator.language || navigator.browserLanguage;
try {
const response = await axios.get('/system/default-locale');
axios.get('/system/default-locale').then((response) => {
if (response.data && response.data.data) {
language = response.data.data.replace('_', '-');
i18n.locale = language;
}
} catch (error) {
console.error(error);
}
});
}
return language;
};

View File

@ -25,12 +25,11 @@ export const getLanguage = () => {
axios.get("/system/default-locale").then((response) => {
if (response.data && response.data.data) {
language = response.data.data.replace("_", "-");
i18n.locale = language;
}
return language;
});
} else {
return language;
}
return language;
};
const i18n = new VueI18n({

View File

@ -25,12 +25,11 @@ export const getLanguage = () => {
axios.get("/system/default-locale").then((response) => {
if (response.data && response.data.data) {
language = response.data.data.replace("_", "-");
i18n.locale = language;
}
return language;
});
} else {
return language;
}
return language;
};
const i18n = new VueI18n({

View File

@ -41,12 +41,11 @@ export const getLanguage = () => {
axios.get("/system/default-locale").then((response) => {
if (response.data && response.data.data) {
language = response.data.data.replace("_", "-");
i18n.locale = language;
}
return language;
});
} else {
return language;
}
return language;
};
const i18n = new VueI18n({

View File

@ -25,12 +25,11 @@ export const getLanguage = () => {
axios.get("/system/default-locale").then((response) => {
if (response.data && response.data.data) {
language = response.data.data.replace("_", "-");
i18n.locale = language;
}
return language;
});
} else {
return language;
}
return language;
};
const i18n = new VueI18n({