1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 00:09:16 +08:00

feat: 登录页增加语言选项 (#1752)

Refs https://github.com/1Panel-dev/1Panel/issues/1728
This commit is contained in:
zhengkunwang 2023-07-25 17:24:15 +08:00 committed by GitHub
parent b05e5736a6
commit 4d368a4de8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 134 additions and 5 deletions

View File

@ -120,6 +120,20 @@ func (b *BaseApi) CheckIsDemo(c *gin.Context) {
helper.SuccessWithData(c, global.CONF.System.IsDemo)
}
// @Tags Auth
// @Summary Load System Language
// @Description 获取系统语言设置
// @Success 200
// @Router /auth/language [get]
func (b *BaseApi) GetLanguage(c *gin.Context) {
settingInfo, err := settingService.GetSettingInfo()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, settingInfo.Language)
}
func saveLoginLogs(c *gin.Context, err error) {
var logs model.LoginLog
if err != nil {

View File

@ -24,6 +24,7 @@ type Login struct {
Captcha string `json:"captcha"`
CaptchaID string `json:"captchaID"`
AuthMethod string `json:"authMethod"`
Language string `json:"language"`
}
type MFALogin struct {

View File

@ -48,10 +48,12 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo,
if err != nil {
return nil, err
}
if err = settingRepo.Update("Language", info.Language); err != nil {
return nil, err
}
if mfa.Value == "enable" {
return &dto.UserLoginInfo{Name: nameSetting.Value, MfaStatus: mfa.Value}, nil
}
return u.generateSession(c, info.Name, info.AuthMethod)
}

View File

@ -17,5 +17,6 @@ func (s *BaseRouter) InitBaseRouter(Router *gin.RouterGroup) {
baseRouter.GET("/issafety", baseApi.CheckIsSafety)
baseRouter.POST("/logout", baseApi.LogOut)
baseRouter.GET("/demo", baseApi.CheckIsDemo)
baseRouter.GET("/language", baseApi.GetLanguage)
}
}

View File

@ -882,6 +882,20 @@ const docTemplate = `{
}
}
},
"/auth/language": {
"get": {
"description": "获取系统语言设置",
"tags": [
"Auth"
],
"summary": "Load System Language",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/auth/login": {
"post": {
"description": "用户登录",
@ -12541,6 +12555,9 @@ const docTemplate = `{
"ignoreCaptcha": {
"type": "boolean"
},
"language": {
"type": "string"
},
"name": {
"type": "string"
},

View File

@ -875,6 +875,20 @@
}
}
},
"/auth/language": {
"get": {
"description": "获取系统语言设置",
"tags": [
"Auth"
],
"summary": "Load System Language",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/auth/login": {
"post": {
"description": "用户登录",
@ -12534,6 +12548,9 @@
"ignoreCaptcha": {
"type": "boolean"
},
"language": {
"type": "string"
},
"name": {
"type": "string"
},

View File

@ -1062,6 +1062,8 @@ definitions:
type: string
ignoreCaptcha:
type: boolean
language:
type: string
name:
type: string
password:
@ -4285,6 +4287,15 @@ paths:
summary: Load safety status
tags:
- Auth
/auth/language:
get:
description: 获取系统语言设置
responses:
"200":
description: OK
summary: Load System Language
tags:
- Auth
/auth/login:
post:
consumes:

View File

@ -24,3 +24,7 @@ export const checkIsSafety = (code: string) => {
export const checkIsDemo = () => {
return http.get<boolean>('/auth/demo');
};
export const getLanguage = () => {
return http.get<string>(`/auth/language`);
};

View File

@ -39,8 +39,26 @@
<div v-else>
<div class="login-form">
<el-form ref="loginFormRef" :model="loginForm" size="default" :rules="loginRules">
<div class="login-title">{{ $t('commons.button.login') }}</div>
<div class="login-form-header">
<div class="title">{{ $t('commons.button.login') }}</div>
<div>
<el-dropdown @command="handleCommand">
<span>
{{ dropdownText }}
<el-icon>
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="zh">中文(简体)</el-dropdown-item>
<el-dropdown-item command="tw">中文(繁體)</el-dropdown-item>
<el-dropdown-item command="en">English</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<el-form-item prop="name" class="no-border">
<el-input
v-model.trim="loginForm.name"
@ -133,14 +151,16 @@
import { ref, reactive, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import type { ElForm } from 'element-plus';
import { loginApi, getCaptcha, mfaLoginApi, checkIsDemo } from '@/api/modules/auth';
import { loginApi, getCaptcha, mfaLoginApi, checkIsDemo, getLanguage } from '@/api/modules/auth';
import { GlobalStore } from '@/store';
import { MenuStore } from '@/store/modules/menu';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { useI18n } from 'vue-i18n';
const globalStore = GlobalStore();
const menuStore = MenuStore();
const usei18n = useI18n();
const errAuthInfo = ref(false);
const errCaptcha = ref(false);
@ -160,6 +180,7 @@ const loginForm = reactive({
captchaID: '',
authMethod: '',
agreeLicense: false,
language: 'zh',
});
const loginRules = reactive({
name: [{ required: true, message: i18n.global.t('commons.rule.username'), trigger: 'blur' }],
@ -183,8 +204,21 @@ const captcha = reactive({
const loading = ref<boolean>(false);
const mfaShow = ref<boolean>(false);
const router = useRouter();
const dropdownText = ref('中文(简体)');
function handleCommand(command: string) {
loginForm.language = command;
usei18n.locale.value = command;
globalStore.updateLanguage(command);
if (command === 'zh') {
dropdownText.value = '中文(简体)';
} else if (command === 'en') {
dropdownText.value = 'English';
} else if (command === 'tw') {
dropdownText.value = '中文(繁體)';
}
}
const login = (formEl: FormInstance | undefined) => {
if (!formEl) return;
@ -197,6 +231,7 @@ const login = (formEl: FormInstance | undefined) => {
captcha: loginForm.captcha,
captchaID: captcha.captchaID,
authMethod: '',
language: loginForm.language,
};
if (!globalStore.ignoreCaptcha && requestLoginForm.captcha == '') {
errCaptcha.value = true;
@ -269,8 +304,17 @@ const checkIsSystemDemo = async () => {
isDemo.value = res.data;
};
const loadLanguage = async () => {
try {
const res = await getLanguage();
loginForm.language = res.data;
handleCommand(res.data);
} catch (error) {}
};
onMounted(() => {
loginVerify();
loadLanguage();
document.title = globalStore.themeConfig.panelName;
loginForm.agreeLicense = globalStore.agreeLicense;
checkIsSystemDemo();
@ -380,5 +424,23 @@ onMounted(() => {
color: red;
}
}
.login-form-header {
display: flex;
margin-bottom: 30px;
justify-content: space-between;
align-items: center;
.title {
color: #646a73;
font-size: 25px;
}
}
.l-select {
:deep(.el-input__wrapper) {
background: none !important;
box-shadow: none !important;
}
}
}
</style>