From 695d4b4a16431c5d568f57afc82d6f0125c4e9e4 Mon Sep 17 00:00:00 2001 From: zhengkunwang223 <31820853+zhengkunwang223@users.noreply.github.com> Date: Mon, 3 Jul 2023 16:36:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E5=8D=87=E7=BA=A7=E5=8A=9F=E8=83=BD=20(#1515?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/app_install.go | 22 ++++ backend/app/dto/request/app.go | 5 + backend/app/model/app_detail.go | 1 + backend/app/service/app_install.go | 13 ++ backend/app/service/app_utils.go | 5 +- backend/init/migration/migrate.go | 1 + backend/init/migration/migrations/init.go | 13 ++ backend/router/ro_app.go | 1 + cmd/server/docs/docs.go | 114 +++++++++++++++++- cmd/server/docs/swagger.json | 114 +++++++++++++++++- cmd/server/docs/swagger.yaml | 74 +++++++++++- frontend/src/api/modules/app.ts | 4 + frontend/src/lang/modules/en.ts | 1 + frontend/src/lang/modules/tw.ts | 1 + frontend/src/lang/modules/zh.ts | 1 + .../src/views/app-store/installed/index.vue | 15 ++- .../app-store/installed/upgrade/index.vue | 53 +++++--- 17 files changed, 414 insertions(+), 24 deletions(-) diff --git a/backend/app/api/v1/app_install.go b/backend/app/api/v1/app_install.go index e1042a5f9..b8c67c1a5 100644 --- a/backend/app/api/v1/app_install.go +++ b/backend/app/api/v1/app_install.go @@ -305,3 +305,25 @@ func (b *BaseApi) UpdateInstalled(c *gin.Context) { } helper.SuccessWithData(c, nil) } + +// @Tags App +// @Summary ignore App Update +// @Description 忽略应用升级版本 +// @Accept json +// @Param request body request.AppInstalledIgnoreUpgrade true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /apps/installed/ignore [post] +// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"忽略应用 [installId] 版本升级","formatEN":"Application param update [installId]"} +func (b *BaseApi) IgnoreUpgrade(c *gin.Context) { + var req request.AppInstalledIgnoreUpgrade + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := appInstallService.IgnoreUpgrade(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithOutData(c) +} diff --git a/backend/app/dto/request/app.go b/backend/app/dto/request/app.go index 1e9b292fa..39cfb3a37 100644 --- a/backend/app/dto/request/app.go +++ b/backend/app/dto/request/app.go @@ -66,6 +66,11 @@ type AppInstalledUpdate struct { AppContainerConfig } +type AppInstalledIgnoreUpgrade struct { + InstallId uint `json:"installId" validate:"required"` + DetailId uint `json:"detailId" validate:"required"` +} + type PortUpdate struct { Key string `json:"key"` Name string `json:"name"` diff --git a/backend/app/model/app_detail.go b/backend/app/model/app_detail.go index 9a4d8c6db..d6b958284 100644 --- a/backend/app/model/app_detail.go +++ b/backend/app/model/app_detail.go @@ -12,4 +12,5 @@ type AppDetail struct { DownloadUrl string `json:"downloadUrl" gorm:"type:varchar;"` DownloadCallBackUrl string `json:"downloadCallBackUrl" gorm:"type:longtext;"` Update bool `json:"update"` + IgnoreUpgrade bool `json:"ignoreUpgrade"` } diff --git a/backend/app/service/app_install.go b/backend/app/service/app_install.go index b5d429d20..ff209c627 100644 --- a/backend/app/service/app_install.go +++ b/backend/app/service/app_install.go @@ -45,6 +45,7 @@ type IAppInstallService interface { SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error) Operate(req request.AppInstalledOperate) error Update(req request.AppInstalledUpdate) error + IgnoreUpgrade(req request.AppInstalledIgnoreUpgrade) error SyncAll(systemInit bool) error GetServices(key string) ([]response.AppService, error) GetUpdateVersions(installId uint) ([]dto.AppVersion, error) @@ -352,6 +353,15 @@ func (a *AppInstallService) Update(req request.AppInstalledUpdate) error { return nil } +func (a *AppInstallService) IgnoreUpgrade(req request.AppInstalledIgnoreUpgrade) error { + appDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(req.DetailId)) + if err != nil { + return err + } + appDetail.IgnoreUpgrade = true + return appDetailRepo.Update(context.Background(), appDetail) +} + func (a *AppInstallService) SyncAll(systemInit bool) error { allList, err := appInstallRepo.ListBy() if err != nil { @@ -412,6 +422,9 @@ func (a *AppInstallService) GetUpdateVersions(installId uint) ([]dto.AppVersion, return versions, err } for _, detail := range details { + if detail.IgnoreUpgrade { + continue + } if common.IsCrossVersion(install.Version, detail.Version) && !app.CrossVersionUpdate { continue } diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index ca7d28ac9..593e76e38 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -751,7 +751,7 @@ func handleErr(install model.AppInstall, err error, out string) error { func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]response.AppInstalledDTO, error) { var res []response.AppInstalledDTO for _, installed := range appInstallList { - if updated && installed.App.Type == "php" { + if updated && installed.App.Type == "php" || installed.Status == constant.Installing { continue } installDTO := response.AppInstalledDTO{ @@ -768,6 +768,9 @@ func handleInstalled(appInstallList []model.AppInstall, updated bool) ([]respons } var versions []string for _, detail := range details { + if detail.IgnoreUpgrade { + continue + } if common.IsCrossVersion(installed.Version, detail.Version) && !app.CrossVersionUpdate { continue } diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go index dbb170784..dc7e804b9 100644 --- a/backend/init/migration/migrate.go +++ b/backend/init/migration/migrate.go @@ -33,6 +33,7 @@ func Init() { migrations.UpdateWebsite, migrations.AddBackupAccountDir, migrations.AddMfaInterval, + migrations.UpdateAppDetail, }) if err := m.Migrate(); err != nil { global.LOG.Error(err) diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index 94a5f8513..60b438a74 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -413,3 +413,16 @@ var AddMfaInterval = &gormigrate.Migration{ return nil }, } + +var UpdateAppDetail = &gormigrate.Migration{ + ID: "20230704-update-app-detail", + Migrate: func(tx *gorm.DB) error { + if err := tx.AutoMigrate(&model.AppDetail{}); err != nil { + return err + } + if err := tx.Model(&model.AppDetail{}).Where("1 = 1").Update("ignore_upgrade", "0").Error; err != nil { + return err + } + return nil + }, +} diff --git a/backend/router/ro_app.go b/backend/router/ro_app.go index 1f734fb95..e31178080 100644 --- a/backend/router/ro_app.go +++ b/backend/router/ro_app.go @@ -36,5 +36,6 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) { appRouter.GET("/installed/conf/:key", baseApi.GetDefaultConfig) appRouter.GET("/installed/params/:appInstallId", baseApi.GetParams) appRouter.POST("/installed/params/update", baseApi.UpdateInstalled) + appRouter.POST("/installed/ignore", baseApi.IgnoreUpgrade) } } diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index a055dd906..f23bee5fb 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -387,6 +387,48 @@ const docTemplate = `{ } } }, + "/apps/installed/ignore": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "忽略应用升级版本", + "consumes": [ + "application/json" + ], + "tags": [ + "App" + ], + "summary": "ignore App Update", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.AppInstalledIgnoreUpgrade" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFuntions": [], + "bodyKeys": [ + "installId" + ], + "formatEN": "Application param update [installId]", + "formatZH": "忽略应用 [installId] 版本升级", + "paramKeys": [] + } + } + }, "/apps/installed/loadport/:key": { "get": { "security": [ @@ -1865,6 +1907,31 @@ const docTemplate = `{ } } }, + "/containers/list": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取容器名称", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Container" + ], + "summary": "List containers", + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/containers/network": { "post": { "security": [ @@ -9632,7 +9699,7 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "更新 php 配置", + "description": "更新 php 配置文件", "consumes": [ "application/json" ], @@ -10967,6 +11034,9 @@ const docTemplate = `{ "type" ], "properties": { + "containerName": { + "type": "string" + }, "day": { "type": "integer" }, @@ -11046,6 +11116,9 @@ const docTemplate = `{ "specType" ], "properties": { + "containerName": { + "type": "string" + }, "day": { "type": "integer" }, @@ -12265,6 +12338,12 @@ const docTemplate = `{ "name": { "type": "string" }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, "page": { "type": "integer" }, @@ -12819,6 +12898,12 @@ const docTemplate = `{ "info": { "type": "string" }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, "page": { "type": "integer" }, @@ -12911,6 +12996,9 @@ const docTemplate = `{ "sslType": { "type": "string" }, + "systemIP": { + "type": "string" + }, "systemVersion": { "type": "string" }, @@ -13562,6 +13650,21 @@ const docTemplate = `{ } } }, + "request.AppInstalledIgnoreUpgrade": { + "type": "object", + "required": [ + "detailId", + "installId" + ], + "properties": { + "detailId": { + "type": "integer" + }, + "installId": { + "type": "integer" + } + } + }, "request.AppInstalledOperate": { "type": "object", "required": [ @@ -14863,6 +14966,12 @@ const docTemplate = `{ "name": { "type": "string" }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, "page": { "type": "integer" }, @@ -15078,6 +15187,9 @@ const docTemplate = `{ "id": { "type": "integer" }, + "ignoreUpgrade": { + "type": "boolean" + }, "image": { "type": "string" }, diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index d7b8bd4a0..0e8ab5bda 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -380,6 +380,48 @@ } } }, + "/apps/installed/ignore": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "忽略应用升级版本", + "consumes": [ + "application/json" + ], + "tags": [ + "App" + ], + "summary": "ignore App Update", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.AppInstalledIgnoreUpgrade" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFuntions": [], + "bodyKeys": [ + "installId" + ], + "formatEN": "Application param update [installId]", + "formatZH": "忽略应用 [installId] 版本升级", + "paramKeys": [] + } + } + }, "/apps/installed/loadport/:key": { "get": { "security": [ @@ -1858,6 +1900,31 @@ } } }, + "/containers/list": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取容器名称", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Container" + ], + "summary": "List containers", + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/containers/network": { "post": { "security": [ @@ -9625,7 +9692,7 @@ "ApiKeyAuth": [] } ], - "description": "更新 php 配置", + "description": "更新 php 配置文件", "consumes": [ "application/json" ], @@ -10960,6 +11027,9 @@ "type" ], "properties": { + "containerName": { + "type": "string" + }, "day": { "type": "integer" }, @@ -11039,6 +11109,9 @@ "specType" ], "properties": { + "containerName": { + "type": "string" + }, "day": { "type": "integer" }, @@ -12258,6 +12331,12 @@ "name": { "type": "string" }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, "page": { "type": "integer" }, @@ -12812,6 +12891,12 @@ "info": { "type": "string" }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, "page": { "type": "integer" }, @@ -12904,6 +12989,9 @@ "sslType": { "type": "string" }, + "systemIP": { + "type": "string" + }, "systemVersion": { "type": "string" }, @@ -13555,6 +13643,21 @@ } } }, + "request.AppInstalledIgnoreUpgrade": { + "type": "object", + "required": [ + "detailId", + "installId" + ], + "properties": { + "detailId": { + "type": "integer" + }, + "installId": { + "type": "integer" + } + } + }, "request.AppInstalledOperate": { "type": "object", "required": [ @@ -14856,6 +14959,12 @@ "name": { "type": "string" }, + "order": { + "type": "string" + }, + "orderBy": { + "type": "string" + }, "page": { "type": "integer" }, @@ -15071,6 +15180,9 @@ "id": { "type": "integer" }, + "ignoreUpgrade": { + "type": "boolean" + }, "image": { "type": "string" }, diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index f57c08583..ca56bd541 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -385,6 +385,8 @@ definitions: type: object dto.CronjobCreate: properties: + containerName: + type: string day: type: integer dbName: @@ -439,6 +441,8 @@ definitions: type: object dto.CronjobUpdate: properties: + containerName: + type: string day: type: integer dbName: @@ -1258,6 +1262,10 @@ definitions: type: string name: type: string + order: + type: string + orderBy: + type: string page: type: integer pageSize: @@ -1627,6 +1635,10 @@ definitions: properties: info: type: string + order: + type: string + orderBy: + type: string page: type: integer pageSize: @@ -1691,6 +1703,8 @@ definitions: type: string sslType: type: string + systemIP: + type: string systemVersion: type: string theme: @@ -2121,6 +2135,16 @@ definitions: - appDetailId - name type: object + request.AppInstalledIgnoreUpgrade: + properties: + detailId: + type: integer + installId: + type: integer + required: + - detailId + - installId + type: object request.AppInstalledOperate: properties: backupId: @@ -2993,6 +3017,10 @@ definitions: properties: name: type: string + order: + type: string + orderBy: + type: string page: type: integer pageSize: @@ -3140,6 +3168,8 @@ definitions: type: boolean id: type: integer + ignoreUpgrade: + type: boolean image: type: string lastModified: @@ -3644,6 +3674,33 @@ paths: summary: Check before delete tags: - App + /apps/installed/ignore: + post: + consumes: + - application/json + description: 忽略应用升级版本 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/request.AppInstalledIgnoreUpgrade' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: ignore App Update + tags: + - App + x-panel-log: + BeforeFuntions: [] + bodyKeys: + - installId + formatEN: Application param update [installId] + formatZH: 忽略应用 [installId] 版本升级 + paramKeys: [] /apps/installed/loadport/:key: get: consumes: @@ -4586,6 +4643,21 @@ paths: security: - ApiKeyAuth: [] summary: Load container limis + /containers/list: + post: + consumes: + - application/json + description: 获取容器名称 + produces: + - application/json + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: List containers + tags: + - Container /containers/network: post: consumes: @@ -9521,7 +9593,7 @@ paths: post: consumes: - application/json - description: 更新 php 配置 + description: 更新 php 配置文件 parameters: - description: request in: body diff --git a/frontend/src/api/modules/app.ts b/frontend/src/api/modules/app.ts index cfe1ed6e5..f8fb943cf 100644 --- a/frontend/src/api/modules/app.ts +++ b/frontend/src/api/modules/app.ts @@ -89,3 +89,7 @@ export const GetAppInstallParams = (id: number) => { export const UpdateAppInstallParams = (req: any) => { return http.post(`apps/installed/params/update`, req); }; + +export const IgnoreUpgrade = (req: any) => { + return http.post(`apps/installed/ignore`, req); +}; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 27dde622f..7d5b1b238 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -44,6 +44,7 @@ const message = { refresh: 'Refresh', get: 'Get', upgrade: 'Upgrade', + ignoreUpgrade: 'Ignore upgrade', }, search: { timeStart: 'Time start', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index a782133f9..9b50dc444 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -44,6 +44,7 @@ const message = { refresh: '刷新', get: '獲取', upgrade: '升級', + ignoreUpgrade: '忽略升級', }, search: { timeStart: '開始時間', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 773baf742..e6074641a 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -44,6 +44,7 @@ const message = { refresh: '刷新', get: '获取', upgrade: '升级', + ignoreUpgrade: '忽略升级', }, search: { timeStart: '开始时间', diff --git a/frontend/src/views/app-store/installed/index.vue b/frontend/src/views/app-store/installed/index.vue index 0ca378209..a08386d5e 100644 --- a/frontend/src/views/app-store/installed/index.vue +++ b/frontend/src/views/app-store/installed/index.vue @@ -158,6 +158,17 @@ > {{ $t('commons.button.backup') }} + + {{ $t('commons.button.ignoreUpgrade') }} + { const openOperate = (row: any, op: string) => { operateReq.installId = row.id; operateReq.operate = op; - if (op == 'upgrade') { - upgradeRef.value.acceptParams(row.id, row.name); + if (op == 'upgrade' || op == 'ignoreUpgrade') { + upgradeRef.value.acceptParams(row.id, row.name, op); } else if (op == 'delete') { AppInstalledDeleteCheck(row.id).then(async (res) => { const items = res.data; diff --git a/frontend/src/views/app-store/installed/upgrade/index.vue b/frontend/src/views/app-store/installed/upgrade/index.vue index f968dc5b5..5ffb50922 100644 --- a/frontend/src/views/app-store/installed/upgrade/index.vue +++ b/frontend/src/views/app-store/installed/upgrade/index.vue @@ -1,7 +1,11 @@