diff --git a/backend/app/api/v1/website.go b/backend/app/api/v1/website.go index 508817d68..6bee070aa 100644 --- a/backend/app/api/v1/website.go +++ b/backend/app/api/v1/website.go @@ -604,3 +604,25 @@ func (b *BaseApi) UpdateRewriteConfig(c *gin.Context) { } helper.SuccessWithData(c, nil) } + +// @Tags Website +// @Summary Update Site Dir +// @Description 更新网站目录 +// @Accept json +// @Param request body request.WebsiteUpdateDir true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /websites/dir/update [post] +// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] 目录","formatEN":"Update domain [domain] dir"} +func (b *BaseApi) UpdateSiteDir(c *gin.Context) { + var req request.WebsiteUpdateDir + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := websiteService.UpdateSiteDir(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithOutData(c) +} diff --git a/backend/app/dto/request/website.go b/backend/app/dto/request/website.go index 9973852a2..35445acbf 100644 --- a/backend/app/dto/request/website.go +++ b/backend/app/dto/request/website.go @@ -145,3 +145,8 @@ type WebsitePHPFileUpdate struct { Type string `json:"type" validate:"required"` Content string `json:"content" validate:"required"` } + +type WebsiteUpdateDir struct { + ID uint `json:"id" validate:"required"` + SiteDir string `json:"siteDir" validate:"required"` +} diff --git a/backend/app/model/website.go b/backend/app/model/website.go index bcb7ad14e..834b36ffe 100644 --- a/backend/app/model/website.go +++ b/backend/app/model/website.go @@ -4,26 +4,30 @@ import "time" type Website struct { BaseModel - Protocol string `gorm:"type:varchar(64);not null" json:"protocol"` - PrimaryDomain string `gorm:"type:varchar(128);not null" json:"primaryDomain"` - Type string `gorm:"type:varchar(64);not null" json:"type"` - Alias string `gorm:"type:varchar(128);not null" json:"alias"` - Remark string `gorm:"type:longtext;" json:"remark"` - Status string `gorm:"type:varchar(64);not null" json:"status"` - HttpConfig string `gorm:"type:varchar(64);not null" json:"httpConfig"` - ExpireDate time.Time `json:"expireDate"` - AppInstallID uint `gorm:"type:integer" json:"appInstallId"` - WebsiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"` - WebsiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"` - Proxy string `gorm:"type:varchar(128);not null" json:"proxy"` - ProxyType string `gorm:"type:varchar;" json:"proxyType"` - ErrorLog bool `json:"errorLog"` - AccessLog bool `json:"accessLog"` - DefaultServer bool `json:"defaultServer"` - Rewrite string `gorm:"type:varchar" json:"rewrite"` - RuntimeID uint `gorm:"type:integer" json:"runtimeID"` - Domains []WebsiteDomain `json:"domains" gorm:"-:migration"` - WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"` + Protocol string `gorm:"type:varchar;not null" json:"protocol"` + PrimaryDomain string `gorm:"type:varchar;not null" json:"primaryDomain"` + Type string `gorm:"type:varchar;not null" json:"type"` + Alias string `gorm:"type:varchar;not null" json:"alias"` + Remark string `gorm:"type:longtext;" json:"remark"` + Status string `gorm:"type:varchar;not null" json:"status"` + HttpConfig string `gorm:"type:varchar;not null" json:"httpConfig"` + ExpireDate time.Time `json:"expireDate"` + + Proxy string `gorm:"type:varchar;" json:"proxy"` + ProxyType string `gorm:"type:varchar;" json:"proxyType"` + SiteDir string `gorm:"type:varchar;" json:"siteDir"` + ErrorLog bool `json:"errorLog"` + AccessLog bool `json:"accessLog"` + DefaultServer bool `json:"defaultServer"` + Rewrite string `gorm:"type:varchar" json:"rewrite"` + + WebsiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"` + WebsiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"` + RuntimeID uint `gorm:"type:integer" json:"runtimeID"` + AppInstallID uint `gorm:"type:integer" json:"appInstallId"` + + Domains []WebsiteDomain `json:"domains" gorm:"-:migration"` + WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"` } func (w Website) TableName() string { diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 60db8357d..f19e046c2 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -61,6 +61,7 @@ type IWebsiteService interface { UpdatePHPConfigFile(req request.WebsitePHPFileUpdate) error GetRewriteConfig(req request.NginxRewriteReq) (*response.NginxRewriteRes, error) UpdateRewriteConfig(req request.NginxRewriteUpdate) error + UpdateSiteDir(req request.WebsiteUpdateDir) error } func NewIWebsiteService() IWebsiteService { @@ -147,6 +148,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error) WebsiteGroupID: create.WebsiteGroupID, Protocol: constant.ProtocolHTTP, Proxy: create.Proxy, + SiteDir: "/", AccessLog: true, ErrorLog: true, } @@ -1056,3 +1058,20 @@ func (w WebsiteService) GetRewriteConfig(req request.NginxRewriteReq) (*response Content: string(contentByte), }, err } + +func (w WebsiteService) UpdateSiteDir(req request.WebsiteUpdateDir) error { + website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.ID)) + if err != nil { + return err + } + runDir := req.SiteDir + siteDir := path.Join("/www/sites", website.Alias, "index") + if req.SiteDir != "/" { + siteDir = fmt.Sprintf("%s/%s", siteDir, req.SiteDir) + } + if err := updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "root", Params: []string{siteDir}}}, &website); err != nil { + return err + } + website.SiteDir = runDir + return websiteRepo.Save(context.Background(), &website) +} diff --git a/backend/app/service/website_utils.go b/backend/app/service/website_utils.go index 0fe47b38c..e581b4139 100644 --- a/backend/app/service/website_utils.go +++ b/backend/app/service/website_utils.go @@ -73,7 +73,7 @@ func createIndexFile(website *model.Website, runtime *model.Runtime) error { return err } } - if runtime.Resource == constant.ResourceAppstore { + if website.Type == constant.Runtime && runtime.Resource == constant.ResourceAppstore { if err := chownRootDir(indexFolder); err != nil { return err } diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go index 4eeb664f2..e24376f9a 100644 --- a/backend/init/migration/migrations/init.go +++ b/backend/init/migration/migrations/init.go @@ -276,8 +276,14 @@ var UpdateTableHost = &gormigrate.Migration{ } var UpdateTableWebsite = &gormigrate.Migration{ - ID: "20230414-update-table-website", + ID: "20230417-update-table-website", Migrate: func(tx *gorm.DB) error { - return tx.AutoMigrate(&model.Website{}) + if err := tx.AutoMigrate(&model.Website{}); err != nil { + return err + } + if err := tx.Model(&model.Website{}).Where("1 = 1").Update("site_dir", "/").Error; err != nil { + return err + } + return nil }, } diff --git a/backend/router/ro_website.go b/backend/router/ro_website.go index 96a6c609f..38a217575 100644 --- a/backend/router/ro_website.go +++ b/backend/router/ro_website.go @@ -48,5 +48,7 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) { groupRouter.POST("/rewrite", baseApi.GetRewriteConfig) groupRouter.POST("/rewrite/update", baseApi.UpdateRewriteConfig) + + groupRouter.POST("/dir/update", baseApi.UpdateSiteDir) } } diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index 656872a20..e943bb767 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -8083,6 +8083,57 @@ var doc = `{ } } }, + "/websites/dir/update": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新网站目录", + "consumes": [ + "application/json" + ], + "tags": [ + "Website" + ], + "summary": "Update Site Dir", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.WebsiteUpdateDir" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFuntions": [ + { + "db": "websites", + "input_colume": "id", + "input_value": "id", + "isList": false, + "output_colume": "primary_domain", + "output_value": "domain" + } + ], + "bodyKeys": [ + "id" + ], + "formatEN": "Update domain [domain] dir", + "formatZH": "更新网站 [domain] 目录", + "paramKeys": [] + } + } + }, "/websites/dns": { "post": { "security": [ @@ -11918,6 +11969,9 @@ var doc = `{ "runtimeID": { "type": "integer" }, + "siteDir": { + "type": "string" + }, "status": { "type": "string" }, @@ -13117,6 +13171,21 @@ var doc = `{ } } }, + "request.WebsiteUpdateDir": { + "type": "object", + "required": [ + "id", + "siteDir" + ], + "properties": { + "id": { + "type": "integer" + }, + "siteDir": { + "type": "string" + } + } + }, "request.WebsiteWafReq": { "type": "object", "required": [ @@ -13533,6 +13602,9 @@ var doc = `{ "runtimeName": { "type": "string" }, + "siteDir": { + "type": "string" + }, "sitePath": { "type": "string" }, diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index c84c03611..e30d0ebfe 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -8069,6 +8069,57 @@ } } }, + "/websites/dir/update": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "更新网站目录", + "consumes": [ + "application/json" + ], + "tags": [ + "Website" + ], + "summary": "Update Site Dir", + "parameters": [ + { + "description": "request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.WebsiteUpdateDir" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-panel-log": { + "BeforeFuntions": [ + { + "db": "websites", + "input_colume": "id", + "input_value": "id", + "isList": false, + "output_colume": "primary_domain", + "output_value": "domain" + } + ], + "bodyKeys": [ + "id" + ], + "formatEN": "Update domain [domain] dir", + "formatZH": "更新网站 [domain] 目录", + "paramKeys": [] + } + } + }, "/websites/dns": { "post": { "security": [ @@ -11904,6 +11955,9 @@ "runtimeID": { "type": "integer" }, + "siteDir": { + "type": "string" + }, "status": { "type": "string" }, @@ -13103,6 +13157,21 @@ } } }, + "request.WebsiteUpdateDir": { + "type": "object", + "required": [ + "id", + "siteDir" + ], + "properties": { + "id": { + "type": "integer" + }, + "siteDir": { + "type": "string" + } + } + }, "request.WebsiteWafReq": { "type": "object", "required": [ @@ -13519,6 +13588,9 @@ "runtimeName": { "type": "string" }, + "siteDir": { + "type": "string" + }, "sitePath": { "type": "string" }, diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index b1af7abc2..2fe04f709 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -1746,6 +1746,8 @@ definitions: type: string runtimeID: type: integer + siteDir: + type: string status: type: string type: @@ -2548,6 +2550,16 @@ definitions: - primaryDomain - webSiteGroupID type: object + request.WebsiteUpdateDir: + properties: + id: + type: integer + siteDir: + type: string + required: + - id + - siteDir + type: object request.WebsiteWafReq: properties: key: @@ -2824,6 +2836,8 @@ definitions: type: integer runtimeName: type: string + siteDir: + type: string sitePath: type: string status: @@ -8009,6 +8023,39 @@ paths: formatEN: Delete website [domain] formatZH: 删除网站 [domain] paramKeys: [] + /websites/dir/update: + post: + consumes: + - application/json + description: 更新网站目录 + parameters: + - description: request + in: body + name: request + required: true + schema: + $ref: '#/definitions/request.WebsiteUpdateDir' + responses: + "200": + description: OK + security: + - ApiKeyAuth: [] + summary: Update Site Dir + tags: + - Website + x-panel-log: + BeforeFuntions: + - db: websites + input_colume: id + input_value: id + isList: false + output_colume: primary_domain + output_value: domain + bodyKeys: + - id + formatEN: Update domain [domain] dir + formatZH: 更新网站 [domain] 目录 + paramKeys: [] /websites/dns: post: consumes: diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 0aec32164..5bc0f6f77 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -294,4 +294,9 @@ export namespace Website { name: string; content: string; } + + export interface DirUpdate { + id: number; + siteDir: string; + } } diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index e3c691a26..6bd09d60b 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -178,3 +178,7 @@ export const GetRewriteConfig = (req: Website.RewriteReq) => { export const UpdateRewriteConfig = (req: Website.RewriteUpdate) => { return http.post(`/websites/rewrite/update`, req); }; + +export const UpdateWebsiteDir = (req: Website.DirUpdate) => { + return http.post(`/websites/dir/update`, req); +}; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index ab87c69d2..d57607749 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -1171,6 +1171,9 @@ const message = { current: 'Current', rewriteHelper: 'If the website cannot be accessed normally after setting pseudo-static, please try to set it back to default', + runDir: 'Run Directory', + runDirHelper: + 'Some programs need to specify a secondary directory as the running directory, such as ThinkPHP5, Laravel', }, php: { short_open_tag: 'Short tag support', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 0ff150d8f..65aa7488a 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1163,6 +1163,8 @@ const message = { rewriteMode: '方案', current: '当前', rewriteHelper: '若设置伪静态后,网站无法正常访问,请尝试设置回default', + runDir: '运行目录', + runDirHelper: '部分程序需要指定二级目录作为运行目录,如ThinkPHP5,Laravel', }, php: { short_open_tag: '短标签支持', diff --git a/frontend/src/views/website/website/config/basic/site-folder/index.vue b/frontend/src/views/website/website/config/basic/site-folder/index.vue index 7d9085772..3ae3321e5 100644 --- a/frontend/src/views/website/website/config/basic/site-folder/index.vue +++ b/frontend/src/views/website/website/config/basic/site-folder/index.vue @@ -1,30 +1,62 @@