From 246c20e1b6426a1ab308853330e447e06cf2eeec Mon Sep 17 00:00:00 2001 From: lan-yonghui Date: Thu, 28 Nov 2024 17:03:53 +0800 Subject: [PATCH] feat: Adapt to internationalization --- backend/app/api/v1/auth.go | 9 + backend/configs/system.go | 2 + backend/init/migration/migrations/init.go | 7 +- backend/init/viper/viper.go | 8 +- backend/router/ro_base.go | 1 + cmd/server/conf/app.yaml | 1 + frontend/src/api/modules/auth.ts | 4 + .../src/components/system-upgrade/index.vue | 15 +- frontend/src/lang/modules/en.ts | 2 + .../src/layout/components/Sidebar/index.vue | 20 +- frontend/src/store/interface/index.ts | 1 + frontend/src/store/modules/global.ts | 1 + frontend/src/views/cronjob/operate/index.vue | 50 ++--- frontend/src/views/home/index.vue | 10 +- .../src/views/login/components/login-form.vue | 47 +++-- frontend/src/views/setting/about/index.vue | 2 +- frontend/src/views/setting/index.vue | 6 + frontend/src/views/setting/panel/index.vue | 4 +- .../src/views/toolbox/clam/operate/index.vue | 178 +++++++++--------- 19 files changed, 219 insertions(+), 149 deletions(-) diff --git a/backend/app/api/v1/auth.go b/backend/app/api/v1/auth.go index 16b1feedeecb..e99874c3e445 100644 --- a/backend/app/api/v1/auth.go +++ b/backend/app/api/v1/auth.go @@ -130,6 +130,15 @@ func (b *BaseApi) CheckIsDemo(c *gin.Context) { helper.SuccessWithData(c, global.CONF.System.IsDemo) } +// @Tags Auth +// @Summary Check System isDemo +// @Description 判断是否为国际版 +// @Success 200 +// @Router /auth/intl [get] +func (b *BaseApi) CheckIsIntl(c *gin.Context) { + helper.SuccessWithData(c, global.CONF.System.IsIntl) +} + // @Tags Auth // @Summary Load System Language // @Description 获取系统语言设置 diff --git a/backend/configs/system.go b/backend/configs/system.go index 4ede9d642a40..1f13b261835b 100644 --- a/backend/configs/system.go +++ b/backend/configs/system.go @@ -20,7 +20,9 @@ type System struct { Username string `mapstructure:"username"` Password string `mapstructure:"password"` Entrance string `mapstructure:"entrance"` + Language string `mapstructure:"language"` IsDemo bool `mapstructure:"is_demo"` + IsIntl bool `mapstructure:"is_intl"` AppRepo string `mapstructure:"app_repo"` ChangeUserInfo string `mapstructure:"change_user_info"` OneDriveID string `mapstructure:"one_drive_id"` diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index 69cb1dadcdd0..e1341278ec07 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -72,6 +72,11 @@ var AddTableSetting = &gormigrate.Migration{ } global.CONF.System.EncryptKey = encryptKey pass, _ := encrypt.StringEncrypt(global.CONF.System.Password) + language := "en" + if global.CONF.System.Language == "zh" { + language = "zh" + } + if err := tx.Create(&model.Setting{Key: "Password", Value: pass}).Error; err != nil { return err } @@ -82,7 +87,7 @@ var AddTableSetting = &gormigrate.Migration{ if err := tx.Create(&model.Setting{Key: "PanelName", Value: "1Panel"}).Error; err != nil { return err } - if err := tx.Create(&model.Setting{Key: "Language", Value: "zh"}).Error; err != nil { + if err := tx.Create(&model.Setting{Key: "Language", Value: language}).Error; err != nil { return err } if err := tx.Create(&model.Setting{Key: "Theme", Value: "light"}).Error; err != nil { diff --git a/backend/init/viper/viper.go b/backend/init/viper/viper.go index 7cae3824bfd1..479e6f2df992 100644 --- a/backend/init/viper/viper.go +++ b/backend/init/viper/viper.go @@ -21,7 +21,7 @@ func Init() { port := "9999" mode := "" version := "v1.0.0" - username, password, entrance := "", "", "" + username, password, entrance, language := "", "", "", "zh" fileOp := files.NewFileOp() v := viper.NewWithOptions() v.SetConfigType("yaml") @@ -46,6 +46,7 @@ func Init() { username = loadParams("ORIGINAL_USERNAME") password = loadParams("ORIGINAL_PASSWORD") entrance = loadParams("ORIGINAL_ENTRANCE") + language = loadParams("LANGUAGE") reader := bytes.NewReader(conf.AppYaml) if err := v.ReadConfig(reader); err != nil { @@ -80,11 +81,15 @@ func Init() { if serverConfig.System.Entrance != "" { entrance = serverConfig.System.Entrance } + if serverConfig.System.IsIntl { + language = "en" + } } global.CONF = serverConfig global.CONF.System.BaseDir = baseDir global.CONF.System.IsDemo = v.GetBool("system.is_demo") + global.CONF.System.IsIntl = v.GetBool("system.is_intl") global.CONF.System.DataDir = path.Join(global.CONF.System.BaseDir, "1panel") global.CONF.System.Cache = path.Join(global.CONF.System.DataDir, "cache") global.CONF.System.Backup = path.Join(global.CONF.System.DataDir, "backup") @@ -96,6 +101,7 @@ func Init() { global.CONF.System.Username = username global.CONF.System.Password = password global.CONF.System.Entrance = entrance + global.CONF.System.Language = language global.CONF.System.ChangeUserInfo = loadChangeInfo() global.Viper = v } diff --git a/backend/router/ro_base.go b/backend/router/ro_base.go index dff0cf8f1c3d..f0f7182d947b 100644 --- a/backend/router/ro_base.go +++ b/backend/router/ro_base.go @@ -17,5 +17,6 @@ func (s *BaseRouter) InitRouter(Router *gin.RouterGroup) { baseRouter.POST("/logout", baseApi.LogOut) baseRouter.GET("/demo", baseApi.CheckIsDemo) baseRouter.GET("/language", baseApi.GetLanguage) + baseRouter.GET("/intl", baseApi.CheckIsIntl) } } diff --git a/cmd/server/conf/app.yaml b/cmd/server/conf/app.yaml index 0da0e516358a..3721a3bb24e1 100644 --- a/cmd/server/conf/app.yaml +++ b/cmd/server/conf/app.yaml @@ -5,6 +5,7 @@ system: repo_url: https://resource.fit2cloud.com/1panel/package app_repo: https://apps-assets.fit2cloud.com is_demo: false + is_intl: true port: 9999 username: admin password: admin123 diff --git a/frontend/src/api/modules/auth.ts b/frontend/src/api/modules/auth.ts index e9f7fbf67357..f4b0f0692754 100644 --- a/frontend/src/api/modules/auth.ts +++ b/frontend/src/api/modules/auth.ts @@ -24,3 +24,7 @@ export const checkIsDemo = () => { export const getLanguage = () => { return http.get(`/auth/language`); }; + +export const checkIsIntl = () => { + return http.get('/auth/intl'); +}; diff --git a/frontend/src/components/system-upgrade/index.vue b/frontend/src/components/system-upgrade/index.vue index d60cb081e2f1..8e5cd76d82a6 100644 --- a/frontend/src/components/system-upgrade/index.vue +++ b/frontend/src/components/system-upgrade/index.vue @@ -5,8 +5,8 @@ {{ $t('setting.forum') }} - - + + {{ $t('setting.doc2') }} @@ -17,7 +17,7 @@
- {{ isProductPro ? $t('license.pro') : $t('license.community') }} + {{ isProductPro && globalStore.isIntl ? $t('license.pro') : $t('license.community') }} {{ version }} @@ -122,7 +122,9 @@ const handleClose = () => { }; const toHalo = () => { - window.open('https://www.lxware.cn/1panel' + '', '_blank', 'noopener,noreferrer'); + if (!globalStore.isIntl) { + window.open('https://www.lxware.cn/1panel' + '', '_blank', 'noopener,noreferrer'); + } }; const toDoc = () => { @@ -130,7 +132,10 @@ const toDoc = () => { }; const toForum = () => { - window.open('https://bbs.fit2cloud.com/c/1p/7', '_blank'); + let url = globalStore.isIntl + ? 'https://github.com/1Panel-dev/1Panel/discussions' + : 'https://bbs.fit2cloud.com/c/1p/7'; + window.open(url, '_blank'); }; const toGithub = () => { diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 9306b95da345..e3193eaa7771 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -344,6 +344,8 @@ const message = { kernelArch: 'Kernel arch', network: 'Network', io: 'Disk IO', + ip: 'Host Address', + proxy: 'System Proxy', baseInfo: 'Base info', totalSend: 'Total send', totalRecv: 'Total recv', diff --git a/frontend/src/layout/components/Sidebar/index.vue b/frontend/src/layout/components/Sidebar/index.vue index 9ded3c4a5827..a56ff33a6931 100644 --- a/frontend/src/layout/components/Sidebar/index.vue +++ b/frontend/src/layout/components/Sidebar/index.vue @@ -42,7 +42,7 @@ import Logo from './components/Logo.vue'; import Collapse from './components/Collapse.vue'; import SubItem from './components/SubItem.vue'; import router, { menuList } from '@/routers/router'; -import { logOutApi } from '@/api/modules/auth'; +import { checkIsIntl, logOutApi } from '@/api/modules/auth'; import i18n from '@/lang'; import { ElMessageBox } from 'element-plus'; import { GlobalStore, MenuStore } from '@/store'; @@ -68,7 +68,7 @@ const activeMenu = computed(() => { const isCollapse = computed((): boolean => menuStore.isCollapse); let routerMenus = computed((): RouteRecordRaw[] => { - return menuStore.menuList.filter((route) => route.meta && !route.meta.hideInSidebar); + return menuStore.menuList.filter((route) => route.meta && !route.meta.hideInSidebar) as RouteRecordRaw[]; }); const screenWidth = ref(0); @@ -132,9 +132,14 @@ function getCheckedLabels(json: Node): string[] { } const search = async () => { - const res = await getSettingInfo(); - const json: Node = JSON.parse(res.data.xpackHideMenu); - const checkedLabels = getCheckedLabels(json); + await checkIsSystemIntl(); + let checkedLabels: string | any[]; + if (!globalStore.isIntl) { + const res = await getSettingInfo(); + const json: Node = JSON.parse(res.data.xpackHideMenu); + checkedLabels = getCheckedLabels(json); + } + let rstMenuList: RouteRecordRaw[] = []; menuStore.menuList.forEach((item) => { let menuItem = JSON.parse(JSON.stringify(item)); @@ -173,6 +178,11 @@ const search = async () => { menuStore.menuList = rstMenuList; }; +const checkIsSystemIntl = async () => { + const res = await checkIsIntl(); + globalStore.isIntl = res.data; +}; + onMounted(() => { menuStore.setMenuList(menuList); search(); diff --git a/frontend/src/store/interface/index.ts b/frontend/src/store/interface/index.ts index bc114a936b86..9e6b28f8a238 100644 --- a/frontend/src/store/interface/index.ts +++ b/frontend/src/store/interface/index.ts @@ -34,6 +34,7 @@ export interface GlobalState { defaultNetwork: string; isProductPro: boolean; + isIntl: boolean; isTrial: boolean; productProExpires: number; diff --git a/frontend/src/store/modules/global.ts b/frontend/src/store/modules/global.ts index a8eca34bd976..7d8cf00d435b 100644 --- a/frontend/src/store/modules/global.ts +++ b/frontend/src/store/modules/global.ts @@ -37,6 +37,7 @@ const GlobalStore = defineStore({ defaultNetwork: 'all', isProductPro: false, + isIntl: false, isTrial: false, productProExpires: 0, diff --git a/frontend/src/views/cronjob/operate/index.vue b/frontend/src/views/cronjob/operate/index.vue index c98ae245fdfc..d66fec842b86 100644 --- a/frontend/src/views/cronjob/operate/index.vue +++ b/frontend/src/views/cronjob/operate/index.vue @@ -320,30 +320,32 @@
- - - {{ $t('alert.cronJobHelper') }} - - - - {{ $t('alert.alertCountHelper') }} - - - {{ $t('alert.licenseHelper') }} - - {{ $t('license.levelUpPro') }} - - +
+ + + {{ $t('alert.cronJobHelper') }} + + + + {{ $t('alert.alertCountHelper') }} + + + {{ $t('alert.licenseHelper') }} + + {{ $t('license.levelUpPro') }} + + +
diff --git a/frontend/src/views/login/components/login-form.vue b/frontend/src/views/login/components/login-form.vue index 4589c253f41f..29c139e57cc5 100644 --- a/frontend/src/views/login/components/login-form.vue +++ b/frontend/src/views/login/components/login-form.vue @@ -120,22 +120,24 @@ {{ $t('commons.button.login') }} - - - - - -
- - {{ $t('commons.login.errorAgree') }} - -
+
@@ -171,7 +173,7 @@ import { ref, reactive, onMounted, computed } from 'vue'; import { useRouter } from 'vue-router'; import type { ElForm } from 'element-plus'; -import { loginApi, getCaptcha, mfaLoginApi, checkIsDemo, getLanguage } from '@/api/modules/auth'; +import { loginApi, getCaptcha, mfaLoginApi, checkIsDemo, getLanguage, checkIsIntl } from '@/api/modules/auth'; import { GlobalStore, MenuStore, TabsStore } from '@/store'; import { MsgSuccess } from '@/utils/message'; import { useI18n } from 'vue-i18n'; @@ -188,6 +190,7 @@ const errAuthInfo = ref(false); const errCaptcha = ref(false); const errMfaInfo = ref(false); const isDemo = ref(false); +const isIntl = ref(true); const agreeVisible = ref(false); type FormInstance = InstanceType; @@ -235,6 +238,12 @@ const mfaShow = ref(false); const router = useRouter(); const dropdownText = ref('中文(简体)'); +const checkIsSystemIntl = async () => { + const res = await checkIsIntl(); + isIntl.value = res.data; + globalStore.isIntl = isIntl.value; +}; + function handleCommand(command: string) { loginForm.language = command; usei18n.locale.value = command; @@ -258,6 +267,9 @@ const login = (formEl: FormInstance | undefined) => { if (!formEl || isLoggingIn) return; formEl.validate(async (valid) => { if (!valid) return; + if (isIntl.value) { + loginForm.agreeLicense = true; + } if (!loginForm.agreeLicense) { if (_isMobile()) { agreeVisible.value = true; @@ -372,6 +384,7 @@ const loadDataFromDB = async () => { onMounted(() => { globalStore.isOnRestart = false; + checkIsSystemIntl(); loginVerify(); loadLanguage(); document.title = globalStore.themeConfig.panelName; diff --git a/frontend/src/views/setting/about/index.vue b/frontend/src/views/setting/about/index.vue index bca358a73770..22a037036846 100644 --- a/frontend/src/views/setting/about/index.vue +++ b/frontend/src/views/setting/about/index.vue @@ -16,7 +16,7 @@
- + {{ $t('setting.doc2') }} diff --git a/frontend/src/views/setting/index.vue b/frontend/src/views/setting/index.vue index 587d8bf39916..d8b0063902d4 100644 --- a/frontend/src/views/setting/index.vue +++ b/frontend/src/views/setting/index.vue @@ -9,6 +9,8 @@ diff --git a/frontend/src/views/setting/panel/index.vue b/frontend/src/views/setting/panel/index.vue index e7aad0c0532b..b55ed6a623ca 100644 --- a/frontend/src/views/setting/panel/index.vue +++ b/frontend/src/views/setting/panel/index.vue @@ -123,7 +123,7 @@ - +