From 7afd23c73b8f40d11d207afcd66a0146ac4d6102 Mon Sep 17 00:00:00 2001 From: Melorise <0d00@0721.hk> Date: Wed, 29 Jul 2026 13:03:28 +0800 Subject: [PATCH] fix: separate app store compatibility level --- agent/app/service/app.go | 10 ++----- agent/app/service/app_sync_task.go | 48 +++++++++++++----------------- agent/app/service/app_utils.go | 6 ++-- agent/global/compatibility.go | 6 ++++ docs/nPanel-nixos-design.md | 2 ++ 5 files changed, 35 insertions(+), 37 deletions(-) create mode 100644 agent/global/compatibility.go diff --git a/agent/app/service/app.go b/agent/app/service/app.go index 409679e..44a57c5 100644 --- a/agent/app/service/app.go +++ b/agent/app/service/app.go @@ -119,14 +119,10 @@ func (a AppService) PageApp(ctx *gin.Context, req request.AppSearch) (*response. return nil, err } appDTOs := make([]*response.AppItem, 0) - info := &dto.SettingInfo{} - if req.Type == "php" { - info, _ = NewISettingService().GetSettingInfo() - } lang := strings.ToLower(common.GetLang(ctx)) for _, ap := range apps { if req.Type == "php" { - if !global.CONF.Base.IsOffline && (ap.RequiredPanelVersion == 0 || !common.CompareAppVersion(common.GetSystemVersion(info.SystemVersion), fmt.Sprintf("%f", ap.RequiredPanelVersion))) { + if !global.CONF.Base.IsOffline && (ap.RequiredPanelVersion == 0 || !common.CompareAppVersion(global.AppStoreCompatibilityVersion, fmt.Sprintf("%f", ap.RequiredPanelVersion))) { continue } } @@ -879,8 +875,8 @@ func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) { if err != nil { return res, err } - if list.Extra.Version != "" && setting.SystemVersion != list.Extra.Version && !common.CompareVersion(setting.SystemVersion, list.Extra.Version) { - global.LOG.Errorf("The current version %s is too low to synchronize with the App Store. The minimum required version is %s", setting.SystemVersion, list.Extra.Version) + if list.Extra.Version != "" && !common.CompareAppVersion(global.AppStoreCompatibilityVersion, list.Extra.Version) { + global.LOG.Errorf("The nPanel app-store compatibility level %s is too low to synchronize with the App Store. The minimum required level is %s", global.AppStoreCompatibilityVersion, list.Extra.Version) return nil, buserr.New("ErrVersionTooLow") } res.AppList = list diff --git a/agent/app/service/app_sync_task.go b/agent/app/service/app_sync_task.go index b05c07f..70024e8 100644 --- a/agent/app/service/app_sync_task.go +++ b/agent/app/service/app_sync_task.go @@ -24,17 +24,17 @@ import ( ) type appSyncContext struct { - task *task.Task - httpClient http.Client - baseRemoteUrl string - systemVersion string - appsMap map[string]model.App - settingService ISettingService - list *dto.AppList - oldAppIds []uint - appTags []*model.AppTag - skipMetaSync bool - pendingIcons map[string]string + task *task.Task + httpClient http.Client + baseRemoteUrl string + compatibilityVersion string + appsMap map[string]model.App + settingService ISettingService + list *dto.AppList + oldAppIds []uint + appTags []*model.AppTag + skipMetaSync bool + pendingIcons map[string]string } func (a AppService) createSyncAppStoreTask(sharedCtx **appSyncContext) func(t *task.Task) error { @@ -74,21 +74,15 @@ func (a AppService) createSyncAppStoreTask(sharedCtx **appSyncContext) func(t *t global.LOG.Warnf("[AppStore] failed to update sync status to syncing: %v", err) } - setting, err := settingService.GetSettingInfo() - if err != nil { - t.LogFailedWithErr("GetSettingInfo", err) - return err - } - ctx := &appSyncContext{ - task: t, - httpClient: http.Client{Timeout: time.Duration(constant.TimeOut20s) * time.Second, Transport: xpack.MultiNodeProvider.LoadRequestTransport()}, - baseRemoteUrl: fmt.Sprintf("%s/%s/1panel", global.AppRepoURL(), global.CONF.Base.Mode), - systemVersion: setting.SystemVersion, - settingService: settingService, - list: list, - appTags: make([]*model.AppTag, 0), - pendingIcons: make(map[string]string), + task: t, + httpClient: http.Client{Timeout: time.Duration(constant.TimeOut20s) * time.Second, Transport: xpack.MultiNodeProvider.LoadRequestTransport()}, + baseRemoteUrl: fmt.Sprintf("%s/%s/1panel", global.AppRepoURL(), global.CONF.Base.Mode), + compatibilityVersion: global.AppStoreCompatibilityVersion, + settingService: settingService, + list: list, + appTags: make([]*model.AppTag, 0), + pendingIcons: make(map[string]string), } if err = SyncTags(list.Extra); err != nil { @@ -107,7 +101,7 @@ func (a AppService) createSyncAppStoreTask(sharedCtx **appSyncContext) func(t *t ctx.oldAppIds = append(ctx.oldAppIds, old.ID) } - ctx.appsMap, ctx.pendingIcons = getApps(oldApps, list.Apps, setting.SystemVersion, t) + ctx.appsMap, ctx.pendingIcons = getApps(oldApps, list.Apps, global.AppStoreCompatibilityVersion, t) var addCount, updateCount, deleteCount int if err = ctx.classifyAndPersistAppsWithStats(&addCount, &updateCount, &deleteCount); err != nil { @@ -184,7 +178,7 @@ func (c *appSyncContext) processOneApp(item appWorkItem) appWorkResult { var appForm dto.AppForm _ = json.Unmarshal(paramByte, &appForm) - if appForm.SupportVersion > 0 && common.CompareVersion(strconv.FormatFloat(appForm.SupportVersion, 'f', -1, 64), c.systemVersion) { + if appForm.SupportVersion > 0 && common.CompareVersion(strconv.FormatFloat(appForm.SupportVersion, 'f', -1, 64), c.compatibilityVersion) { delete(detailsMap, version) continue } diff --git a/agent/app/service/app_utils.go b/agent/app/service/app_utils.go index cd48dfe..815b333 100644 --- a/agent/app/service/app_utils.go +++ b/agent/app/service/app_utils.go @@ -1596,7 +1596,7 @@ func getAppDetails(details []model.AppDetail, versions []dto.AppConfigVersion) m return appDetails } -func getApps(oldApps []model.App, items []dto.AppDefine, systemVersion string, task *task.Task) (map[string]model.App, map[string]string) { +func getApps(oldApps []model.App, items []dto.AppDefine, compatibilityVersion string, task *task.Task) (map[string]model.App, map[string]string) { apps := make(map[string]model.App, len(oldApps)) pendingIcons := make(map[string]string, len(items)) for _, old := range oldApps { @@ -1605,11 +1605,11 @@ func getApps(oldApps []model.App, items []dto.AppDefine, systemVersion string, t } for _, item := range items { config := item.AppProperty - if config.Version > 0 && common.CompareVersion(strconv.FormatFloat(config.Version, 'f', -1, 64), systemVersion) { + if config.Version > 0 && common.CompareVersion(strconv.FormatFloat(config.Version, 'f', -1, 64), compatibilityVersion) { task.Log(i18n.GetWithName("AppVersionNotMatch", item.Name)) continue } - if config.Deprecated > 0 && common.CompareAppVersion(systemVersion, strconv.FormatFloat(config.Deprecated, 'f', -1, 64)) { + if config.Deprecated > 0 && common.CompareAppVersion(compatibilityVersion, strconv.FormatFloat(config.Deprecated, 'f', -1, 64)) { continue } diff --git a/agent/global/compatibility.go b/agent/global/compatibility.go new file mode 100644 index 0000000..70e2a71 --- /dev/null +++ b/agent/global/compatibility.go @@ -0,0 +1,6 @@ +package global + +// AppStoreCompatibilityVersion is the newest upstream app-catalog contract +// that nPanel has audited against. It is intentionally separate from the +// nPanel product version stored in SystemVersion. +const AppStoreCompatibilityVersion = "v2.2.3" diff --git a/docs/nPanel-nixos-design.md b/docs/nPanel-nixos-design.md index 42e8a65..d6aa476 100644 --- a/docs/nPanel-nixos-design.md +++ b/docs/nPanel-nixos-design.md @@ -120,6 +120,8 @@ nPanel 不向用户导向上游社区或商业站点。删除: 应用商店与资源端点需要单独进行兼容性审计:只要它们是保留 Docker 应用生态所必需的,就不自动删除;但 UI 不得展示上游品牌、商业、支持或社区链接。 +应用商店使用单独的内部兼容级别 `v2.2.3`。它表示 nPanel 已审计应用目录及其版本门槛所需的上游协议基线,不是 nPanel 的产品版本,也不写入用户配置或开放给用户覆盖。nPanel 的产品版本仍独立维护。 + ## 架构 ### 打包与服务布局