diff --git a/agent/app/model/setting.go b/agent/app/model/setting.go index 22f12cf6c..66b516761 100644 --- a/agent/app/model/setting.go +++ b/agent/app/model/setting.go @@ -19,6 +19,7 @@ type NodeInfo struct { Scope string `json:"scope"` BaseDir string `json:"baseDir"` NodePort uint `json:"nodePort"` + Edition string `json:"edition"` Version string `json:"version"` ServerCrt string `json:"serverCrt"` ServerKey string `json:"serverKey"` diff --git a/agent/app/service/app.go b/agent/app/service/app.go index ef61f92f9..a0f5c16e7 100644 --- a/agent/app/service/app.go +++ b/agent/app/service/app.go @@ -416,7 +416,7 @@ func (a AppService) Install(req request.AppInstallCreate, executeScript bool) (a } } else { if appDetail.DockerCompose == "" { - dockerComposeUrl := fmt.Sprintf("%s/%s/1panel/%s/%s/docker-compose.yml", global.CONF.RemoteURL.AppRepo, global.CONF.Base.Mode, app.Key, appDetail.Version) + dockerComposeUrl := fmt.Sprintf("%s/%s/1panel/%s/%s/docker-compose.yml", global.AppRepoURL(), global.CONF.Base.Mode, app.Key, appDetail.Version) _, composeRes, err = req_helper.HandleRequest(dockerComposeUrl, http.MethodGet, constant.TimeOut20s) if err != nil { return @@ -817,7 +817,7 @@ func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) { return res, nil } - versionUrl := fmt.Sprintf("%s/%s/1panel.json.version.txt", global.CONF.RemoteURL.AppRepo, global.CONF.Base.Mode) + versionUrl := fmt.Sprintf("%s/%s/1panel.json.version.txt", global.AppRepoURL(), global.CONF.Base.Mode) _, versionRes, err := req_helper.HandleRequest(versionUrl, http.MethodGet, constant.TimeOut20s) if err != nil { return nil, err @@ -889,7 +889,7 @@ func getAppFromRepo(downloadPath string) error { func getAppList() (*dto.AppList, error) { list := &dto.AppList{} - if err := getAppFromRepo(fmt.Sprintf("%s/%s/1panel.json.zip", global.CONF.RemoteURL.AppRepo, global.CONF.Base.Mode)); err != nil { + if err := getAppFromRepo(fmt.Sprintf("%s/%s/1panel.json.zip", global.AppRepoURL(), global.CONF.Base.Mode)); err != nil { return nil, err } listFile := filepath.Join(global.Dir.ResourceDir, "1panel.json") diff --git a/agent/app/service/app_sync_task.go b/agent/app/service/app_sync_task.go index 1aea0753f..03231b37e 100644 --- a/agent/app/service/app_sync_task.go +++ b/agent/app/service/app_sync_task.go @@ -81,7 +81,7 @@ func (a AppService) createSyncAppStoreTask(sharedCtx **appSyncContext) func(t *t ctx := &appSyncContext{ task: t, httpClient: http.Client{Timeout: time.Duration(constant.TimeOut20s) * time.Second, Transport: xpack.LoadRequestTransport()}, - baseRemoteUrl: fmt.Sprintf("%s/%s/1panel", global.CONF.RemoteURL.AppRepo, global.CONF.Base.Mode), + baseRemoteUrl: fmt.Sprintf("%s/%s/1panel", global.AppRepoURL(), global.CONF.Base.Mode), systemVersion: setting.SystemVersion, settingService: settingService, list: list, diff --git a/agent/cmd/server/conf/app.yaml b/agent/cmd/server/conf/app.yaml index 74af8be88..654c8648c 100644 --- a/agent/cmd/server/conf/app.yaml +++ b/agent/cmd/server/conf/app.yaml @@ -4,11 +4,6 @@ base: is_demo: false is_offline: false -remote_url: - app_repo: https://apps-assets.fit2cloud.com - repo_url: https://resource.fit2cloud.com/1panel/package/v2 - resource_url: https://resource.fit2cloud.com/1panel/resource/v2 - log: level: debug time_zone: Asia/Shanghai diff --git a/agent/global/config.go b/agent/global/config.go index 31bcad6b5..a1b7de6ec 100644 --- a/agent/global/config.go +++ b/agent/global/config.go @@ -2,13 +2,13 @@ package global type ServerConfig struct { Base Base `mapstructure:"base"` - RemoteURL RemoteURL `mapstructure:"remote_url"` Log LogConfig `mapstructure:"log"` DockerConfig DockerConfig } type Base struct { Port string `mapstructure:"port"` + Edition string `mapstructure:"edition"` // [ cn / intl] Version string `mapstructure:"version"` EncryptKey string `mapstructure:"encrypt_key"` Mode string `mapstructure:"mode"` // xpack [ Enable / Disable ] @@ -17,12 +17,6 @@ type Base struct { IsOffLine bool `mapstructure:"is_offline"` } -type RemoteURL struct { - AppRepo string `mapstructure:"app_repo"` - RepoUrl string `mapstructure:"repo_url"` - ResourceUrl string `mapstructure:"resource_url"` -} - type SystemDir struct { BaseDir string DbDir string diff --git a/agent/global/global.go b/agent/global/global.go index efff79643..6e5f458e8 100644 --- a/agent/global/global.go +++ b/agent/global/global.go @@ -40,3 +40,25 @@ var ( TaskCtxMap = make(map[string]context.CancelFunc) ) + +func RepoURL() string { + if CONF.Base.Edition == "cn" { + return "https://resource.fit2cloud.com/1panel/package/v2" + } else { + return "https://resource.1panel.pro" + } +} +func ResourceURL() string { + if CONF.Base.Edition == "cn" { + return "https://resource.fit2cloud.com/1panel/resource/v2" + } else { + return "https://resource.1panel.pro" + } +} +func AppRepoURL() string { + if CONF.Base.Edition == "cn" { + return "https://apps-assets.fit2cloud.com" + } else { + return "https://apps.1panel.pro" + } +} diff --git a/agent/init/hook/hook.go b/agent/init/hook/hook.go index ec1ce3b15..a0a1078c0 100644 --- a/agent/init/hook/hook.go +++ b/agent/init/hook/hook.go @@ -42,6 +42,7 @@ func initGlobalData() { _ = settingRepo.Update("SystemVersion", node.Version) } global.CONF.Base.Version = node.Version + global.CONF.Base.Edition = node.Edition global.CONF.Base.EncryptKey, _ = settingRepo.GetValueByKey("EncryptKey") } diff --git a/agent/init/lang/lang.go b/agent/init/lang/lang.go index 8091e541f..f13bc83bc 100644 --- a/agent/init/lang/lang.go +++ b/agent/init/lang/lang.go @@ -105,7 +105,7 @@ func loadRestorePath(upgradeDir string) (string, error) { } func downloadLangFromRemote(fileOp files.FileOp) { - path := fmt.Sprintf("%s/language/lang.tar.gz", global.CONF.RemoteURL.RepoUrl) + path := fmt.Sprintf("%s/language/lang.tar.gz", global.RepoURL()) if err := fileOp.DownloadFile(path, "/usr/local/bin/lang.tar.gz"); err != nil { global.LOG.Errorf("download lang.tar.gz failed, err: %v", err) return @@ -123,7 +123,7 @@ func downloadLangFromRemote(fileOp files.FileOp) { } func downloadGeoFromRemote(fileOp files.FileOp, targetPath string) { _ = os.MkdirAll(path.Dir(targetPath), os.ModePerm) - pathItem := fmt.Sprintf("%s/geo/GeoIP.mmdb", global.CONF.RemoteURL.RepoUrl) + pathItem := fmt.Sprintf("%s/geo/GeoIP.mmdb", global.RepoURL()) if err := fileOp.DownloadFile(pathItem, targetPath); err != nil { global.LOG.Errorf("download geo ip failed, err: %v", err) return diff --git a/agent/utils/common/common.go b/agent/utils/common/common.go index 749d5504a..4f2d61537 100644 --- a/agent/utils/common/common.go +++ b/agent/utils/common/common.go @@ -419,3 +419,22 @@ func GetDockerComposeCommand() string { } return "" } + +func LoadParams(param string) string { + stdout, err := cmd.RunDefaultWithStdoutBashCf("grep '^%s=' /usr/local/bin/1pctl | cut -d'=' -f2", param) + if err != nil { + panic(err) + } + info := strings.ReplaceAll(stdout, "\n", "") + if len(info) == 0 || info == `""` { + panic(fmt.Sprintf("error `%s` find in /usr/local/bin/1pctl", param)) + } + return info +} +func LoadParamsWithoutPanic(param string) string { + stdout, err := cmd.RunDefaultWithStdoutBashCf("grep '^%s=' /usr/local/bin/1pctl | cut -d'=' -f2", param) + if err != nil { + return "" + } + return strings.ReplaceAll(stdout, "\n", "") +} diff --git a/agent/utils/version/version.go b/agent/utils/version/version.go index 4f2f6a42b..a8b77e3e0 100644 --- a/agent/utils/version/version.go +++ b/agent/utils/version/version.go @@ -51,7 +51,7 @@ func GetUpgradeVersionInfo() (*dto.UpgradeInfo, error) { if strings.Contains(itemVersion, "beta") { mode = "beta" } - notes, err := loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.RemoteURL.RepoUrl, mode, itemVersion, itemVersion)) + notes, err := loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.RepoURL(), mode, itemVersion, itemVersion)) if err != nil { return nil, fmt.Errorf("load releases-notes of version %s failed, err: %v", itemVersion, err) } @@ -101,9 +101,9 @@ func loadVersionByMode(developer, currentVersion string) (string, string, string } func loadVersion(isLatest bool, currentVersion, mode string) string { - path := fmt.Sprintf("%s/%s/latest", global.CONF.RemoteURL.RepoUrl, mode) + path := fmt.Sprintf("%s/%s/latest", global.RepoURL(), mode) if !isLatest { - path = fmt.Sprintf("%s/%s/latest.current", global.CONF.RemoteURL.RepoUrl, mode) + path = fmt.Sprintf("%s/%s/latest.current", global.RepoURL(), mode) } _, latestVersionRes, err := HandleRequest(path, http.MethodGet, constant.TimeOut20s) if err != nil { diff --git a/agent/utils/xpack/community.go b/agent/utils/xpack/community.go index dfaff10dc..838759bb2 100644 --- a/agent/utils/xpack/community.go +++ b/agent/utils/xpack/community.go @@ -4,17 +4,15 @@ package xpack import ( "crypto/tls" - "fmt" "net" "net/http" - "strings" "time" "github.com/1Panel-dev/1Panel/agent/app/dto" "github.com/1Panel-dev/1Panel/agent/app/model" "github.com/1Panel-dev/1Panel/agent/buserr" "github.com/1Panel-dev/1Panel/agent/global" - "github.com/1Panel-dev/1Panel/agent/utils/cmd" + "github.com/1Panel-dev/1Panel/agent/utils/common" "github.com/gin-gonic/gin" ) @@ -26,25 +24,14 @@ func StartClam(startClam *model.Clam, isUpdate bool) (int, error) { func LoadNodeInfo(isBase bool) (model.NodeInfo, error) { var info model.NodeInfo - info.BaseDir = loadParams("BASE_DIR") - info.Version = loadParams("ORIGINAL_VERSION") + info.BaseDir = common.LoadParams("BASE_DIR") + info.Version = common.LoadParams("ORIGINAL_VERSION") + info.Edition = common.LoadParamsWithoutPanic("EDITION") info.Scope = "master" global.IsMaster = true return info, nil } -func loadParams(param string) string { - stdout, err := cmd.RunDefaultWithStdoutBashCf("grep '^%s=' /usr/local/bin/1pctl | cut -d'=' -f2", param) - if err != nil { - panic(err) - } - info := strings.ReplaceAll(stdout, "\n", "") - if len(info) == 0 || info == `""` { - panic(fmt.Sprintf("error `%s` find in /usr/local/bin/1pctl", param)) - } - return info -} - func GetImagePrefix() string { return "" } diff --git a/core/app/api/v2/auth.go b/core/app/api/v2/auth.go index 4ce6087dd..a94151071 100644 --- a/core/app/api/v2/auth.go +++ b/core/app/api/v2/auth.go @@ -211,7 +211,7 @@ func (b *BaseApi) GetLoginSetting(c *gin.Context) { needCaptcha := global.IPTracker.NeedCaptcha(ip) res := &dto.LoginSetting{ IsDemo: global.CONF.Base.IsDemo, - IsIntl: global.CONF.Base.IsIntl, + IsIntl: global.CONF.Base.Edition == "intl", IsFxplay: global.CONF.Base.IsFxplay, IsOffLine: global.CONF.Base.IsOffLine, Language: settingInfo.Language, diff --git a/core/app/dto/setting.go b/core/app/dto/setting.go index 5236578a1..4b4eb4ecb 100644 --- a/core/app/dto/setting.go +++ b/core/app/dto/setting.go @@ -15,6 +15,7 @@ type SettingInfo struct { Ipv6 string `json:"ipv6"` BindAddress string `json:"bindAddress"` PanelName string `json:"panelName"` + Edition string `json:"edition"` Theme string `json:"theme"` MenuTabs string `json:"menuTabs"` Language string `json:"language"` diff --git a/core/app/service/script_library.go b/core/app/service/script_library.go index cb58ec954..93a91df3a 100644 --- a/core/app/service/script_library.go +++ b/core/app/service/script_library.go @@ -201,7 +201,7 @@ func (u *ScriptService) Sync(req dto.OperateByTaskID) error { } syncTask.AddSubTask(task.GetTaskName(i18n.GetMsgByKey("RemoteScriptLibrary"), task.TaskSync, task.TaskScopeScript), func(t *task.Task) (err error) { - versionUrl := fmt.Sprintf("%s/scripts/version.txt", global.CONF.RemoteURL.ResourceURL) + versionUrl := fmt.Sprintf("%s/scripts/version.txt", global.ResourceURL()) _, versionRes, err := req_helper.HandleRequestWithProxy(versionUrl, http.MethodGet, constant.TimeOut20s) if err != nil { return fmt.Errorf("load scripts version from remote failed, err: %v", err) @@ -216,7 +216,7 @@ func (u *ScriptService) Sync(req dto.OperateByTaskID) error { return nil } - dataUrl := fmt.Sprintf("%s/scripts/data.yaml", global.CONF.RemoteURL.ResourceURL) + dataUrl := fmt.Sprintf("%s/scripts/data.yaml", global.ResourceURL()) _, dataRes, err := req_helper.HandleRequestWithProxy(dataUrl, http.MethodGet, constant.TimeOut20s) syncTask.LogWithStatus(i18n.GetMsgByKey("DownloadData"), err) if err != nil { @@ -232,7 +232,7 @@ func (u *ScriptService) Sync(req dto.OperateByTaskID) error { if _, err := os.Stat(tmpDir); err != nil { _ = os.MkdirAll(tmpDir, 0755) } - scriptsUrl := fmt.Sprintf("%s/scripts/scripts.tar.gz", global.CONF.RemoteURL.ResourceURL) + scriptsUrl := fmt.Sprintf("%s/scripts/scripts.tar.gz", global.ResourceURL()) err = files.DownloadFileWithProxyStream(scriptsUrl, tmpDir+"/scripts.tar.gz") syncTask.LogWithStatus(i18n.GetMsgByKey("DownloadPackage"), err) if err != nil { diff --git a/core/app/service/setting.go b/core/app/service/setting.go index 3b206daab..9e8675043 100644 --- a/core/app/service/setting.go +++ b/core/app/service/setting.go @@ -61,8 +61,6 @@ type ISettingService interface { UpdateSystemSSL() error GenerateRSAKey() error - GetLoginSetting() (*dto.SystemSetting, error) - UpdateAppstoreConfig(req dto.AppstoreUpdate) error GetAppstoreConfig() (*dto.AppstoreConfig, error) DefaultMenu() error @@ -92,6 +90,10 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) { if err := json.Unmarshal(arr, &info); err != nil { return nil, err } + if info.Edition == "" { + info.Edition = "cn" + _ = settingRepo.UpdateOrCreate("Edition", info.Edition) + } if info.ProxyPasswdKeep != constant.StatusEnable { info.ProxyPasswd = "" } else { @@ -168,6 +170,8 @@ func (u *SettingService) Update(key, value string) error { } else { global.Cron.Remove(global.ScriptSyncJobID) } + case "Edition": + global.CONF.Base.Edition = value } return nil @@ -679,19 +683,6 @@ func (u *SettingService) GenerateRSAKey() error { return nil } -func (u *SettingService) GetLoginSetting() (*dto.SystemSetting, error) { - settingInfo, err := u.GetSettingInfo() - if err != nil { - return nil, err - } - res := &dto.SystemSetting{ - Language: settingInfo.Language, - IsDemo: global.CONF.Base.IsDemo, - IsIntl: global.CONF.Base.IsIntl, - } - return res, nil -} - func (u *SettingService) UpdateAppstoreConfig(req dto.AppstoreUpdate) error { return settingRepo.UpdateOrCreate(req.Scope, req.Status) } diff --git a/core/app/service/upgrade.go b/core/app/service/upgrade.go index 446268f9a..a3247c83b 100644 --- a/core/app/service/upgrade.go +++ b/core/app/service/upgrade.go @@ -117,7 +117,7 @@ func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) { if strings.HasPrefix(upgrade.TestVersion, upgrade.LatestVersion+"-beta") { upgrade.TestVersion = "" } - notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.RemoteURL.RepoUrl, mode, itemVersion, itemVersion)) + notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.RepoURL(), mode, itemVersion, itemVersion)) if err != nil { return nil, fmt.Errorf("load releases-notes of version %s failed, err: %v", itemVersion, err) } @@ -130,7 +130,7 @@ func (u *UpgradeService) LoadNotes(req dto.Upgrade) (string, error) { if strings.Contains(req.Version, "beta") { mode = "beta" } - notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.RemoteURL.RepoUrl, mode, req.Version, req.Version)) + notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.RepoURL(), mode, req.Version, req.Version)) if err != nil { return "", fmt.Errorf("load releases-notes of version %s failed, err: %v", req.Version, err) } @@ -162,7 +162,7 @@ func (u *UpgradeService) Upgrade(req dto.Upgrade) error { if strings.Contains(req.Version, "beta") { mode = "beta" } - downloadPath := fmt.Sprintf("%s/%s/%s/release", global.CONF.RemoteURL.RepoUrl, mode, req.Version) + downloadPath := fmt.Sprintf("%s/%s/%s/release", global.RepoURL(), mode, req.Version) fileName := fmt.Sprintf("1panel-%s-%s-%s.tar.gz", req.Version, "linux", itemArch) _ = settingRepo.Update("SystemStatus", "Upgrading") go func() { @@ -442,9 +442,9 @@ func (u *UpgradeService) loadVersionByMode(developer, currentVersion string) (st } func (u *UpgradeService) loadVersion(isLatest bool, currentVersion, mode string) string { - path := fmt.Sprintf("%s/%s/latest", global.CONF.RemoteURL.RepoUrl, mode) + path := fmt.Sprintf("%s/%s/latest", global.RepoURL(), mode) if !isLatest { - path = fmt.Sprintf("%s/%s/latest.current", global.CONF.RemoteURL.RepoUrl, mode) + path = fmt.Sprintf("%s/%s/latest.current", global.RepoURL(), mode) } _, latestVersionRes, err := req_helper.HandleRequestWithProxy(path, http.MethodGet, constant.TimeOut20s) if err != nil { diff --git a/core/cmd/server/conf/app.yaml b/core/cmd/server/conf/app.yaml index 242791123..db1c3b947 100644 --- a/core/cmd/server/conf/app.yaml +++ b/core/cmd/server/conf/app.yaml @@ -10,11 +10,6 @@ base: password: admin123 version: v2.0.0 -remote_url: - app_repo: https://apps-assets.fit2cloud.com - repo_url: https://resource.fit2cloud.com/1panel/package/v2 - resource_url: https://resource.fit2cloud.com/1panel/resource/v2 - log: level: debug time_zone: Asia/Shanghai diff --git a/core/global/config.go b/core/global/config.go index 6ed456441..f0ea640fc 100644 --- a/core/global/config.go +++ b/core/global/config.go @@ -3,7 +3,6 @@ package global type ServerConfig struct { Base Base `mapstructure:"base"` Conn Conn `mapstructure:"conn"` - RemoteURL RemoteURL `mapstructure:"remote_url"` LogConfig LogConfig `mapstructure:"log"` } @@ -13,9 +12,9 @@ type Base struct { Password string `mapstructure:"password"` Language string `mapstructure:"language"` IsDemo bool `mapstructure:"is_demo"` - IsIntl bool `mapstructure:"is_intl"` IsOffLine bool `mapstructure:"is_offline"` IsFxplay bool `mapstructure:"is_fxplay"` + Edition string `mapstructure:"edition"` Version string `mapstructure:"version"` InstallDir string `mapstructure:"install_dir"` ChangeUserInfo string `mapstructure:"change_user_info"` @@ -37,11 +36,6 @@ type ApiInterface struct { ApiKeyValidityTime string `mapstructure:"api_key_validity_time"` } -type RemoteURL struct { - RepoUrl string `mapstructure:"repo_url"` - ResourceURL string `mapstructure:"resource_url"` -} - type LogConfig struct { Level string `mapstructure:"level"` TimeZone string `mapstructure:"timeZone"` diff --git a/core/global/global.go b/core/global/global.go index afb5e97a8..7d82de236 100644 --- a/core/global/global.go +++ b/core/global/global.go @@ -34,3 +34,25 @@ var ( ) type DBOption func(*gorm.DB) *gorm.DB + +func RepoURL() string { + if CONF.Base.Edition == "cn" { + return "https://resource.fit2cloud.com/1panel/package/v2" + } else { + return "https://resource.1panel.pro" + } +} +func ResourceURL() string { + if CONF.Base.Edition == "cn" { + return "https://resource.fit2cloud.com/1panel/resource/v2" + } else { + return "https://resource.1panel.pro" + } +} +func AppRepoURL() string { + if CONF.Base.Edition == "cn" { + return "https://apps-assets.fit2cloud.com" + } else { + return "https://apps.1panel.pro" + } +} diff --git a/core/i18n/lang/en.yaml b/core/i18n/lang/en.yaml index b5296918a..74ec16452 100644 --- a/core/i18n/lang/en.yaml +++ b/core/i18n/lang/en.yaml @@ -86,6 +86,7 @@ ErrNoSuchNode: "Node information not found, please check and retry!" ErrNodeUnbind: "This node is not within the license binding range, please check and retry!" ErrNodeBind: "This node is already bound to a license, please check and retry!" ErrNodeLocalRollback: "The primary node does not support direct rollback. Please manually execute the '1pctl restore' command to rollback!" +ErrIntlLicense: "The current version does not support importing international licenses yet. Stay tuned!" InvalidRequestBodyType: "Invalid request body format, please check and ensure the content meets the required format before retrying!" InvalidLicenseCodeType: "Invalid license code format provided, please check and try again!" diff --git a/core/i18n/lang/es-ES.yaml b/core/i18n/lang/es-ES.yaml index f6abf343e..3648ddd4d 100644 --- a/core/i18n/lang/es-ES.yaml +++ b/core/i18n/lang/es-ES.yaml @@ -86,6 +86,7 @@ ErrNoSuchNode: "Información del nodo no encontrada, ¡verifique e intente de nu ErrNodeUnbind: "Este nodo no está dentro del rango de vinculación de la licencia, ¡verifique e intente de nuevo!" ErrNodeBind: "Este nodo ya está vinculado a una licencia, ¡verifique e intente de nuevo!" ErrNodeLocalRollback: "El nodo principal no admite la reversión directa. ¡Ejecute manualmente el comando '1pctl restore' para revertir!" +ErrIntlLicense: "La versión actual aún no admite importar licencias de la edición internacional. ¡Próximamente!" InvalidRequestBodyType: "Formato del cuerpo de la solicitud no válido, por favor revisa y asegúrate de que el contenido cumpla con el formato requerido antes de reintentar." InvalidLicenseCodeType: "Formato de código de licencia no válido, por favor revisa e inténtalo de nuevo." LicenseNotFoundType: "Licencia no encontrada, no existe ningún registro coincidente en el sistema para la licencia proporcionada. Por favor revisa e inténtalo de nuevo." diff --git a/core/i18n/lang/ja.yaml b/core/i18n/lang/ja.yaml index 4a4b101e6..c400de518 100644 --- a/core/i18n/lang/ja.yaml +++ b/core/i18n/lang/ja.yaml @@ -81,6 +81,7 @@ ErrNoSuchNode: "そのノード情報が見つかりませんでした、確認 ErrNodeUnbind: "そのノードはライセンスのバインド範囲内ではありません、確認して再試行してください!" ErrNodeBind: "そのノードはライセンスにバインドされています、確認して再試行してください!" ErrNodeLocalRollback: "マスターノードは直接ロールバックをサポートしていません。手動で「1pctl restore」コマンドを実行してロールバックしてください!" +ErrIntlLicense: "現在のバージョンでは国際版ライセンスのインポートはまだサポートされていません。しばらくお待ちください!" InvalidRequestBodyType: "リクエストボディの形式が無効です。内容が要求された形式に準拠しているか確認してから再試行してください!" InvalidLicenseCodeType: "提供されたライセンスコードの形式が無効です。確認してから再試行してください!" diff --git a/core/i18n/lang/ko.yaml b/core/i18n/lang/ko.yaml index 100562236..31c37e808 100644 --- a/core/i18n/lang/ko.yaml +++ b/core/i18n/lang/ko.yaml @@ -80,6 +80,7 @@ ErrNoSuchNode: "노드 정보를 찾을 수 없습니다. 다시 확인하고 ErrNodeUnbind: "이 노드가 라이선스 바인딩 범위에 있지 않음을 감지하였습니다. 다시 확인하고 시도해 주세요!" ErrNodeBind: "이 노드가 이미 라이선스에 바인딩되어 있음을 감지하였습니다. 다시 확인하고 시도해 주세요!" ErrNodeLocalRollback: "마스터 노드는 직접 롤백을 지원하지 않습니다. 수동으로 '1pctl restore' 명령어를 실행하여 롤백하세요!" +ErrIntlLicense: "현재 버전에서는 국제판 라이선스 가져오기를 아직 지원하지 않습니다. 곧 제공될 예정입니다!" InvalidRequestBodyType: "요청 본문 형식이 잘못되었습니다. 내용이 형식 요구 사항을 충족하는지 확인한 후 다시 시도하세요!" InvalidLicenseCodeType: "제공된 라이선스 코드 형식이 잘못되었습니다. 확인 후 다시 시도하세요!" diff --git a/core/i18n/lang/ms.yaml b/core/i18n/lang/ms.yaml index dfe67ddd7..74330ab2c 100644 --- a/core/i18n/lang/ms.yaml +++ b/core/i18n/lang/ms.yaml @@ -75,6 +75,7 @@ ErrNoSuchNode: "Maklumat nod tidak ditemui, sila semak dan cuba lagi!" ErrNodeUnbind: "Nod di luar skop lesen dikesan, sila semak dan cuba lagi!" ErrNodeBind: "Nod ini telah diikat dengan lesen, sila semak dan cuba lagi!" ErrNodeLocalRollback: "Nod utama tidak menyokong rollback secara langsung. Sila laksanakan arahan '1pctl restore' secara manual untuk rollback!" +ErrIntlLicense: "Versi semasa belum menyokong import lesen edisi antarabangsa. Nantikan!" InvalidRequestBodyType: "Format badan permintaan tidak sah, sila periksa dan pastikan kandungan memenuhi format yang diperlukan sebelum mencuba semula!" InvalidLicenseCodeType: "Format kod lesen yang diberikan tidak sah, sila periksa dan cuba lagi!" diff --git a/core/i18n/lang/pt-BR.yaml b/core/i18n/lang/pt-BR.yaml index c93a314c0..69d686192 100644 --- a/core/i18n/lang/pt-BR.yaml +++ b/core/i18n/lang/pt-BR.yaml @@ -80,6 +80,7 @@ ErrNoSuchNode: "As informações deste nó não foram encontradas, por favor ver ErrNodeUnbind: "Nó fora do escopo da licença detectado, por favor verifique e tente novamente!" ErrNodeBind: "Este nó já está vinculado a uma licença, por favor verifique e tente novamente!" ErrNodeLocalRollback: "O nó principal não suporta rollback direto. Por favor, execute manualmente o comando '1pctl restore' para fazer o rollback!" +ErrIntlLicense: "A versão atual ainda não oferece suporte à importação de licença da edição internacional. Em breve!" InvalidRequestBodyType: "Formato do corpo da requisição inválido. Verifique se o conteúdo está no formato correto e tente novamente!" InvalidLicenseCodeType: "Formato do código de licença inválido. Verifique e tente novamente!" diff --git a/core/i18n/lang/ru.yaml b/core/i18n/lang/ru.yaml index a50b42165..48cd9e071 100644 --- a/core/i18n/lang/ru.yaml +++ b/core/i18n/lang/ru.yaml @@ -80,6 +80,7 @@ ErrNoSuchNode: "Информация об узле не найдена, пров ErrNodeUnbind: "Обнаружен узел вне области действия лицензии, проверьте и повторите попытку!" ErrNodeBind: "Этот узел уже связан с лицензией, проверьте и повторите попытку!" ErrNodeLocalRollback: "Основной узел не поддерживает прямой откат. Пожалуйста, вручную выполните команду '1pctl restore' для отката!" +ErrIntlLicense: "Текущая версия пока не поддерживает импорт международной лицензии. Скоро будет доступно!" InvalidRequestBodyType: "Неверный формат тела запроса. Проверьте, соответствует ли содержимое требуемому формату, и повторите попытку!" InvalidLicenseCodeType: "Указан неверный формат лицензионного кода. Проверьте и повторите попытку!" diff --git a/core/i18n/lang/tr.yaml b/core/i18n/lang/tr.yaml index 10c78f145..0903cb80d 100644 --- a/core/i18n/lang/tr.yaml +++ b/core/i18n/lang/tr.yaml @@ -79,6 +79,7 @@ ErrNoSuchNode: "Düğüm bilgisi bulunamadı, lütfen kontrol edip tekrar deneyi ErrNodeUnbind: "Bu düğüm lisans bağlama aralığında değil, lütfen kontrol edip tekrar deneyin!" ErrNodeBind: "Bu düğüm zaten bir lisansa bağlı, lütfen kontrol edip tekrar deneyin!" ErrNodeLocalRollback: "Ana düğüm doğrudan geri alma desteklemiyor. Lütfen geri almak için '1pctl restore' komutunu manuel olarak çalıştırın!" +ErrIntlLicense: "Mevcut sürüm uluslararası sürüm lisansının içe aktarılmasını henüz desteklemiyor. Yakında!" InvalidRequestBodyType: "Geçersiz istek gövdesi formatı, lütfen içeriğin format gereksinimlerine uygun olduğunu kontrol edip tekrar deneyin!" InvalidLicenseCodeType: "Sağlanan lisans kodu formatı geçersiz, lütfen kontrol edip tekrar deneyin!" diff --git a/core/i18n/lang/zh-Hant.yaml b/core/i18n/lang/zh-Hant.yaml index f338a5eec..e1e492ecc 100644 --- a/core/i18n/lang/zh-Hant.yaml +++ b/core/i18n/lang/zh-Hant.yaml @@ -80,6 +80,7 @@ ErrNoSuchNode: "未能找到該節點資訊,請檢查後重試!" ErrNodeUnbind: "檢測到該節點未在許可證綁定範圍內,請檢查後重試!" ErrNodeBind: "檢測到該節點已綁定許可證,請檢查後重試!" ErrNodeLocalRollback: "主節點暫不支援直接回滾,請手動執行「1pctl restore」指令回滾!" +ErrIntlLicense: "當前版本暫不支援匯入國際版許可證,敬請期待!" InvalidRequestBodyType: "請求體格式錯誤,請檢查請求內容是否符合格式要求後重試!" InvalidLicenseCodeType: "提供的許可證格式錯誤,請檢查後重試!" diff --git a/core/i18n/lang/zh.yaml b/core/i18n/lang/zh.yaml index f48431e17..9e382def6 100644 --- a/core/i18n/lang/zh.yaml +++ b/core/i18n/lang/zh.yaml @@ -86,6 +86,7 @@ ErrNoSuchNode: "未能找到该节点信息,请检查后重试!" ErrNodeUnbind: "检测到该节点未在许可证绑定范围内,请检查后重试!" ErrNodeBind: "检测到该节点已绑定许可证,请检查后重试!" ErrNodeLocalRollback: "主节点暂不支持直接回滚,请手动执行 1pctl restore 命令回滚!" +ErrIntlLicense: "当前版本暂不支持导入国际版许可证,敬请期待!" InvalidRequestBodyType: "请求体格式错误,请检查请求内容是否符合格式要求后重试!" InvalidLicenseCodeType: "提供的许可证格式错误,请检查后重试!" diff --git a/core/init/geo/lang.go b/core/init/geo/lang.go index 44c9bd620..1af9920b3 100644 --- a/core/init/geo/lang.go +++ b/core/init/geo/lang.go @@ -104,7 +104,7 @@ func loadRestorePath(upgradeDir string) (string, error) { } func downloadLangFromRemote() { - path := fmt.Sprintf("%s/language/lang.tar.gz", global.CONF.RemoteURL.RepoUrl) + path := fmt.Sprintf("%s/language/lang.tar.gz", global.RepoURL()) if err := fileUtils.DownloadFile(path, "/usr/local/bin/lang.tar.gz"); err != nil { global.LOG.Errorf("download lang.tar.gz failed, err: %v", err) return @@ -122,7 +122,7 @@ func downloadLangFromRemote() { } func downloadGeoFromRemote(targetPath string) { _ = os.MkdirAll(path.Dir(targetPath), os.ModePerm) - pathItem := fmt.Sprintf("%s/geo/GeoIP.mmdb", global.CONF.RemoteURL.RepoUrl) + pathItem := fmt.Sprintf("%s/geo/GeoIP.mmdb", global.RepoURL()) if err := fileUtils.DownloadFile(pathItem, targetPath); err != nil { global.LOG.Errorf("download geo ip failed, err: %v", err) return diff --git a/core/init/hook/hook.go b/core/init/hook/hook.go index 5991dabe6..52b365be5 100644 --- a/core/init/hook/hook.go +++ b/core/init/hook/hook.go @@ -16,6 +16,7 @@ func Init() { settingRepo := repo.NewISettingRepo() global.CONF.Conn.Port, _ = settingRepo.GetValueByKey("ServerPort") global.CONF.Conn.Ipv6, _ = settingRepo.GetValueByKey("Ipv6") + global.CONF.Base.Edition, _ = settingRepo.GetValueByKey("Edition") global.Api.ApiInterfaceStatus, _ = settingRepo.GetValueByKey("ApiInterfaceStatus") if global.Api.ApiInterfaceStatus == constant.StatusEnable { global.Api.ApiKey, _ = settingRepo.GetValueByKey("ApiKey") diff --git a/core/init/migration/migrate.go b/core/init/migration/migrate.go index c8b0c0cee..0ea4183b8 100644 --- a/core/init/migration/migrate.go +++ b/core/init/migration/migrate.go @@ -32,6 +32,7 @@ func Init() { migrations.AdjustXpackNode, migrations.UpdateAiAgentsMenu, migrations.AddDashboardCarouselSetting, + migrations.AddEditionSetting, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/core/init/migration/migrations/init.go b/core/init/migration/migrations/init.go index c2026fd85..b01fd7d2c 100644 --- a/core/init/migration/migrations/init.go +++ b/core/init/migration/migrations/init.go @@ -64,6 +64,9 @@ var InitSetting = &gormigrate.Migration{ if err := tx.Create(&model.Setting{Key: "PanelName", Value: "1Panel"}).Error; err != nil { return err } + if err := tx.Create(&model.Setting{Key: "Edition", Value: global.CONF.Base.Edition}).Error; err != nil { + return err + } if err := tx.Create(&model.Setting{Key: "Language", Value: language}).Error; err != nil { return err } @@ -814,3 +817,20 @@ var UpdateAiAgentsMenu = &gormigrate.Migration{ return tx.Model(&model.Setting{}).Where("key = ?", "HideMenu").Update("value", string(updatedJSON)).Error }, } + +var AddEditionSetting = &gormigrate.Migration{ + ID: "20260224-add-edition-setting", + Migrate: func(tx *gorm.DB) error { + var setting model.Setting + if err := tx.Where("key = ?", "Edition").First(&setting).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return tx.Create(&model.Setting{Key: "Edition", Value: global.CONF.Base.Edition}).Error + } + return err + } + if setting.Value == "" { + return tx.Model(&model.Setting{}).Where("key = ?", "Edition").Update("value", global.CONF.Base.Edition).Error + } + return nil + }, +} diff --git a/core/init/viper/viper.go b/core/init/viper/viper.go index 73a01908d..6e8baaebd 100644 --- a/core/init/viper/viper.go +++ b/core/init/viper/viper.go @@ -21,7 +21,7 @@ func Init() { port := "9999" mode := "" version := "v2.0.0" - username, password, entrance, language := "", "", "", "zh" + username, password, entrance, language, edition := "", "", "", "zh", "" v := viper.NewWithOptions() v.SetConfigType("yaml") @@ -37,7 +37,7 @@ func Init() { v.SetConfigName("app") v.AddConfigPath(path.Join("/opt/1panel/conf")) if err := v.ReadInConfig(); err != nil { - panic(fmt.Errorf("Fatal error config file: %s \n", err)) + panic(fmt.Errorf("fatal error config file: %s", err)) } } else { baseDir = common.LoadParams("BASE_DIR") @@ -47,10 +47,11 @@ func Init() { password = common.LoadParams("ORIGINAL_PASSWORD") entrance = common.LoadParams("ORIGINAL_ENTRANCE") language = common.LoadParams("LANGUAGE") + edition = common.LoadParamsWithoutPanic("EDITION") reader := bytes.NewReader(conf.AppYaml) if err := v.ReadConfig(reader); err != nil { - panic(fmt.Errorf("Fatal error config file: %s \n", err)) + panic(fmt.Errorf("fatal error config file: %s", err)) } } v.OnConfigChange(func(e fsnotify.Event) { @@ -82,17 +83,18 @@ func Init() { if serverConfig.Conn.Entrance != "" { entrance = serverConfig.Conn.Entrance } - if serverConfig.Base.IsIntl { - language = "en" - } } global.CONF = serverConfig global.CONF.Base.InstallDir = baseDir global.CONF.Base.IsDemo = v.GetBool("base.is_demo") - global.CONF.Base.IsIntl = v.GetBool("base.is_intl") global.CONF.Base.IsFxplay = v.GetBool("base.is_fxplay") global.CONF.Base.IsOffLine = v.GetBool("base.is_offline") + if edition == "intl" { + global.CONF.Base.Edition = "intl" + } else { + global.CONF.Base.Edition = "cn" + } global.CONF.Base.Version = version global.CONF.Base.Username = username global.CONF.Base.Password = password diff --git a/core/utils/common/common.go b/core/utils/common/common.go index 1d2bb5d44..a17e6324d 100644 --- a/core/utils/common/common.go +++ b/core/utils/common/common.go @@ -245,6 +245,13 @@ func LoadParams(param string) string { } return info } +func LoadParamsWithoutPanic(param string) string { + stdout, err := cmd.RunDefaultWithStdoutBashCf("grep '^%s=' /usr/local/bin/1pctl | cut -d'=' -f2", param) + if err != nil { + return "" + } + return strings.ReplaceAll(stdout, "\n", "") +} func GetRealClientIP(c *gin.Context) string { addr := c.Request.RemoteAddr diff --git a/frontend/src/api/interface/setting.ts b/frontend/src/api/interface/setting.ts index 27933f5d4..d0a056fcf 100644 --- a/frontend/src/api/interface/setting.ts +++ b/frontend/src/api/interface/setting.ts @@ -17,6 +17,7 @@ export namespace Setting { ntpSite: string; panelName: string; + edition: string; theme: string; menuTabs: string; language: string; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index efd4a38d5..b5fbf4619 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1812,6 +1812,11 @@ const message = { light: 'Light', auto: 'Follow System', language: 'Language', + region: 'Region', + regionHelper: + 'Different regions use different download sources and related documentation links for app store and script library. Choose as needed.', + cn: 'China Mainland', + intl: 'Overseas', languageHelper: 'By default, it follows the browser language. This parameter takes effect only on the current browser', sessionTimeout: 'Session timeout', diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index c86e88ba1..cfec24a7e 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -1818,6 +1818,11 @@ const message = { light: 'Claro', auto: 'Seguir sistema', language: 'Idioma', + region: 'Región de operación', + regionHelper: + 'Diferentes regiones tienen distintas direcciones de descarga y enlaces de documentación para la tienda de aplicaciones y la biblioteca de scripts.', + cn: 'China continental', + intl: 'Internacional', languageHelper: 'Por defecto sigue el idioma del navegador. Este parámetro solo tiene efecto en el navegador actual', sessionTimeout: 'Tiempo de espera de sesión', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index 59eb94efe..88b175a86 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -1770,6 +1770,11 @@ const message = { light: 'ライト', auto: 'システムをフォローします', language: '言語', + region: '運用リージョン', + regionHelper: + '運用リージョンにより、アプリストアやスクリプトライブラリのダウンロード先および関連ドキュメントのリンクが異なります。', + cn: '中国本土', + intl: '海外', languageHelper: 'デフォルトでは、ブラウザ言語に従います。このパラメーターは、現在のブラウザでのみ有効になります', sessionTimeout: 'セッションタイムアウト', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 6475584e1..7ac3fb57d 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -1749,6 +1749,11 @@ const message = { light: '라이트', auto: '시스템 따라가기', language: '언어', + region: '운영 지역', + regionHelper: + '운영 지역에 따라 앱 스토어, 스크립트 라이브러리의 다운로드 주소 및 관련 문서 링크가 다를 수 있습니다.', + cn: '중국 본토', + intl: '해외', languageHelper: '기본적으로 브라우저 언어를 따릅니다. 이 설정은 현재 브라우저에서만 적용됩니다.', sessionTimeout: '세션 타임아웃', sessionTimeoutError: '최소 세션 타임아웃은 300초입니다.', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index 3276908ca..9ce0dba91 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -1816,6 +1816,11 @@ const message = { light: 'Terang', auto: 'Ikut Sistem', language: 'Bahasa', + region: 'Wilayah operasi', + regionHelper: + 'Wilayah operasi yang berbeza mempunyai alamat muat turun dan pautan dokumentasi berbeza untuk gedung aplikasi serta pustaka skrip.', + cn: 'Tanah Besar China', + intl: 'Antarabangsa', languageHelper: 'Secara lalai, ia mengikuti bahasa penyemak imbas. Parameter ini hanya berkuat kuasa pada penyemak imbas semasa', sessionTimeout: 'Tempoh tamat sesi', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index cbdf7c520..1eadf0b46 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -1805,6 +1805,11 @@ const message = { light: 'Claro', auto: 'Seguir o sistema', language: 'Idioma', + region: 'Região de operação', + regionHelper: + 'Regiões de operação diferentes usam endereços de download e links de documentação distintos para a loja de aplicativos e a biblioteca de scripts.', + cn: 'China continental', + intl: 'Internacional', languageHelper: 'Por padrão, segue o idioma do navegador. Este parâmetro tem efeito apenas no navegador atual', sessionTimeout: 'Tempo limite de sessão', sessionTimeoutError: 'O tempo mínimo de sessão é de 300 segundos', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index b5a40317a..7ee7de03d 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -1805,6 +1805,11 @@ const message = { light: 'Светлая', auto: 'Как в системе', language: 'Язык', + region: 'Регион работы', + regionHelper: + 'Для разных регионов используются разные адреса загрузки и ссылки на документацию для магазина приложений и библиотеки скриптов.', + cn: 'Материковый Китай', + intl: 'Международный', languageHelper: 'По умолчанию следует языку браузера. Этот параметр действует только в текущем браузере', sessionTimeout: 'Время сессии', sessionTimeoutError: 'Минимальное время сессии 300 секунд', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index c89a000f1..020d69781 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -1831,6 +1831,11 @@ const message = { light: 'Açık', auto: 'Sistemi takip et', language: 'Dil', + region: 'Çalışma bölgesi', + regionHelper: + 'Farklı çalışma bölgelerinde uygulama mağazası ve betik kütüphanesi için indirme adresleri ile ilgili dokümantasyon bağlantıları farklı olabilir.', + cn: 'Çin anakarası', + intl: 'Uluslararası', languageHelper: 'Varsayılan olarak tarayıcı dilini takip eder. Bu parametre yalnızca geçerli tarayıcıda etkilidir', sessionTimeout: 'Oturum zaman aşımı', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index ced7dae75..927049177 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -1716,6 +1716,10 @@ const message = { light: '亮色', auto: '跟隨系統', language: '系統語言', + region: '運行區域', + regionHelper: '不同運行區域的應用商店、腳本庫下載地址及相關文件連結有所差異,請按需選擇', + cn: '中國大陸', + intl: '海外', languageHelper: '預設跟隨瀏覽器語言,設定後只對目前瀏覽器生效,更換瀏覽器後需要重新設定', sessionTimeout: '超時時間', sessionTimeoutError: '最小超時時間為 300 秒', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 392198b79..5582782b2 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1720,6 +1720,10 @@ const message = { light: '亮色', auto: '跟随系统', language: '系统语言', + region: '运行区域', + regionHelper: '不同运行区域应用商店、脚本库等下载地址及相关文档链接有所区别,请按需选择', + cn: '中国大陆', + intl: '海外', languageHelper: '默认跟随浏览器语言,设置后只对当前浏览器生效,更换浏览器后需要重新设置', sessionTimeout: '超时时间', sessionTimeoutError: '最小超时时间为 300 秒', diff --git a/frontend/src/views/setting/panel/index.vue b/frontend/src/views/setting/panel/index.vue index 81b8566f1..5621b56cb 100644 --- a/frontend/src/views/setting/panel/index.vue +++ b/frontend/src/views/setting/panel/index.vue @@ -201,6 +201,18 @@ {{ $t('commons.button.set') }} + + + + + {{ $t('setting.cn') }} + + + {{ $t('setting.intl') }} + + + {{ $t('setting.regionHelper') }} + @@ -278,6 +290,7 @@ const form = reactive({ themeColor: {} as ThemeColor, menuTabs: '', language: '', + edition: '', complexityVerification: '', developerMode: '', systemIP: '', @@ -341,6 +354,7 @@ const search = async () => { form.menuTabs = res.data.menuTabs; form.panelName = res.data.panelName; form.language = res.data.language; + form.edition = res.data.edition; form.sessionTimeout = Number(res.data.sessionTimeout); form.proxyUrl = res.data.proxyUrl; @@ -511,15 +525,20 @@ const onSave = async (key: string, val: any) => { }; try { await updateSetting(param); - if (key === 'Language') { - await globalStore.updateLanguage(val); - location.reload(); - } - if (key === 'Theme') { - handleThemeChange(val); - } - if (key === 'MenuTabs') { - globalStore.setOpenMenuTabs(val === 'Enable'); + switch (key) { + case 'Theme': + handleThemeChange(val); + break; + case 'MenuTabs': + globalStore.setOpenMenuTabs(val === 'Enable'); + break; + case 'Language': + await globalStore.updateLanguage(val); + location.reload(); + break; + case 'Edition': + globalStore.isIntl = val === 'intl'; + break; } MsgSuccess(i18n.global.t('commons.msg.operationSuccess')); search();