diff --git a/backend/app.yaml b/backend/app.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/backend/app/api/v1/app.go b/backend/app/api/v1/app.go index c18a0c345..90f065b2b 100644 --- a/backend/app/api/v1/app.go +++ b/backend/app/api/v1/app.go @@ -115,3 +115,12 @@ func (b *BaseApi) InstallApp(c *gin.Context) { tx.Commit() helper.SuccessWithData(c, install) } + +func (b *BaseApi) GetAppTags(c *gin.Context) { + tags, err := appService.GetAppTags() + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, tags) +} diff --git a/backend/app/api/v1/app_install.go b/backend/app/api/v1/app_install.go index a03d2db8e..31684c87e 100644 --- a/backend/app/api/v1/app_install.go +++ b/backend/app/api/v1/app_install.go @@ -38,7 +38,7 @@ func (b *BaseApi) SearchAppInstalled(c *gin.Context) { Total: total, }) } else { - list, err := appInstallService.Search(req) + list, err := appInstallService.SearchForWebsite(req) if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/dto/request/app.go b/backend/app/dto/request/app.go index 573f8d8fe..7ca73ca56 100644 --- a/backend/app/dto/request/app.go +++ b/backend/app/dto/request/app.go @@ -21,8 +21,11 @@ type AppInstallCreate struct { type AppInstalledSearch struct { dto.PageInfo - Type string `json:"type"` - Name string `json:"name"` + Type string `json:"type"` + Name string `json:"name"` + Tags []string `json:"tags"` + Update bool `json:"update"` + Unused bool `json:"unused"` } type AppBackupSearch struct { diff --git a/backend/app/dto/response/app.go b/backend/app/dto/response/app.go index 103d81837..3426a482f 100644 --- a/backend/app/dto/response/app.go +++ b/backend/app/dto/response/app.go @@ -19,6 +19,10 @@ type AppDTO struct { Tags []model.Tag `json:"tags"` } +type TagDTO struct { + model.Tag +} + type AppInstalledCheck struct { IsExist bool `json:"isExist"` Name string `json:"name"` diff --git a/backend/app/service/app.go b/backend/app/service/app.go index 26b7e1735..081a0fce3 100644 --- a/backend/app/service/app.go +++ b/backend/app/service/app.go @@ -90,25 +90,38 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) { return res, nil } -func (a AppService) GetApp(id uint) (response.AppDTO, error) { +func (a AppService) GetAppTags() ([]response.TagDTO, error) { + tags, err := tagRepo.All() + if err != nil { + return nil, err + } + var res []response.TagDTO + for _, tag := range tags { + res = append(res, response.TagDTO{ + Tag: tag, + }) + } + return res, nil +} + +func (a AppService) GetApp(id uint) (*response.AppDTO, error) { var appDTO response.AppDTO app, err := appRepo.GetFirst(commonRepo.WithByID(id)) if err != nil { - return appDTO, err + return nil, err } appDTO.App = app details, err := appDetailRepo.GetBy(appDetailRepo.WithAppId(app.ID)) if err != nil { - return appDTO, err + return nil, err } var versionsRaw []string for _, detail := range details { versionsRaw = append(versionsRaw, detail.Version) } - appDTO.Versions = common.GetSortedVersions(versionsRaw) - return appDTO, nil + return &appDTO, nil } func (a AppService) GetAppDetail(appId uint, version string) (response.AppDetailDTO, error) { diff --git a/backend/app/service/app_install.go b/backend/app/service/app_install.go index 473913416..ce9dead40 100644 --- a/backend/app/service/app_install.go +++ b/backend/app/service/app_install.go @@ -36,13 +36,33 @@ func (a AppInstallService) Page(req request.AppInstalledSearch) (int64, []respon if req.Name != "" { opts = append(opts, commonRepo.WithLikeName(req.Name)) } + if len(req.Tags) != 0 { + tags, err := tagRepo.GetByKeys(req.Tags) + if err != nil { + return 0, nil, err + } + var tagIds []uint + for _, t := range tags { + tagIds = append(tagIds, t.ID) + } + appTags, err := appTagRepo.GetByTagIds(tagIds) + if err != nil { + return 0, nil, err + } + var appIds []uint + for _, t := range appTags { + appIds = append(appIds, t.AppId) + } + + opts = append(opts, appInstallRepo.WithAppIdsIn(appIds)) + } total, installs, err := appInstallRepo.Page(req.Page, req.PageSize, opts...) if err != nil { return 0, nil, err } - installDTOs, err := handleInstalled(installs) + installDTOs, err := handleInstalled(installs, req.Update) if err != nil { return 0, nil, err } @@ -98,9 +118,12 @@ func (a AppInstallService) LoadPassword(key string) (string, error) { return app.Password, nil } -func (a AppInstallService) Search(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error) { - var installs []model.AppInstall - var err error +func (a AppInstallService) SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error) { + var ( + installs []model.AppInstall + err error + opts []repo.DBOption + ) if req.Type != "" { apps, err := appRepo.GetBy(appRepo.WithType(req.Type)) if err != nil { @@ -110,7 +133,11 @@ func (a AppInstallService) Search(req request.AppInstalledSearch) ([]response.Ap for _, app := range apps { ids = append(ids, app.ID) } - installs, err = appInstallRepo.GetBy(appInstallRepo.WithAppIdsIn(ids), appInstallRepo.WithIdNotInWebsite()) + if req.Unused { + opts = append(opts, appInstallRepo.WithIdNotInWebsite()) + } + opts = append(opts, appInstallRepo.WithAppIdsIn(ids)) + installs, err = appInstallRepo.GetBy(opts...) if err != nil { return nil, err } @@ -121,7 +148,7 @@ func (a AppInstallService) Search(req request.AppInstalledSearch) ([]response.Ap } } - return handleInstalled(installs) + return handleInstalled(installs, false) } func (a AppInstallService) Operate(req request.AppInstalledOperate) error { diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index 7ce4d6b98..3339297da 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -536,15 +536,12 @@ func getAppFromOss() error { return nil } -func handleInstalled(installed []model.AppInstall) ([]response.AppInstalledDTO, error) { +func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]response.AppInstalledDTO, error) { var res []response.AppInstalledDTO - - for _, installed := range installed { - + for _, installed := range appInstallList { installDTO := response.AppInstalledDTO{ AppInstall: installed, } - app, err := appRepo.GetFirst(commonRepo.WithByID(installed.AppId)) if err != nil { return nil, err @@ -559,15 +556,19 @@ func handleInstalled(installed []model.AppInstall) ([]response.AppInstalledDTO, } versions = common.GetSortedVersions(versions) lastVersion := versions[0] - if common.IsCrossVersion(installed.Version, lastVersion) { installDTO.CanUpdate = app.CrossVersionUpdate } else { installDTO.CanUpdate = common.CompareVersion(lastVersion, installed.Version) } - res = append(res, installDTO) + if updated { + if installDTO.CanUpdate { + res = append(res, installDTO) + } + } else { + res = append(res, installDTO) + } } - return res, nil } diff --git a/backend/router/ro_app.go b/backend/router/ro_app.go index ab497230b..b60588f66 100644 --- a/backend/router/ro_app.go +++ b/backend/router/ro_app.go @@ -20,6 +20,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) { appRouter.GET("/:id", baseApi.GetApp) appRouter.GET("/detail/:appId/:version", baseApi.GetAppDetail) appRouter.POST("/install", baseApi.InstallApp) + appRouter.GET("/tags", baseApi.GetAppTags) appRouter.GET("/installed/:appInstallId/versions", baseApi.GetUpdateVersions) appRouter.GET("/installed/check/:key", baseApi.CheckAppInstalled) appRouter.GET("/installed/loadport/:key", baseApi.LoadPort) diff --git a/frontend/components.d.ts b/frontend/components.d.ts index b5549d394..b0337b100 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -12,6 +12,7 @@ declare module 'vue' { BackButton: typeof import('./src/components/back-button/index.vue')['default'] BreadCrumbs: typeof import('./src/components/bread-crumbs/index.vue')['default'] BreadCrumbsItem: typeof import('./src/components/bread-crumbs/bread-crumbs-item.vue')['default'] + CardWithHeader: typeof import('./src/components/card-with-header/index.vue')['default'] Codemirror: typeof import('./src/components/codemirror-dialog/codemirror.vue')['default'] ComplexTable: typeof import('./src/components/complex-table/index.vue')['default'] ConfirmDialog: typeof import('./src/components/confirm-dialog/index.vue')['default'] @@ -40,6 +41,7 @@ declare module 'vue' { ElDropdown: typeof import('element-plus/es')['ElDropdown'] ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] + ElEmpty: typeof import('element-plus/es')['ElEmpty'] ElFooter: typeof import('element-plus/es')['ElFooter'] ElForm: typeof import('element-plus/es')['ElForm'] ElFormItem: typeof import('element-plus/es')['ElFormItem'] @@ -79,6 +81,7 @@ declare module 'vue' { Loading: typeof import('element-plus/es')['ElLoadingDirective'] Logo: typeof import('./src/components/app-layout/menu/components/Logo.vue')['default'] Menu: typeof import('./src/components/app-layout/menu/index.vue')['default'] + Popover: typeof import('element-plus/es')['ElPopoverDirective'] RouterButton: typeof import('./src/components/router-button/index.vue')['default'] Status: typeof import('./src/components/status/index.vue')['default'] SubItem: typeof import('./src/components/app-layout/menu/components/sub-item.vue')['default'] diff --git a/frontend/src/api/interface/app.ts b/frontend/src/api/interface/app.ts index 304d45afb..f1ef7a898 100644 --- a/frontend/src/api/interface/app.ts +++ b/frontend/src/api/interface/app.ts @@ -66,6 +66,9 @@ export namespace App { export interface AppInstallSearch extends ReqPage { name?: string; + tags?: string[]; + updated?: boolean; + unused?: boolean; } export interface ChangePort { key: string; diff --git a/frontend/src/api/modules/app.ts b/frontend/src/api/modules/app.ts index 0d0eb92f1..6bce18c20 100644 --- a/frontend/src/api/modules/app.ts +++ b/frontend/src/api/modules/app.ts @@ -14,6 +14,10 @@ export const GetApp = (id: number) => { return http.get('apps/' + id); }; +export const GetAppTags = () => { + return http.get('apps/tags'); +}; + export const GetAppDetail = (id: number, version: string) => { return http.get(`apps/detail/${id}/${version}`); }; diff --git a/frontend/src/components/app-status/index.vue b/frontend/src/components/app-status/index.vue index 1f466872e..819c619ac 100644 --- a/frontend/src/components/app-status/index.vue +++ b/frontend/src/components/app-status/index.vue @@ -1,14 +1,12 @@ diff --git a/frontend/src/views/website/website/index.vue b/frontend/src/views/website/website/index.vue index 63fdedb5c..13762215d 100644 --- a/frontend/src/views/website/website/index.vue +++ b/frontend/src/views/website/website/index.vue @@ -10,7 +10,7 @@