diff --git a/backend/app/api/v1/app.go b/backend/app/api/v1/app.go index e55af6dd1..eab5a5dff 100644 --- a/backend/app/api/v1/app.go +++ b/backend/app/api/v1/app.go @@ -75,7 +75,7 @@ func (b *BaseApi) GetApp(c *gin.Context) { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - appDTO, err := appService.GetApp(appKey) + appDTO, err := appService.GetApp(c, appKey) if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/dto/app.go b/backend/app/dto/app.go index e37a51f80..21b2766f3 100644 --- a/backend/app/dto/app.go +++ b/backend/app/dto/app.go @@ -1,9 +1,5 @@ package dto -import ( - "github.com/1Panel-dev/1Panel/backend/app/model" -) - type AppDatabase struct { ServiceName string `json:"PANEL_DB_HOST"` DbName string `json:"PANEL_DB_NAME"` @@ -62,7 +58,7 @@ type AppDefine struct { } type LocalAppAppDefine struct { - AppProperty model.App `json:"additionalProperties" yaml:"additionalProperties"` + AppProperty AppProperty `json:"additionalProperties" yaml:"additionalProperties"` } type LocalAppParam struct { @@ -84,6 +80,7 @@ type AppProperty struct { Tags []string `json:"tags"` ShortDescZh string `json:"shortDescZh"` ShortDescEn string `json:"shortDescEn"` + Description Locale `json:"description"` Key string `json:"key"` Required []string `json:"Required"` CrossVersionUpdate bool `json:"crossVersionUpdate"` @@ -114,9 +111,9 @@ type Locale struct { En string `json:"en"` Ja string `json:"ja"` Ms string `json:"ms"` - PtBr string `json:"pt-br"` + PtBr string `json:"pt-br" yaml:"pt-br"` Ru string `json:"ru"` - ZhHant string `json:"zh-hant"` + ZhHant string `json:"zh-hant" yaml:"zh-hant"` Zh string `json:"zh"` } @@ -129,6 +126,7 @@ type AppFormFields struct { Type string `json:"type"` LabelZh string `json:"labelZh"` LabelEn string `json:"labelEn"` + Label Locale `json:"label"` Required bool `json:"required"` Default interface{} `json:"default"` EnvKey string `json:"envKey"` diff --git a/backend/app/dto/response/app.go b/backend/app/dto/response/app.go index 72773f466..2bd231deb 100644 --- a/backend/app/dto/response/app.go +++ b/backend/app/dto/response/app.go @@ -32,8 +32,7 @@ type AppItem struct { Name string `json:"name"` Key string `json:"key"` ID uint `json:"id"` - ShortDescZh string `json:"shortDescZh"` - ShortDescEn string `json:"shortDescEn"` + Description string `json:"description"` Icon string `json:"icon"` Type string `json:"type"` Status string `json:"status"` diff --git a/backend/app/model/app.go b/backend/app/model/app.go index 3e67391e8..2fd729d79 100644 --- a/backend/app/model/app.go +++ b/backend/app/model/app.go @@ -1,7 +1,10 @@ package model import ( + "encoding/json" "github.com/1Panel-dev/1Panel/backend/constant" + "github.com/1Panel-dev/1Panel/backend/utils/common" + "github.com/gin-gonic/gin" "path/filepath" "strings" ) @@ -12,6 +15,7 @@ type App struct { Key string `json:"key" gorm:"type:varchar(64);not null;"` ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh" gorm:"type:longtext;"` ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn" gorm:"type:longtext;"` + Description string `json:"description"` Icon string `json:"icon" gorm:"type:longtext;"` Type string `json:"type" gorm:"type:varchar(64);not null"` Status string `json:"status" gorm:"type:varchar(64);not null"` @@ -36,8 +40,20 @@ func (i *App) IsLocalApp() bool { } func (i *App) GetAppResourcePath() string { if i.IsLocalApp() { - //这里要去掉本地应用的local前缀 return filepath.Join(constant.LocalAppResourceDir, strings.TrimPrefix(i.Key, "local")) } return filepath.Join(constant.RemoteAppResourceDir, i.Key) } + +func (i *App) GetDescription(ctx *gin.Context) string { + var translations = make(map[string]string) + _ = json.Unmarshal([]byte(i.Description), &translations) + lang := strings.ToLower(common.GetLang(ctx)) + if desc, ok := translations[lang]; ok { + return desc + } + if lang == "zh" { + return i.ShortDescZh + } + return i.ShortDescEn +} diff --git a/backend/app/service/app.go b/backend/app/service/app.go index d69c5bd92..159dd6912 100644 --- a/backend/app/service/app.go +++ b/backend/app/service/app.go @@ -37,7 +37,7 @@ type AppService struct { type IAppService interface { PageApp(ctx *gin.Context, req request.AppSearch) (interface{}, error) GetAppTags(ctx *gin.Context) ([]response.TagDTO, error) - GetApp(key string) (*response.AppDTO, error) + GetApp(ctx *gin.Context, key string) (*response.AppDTO, error) GetAppDetail(appId uint, version, appType string) (response.AppDetailDTO, error) Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error) SyncAppListFromRemote() error @@ -94,16 +94,15 @@ func (a AppService) PageApp(ctx *gin.Context, req request.AppSearch) (interface{ lang := strings.ToLower(common.GetLang(ctx)) for _, ap := range apps { appDTO := &response.AppItem{ - ID: ap.ID, - Name: ap.Name, - Key: ap.Key, - Type: ap.Type, - Icon: ap.Icon, - ShortDescZh: ap.ShortDescZh, - ShortDescEn: ap.ShortDescEn, - Resource: ap.Resource, - Limit: ap.Limit, + ID: ap.ID, + Name: ap.Name, + Key: ap.Key, + Type: ap.Type, + Icon: ap.Icon, + Resource: ap.Resource, + Limit: ap.Limit, } + appDTO.Description = ap.GetDescription(ctx) appDTOs = append(appDTOs, appDTO) appTags, err := appTagRepo.GetByAppId(ap.ID) if err != nil { @@ -166,7 +165,7 @@ func (a AppService) GetAppTags(ctx *gin.Context) ([]response.TagDTO, error) { return res, nil } -func (a AppService) GetApp(key string) (*response.AppDTO, error) { +func (a AppService) GetApp(ctx *gin.Context, key string) (*response.AppDTO, error) { var appDTO response.AppDTO if key == "postgres" { key = "postgresql" @@ -176,6 +175,7 @@ func (a AppService) GetApp(key string) (*response.AppDTO, error) { return nil, err } appDTO.App = app + appDTO.App.Description = app.GetDescription(ctx) details, err := appDetailRepo.GetBy(appDetailRepo.WithAppId(app.ID)) if err != nil { return nil, err diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index ef70e974c..8da246856 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -1051,6 +1051,8 @@ func getApps(oldApps []model.App, items []dto.AppDefine) map[string]model.App { app.Key = key app.ShortDescZh = config.ShortDescZh app.ShortDescEn = config.ShortDescEn + description, _ := json.Marshal(config.Description) + app.Description = string(description) app.Website = config.Website app.Document = config.Document app.Github = config.Github @@ -1150,14 +1152,32 @@ func handleLocalApp(appDir string) (app *model.App, err error) { err = buserr.WithMap(constant.ErrFileParseApp, map[string]interface{}{"name": "data.yml", "err": err.Error()}, err) return } - app = &localAppDefine.AppProperty + appDefine := localAppDefine.AppProperty + app = &model.App{} + app.Name = appDefine.Name + app.TagsKey = append(appDefine.Tags, "Local") + app.Type = appDefine.Type + app.CrossVersionUpdate = appDefine.CrossVersionUpdate + app.Limit = appDefine.Limit + app.Recommend = appDefine.Recommend + app.Website = appDefine.Website + app.Github = appDefine.Github + app.Document = appDefine.Document + + if appDefine.ShortDescZh != "" { + appDefine.Description.Zh = appDefine.ShortDescZh + } + if appDefine.ShortDescEn != "" { + appDefine.Description.En = appDefine.ShortDescEn + } + desc, _ := json.Marshal(appDefine.Description) + app.Description = string(desc) + + app.Key = "local" + appDefine.Key app.Resource = constant.AppResourceLocal app.Status = constant.AppNormal app.Recommend = 9999 - app.TagsKey = append(app.TagsKey, "Local") - app.Key = "local" + app.Key - readMePath := path.Join(appDir, "README.md") - readMeByte, err := fileOp.GetContent(readMePath) + readMeByte, err := fileOp.GetContent(path.Join(appDir, "README.md")) if err == nil { app.ReadMe = string(readMeByte) } diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index e548494ec..4ca6e8ef8 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -101,6 +101,7 @@ func Init() { migrations.AddApiKeyValidityTime, migrations.UpdateAppTag, + migrations.UpdateApp, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/v_1_10.go b/backend/init/migration/migrations/v_1_10.go index 4fa3098a8..cdb2687f5 100644 --- a/backend/init/migration/migrations/v_1_10.go +++ b/backend/init/migration/migrations/v_1_10.go @@ -362,7 +362,7 @@ var AddApiKeyValidityTime = &gormigrate.Migration{ } var UpdateAppTag = &gormigrate.Migration{ - ID: "20241226-update-app-tag", + ID: "20250114-update-app-tag", Migrate: func(tx *gorm.DB) error { if err := tx.AutoMigrate(&model.Tag{}); err != nil { return err @@ -370,3 +370,13 @@ var UpdateAppTag = &gormigrate.Migration{ return nil }, } + +var UpdateApp = &gormigrate.Migration{ + ID: "20250114-update-app", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&model.App{}); err != nil { + return err + } + return nil + }, +} diff --git a/frontend/src/api/interface/app.ts b/frontend/src/api/interface/app.ts index cf27cb27f..a7a05fe75 100644 --- a/frontend/src/api/interface/app.ts +++ b/frontend/src/api/interface/app.ts @@ -8,6 +8,7 @@ export namespace App { tags: Tag[]; shortDescZh: string; shortDescEn: string; + description: string; author: string; source: string; type: string; @@ -58,10 +59,21 @@ export namespace App { formFields: FromField[]; } + interface Locale { + zh: string; + en: string; + 'zh-Hant': string; + ja: string; + ms: string; + 'pt-br': string; + ru: string; + } + export interface FromField { type: string; labelZh: string; labelEn: string; + label: Locale; required: boolean; default: any; envKey: string; diff --git a/frontend/src/views/app-store/apps/index.vue b/frontend/src/views/app-store/apps/index.vue index d630a9b42..e52c9ce39 100644 --- a/frontend/src/views/app-store/apps/index.vue +++ b/frontend/src/views/app-store/apps/index.vue @@ -129,11 +129,7 @@