diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index 126bfe8f..88cac56f 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -31,6 +31,7 @@ type RPCClient struct { httpGzipClients []pb.HTTPGzipServiceClient httpHeaderPolicyClients []pb.HTTPHeaderPolicyServiceClient httpHeaderClients []pb.HTTPHeaderServiceClient + httpPageClients []pb.HTTPPageServiceClient } func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { @@ -51,6 +52,7 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { httpGzipClients := []pb.HTTPGzipServiceClient{} httpHeaderPolicyClients := []pb.HTTPHeaderPolicyServiceClient{} httpHeaderClients := []pb.HTTPHeaderServiceClient{} + httpPageClients := []pb.HTTPPageServiceClient{} conns := []*grpc.ClientConn{} for _, endpoint := range apiConfig.RPC.Endpoints { @@ -79,6 +81,7 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { httpGzipClients = append(httpGzipClients, pb.NewHTTPGzipServiceClient(conn)) httpHeaderPolicyClients = append(httpHeaderPolicyClients, pb.NewHTTPHeaderPolicyServiceClient(conn)) httpHeaderClients = append(httpHeaderClients, pb.NewHTTPHeaderServiceClient(conn)) + httpPageClients = append(httpPageClients, pb.NewHTTPPageServiceClient(conn)) } return &RPCClient{ @@ -96,6 +99,7 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { httpGzipClients: httpGzipClients, httpHeaderPolicyClients: httpHeaderPolicyClients, httpHeaderClients: httpHeaderClients, + httpPageClients: httpPageClients, }, nil } @@ -190,6 +194,13 @@ func (this *RPCClient) HTTPHeaderPolicyRPC() pb.HTTPHeaderPolicyServiceClient { return nil } +func (this *RPCClient) HTTPPageRPC() pb.HTTPPageServiceClient { + if len(this.httpPageClients) > 0 { + return this.httpPageClients[rands.Int(0, len(this.httpPageClients)-1)] + } + return nil +} + func (this *RPCClient) Context(adminId int64) context.Context { ctx := context.Background() m := maps.Map{ diff --git a/internal/web/actions/default/servers/server/settings/pages/createPopup.go b/internal/web/actions/default/servers/server/settings/pages/createPopup.go new file mode 100644 index 00000000..4cea35d0 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/pages/createPopup.go @@ -0,0 +1,64 @@ +package pages + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/actions" + "github.com/iwind/TeaGo/types" +) + +type CreatePopupAction struct { + actionutils.ParentAction +} + +func (this *CreatePopupAction) Init() { + this.Nav("", "", "") +} + +func (this *CreatePopupAction) RunGet(params struct{}) { + this.Show() +} + +func (this *CreatePopupAction) RunPost(params struct { + Status string + URL string `alias:"url"` + NewStatus int + Must *actions.Must +}) { + // TODO 对状态码进行更多校验 + + params.Must. + Field("status", params.Status). + Require("请输入响应状态码"). + Field("url", params.URL). + Require("请输入要显示的URL") + + createResp, err := this.RPC().HTTPPageRPC().CreateHTTPPage(this.AdminContext(), &pb.CreateHTTPPageRequest{ + StatusList: []string{params.Status}, + Url: params.URL, + NewStatus: types.Int32(params.NewStatus), + }) + if err != nil { + this.ErrorPage(err) + return + } + pageId := createResp.PageId + + configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{PageId: pageId}) + if err != nil { + this.ErrorPage(err) + return + } + + pageConfig := &serverconfigs.HTTPPageConfig{} + err = json.Unmarshal(configResp.Config, pageConfig) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["page"] = pageConfig + + this.Success() +} diff --git a/internal/web/actions/default/servers/server/settings/pages/index.go b/internal/web/actions/default/servers/server/settings/pages/index.go index 8cbf2939..5d8e44bc 100644 --- a/internal/web/actions/default/servers/server/settings/pages/index.go +++ b/internal/web/actions/default/servers/server/settings/pages/index.go @@ -1,7 +1,11 @@ package pages import ( + "encoding/json" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/actions" ) type IndexAction struct { @@ -16,7 +20,50 @@ func (this *IndexAction) Init() { func (this *IndexAction) RunGet(params struct { ServerId int64 }) { - // TODO + webResp, err := this.RPC().ServerRPC().FindAndInitServerWebConfig(this.AdminContext(), &pb.FindAndInitServerWebRequest{ServerId: params.ServerId}) + if err != nil { + this.ErrorPage(err) + return + } + webConfig := &serverconfigs.HTTPWebConfig{} + err = json.Unmarshal(webResp.Config, webConfig) + if err != nil { + this.ErrorPage(err) + return + } + + this.Data["webId"] = webConfig.Id + this.Data["pages"] = webConfig.Pages + this.Data["shutdownConfig"] = webConfig.Shutdown this.Show() } + +func (this *IndexAction) RunPost(params struct { + WebId int64 + PagesJSON string + ShutdownJSON string + Must *actions.Must +}) { + // TODO 检查配置 + + _, err := this.RPC().HTTPWebRPC().UpdateHTTPWebPages(this.AdminContext(), &pb.UpdateHTTPWebPagesRequest{ + WebId: params.WebId, + PagesJSON: []byte(params.PagesJSON), + }) + if err != nil { + this.ErrorPage(err) + return + } + + _, err = this.RPC().HTTPWebRPC().UpdateHTTPWebShutdown(this.AdminContext(), &pb.UpdateHTTPWebShutdownRequest{ + WebId: params.WebId, + ShutdownJSON: []byte(params.ShutdownJSON), + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/servers/server/settings/pages/init.go b/internal/web/actions/default/servers/server/settings/pages/init.go index fa790f6d..9947900d 100644 --- a/internal/web/actions/default/servers/server/settings/pages/init.go +++ b/internal/web/actions/default/servers/server/settings/pages/init.go @@ -12,7 +12,9 @@ func init() { Helper(helpers.NewUserMustAuth()). Helper(serverutils.NewServerHelper()). Prefix("/servers/server/settings/pages"). - Get("", new(IndexAction)). + GetPost("", new(IndexAction)). + GetPost("/createPopup", new(CreatePopupAction)). + GetPost("/updatePopup", new(UpdatePopupAction)). EndAll() }) } diff --git a/internal/web/actions/default/servers/server/settings/pages/updatePopup.go b/internal/web/actions/default/servers/server/settings/pages/updatePopup.go new file mode 100644 index 00000000..d53581f2 --- /dev/null +++ b/internal/web/actions/default/servers/server/settings/pages/updatePopup.go @@ -0,0 +1,82 @@ +package pages + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/actions" + "github.com/iwind/TeaGo/types" +) + +type UpdatePopupAction struct { + actionutils.ParentAction +} + +func (this *UpdatePopupAction) Init() { + this.Nav("", "", "") +} + +func (this *UpdatePopupAction) RunGet(params struct { + PageId int64 +}) { + configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{PageId: params.PageId}) + if err != nil { + this.ErrorPage(err) + return + } + + pageConfig := &serverconfigs.HTTPPageConfig{} + err = json.Unmarshal(configResp.Config, pageConfig) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["pageConfig"] = pageConfig + + this.Show() +} + +func (this *UpdatePopupAction) RunPost(params struct { + PageId int64 + + Status string + URL string `alias:"url"` + NewStatus int + + Must *actions.Must +}) { + params.Must. + Field("status", params.Status). + Require("请输入响应状态码"). + Field("url", params.URL). + Require("请输入要显示的URL") + + _, err := this.RPC().HTTPPageRPC().UpdateHTTPPage(this.AdminContext(), &pb.UpdateHTTPPageRequest{ + PageId: params.PageId, + StatusList: []string{params.Status}, + Url: params.URL, + NewStatus: types.Int32(params.NewStatus), + }) + if err != nil { + this.ErrorPage(err) + return + } + + // 返回修改后的配置 + configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{PageId: params.PageId}) + if err != nil { + this.ErrorPage(err) + return + } + + pageConfig := &serverconfigs.HTTPPageConfig{} + err = json.Unmarshal(configResp.Config, pageConfig) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["page"] = pageConfig + + this.Success() +} diff --git a/internal/web/actions/default/servers/serverutils/server_helper.go b/internal/web/actions/default/servers/serverutils/server_helper.go index 688ef764..975221be 100644 --- a/internal/web/actions/default/servers/serverutils/server_helper.go +++ b/internal/web/actions/default/servers/serverutils/server_helper.go @@ -40,6 +40,9 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) { secondMenuItem, _ := action.Data["secondMenuItem"] serverId := action.ParamInt64("serverId") + if serverId == 0 { + return + } serverIdString := strconv.FormatInt(serverId, 10) action.Data["serverId"] = serverId diff --git a/web/public/js/components/server/pages-and-shutdown-box.js b/web/public/js/components/server/pages-and-shutdown-box.js new file mode 100644 index 00000000..312be198 --- /dev/null +++ b/web/public/js/components/server/pages-and-shutdown-box.js @@ -0,0 +1,113 @@ +Vue.component("pages-and-shutdown-box", { + props: ["v-pages", "v-shutdown-config"], + data: function () { + let pages = [] + if (this.vPages != null) { + pages = this.vPages + } + let shutdownConfig = { + isOn: false, + url: "", + status: 0 + } + if (this.vShutdownConfig != null) { + shutdownConfig = this.vShutdownConfig + } + + let shutdownStatus = "" + if (shutdownConfig.status > 0) { + shutdownStatus = shutdownConfig.status.toString() + } + + return { + pages: pages, + shutdownConfig: shutdownConfig, + shutdownStatus: shutdownStatus + } + }, + watch: { + shutdownStatus: function (status) { + let statusInt = parseInt(status) + if (!isNaN(statusInt) && statusInt > 0 && statusInt < 1000) { + this.shutdownConfig.status = statusInt + } else { + this.shutdownConfig.status = 0 + } + } + }, + methods: { + addPage: function () { + let that = this + teaweb.popup("/servers/server/settings/pages/createPopup", { + height: "22em", + callback: function (resp) { + that.pages.push(resp.data.page) + } + }) + }, + updatePage: function (pageIndex, pageId) { + let that = this + teaweb.popup("/servers/server/settings/pages/updatePopup?pageId=" + pageId, { + height: "22em", + callback: function (resp) { + Vue.set(that.pages, pageIndex, resp.data.page) + } + }) + }, + removePage: function (pageIndex) { + let that = this + teaweb.confirm("确定要移除此页面吗?", function () { + that.pages.$remove(pageIndex) + }) + } + }, + template: `
+ + + + + + + + + + + +
特殊页面 +
+
+ {{page.status}} -> {{page.url}} +
+
+
+
+ +
+

根据响应状态码返回一些特殊页面,比如404,500等错误页面。

+
临时关闭页面 +
+
+ + +
+
+ + + + + + + + + +
页面URL + +

页面文件是相对于节点安装目录的页面文件比如web/pages/40x.html,或者一个完整的URL。

+
状态码
+
+

开启临时关闭页面时,所有请求的响应都会显示此页面。可用于临时升级网站使用。

+
+
+
+
` +}) \ No newline at end of file diff --git a/web/views/@default/servers/server/settings/pages/createPopup.html b/web/views/@default/servers/server/settings/pages/createPopup.html new file mode 100644 index 00000000..565ea8cb --- /dev/null +++ b/web/views/@default/servers/server/settings/pages/createPopup.html @@ -0,0 +1,28 @@ +{$layout "layout_popup"} +

添加特殊页面

+
+ + + + + + + + + + + + + +
响应状态码 * + +

比如404,或者50x。

+
URL * + +

页面文件是相对于节点安装目录的页面文件比如web/pages/40x.html,或者一个完整的URL。

+
新状态码 + +

可以用来修改响应的状态码,不填表示不改变原有状态码。

+
+ +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/pages/createPopup.js b/web/views/@default/servers/server/settings/pages/createPopup.js new file mode 100644 index 00000000..c8fe9515 --- /dev/null +++ b/web/views/@default/servers/server/settings/pages/createPopup.js @@ -0,0 +1,3 @@ +Tea.context(function () { + this.success = NotifyPopup +}) \ No newline at end of file diff --git a/web/views/@default/servers/server/settings/pages/index.html b/web/views/@default/servers/server/settings/pages/index.html index eae519e9..986ad022 100644 --- a/web/views/@default/servers/server/settings/pages/index.html +++ b/web/views/@default/servers/server/settings/pages/index.html @@ -3,5 +3,9 @@ {$template "/left_menu"}
-

此功能暂未开放,敬请期待。

+
+ + + +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/pages/index.js b/web/views/@default/servers/server/settings/pages/index.js new file mode 100644 index 00000000..295a9aaf --- /dev/null +++ b/web/views/@default/servers/server/settings/pages/index.js @@ -0,0 +1,3 @@ +Tea.context(function () { + this.success = NotifyReloadSuccess("保存成功") +}) \ No newline at end of file diff --git a/web/views/@default/servers/server/settings/pages/updatePopup.html b/web/views/@default/servers/server/settings/pages/updatePopup.html new file mode 100644 index 00000000..89fa18dc --- /dev/null +++ b/web/views/@default/servers/server/settings/pages/updatePopup.html @@ -0,0 +1,29 @@ +{$layout "layout_popup"} +

修改特殊页面

+
+ + + + + + + + + + + + + + +
响应状态码 * + +

比如404,或者50x。

+
URL * + +

页面文件是相对于节点安装目录的页面文件比如web/pages/40x.html,或者一个完整的URL。

+
新状态码 + +

可以用来修改响应的状态码,不填表示不改变原有状态码。

+
+ +
\ No newline at end of file diff --git a/web/views/@default/servers/server/settings/pages/updatePopup.js b/web/views/@default/servers/server/settings/pages/updatePopup.js new file mode 100644 index 00000000..c064bd22 --- /dev/null +++ b/web/views/@default/servers/server/settings/pages/updatePopup.js @@ -0,0 +1,8 @@ +Tea.context(function () { + this.success = NotifyPopup + + this.newStatus = "" + if (this.pageConfig.newStatus > 0) { + this.newStatus = this.pageConfig.newStatus + } +}) \ No newline at end of file