From 1e1fce4c777dc73ee1c04ac520d13179080077dd Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Thu, 26 Sep 2024 21:59:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BD=91=E7=AB=99=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E6=95=B0=E6=8D=AE=E5=BA=93=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20(#6592)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/app/api/v2/website.go | 59 ++++++++- agent/app/dto/request/website.go | 6 + agent/app/dto/response/website.go | 13 ++ agent/app/service/website.go | 117 ++++++++++++++++++ agent/router/ro_website.go | 4 + agent/utils/docker/compose.go | 1 - frontend/src/api/interface/website.ts | 19 +++ frontend/src/api/modules/website.ts | 12 ++ frontend/src/lang/modules/en.ts | 5 + frontend/src/lang/modules/tw.ts | 5 + frontend/src/lang/modules/zh.ts | 5 + .../website/config/basic/anti-Leech/index.vue | 17 ++- .../website/website/config/basic/index.vue | 12 +- .../website/config/basic/limit-conn/index.vue | 10 +- .../website/config/basic/other/index.vue | 2 +- .../website/config/basic/php/index.vue | 6 +- .../website/config/basic/resource/index.vue | 93 ++++++++++++++ 17 files changed, 368 insertions(+), 18 deletions(-) create mode 100644 frontend/src/views/website/website/config/basic/resource/index.vue diff --git a/agent/app/api/v2/website.go b/agent/app/api/v2/website.go index 7da137e5a..acddda770 100644 --- a/agent/app/api/v2/website.go +++ b/agent/app/api/v2/website.go @@ -968,7 +968,6 @@ func (b *BaseApi) SetRealIPConfig(c *gin.Context) { helper.SuccessWithOutData(c) } -// 写一个调用 GetRealIPConfig 的接口 // @Tags Website // @Summary Get Real IP Config // @Description 获取真实 IP 配置 @@ -990,3 +989,61 @@ func (b *BaseApi) GetRealIPConfig(c *gin.Context) { } helper.SuccessWithData(c, res) } + +// @Tags Website +// @Summary Get website resource +// @Description 获取网站资源 +// @Accept json +// @Param id path int true "id" +// @Success 200 {object} response.WebsiteResource +// @Security ApiKeyAuth +// @Router /websites/resource/{id} [get] +func (b *BaseApi) GetWebsiteResource(c *gin.Context) { + id, err := helper.GetParamID(c) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil) + return + } + res, err := websiteService.GetWebsiteResource(id) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, res) +} + +// @Tags Website +// @Summary Get databases +// @Description 获取数据库列表 +// @Accept json +// @Success 200 {object} response.WebsiteDatabase +// @Security ApiKeyAuth +// @Router /websites/databases [get] +func (b *BaseApi) GetWebsiteDatabase(c *gin.Context) { + res, err := websiteService.ListDatabases() + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, res) +} + +// @Tags Website +// @Summary Change website database +// @Description 切换网站数据库 +// @Accept json +// @Param request body request.ChangeDatabase true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /websites/databases [post] +func (b *BaseApi) ChangeWebsiteDatabase(c *gin.Context) { + var req request.ChangeDatabase + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + if err := websiteService.ChangeDatabase(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithOutData(c) +} diff --git a/agent/app/dto/request/website.go b/agent/app/dto/request/website.go index a0b6721db..85d1c95f6 100644 --- a/agent/app/dto/request/website.go +++ b/agent/app/dto/request/website.go @@ -275,3 +275,9 @@ type WebsiteRealIP struct { IPHeader string `json:"ipHeader"` IPOther string `json:"ipOther"` } + +type ChangeDatabase struct { + WebsiteID uint `json:"websiteID" validate:"required"` + DatabaseID uint `json:"databaseID" validate:"required"` + DatabaseType string `json:"databaseType" validate:"required"` +} diff --git a/agent/app/dto/response/website.go b/agent/app/dto/response/website.go index bb0d347c9..857a5cd0d 100644 --- a/agent/app/dto/response/website.go +++ b/agent/app/dto/response/website.go @@ -102,3 +102,16 @@ type WebsiteRealIP struct { IPHeader string `json:"ipHeader"` IPOther string `json:"ipOther"` } + +type Resource struct { + Name string `json:"name"` + Type string `json:"type"` + ResourceID uint `json:"resourceID"` + Detail interface{} `json:"detail"` +} + +type Database struct { + Name string `json:"name"` + Type string `json:"type"` + ID uint `json:"id"` +} diff --git a/agent/app/service/website.go b/agent/app/service/website.go index e9c84adb6..cf9061138 100644 --- a/agent/app/service/website.go +++ b/agent/app/service/website.go @@ -113,6 +113,10 @@ type IWebsiteService interface { GetRealIPConfig(websiteID uint) (*response.WebsiteRealIP, error) ChangeGroup(group, newGroup uint) error + + GetWebsiteResource(websiteID uint) ([]response.Resource, error) + ListDatabases() ([]response.Database, error) + ChangeDatabase(req request.ChangeDatabase) error } func NewIWebsiteService() IWebsiteService { @@ -3052,3 +3056,116 @@ func (w WebsiteService) GetRealIPConfig(websiteID uint) (*response.WebsiteRealIP res.IPFrom = strings.Join(ips, "\n") return res, err } + +func (w WebsiteService) GetWebsiteResource(websiteID uint) ([]response.Resource, error) { + website, err := websiteRepo.GetFirst(commonRepo.WithByID(websiteID)) + if err != nil { + return nil, err + } + var ( + res []response.Resource + databaseID uint + databaseType string + ) + if website.Type == constant.Runtime { + runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(website.RuntimeID)) + if err != nil { + return nil, err + } + res = append(res, response.Resource{ + Name: runtime.Name, + Type: "runtime", + ResourceID: runtime.ID, + Detail: runtime, + }) + } + if website.Type == constant.Deployment { + install, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID)) + if err != nil { + return nil, err + } + res = append(res, response.Resource{ + Name: install.Name, + Type: "app", + ResourceID: install.ID, + Detail: install, + }) + installResources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID)) + for _, resource := range installResources { + if resource.Key == constant.AppMysql || resource.Key == constant.AppMariaDB || resource.Key == constant.AppPostgres || resource.Key == constant.AppPostgresql { + databaseType = resource.Key + databaseID = resource.ResourceId + } + } + } + if website.DbID > 0 { + databaseType = website.DbType + databaseID = website.DbID + } + if databaseID > 0 { + switch databaseType { + case constant.AppMysql, constant.AppMariaDB: + db, _ := mysqlRepo.Get(commonRepo.WithByID(databaseID)) + if db.ID > 0 { + res = append(res, response.Resource{ + Name: db.Name, + Type: "database", + ResourceID: db.ID, + Detail: db, + }) + } + case constant.AppPostgresql, constant.AppPostgres: + db, _ := postgresqlRepo.Get(commonRepo.WithByID(databaseID)) + if db.ID > 0 { + res = append(res, response.Resource{ + Name: db.Name, + Type: "database", + ResourceID: db.ID, + Detail: db, + }) + } + } + } + + return res, nil +} + +func (w WebsiteService) ListDatabases() ([]response.Database, error) { + var res []response.Database + mysqlDBs, _ := mysqlRepo.List() + for _, db := range mysqlDBs { + database, _ := databaseRepo.Get(commonRepo.WithByName(db.MysqlName)) + if database.ID > 0 { + res = append(res, response.Database{ + ID: db.ID, + Name: db.Name, + Type: database.Type, + }) + } + } + pgSqls, _ := postgresqlRepo.List() + for _, db := range pgSqls { + database, _ := databaseRepo.Get(commonRepo.WithByName(db.Name)) + if database.ID > 0 { + res = append(res, response.Database{ + ID: db.ID, + Name: db.Name, + Type: database.Type, + }) + } + } + return res, nil +} + +func (w WebsiteService) ChangeDatabase(req request.ChangeDatabase) error { + website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.WebsiteID)) + if err != nil { + return err + } + if website.DbID == req.DatabaseID { + return nil + } + website.DbID = req.DatabaseID + website.DbType = req.DatabaseType + return websiteRepo.Save(context.Background(), &website) +} diff --git a/agent/router/ro_website.go b/agent/router/ro_website.go index c5d837ca7..dabb3a384 100644 --- a/agent/router/ro_website.go +++ b/agent/router/ro_website.go @@ -77,5 +77,9 @@ func (a *WebsiteRouter) InitRouter(Router *gin.RouterGroup) { websiteRouter.POST("/realip/config", baseApi.SetRealIPConfig) websiteRouter.GET("/realip/config/:id", baseApi.GetRealIPConfig) + + websiteRouter.GET("/resource/:id", baseApi.GetWebsiteResource) + websiteRouter.GET("/databases", baseApi.GetWebsiteDatabase) + websiteRouter.POST("/databases", baseApi.ChangeWebsiteDatabase) } } diff --git a/agent/utils/docker/compose.go b/agent/utils/docker/compose.go index f11152153..ce5dae58e 100644 --- a/agent/utils/docker/compose.go +++ b/agent/utils/docker/compose.go @@ -15,7 +15,6 @@ import ( type ComposeService struct { api.Service - project *types.Project } func GetComposeProject(projectName, workDir string, yml []byte, env []byte, skipNormalization bool) (*types.Project, error) { diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 8fbeab6e9..e556a2b0c 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -607,4 +607,23 @@ export namespace Website { ipHeader: string; ipOther: string; } + + export interface WebsiteResource { + name: string; + type: string; + resourceID: number; + detail: any; + } + + export interface WebsiteDatabase { + type: string; + databaseID: number; + websiteID: number; + } + + export interface ChangeDatabase { + websiteID: number; + databaseID: number; + databaseType: string; + } } diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index bc121c1a2..142d13044 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -319,3 +319,15 @@ export const UpdateRealIPConfig = (req: Website.WebsiteRealIPConfig) => { export const GetRealIPConfig = (id: number) => { return http.get(`/websites/realip/config/${id}`); }; + +export const GetWebsiteResource = (id: number) => { + return http.get(`/websites/resource/${id}`); +}; + +export const GetWebsiteDatabase = () => { + return http.get(`/websites/databases`); +}; + +export const ChangeDatabase = (req: Website.ChangeDatabase) => { + return http.post(`/websites/databases`, req); +}; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 85bdfdda0..1b5cb952d 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2238,6 +2238,11 @@ const message = { 'If unsure, you can enter 0.0.0.0/0 (ipv4) ::/0 (ipv6) [Note: Allowing any source IP is not secure]', http3Helper: 'HTTP/3 is an upgrade to HTTP/2, offering faster connection speeds and better performance, but not all browsers support HTTP/3. Enabling it may cause some browsers to be unable to access the site.', + + database: 'Database', + changeDatabase: 'Change Database', + changeDatabaseHelper1: 'Database association is used for backing up and restoring the website.', + changeDatabaseHelper2: 'Switching to another database will cause previous backups to be unrecoverable.', }, php: { short_open_tag: 'Short tag support', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 83ccae5b6..3e7cdaea6 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -2085,6 +2085,11 @@ const message = { ipFromExample3: '如果不確定,可以填 0.0.0.0/0(ipv4) ::/0(ipv6) [注意:允許任意來源 IP 不安全]', http3Helper: 'HTTP/3 是 HTTP/2 的升級版本,提供更快的連線速度和更好的性能,但並非所有瀏覽器都支援 HTTP/3,啟用後可能會導致部分瀏覽器無法訪問', + + database: '資料庫', + changeDatabase: '切換資料庫', + changeDatabaseHelper1: '資料庫關聯用於備份恢復網站。', + changeDatabaseHelper2: '切換其他資料庫會導致以前的備份無法恢復。', }, php: { short_open_tag: '短標簽支持', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 11f5115a7..98ab6e635 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2083,6 +2083,11 @@ const message = { ipFromExample3: '如果不确定,可以填 0.0.0.0/0(ipv4) ::/0(ipv6) [注意:允许任意来源 IP 不安全]', http3Helper: 'HTTP/3 是 HTTP/2 的升级版本,提供更快的连接速度和更好的性能,但是不是所有浏览器都支持 HTTP/3,开启后可能会导致部分浏览器无法访问', + + database: '数据库', + changeDatabase: '切换数据库', + changeDatabaseHelper1: '数据库关联用于备份恢复网站', + changeDatabaseHelper2: '切换其他数据库会导致以前的备份无法恢复', }, php: { short_open_tag: '短标签支持', diff --git a/frontend/src/views/website/website/config/basic/anti-Leech/index.vue b/frontend/src/views/website/website/config/basic/anti-Leech/index.vue index 6b4708401..9a8ca09de 100644 --- a/frontend/src/views/website/website/config/basic/anti-Leech/index.vue +++ b/frontend/src/views/website/website/config/basic/anti-Leech/index.vue @@ -1,13 +1,13 @@ @@ -65,6 +70,7 @@ import Redirect from './redirect/index.vue'; import LoadBalance from './load-balance/index.vue'; import PHP from './php/index.vue'; import RealIP from './real-ip/index.vue'; +import Resource from './resource/index.vue'; const props = defineProps({ website: { diff --git a/frontend/src/views/website/website/config/basic/limit-conn/index.vue b/frontend/src/views/website/website/config/basic/limit-conn/index.vue index 6d2d411a0..47889d128 100644 --- a/frontend/src/views/website/website/config/basic/limit-conn/index.vue +++ b/frontend/src/views/website/website/config/basic/limit-conn/index.vue @@ -28,11 +28,13 @@ {{ $t('website.rateHelper') }} + + + {{ $t('commons.button.save') }} + {{ $t('commons.button.saveAndEnable') }} + + - - {{ $t('commons.button.save') }} - {{ $t('commons.button.saveAndEnable') }} - diff --git a/frontend/src/views/website/website/config/basic/other/index.vue b/frontend/src/views/website/website/config/basic/other/index.vue index d459f2003..8ef89e72f 100644 --- a/frontend/src/views/website/website/config/basic/other/index.vue +++ b/frontend/src/views/website/website/config/basic/other/index.vue @@ -1,7 +1,7 @@