diff --git a/build/configs/.gitignore b/build/configs/.gitignore index 67c5fd83..fb0ef7fb 100644 --- a/build/configs/.gitignore +++ b/build/configs/.gitignore @@ -1,3 +1,3 @@ server.yaml -db.yaml +api_db.yaml api.yaml \ No newline at end of file diff --git a/build/configs/api_db.template.yaml b/build/configs/api_db.template.yaml new file mode 100644 index 00000000..7696ed29 --- /dev/null +++ b/build/configs/api_db.template.yaml @@ -0,0 +1,11 @@ +default: + db: "prod" + prefix: "" + +dbs: + prod: + driver: "mysql" + dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge?charset=utf8mb4&timeout=30s" + prefix: "edge" + models: + package: internal/web/models diff --git a/internal/web/actions/default/api/init.go b/internal/web/actions/default/api/init.go index ec7fa9fc..005c1067 100644 --- a/internal/web/actions/default/api/init.go +++ b/internal/web/actions/default/api/init.go @@ -12,7 +12,7 @@ func init() { server. Helper(helpers.NewUserMustAuth()). Helper(NewHelper()). - Helper(settingutils.NewHelper("api")). + Helper(settingutils.NewHelper("apiNodes")). Prefix("/api"). Get("", new(IndexAction)). GetPost("/node/createPopup", new(node.CreatePopupAction)). diff --git a/internal/web/actions/default/api/node/helper.go b/internal/web/actions/default/api/node/helper.go index badb413b..689a22cc 100644 --- a/internal/web/actions/default/api/node/helper.go +++ b/internal/web/actions/default/api/node/helper.go @@ -1,13 +1,8 @@ package node import ( - "github.com/TeaOSLab/EdgeAdmin/internal/rpc" - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" - "github.com/iwind/TeaGo/logs" - "github.com/iwind/TeaGo/maps" "net/http" - "strconv" ) type Helper struct { @@ -22,43 +17,5 @@ func (this *Helper) BeforeAction(action *actions.ActionObject) (goNext bool) { return true } - action.Data["teaMenu"] = "api" - - nodeId := action.ParamInt64("nodeId") - nodeIdString := strconv.FormatInt(nodeId, 10) - - // 节点信息 - rpcClient, err := rpc.SharedRPC() - if err != nil { - logs.Error(err) - return - } - nodeResp, err := rpcClient.APINodeRPC().FindEnabledAPINode(rpcClient.Context(action.Context.GetInt64("adminId")), &pb.FindEnabledAPINodeRequest{NodeId: nodeId}) - if err != nil { - action.WriteString(err.Error()) - return - } - if nodeResp.Node == nil { - action.WriteString("node not found") - return - } - - // 左侧菜单栏 - secondMenuItem := action.Data.GetString("secondMenuItem") - switch action.Data.GetString("firstMenuItem") { - case "setting": - action.Data["leftMenuItems"] = this.createSettingMenu(nodeIdString, secondMenuItem) - } - return true } - -// 设置相关菜单 -func (this *Helper) createSettingMenu(nodeIdString string, selectedItem string) (items []maps.Map) { - items = append(items, maps.Map{ - "name": "基础设置", - "url": "/api/node/settings?nodeId=" + nodeIdString, - "isActive": selectedItem == "basic", - }) - return -} diff --git a/internal/web/actions/default/api/node/index.go b/internal/web/actions/default/api/node/index.go new file mode 100644 index 00000000..379b60bb --- /dev/null +++ b/internal/web/actions/default/api/node/index.go @@ -0,0 +1,102 @@ +package node + +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/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "github.com/iwind/TeaGo/maps" +) + +type IndexAction struct { + actionutils.ParentAction +} + +func (this *IndexAction) Init() { + this.Nav("", "", "index") +} + +func (this *IndexAction) RunGet(params struct { + NodeId int64 +}) { + nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId}) + if err != nil { + this.ErrorPage(err) + return + } + node := nodeResp.Node + if node == nil { + this.NotFound("apiNode", params.NodeId) + return + } + + // 监听地址 + httpConfig := &serverconfigs.HTTPProtocolConfig{} + if len(node.HttpJSON) > 0 { + err = json.Unmarshal(node.HttpJSON, httpConfig) + if err != nil { + this.ErrorPage(err) + return + } + } + httpsConfig := &serverconfigs.HTTPSProtocolConfig{} + if len(node.HttpsJSON) > 0 { + err = json.Unmarshal(node.HttpsJSON, httpsConfig) + if err != nil { + this.ErrorPage(err) + return + } + } + + // 监听地址 + listens := []*serverconfigs.NetworkAddressConfig{} + listens = append(listens, httpConfig.Listen...) + listens = append(listens, httpsConfig.Listen...) + + // 证书信息 + certs := []*sslconfigs.SSLCertConfig{} + sslPolicyId := int64(0) + if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 { + sslPolicyConfigResp, err := this.RPC().SSLPolicyRPC().FindEnabledSSLPolicyConfig(this.AdminContext(), &pb.FindEnabledSSLPolicyConfigRequest{SslPolicyId: httpsConfig.SSLPolicyRef.SSLPolicyId}) + if err != nil { + this.ErrorPage(err) + return + } + sslPolicyConfigJSON := sslPolicyConfigResp.SslPolicyJSON + if len(sslPolicyConfigJSON) > 0 { + sslPolicyId = httpsConfig.SSLPolicyRef.SSLPolicyId + + sslPolicy := &sslconfigs.SSLPolicy{} + err = json.Unmarshal(sslPolicyConfigJSON, sslPolicy) + if err != nil { + this.ErrorPage(err) + return + } + certs = sslPolicy.Certs + } + } + + // 访问地址 + accessAddrs := []*serverconfigs.NetworkAddressConfig{} + if len(node.AccessAddrsJSON) > 0 { + err = json.Unmarshal(node.AccessAddrsJSON, &accessAddrs) + if err != nil { + this.ErrorPage(err) + return + } + } + + this.Data["node"] = maps.Map{ + "id": node.Id, + "name": node.Name, + "description": node.Description, + "isOn": node.IsOn, + "listens": listens, + "accessAddrs": accessAddrs, + "hasHTTPS": sslPolicyId > 0, + "certs": certs, + } + + this.Show() +} diff --git a/internal/web/actions/default/api/node/init.go b/internal/web/actions/default/api/node/init.go index b7bdeba7..413a526f 100644 --- a/internal/web/actions/default/api/node/init.go +++ b/internal/web/actions/default/api/node/init.go @@ -10,7 +10,7 @@ func init() { TeaGo.BeforeStart(func(server *TeaGo.Server) { server. Helper(helpers.NewUserMustAuth()). - Helper(settingutils.NewHelper("api")). + Helper(settingutils.NewHelper("apiNodes")). Prefix("/api/node"). // 这里不受Helper的约束 @@ -19,8 +19,9 @@ func init() { // 节点相关 Helper(NewHelper()). - GetPost("/settings", new(SettingsAction)). - + Get("", new(IndexAction)). + GetPost("/update", new(UpdateAction)). + Get("/install", new(InstallAction)). EndAll() }) diff --git a/internal/web/actions/default/api/node/install.go b/internal/web/actions/default/api/node/install.go new file mode 100644 index 00000000..93625293 --- /dev/null +++ b/internal/web/actions/default/api/node/install.go @@ -0,0 +1,58 @@ +package node + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/maps" + "io/ioutil" + "os" +) + +type InstallAction struct { + actionutils.ParentAction +} + +func (this *InstallAction) Init() { + this.Nav("", "", "install") +} + +func (this *InstallAction) RunGet(params struct { + NodeId int64 +}) { + // API节点信息 + nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId}) + if err != nil { + this.ErrorPage(err) + return + } + node := nodeResp.Node + if node == nil { + this.NotFound("apiNode", params.NodeId) + return + } + + this.Data["node"] = maps.Map{ + "id": node.Id, + "name": node.Name, + "uniqueId": node.UniqueId, + "secret": node.Secret, + } + + // 数据库配置 + dbConfigMap := maps.Map{ + "config": "", + "error": "", + "isNotFound": false, + } + dbConfigFile := Tea.ConfigFile("api_db.yaml") + data, err := ioutil.ReadFile(dbConfigFile) + dbConfigMap["config"] = string(data) + if err != nil { + dbConfigMap["error"] = err.Error() + dbConfigMap["isNotFound"] = os.IsNotExist(err) + } + this.Data["dbConfig"] = dbConfigMap + + this.Show() +} diff --git a/internal/web/actions/default/api/node/settings.go b/internal/web/actions/default/api/node/update.go similarity index 96% rename from internal/web/actions/default/api/node/settings.go rename to internal/web/actions/default/api/node/update.go index 91d4d374..6682b500 100644 --- a/internal/web/actions/default/api/node/settings.go +++ b/internal/web/actions/default/api/node/update.go @@ -10,16 +10,15 @@ import ( "github.com/iwind/TeaGo/maps" ) -type SettingsAction struct { +type UpdateAction struct { actionutils.ParentAction } -func (this *SettingsAction) Init() { - this.Nav("", "setting", "setting") - this.SecondMenu("basic") +func (this *UpdateAction) Init() { + this.Nav("", "", "update") } -func (this *SettingsAction) RunGet(params struct { +func (this *UpdateAction) RunGet(params struct { NodeId int64 }) { nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ @@ -104,7 +103,7 @@ func (this *SettingsAction) RunGet(params struct { } // 保存基础设置 -func (this *SettingsAction) RunPost(params struct { +func (this *UpdateAction) RunPost(params struct { NodeId int64 Name string SslPolicyId int64 diff --git a/internal/web/actions/default/db/init.go b/internal/web/actions/default/db/init.go index c93c4e7f..0b4c439a 100644 --- a/internal/web/actions/default/db/init.go +++ b/internal/web/actions/default/db/init.go @@ -11,7 +11,7 @@ func init() { server. Helper(new(helpers.UserMustAuth)). Helper(new(Helper)). - Helper(settingutils.NewHelper("db")). + Helper(settingutils.NewHelper("dbNodes")). Prefix("/db"). Get("", new(IndexAction)). GetPost("/createPopup", new(CreatePopupAction)). diff --git a/internal/web/actions/default/settings/database/index.go b/internal/web/actions/default/settings/database/index.go new file mode 100644 index 00000000..0c8d28d4 --- /dev/null +++ b/internal/web/actions/default/settings/database/index.go @@ -0,0 +1,15 @@ +package profile + +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + +type IndexAction struct { + actionutils.ParentAction +} + +func (this *IndexAction) Init() { + this.Nav("", "", "") +} + +func (this *IndexAction) RunGet(params struct{}) { + this.Show() +} diff --git a/internal/web/actions/default/settings/database/init.go b/internal/web/actions/default/settings/database/init.go new file mode 100644 index 00000000..7a4a9887 --- /dev/null +++ b/internal/web/actions/default/settings/database/init.go @@ -0,0 +1,18 @@ +package profile + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/helpers" + "github.com/iwind/TeaGo" +) + +func init() { + TeaGo.BeforeStart(func(server *TeaGo.Server) { + server. + Helper(helpers.NewUserMustAuth()). + Helper(settingutils.NewHelper("database")). + Prefix("/settings/database"). + Get("", new(IndexAction)). + EndAll() + }) +} diff --git a/internal/web/actions/default/settings/settingutils/utils.go b/internal/web/actions/default/settings/settingutils/utils.go index f852a98f..d04337e0 100644 --- a/internal/web/actions/default/settings/settingutils/utils.go +++ b/internal/web/actions/default/settings/settingutils/utils.go @@ -27,12 +27,13 @@ func (this *Helper) BeforeAction(actionPtr actions.ActionWrapper) (goNext bool) tabbar := actionutils.NewTabbar() tabbar.Add("管理界面", "", "/settings", "", this.tab == "console") tabbar.Add("安全设置", "", "/settings/security", "", this.tab == "security") - tabbar.Add("API节点", "", "/api", "exchange", this.tab == "api") - tabbar.Add("日志数据库节点", "", "/db", "database", this.tab == "db") + tabbar.Add("数据库", "", "/settings/database", "", this.tab == "database") + tabbar.Add("API节点", "", "/api", "", this.tab == "apiNodes") + tabbar.Add("日志数据库", "", "/db", "", this.tab == "dbNodes") tabbar.Add("备份", "", "/settings/backup", "", this.tab == "backup") tabbar.Add("个人资料", "", "/settings/profile", "", this.tab == "profile") tabbar.Add("登录设置", "", "/settings/login", "", this.tab == "login") - tabbar.Add("检查版本更新", "", "/settings/upgrade", "", this.tab == "upgrade") + tabbar.Add("检查新版本", "", "/settings/upgrade", "", this.tab == "upgrade") actionutils.SetTabbar(actionPtr, tabbar) return diff --git a/internal/web/actions/default/ui/download.go b/internal/web/actions/default/ui/download.go new file mode 100644 index 00000000..fe7d99e1 --- /dev/null +++ b/internal/web/actions/default/ui/download.go @@ -0,0 +1,23 @@ +package ui + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" +) + +// 下载指定的文本内容 +type DownloadAction struct { + actionutils.ParentAction +} + +func (this *DownloadAction) Init() { + this.Nav("", "", "") +} + +func (this *DownloadAction) RunGet(params struct { + File string + Text string +}) { + this.AddHeader("Content-Disposition", "attachment; filename=\""+params.File+"\";") + this.WriteString(params.Text) + +} diff --git a/internal/web/actions/default/ui/init.go b/internal/web/actions/default/ui/init.go index b6b5fb6e..8b5b0bfa 100644 --- a/internal/web/actions/default/ui/init.go +++ b/internal/web/actions/default/ui/init.go @@ -8,8 +8,11 @@ import ( func init() { TeaGo.BeforeStart(func(server *TeaGo.Server) { server. - Helper(new(actions.Gzip)). Prefix("/ui"). + Get("/download", new(DownloadAction)). + + // 以下的需要压缩 + Helper(new(actions.Gzip)). Get("/components.js", new(ComponentsAction)). EndAll() }) diff --git a/internal/web/import.go b/internal/web/import.go index ce923e5e..044ad8b1 100644 --- a/internal/web/import.go +++ b/internal/web/import.go @@ -66,6 +66,7 @@ import ( _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/backup" + _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/database" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/login" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/profile" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/security" diff --git a/web/public/js/components/common/download-link.js b/web/public/js/components/common/download-link.js new file mode 100644 index 00000000..cc79df0e --- /dev/null +++ b/web/public/js/components/common/download-link.js @@ -0,0 +1,37 @@ +Vue.component("download-link", { + props: ["v-element", "v-file"], + created: function () { + let that = this + setTimeout(function () { + that.url = that.composeURL() + }, 1000) + }, + data: function () { + let filename = this.vFile + if (filename == null || filename.length == 0) { + filename = "unknown-file" + } + return { + file: filename, + url: this.composeURL() + } + }, + methods: { + composeURL: function () { + let e = document.getElementById(this.vElement) + if (e == null) { + teaweb.warn("找不到要下载的内容") + return + } + let text = e.innerText + if (text == null) { + text = e.textContent + } + return Tea.url("/ui/download", { + file: this.file, + text: text + }) + } + }, + template: ``, +}) \ No newline at end of file diff --git a/web/public/js/components/common/labels.js b/web/public/js/components/common/labels.js index c4bf19bf..57b4a8cc 100644 --- a/web/public/js/components/common/labels.js +++ b/web/public/js/components/common/labels.js @@ -1,4 +1,10 @@ +// 启用状态标签 Vue.component("label-on", { props: ["v-is-on"], template: '
已启用已停用
' +}) + +// 文字代码标签 +Vue.component("code-label", { + template: `` }) \ No newline at end of file diff --git a/web/public/js/components/common/network-addresses-box.js b/web/public/js/components/common/network-addresses-box.js index 38570ca7..8109954d 100644 --- a/web/public/js/components/common/network-addresses-box.js +++ b/web/public/js/components/common/network-addresses-box.js @@ -29,7 +29,9 @@ Vue.component("network-addresses-box", { methods: { addAddr: function () { let that = this + window.UPDATING_ADDR = null teaweb.popup("/servers/addPortPopup?serverType=" + this.vServerType + "&protocol=" + this.protocol, { + height: "16em", callback: function (resp) { var addr = resp.data.address that.addresses.push(addr) @@ -47,6 +49,29 @@ Vue.component("network-addresses-box", { removeAddr: function (index) { this.addresses.$remove(index); + // 发送事件 + this.$emit("change", this.addresses) + }, + updateAddr: function (index, addr) { + let that = this + window.UPDATING_ADDR = addr + teaweb.popup("/servers/addPortPopup?serverType=" + this.vServerType + "&protocol=" + this.protocol, { + height: "16em", + callback: function (resp) { + var addr = resp.data.address + Vue.set(that.addresses, index, addr) + + if (["https", "https4", "https6"].$contains(addr.protocol)) { + this.tlsProtocolName = "HTTPS" + } else if (["tls", "tls4", "tls6"].$contains(addr.protocol)) { + this.tlsProtocolName = "TLS" + } + + // 发送事件 + that.$emit("change", that.addresses) + } + }) + // 发送事件 this.$emit("change", this.addresses) } @@ -56,6 +81,7 @@ Vue.component("network-addresses-box", {
{{addr.protocol}}://{{addr.host}}*:{{addr.portRange}} +
diff --git a/web/public/js/components/common/network-addresses-view.js b/web/public/js/components/common/network-addresses-view.js new file mode 100644 index 00000000..81b76ebf --- /dev/null +++ b/web/public/js/components/common/network-addresses-view.js @@ -0,0 +1,8 @@ +Vue.component("network-addresses-view", { + props: ["v-addresses"], + template: `
+
+ {{addr.protocol}}://{{addr.host}}:{{addr.portRange}} +
+
` +}) \ No newline at end of file diff --git a/web/public/js/components/server/ssl-certs-view.js b/web/public/js/components/server/ssl-certs-view.js new file mode 100644 index 00000000..fc6f4181 --- /dev/null +++ b/web/public/js/components/server/ssl-certs-view.js @@ -0,0 +1,33 @@ +Vue.component("ssl-certs-view", { + props: ["v-certs"], + data: function () { + let certs = this.vCerts + if (certs == null) { + certs = [] + } + return { + certs: certs + } + }, + methods: { + // 格式化时间 + formatTime: function (timestamp) { + return new Date(timestamp * 1000).format("Y-m-d") + }, + + // 查看详情 + viewCert: function (certId) { + teaweb.popup("/servers/components/ssl/certPopup?certId=" + certId, { + height: "28em", + width: "48em" + }) + } + }, + template: `
+
+
+ {{cert.name}} / {{cert.dnsNames}} / 有效至{{formatTime(cert.timeEndAt)}}   +
+
+
` +}) \ No newline at end of file diff --git a/web/views/@default/@layout.css b/web/views/@default/@layout.css index 9634b04f..6c4ebaae 100644 --- a/web/views/@default/@layout.css +++ b/web/views/@default/@layout.css @@ -354,6 +354,8 @@ body.expanded .main { .main .tab-menu { margin-top: 1em !important; margin-bottom: 0 !important; + overflow-x: auto; + overflow-y: hidden; } .main .tab-menu .item { padding: 1em !important; @@ -365,14 +367,11 @@ body.expanded .main { font-size: 0.8em; padding-left: 0.3em; } -@media screen and (max-width: 512px) { - .main .tab-menu { - overflow-x: auto; - overflow-y: hidden; - } - .main .tab-menu::-webkit-scrollbar { - height: 4px; - } +.main .tab-menu .item .icon { + margin-left: 0.6em; +} +.main .tab-menu::-webkit-scrollbar { + height: 4px; } .main .go-top-btn { position: fixed; diff --git a/web/views/@default/@layout.css.map b/web/views/@default/@layout.css.map index 2daf13b0..9197ec34 100644 --- a/web/views/@default/@layout.css.map +++ b/web/views/@default/@layout.css.map @@ -1 +1 @@ -{"version":3,"sources":["@left_menu.less","@layout.less"],"names":[],"mappings":"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","file":"@layout.css"} \ No newline at end of file +{"version":3,"sources":["@left_menu.less","@layout.less"],"names":[],"mappings":"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","file":"@layout.css"} \ No newline at end of file diff --git a/web/views/@default/@layout.html b/web/views/@default/@layout.html index ffa134e1..bb733aa8 100644 --- a/web/views/@default/@layout.html +++ b/web/views/@default/@layout.html @@ -76,7 +76,7 @@ diff --git a/web/views/@default/@layout.less b/web/views/@default/@layout.less index 3e8c1c68..5aaf74d5 100644 --- a/web/views/@default/@layout.less +++ b/web/views/@default/@layout.less @@ -341,35 +341,38 @@ body.expanded .main { width: 2px; } -.main .tab-menu { - margin-top: 1em !important; - margin-bottom: 0 !important; -} +.main { -.main .tab-menu .item { - padding: 1em !important; -} - -.main .tab-menu .item var { - font-style: normal; -} - -.main .tab-menu .item span { - font-size: 0.8em; - padding-left: 0.3em; -} - -@media screen and (max-width: 512px) { - .main .tab-menu { + .tab-menu { + margin-top: 1em !important; + margin-bottom: 0 !important; overflow-x: auto; overflow-y: hidden; + + .item { + padding: 1em !important; + + var { + font-style: normal; + } + + span { + font-size: 0.8em; + padding-left: 0.3em; + } + + .icon { + margin-left: 0.6em; + } + } } - .main .tab-menu::-webkit-scrollbar { + .tab-menu::-webkit-scrollbar { height: 4px; } } + .main .go-top-btn { position: fixed; right: 2.6em; diff --git a/web/views/@default/api/index.html b/web/views/@default/api/index.html index f14d049a..214c10ec 100644 --- a/web/views/@default/api/index.html +++ b/web/views/@default/api/index.html @@ -26,7 +26,7 @@ - 设置   + 详情   删除 diff --git a/web/views/@default/api/node/@menu.html b/web/views/@default/api/node/@menu.html index a9239cdc..b56ca1e8 100644 --- a/web/views/@default/api/node/@menu.html +++ b/web/views/@default/api/node/@menu.html @@ -1,5 +1,7 @@ - 节点列表 + 节点列表 | - {{node.name}} + "{{node.name}}"详情 + 修改节点 + 安装节点 diff --git a/web/views/@default/api/node/index.html b/web/views/@default/api/node/index.html new file mode 100644 index 00000000..e551af06 --- /dev/null +++ b/web/views/@default/api/node/index.html @@ -0,0 +1,44 @@ +{$layout} +{$template "menu"} + + + + + + + + + + + + + + + + + + + + + + + + + + +
节点名称 + {{node.name}} +
状态 + +
进程监听端口 + +

API节点进程监听的网络端口。

+
HTTPS证书 + +
外部访问地址 + +

外部访问API节点的网络地址。

+
描述 + {{node.description}} + 暂时还没有描述。 +
\ No newline at end of file diff --git a/web/views/@default/api/node/install.html b/web/views/@default/api/node/install.html new file mode 100644 index 00000000..06788747 --- /dev/null +++ b/web/views/@default/api/node/install.html @@ -0,0 +1,33 @@ +{$layout} +{$template "menu"} + +

安装步骤

+
    +
  1. 按照下面的配置信息替换configs/api.yaml内容
  2. +
  3. 按照下面的配置信息替换configs/db.yaml内容
  4. +
  5. 使用bin/edge-api start启动节点
  6. +
  7. 可以在logs/run.log中查看启动是否有异常
  8. +
+ +
+

配置信息

+ + + + + + + + + +
configs/api.yaml
[下载]
+
nodeId: "{{node.uniqueId}}"
+secret: "{{node.secret}}"
+
configs/db.yaml
[下载]
+ + 找不到数据库配置文件:configs/api_db.yaml ,请重新 [配置数据库] + 无法生成配置内容,错误原因: + {{dbConfig.error}} + +
{{dbConfig.config}}
+
diff --git a/web/views/@default/api/node/settings.html b/web/views/@default/api/node/settings.html deleted file mode 100644 index 1ef5b019..00000000 --- a/web/views/@default/api/node/settings.html +++ /dev/null @@ -1,61 +0,0 @@ -{$layout} -{$template "/left_menu"} - -
- {$template "menu"} - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
节点名称 * - -
进程监听端口 * - -

API节点进程监听的网络端口。

-
HTTPS证书 * - -
外部访问地址 * - -

外部访问API节点的网络地址。

-
描述 - -
是否启用 -
- - -
-
- -
-
\ No newline at end of file diff --git a/web/views/@default/api/node/update.html b/web/views/@default/api/node/update.html new file mode 100644 index 00000000..dfdfd302 --- /dev/null +++ b/web/views/@default/api/node/update.html @@ -0,0 +1,58 @@ +{$layout} + +{$template "menu"} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
节点名称 * + +
进程监听端口 * + +

API节点进程监听的网络端口。

+
HTTPS证书 * + +
外部访问地址 * + +

外部访问API节点的网络地址。

+
描述 + +
是否启用 +
+ + +
+
+ +
\ No newline at end of file diff --git a/web/views/@default/api/node/settings.js b/web/views/@default/api/node/update.js similarity index 73% rename from web/views/@default/api/node/settings.js rename to web/views/@default/api/node/update.js index 5c7da176..58842b48 100644 --- a/web/views/@default/api/node/settings.js +++ b/web/views/@default/api/node/update.js @@ -1,5 +1,5 @@ Tea.context(function () { - this.success = NotifySuccess("保存成功", "/api/node/settings?nodeId=" + this.node.id) + this.success = NotifySuccess("保存成功", "/api/node?nodeId=" + this.node.id) this.hasHTTPS = this.node.listens.$any(function (k, v) { return v.protocol == "https" diff --git a/web/views/@default/servers/addPortPopup.html b/web/views/@default/servers/addPortPopup.html index 25716b94..3324e1d4 100644 --- a/web/views/@default/servers/addPortPopup.html +++ b/web/views/@default/servers/addPortPopup.html @@ -1,6 +1,7 @@ {$layout "layout_popup"} -

添加端口绑定

+

添加端口绑定

+

修改端口绑定

@@ -14,7 +15,7 @@ diff --git a/web/views/@default/servers/addPortPopup.js b/web/views/@default/servers/addPortPopup.js index b0f74795..d01a6736 100644 --- a/web/views/@default/servers/addPortPopup.js +++ b/web/views/@default/servers/addPortPopup.js @@ -1,3 +1,19 @@ Tea.context(function () { this.success = NotifyPopup; + + this.isUpdating = false + + this.address = "" + this.protocol = this.protocols[0].code + + if (window.parent.UPDATING_ADDR != null) { + this.isUpdating = true + let addr = window.parent.UPDATING_ADDR + this.protocol = addr.protocol + if (addr.host.length == 0) { + this.address = addr.portRange + } else { + this.address = addr.host + ":" + addr.portRange + } + } }); \ No newline at end of file diff --git a/web/views/@default/settings/database/index.html b/web/views/@default/settings/database/index.html new file mode 100644 index 00000000..79a92a06 --- /dev/null +++ b/web/views/@default/settings/database/index.html @@ -0,0 +1,3 @@ +{$layout} + +

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

\ No newline at end of file
端口 - +

可以是一个数字端口(通常不超过65535),也可以是"地址:端口"的方式。