diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index 6bc3cd49..c6818677 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -131,6 +131,10 @@ func (this *RPCClient) ServerHTTPFirewallDailyStatRPC() pb.ServerHTTPFirewallDai return pb.NewServerHTTPFirewallDailyStatServiceClient(this.pickConn()) } +func (this *RPCClient) ServerDailyStatRPC() pb.ServerDailyStatServiceClient { + return pb.NewServerDailyStatServiceClient(this.pickConn()) +} + func (this *RPCClient) ServerGroupRPC() pb.ServerGroupServiceClient { return pb.NewServerGroupServiceClient(this.pickConn()) } diff --git a/internal/web/actions/default/servers/server/stat/index.go b/internal/web/actions/default/servers/server/stat/index.go index 3cc09479..ebcc1c77 100644 --- a/internal/web/actions/default/servers/server/stat/index.go +++ b/internal/web/actions/default/servers/server/stat/index.go @@ -1,12 +1,12 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + package stat import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" - "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/iwind/TeaGo/maps" - timeutil "github.com/iwind/TeaGo/utils/time" + "sort" ) type IndexAction struct { @@ -20,140 +20,34 @@ func (this *IndexAction) Init() { func (this *IndexAction) RunGet(params struct { ServerId int64 - Month string }) { - month := params.Month - if len(month) != 6 { - month = timeutil.Format("Ym") - } - this.Data["month"] = month - - serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId}) - if err != nil { - this.ErrorPage(err) - return - } - serverType := serverTypeResp.Type - - statIsOn := false - - // 是否已开启 - if serverconfigs.IsHTTPServerType(serverType) { - webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId) + { + resp, err := this.RPC().ServerDailyStatRPC().FindServerHourlyStats(this.AdminContext(), &pb.FindServerHourlyStatsRequest{ + ServerId: params.ServerId, + Hours: 24, + }) if err != nil { this.ErrorPage(err) return } - if webConfig != nil && webConfig.StatRef != nil { - statIsOn = webConfig.StatRef.IsOn - } - } else { - this.WriteString("此类型服务暂不支持统计") - return - } - this.Data["statIsOn"] = statIsOn - - // 统计数据 - countryStatMaps := []maps.Map{} - provinceStatMaps := []maps.Map{} - cityStatMaps := []maps.Map{} - - if statIsOn { - // 地区 - { - resp, err := this.RPC().ServerRegionCountryMonthlyStatRPC().FindTopServerRegionCountryMonthlyStats(this.AdminContext(), &pb.FindTopServerRegionCountryMonthlyStatsRequest{ - Month: month, - ServerId: params.ServerId, - Offset: 0, - Size: 10, + sort.Slice(resp.Stats, func(i, j int) bool { + stat1 := resp.Stats[i] + stat2 := resp.Stats[j] + return stat1.Hour < stat2.Hour + }) + statMaps := []maps.Map{} + for _, stat := range resp.Stats { + statMaps = append(statMaps, maps.Map{ + "day": stat.Hour[:4] + "-" + stat.Hour[4:6] + "-" + stat.Hour[6:8], + "hour": stat.Hour[8:], + "bytes": stat.Bytes, + "cachedBytes": stat.CachedBytes, + "countRequests": stat.CountRequests, + "countCachedRequests": stat.CountCachedRequests, }) - if err != nil { - this.ErrorPage(err) - return - } - for _, stat := range resp.Stats { - countryStatMaps = append(countryStatMaps, maps.Map{ - "count": stat.Count, - "country": maps.Map{ - "id": stat.RegionCountry.Id, - "name": stat.RegionCountry.Name, - }, - }) - } } - - // 省份 - { - resp, err := this.RPC().ServerRegionProvinceMonthlyStatRPC().FindTopServerRegionProvinceMonthlyStats(this.AdminContext(), &pb.FindTopServerRegionProvinceMonthlyStatsRequest{ - Month: month, - ServerId: params.ServerId, - Offset: 0, - Size: 10, - }) - if err != nil { - this.ErrorPage(err) - return - } - for _, stat := range resp.Stats { - provinceStatMaps = append(provinceStatMaps, maps.Map{ - "count": stat.Count, - "country": maps.Map{ - "id": stat.RegionCountry.Id, - "name": stat.RegionCountry.Name, - }, - "province": maps.Map{ - "id": stat.RegionProvince.Id, - "name": stat.RegionProvince.Name, - }, - }) - } - } - - // 城市 - { - resp, err := this.RPC().ServerRegionCityMonthlyStatRPC().FindTopServerRegionCityMonthlyStats(this.AdminContext(), &pb.FindTopServerRegionCityMonthlyStatsRequest{ - Month: month, - ServerId: params.ServerId, - Offset: 0, - Size: 10, - }) - if err != nil { - this.ErrorPage(err) - return - } - for _, stat := range resp.Stats { - cityStatMaps = append(cityStatMaps, maps.Map{ - "count": stat.Count, - "country": maps.Map{ - "id": stat.RegionCountry.Id, - "name": stat.RegionCountry.Name, - }, - "province": maps.Map{ - "id": stat.RegionProvince.Id, - "name": stat.RegionProvince.Name, - }, - "city": maps.Map{ - "id": stat.RegionCity.Id, - "name": stat.RegionCity.Name, - }, - }) - } - } - } - - this.Data["countryStats"] = countryStatMaps - this.Data["provinceStats"] = provinceStatMaps - this.Data["cityStats"] = cityStatMaps - - // 记录最近使用 - _, err = this.RPC().LatestItemRPC().IncreaseLatestItem(this.AdminContext(), &pb.IncreaseLatestItemRequest{ - ItemType: "server", - ItemId: params.ServerId, - }) - if err != nil { - this.ErrorPage(err) - return + this.Data["hourlyStats"] = statMaps } this.Show() diff --git a/internal/web/actions/default/servers/server/stat/init.go b/internal/web/actions/default/servers/server/stat/init.go index 4cb64f65..e2c31542 100644 --- a/internal/web/actions/default/servers/server/stat/init.go +++ b/internal/web/actions/default/servers/server/stat/init.go @@ -14,6 +14,7 @@ func init() { Helper(serverutils.NewServerHelper()). Prefix("/servers/server/stat"). Get("", new(IndexAction)). + Get("/regions", new(RegionsAction)). Get("/providers", new(ProvidersAction)). Get("/clients", new(ClientsAction)). Get("/waf", new(WafAction)). diff --git a/internal/web/actions/default/servers/server/stat/regions.go b/internal/web/actions/default/servers/server/stat/regions.go new file mode 100644 index 00000000..c491e614 --- /dev/null +++ b/internal/web/actions/default/servers/server/stat/regions.go @@ -0,0 +1,160 @@ +package stat + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/maps" + timeutil "github.com/iwind/TeaGo/utils/time" +) + +type RegionsAction struct { + actionutils.ParentAction +} + +func (this *RegionsAction) Init() { + this.Nav("", "stat", "") + this.SecondMenu("region") +} + +func (this *RegionsAction) RunGet(params struct { + ServerId int64 + Month string +}) { + month := params.Month + if len(month) != 6 { + month = timeutil.Format("Ym") + } + this.Data["month"] = month + + serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId}) + if err != nil { + this.ErrorPage(err) + return + } + serverType := serverTypeResp.Type + + statIsOn := false + + // 是否已开启 + if serverconfigs.IsHTTPServerType(serverType) { + webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerId(this.AdminContext(), params.ServerId) + if err != nil { + this.ErrorPage(err) + return + } + if webConfig != nil && webConfig.StatRef != nil { + statIsOn = webConfig.StatRef.IsOn + } + } else { + this.WriteString("此类型服务暂不支持统计") + return + } + + this.Data["statIsOn"] = statIsOn + + // 统计数据 + countryStatMaps := []maps.Map{} + provinceStatMaps := []maps.Map{} + cityStatMaps := []maps.Map{} + + if statIsOn { + // 地区 + { + resp, err := this.RPC().ServerRegionCountryMonthlyStatRPC().FindTopServerRegionCountryMonthlyStats(this.AdminContext(), &pb.FindTopServerRegionCountryMonthlyStatsRequest{ + Month: month, + ServerId: params.ServerId, + Offset: 0, + Size: 10, + }) + if err != nil { + this.ErrorPage(err) + return + } + for _, stat := range resp.Stats { + countryStatMaps = append(countryStatMaps, maps.Map{ + "count": stat.Count, + "country": maps.Map{ + "id": stat.RegionCountry.Id, + "name": stat.RegionCountry.Name, + }, + }) + } + } + + // 省份 + { + resp, err := this.RPC().ServerRegionProvinceMonthlyStatRPC().FindTopServerRegionProvinceMonthlyStats(this.AdminContext(), &pb.FindTopServerRegionProvinceMonthlyStatsRequest{ + Month: month, + ServerId: params.ServerId, + Offset: 0, + Size: 10, + }) + if err != nil { + this.ErrorPage(err) + return + } + for _, stat := range resp.Stats { + provinceStatMaps = append(provinceStatMaps, maps.Map{ + "count": stat.Count, + "country": maps.Map{ + "id": stat.RegionCountry.Id, + "name": stat.RegionCountry.Name, + }, + "province": maps.Map{ + "id": stat.RegionProvince.Id, + "name": stat.RegionProvince.Name, + }, + }) + } + } + + // 城市 + { + resp, err := this.RPC().ServerRegionCityMonthlyStatRPC().FindTopServerRegionCityMonthlyStats(this.AdminContext(), &pb.FindTopServerRegionCityMonthlyStatsRequest{ + Month: month, + ServerId: params.ServerId, + Offset: 0, + Size: 10, + }) + if err != nil { + this.ErrorPage(err) + return + } + for _, stat := range resp.Stats { + cityStatMaps = append(cityStatMaps, maps.Map{ + "count": stat.Count, + "country": maps.Map{ + "id": stat.RegionCountry.Id, + "name": stat.RegionCountry.Name, + }, + "province": maps.Map{ + "id": stat.RegionProvince.Id, + "name": stat.RegionProvince.Name, + }, + "city": maps.Map{ + "id": stat.RegionCity.Id, + "name": stat.RegionCity.Name, + }, + }) + } + } + } + + this.Data["countryStats"] = countryStatMaps + this.Data["provinceStats"] = provinceStatMaps + this.Data["cityStats"] = cityStatMaps + + // 记录最近使用 + _, err = this.RPC().LatestItemRPC().IncreaseLatestItem(this.AdminContext(), &pb.IncreaseLatestItemRequest{ + ItemType: "server", + ItemId: params.ServerId, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Show() +} diff --git a/internal/web/actions/default/servers/serverutils/server_helper.go b/internal/web/actions/default/servers/serverutils/server_helper.go index 2872507a..bdba14de 100644 --- a/internal/web/actions/default/servers/serverutils/server_helper.go +++ b/internal/web/actions/default/servers/serverutils/server_helper.go @@ -159,10 +159,15 @@ func (this *ServerHelper) createLogMenu(secondMenuItem string, serverIdString st func (this *ServerHelper) createStatMenu(secondMenuItem string, serverIdString string, serverConfig *serverconfigs.ServerConfig) []maps.Map { menuItems := []maps.Map{} menuItems = append(menuItems, maps.Map{ - "name": "地域分布", + "name": "流量统计", "url": "/servers/server/stat?serverId=" + serverIdString, "isActive": secondMenuItem == "index", }) + menuItems = append(menuItems, maps.Map{ + "name": "地域分布", + "url": "/servers/server/stat/regions?serverId=" + serverIdString, + "isActive": secondMenuItem == "region", + }) menuItems = append(menuItems, maps.Map{ "name": "运营商", "url": "/servers/server/stat/providers?serverId=" + serverIdString, diff --git a/web/public/js/utils.js b/web/public/js/utils.js index d635463c..9ecbdf77 100644 --- a/web/public/js/utils.js +++ b/web/public/js/utils.js @@ -1,302 +1,352 @@ window.teaweb = { - set: function (key, value) { - localStorage.setItem(key, JSON.stringify(value)); - }, - get: function (key) { - var item = localStorage.getItem(key); - if (item == null || item.length == 0) { - return null; - } + set: function (key, value) { + localStorage.setItem(key, JSON.stringify(value)); + }, + get: function (key) { + var item = localStorage.getItem(key); + if (item == null || item.length == 0) { + return null; + } - return JSON.parse(item); - }, - getString: function (key) { - var value = this.get(key); - if (typeof (value) == "string") { - return value; - } - return ""; - }, - getBool: function (key) { - return Boolean(this.get(key)); - }, - remove: function (key) { - localStorage.removeItem(key) - }, - match: function (source, keyword) { - if (source == null) { - return false; - } - if (keyword == null) { - return true; - } - source = source.trim(); - keyword = keyword.trim(); - if (keyword.length == 0) { - return true; - } - if (source.length == 0) { - return false; - } - var pieces = keyword.split(/\s+/); - for (var i = 0; i < pieces.length; i++) { - var pattern = pieces[i]; - pattern = pattern.replace(/(\+|\*|\?|[|]|{|}|\||\\|\(|\)|\.)/g, "\\$1"); - var reg = new RegExp(pattern, "i"); - if (!reg.test(source)) { - return false; - } - } - return true; - }, + return JSON.parse(item); + }, + getString: function (key) { + var value = this.get(key); + if (typeof (value) == "string") { + return value; + } + return ""; + }, + getBool: function (key) { + return Boolean(this.get(key)); + }, + remove: function (key) { + localStorage.removeItem(key) + }, + match: function (source, keyword) { + if (source == null) { + return false; + } + if (keyword == null) { + return true; + } + source = source.trim(); + keyword = keyword.trim(); + if (keyword.length == 0) { + return true; + } + if (source.length == 0) { + return false; + } + var pieces = keyword.split(/\s+/); + for (var i = 0; i < pieces.length; i++) { + var pattern = pieces[i]; + pattern = pattern.replace(/(\+|\*|\?|[|]|{|}|\||\\|\(|\)|\.)/g, "\\$1"); + var reg = new RegExp(pattern, "i"); + if (!reg.test(source)) { + return false; + } + } + return true; + }, - loadJS: function (file, callback) { - let element = document.createElement("script") - element.setAttribute("type", "text/javascript") - element.setAttribute("src", file) - if (typeof callback == "function") { - element.addEventListener("load", callback) - } - document.head.append(element) - }, - loadCSS: function (file, callback) { - let element = document.createElement("link") - element.setAttribute("rel", "stylesheet") - element.setAttribute("type", "text/css") - element.setAttribute("href", file) - if (typeof callback == "function") { - element.addEventListener("load", callback) - } - document.head.append(element) - }, - datepicker: function (element, callback) { - // 加载 - if (typeof Pikaday == "undefined") { - let that = this - this.loadJS("/js/moment.min.js") - this.loadJS("/js/pikaday.js", function () { - that.datepicker(element, callback) - }) - this.loadCSS("/js/pikaday.css") - this.loadCSS("/js/pikaday.theme.css") - this.loadCSS("/js/pikaday.triangle.css") + loadJS: function (file, callback) { + let element = document.createElement("script") + element.setAttribute("type", "text/javascript") + element.setAttribute("src", file) + if (typeof callback == "function") { + element.addEventListener("load", callback) + } + document.head.append(element) + }, + loadCSS: function (file, callback) { + let element = document.createElement("link") + element.setAttribute("rel", "stylesheet") + element.setAttribute("type", "text/css") + element.setAttribute("href", file) + if (typeof callback == "function") { + element.addEventListener("load", callback) + } + document.head.append(element) + }, + datepicker: function (element, callback) { + // 加载 + if (typeof Pikaday == "undefined") { + let that = this + this.loadJS("/js/moment.min.js") + this.loadJS("/js/pikaday.js", function () { + that.datepicker(element, callback) + }) + this.loadCSS("/js/pikaday.css") + this.loadCSS("/js/pikaday.theme.css") + this.loadCSS("/js/pikaday.triangle.css") - return - } + return + } - if (typeof (element) == "string") { - element = document.getElementById(element); - } - var year = new Date().getFullYear(); - var picker = new Pikaday({ - field: element, - firstDay: 1, - minDate: new Date(year - 1, 0, 1), - maxDate: new Date(year + 10, 11, 31), - yearRange: [year - 1, year + 10], - format: "YYYY-MM-DD", - i18n: { - previousMonth: '上月', - nextMonth: '下月', - months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], - weekdays: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], - weekdaysShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] - }, - theme: 'triangle-theme', - onSelect: function () { - if (typeof (callback) == "function") { - callback.call(Tea.Vue, picker.toString()); - } - } - }); - }, + if (typeof (element) == "string") { + element = document.getElementById(element); + } + var year = new Date().getFullYear(); + var picker = new Pikaday({ + field: element, + firstDay: 1, + minDate: new Date(year - 1, 0, 1), + maxDate: new Date(year + 10, 11, 31), + yearRange: [year - 1, year + 10], + format: "YYYY-MM-DD", + i18n: { + previousMonth: '上月', + nextMonth: '下月', + months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], + weekdays: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], + weekdaysShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] + }, + theme: 'triangle-theme', + onSelect: function () { + if (typeof (callback) == "function") { + callback.call(Tea.Vue, picker.toString()); + } + } + }); + }, - formatBytes: function (bytes) { - bytes = Math.ceil(bytes); - if (bytes < 1024) { - return bytes + " bytes"; - } - if (bytes < 1024 * 1024) { - return (Math.ceil(bytes * 100 / 1024) / 100) + " k"; - } - return (Math.ceil(bytes * 100 / 1024 / 1024) / 100) + " m"; - }, - formatNumber: function (x) { - return x.toString().replace(/\B(?= 1024 * 1024 * 1024 * 1024) { + unit = "T" + divider = 1024 * 1024 * 1024 * 1024 + } else if (max >= 1024 * 1024 * 1024) { + unit = "G" + divider = 1024 * 1024 * 1024 + } else if (max >= 1024 * 1024) { + unit = "M" + divider = 1024 * 1024 + } else if (max >= 1024) { + unit = "K" + divider = 1024 + } + return { + unit: unit, + divider: divider + } + }, + countAxis: function (stats, countFunc) { + let max = Math.max.apply(this, stats.map(countFunc)) + let divider = 1 + let unit = "" + if (max >= 1000 * 1000 * 1000) { + unit = "B" + divider = 1000 * 1000 * 1000 + } else if (max >= 1000 * 1000) { + unit = "M" + divider = 1000 * 1000 + } else if (max >= 1000) { + unit = "K" + divider = 1000 + } + return { + unit: unit, + divider: divider + } + }, + popup: function (url, options) { + if (options == null) { + options = {}; + } + var width = "40em"; + var height = "20em"; + window.POPUP_CALLBACK = function () { + Swal.close(); + }; - if (options["width"] != null) { - width = options["width"]; - } - if (options["height"] != null) { - height = options["height"]; - } - if (typeof (options["callback"]) == "function") { - window.POPUP_CALLBACK = function () { - Swal.close(); - options["callback"].apply(Tea.Vue, arguments); - }; - } + if (options["width"] != null) { + width = options["width"]; + } + if (options["height"] != null) { + height = options["height"]; + } + if (typeof (options["callback"]) == "function") { + window.POPUP_CALLBACK = function () { + Swal.close(); + options["callback"].apply(Tea.Vue, arguments); + }; + } - Swal.fire({ - html: '', - width: width, - padding: "0.5em", - showConfirmButton: false, - showCloseButton: true, - focusConfirm: false, - onClose: function (popup) { - if (typeof (options["onClose"]) == "function") { - options["onClose"].apply(Tea.Vue, arguments) - } - } - }); - }, - popupFinish: function () { - if (window.POPUP_CALLBACK != null) { - window.POPUP_CALLBACK.apply(window, arguments); - } - }, - popupTip: function (html) { - Swal.fire({ - html: '' + html + "", - width: "30em", - padding: "5em", - showConfirmButton: false, - showCloseButton: true, - focusConfirm: false - }); - }, - isPopup: function () { - var hash = window.location.hash; - return hash != null && hash.startsWith("#popup"); - }, - closePopup: function () { - if (this.isPopup()) { - window.parent.Swal.close(); - } - }, - Swal: function () { - return this.isPopup() ? window.parent.Swal : window.Swal; - }, - success: function (message, callback) { - var width = "20em"; - if (message.length > 30) { - width = "30em"; - } + Swal.fire({ + html: '', + width: width, + padding: "0.5em", + showConfirmButton: false, + showCloseButton: true, + focusConfirm: false, + onClose: function (popup) { + if (typeof (options["onClose"]) == "function") { + options["onClose"].apply(Tea.Vue, arguments) + } + } + }); + }, + popupFinish: function () { + if (window.POPUP_CALLBACK != null) { + window.POPUP_CALLBACK.apply(window, arguments); + } + }, + popupTip: function (html) { + Swal.fire({ + html: '' + html + "", + width: "30em", + padding: "5em", + showConfirmButton: false, + showCloseButton: true, + focusConfirm: false + }); + }, + isPopup: function () { + var hash = window.location.hash; + return hash != null && hash.startsWith("#popup"); + }, + closePopup: function () { + if (this.isPopup()) { + window.parent.Swal.close(); + } + }, + Swal: function () { + return this.isPopup() ? window.parent.Swal : window.Swal; + }, + success: function (message, callback) { + var width = "20em"; + if (message.length > 30) { + width = "30em"; + } - let config = { - confirmButtonText: "确定", - buttonsStyling: false, - icon: "success", - customClass: { - closeButton: "ui button", - cancelButton: "ui button", - confirmButton: "ui button primary" - }, - width: width, - onAfterClose: function () { - if (typeof (callback) == "function") { - setTimeout(function () { - callback(); - }); - } else if (typeof (callback) == "string") { - window.location = callback - } - } - } + let config = { + confirmButtonText: "确定", + buttonsStyling: false, + icon: "success", + customClass: { + closeButton: "ui button", + cancelButton: "ui button", + confirmButton: "ui button primary" + }, + width: width, + onAfterClose: function () { + if (typeof (callback) == "function") { + setTimeout(function () { + callback(); + }); + } else if (typeof (callback) == "string") { + window.location = callback + } + } + } - if (message.startsWith("html:")) { - config.html = message.substring(5) - } else { - config.text = message - } + if (message.startsWith("html:")) { + config.html = message.substring(5) + } else { + config.text = message + } - Swal.fire(config); - }, - successToast: function (message, timeout) { - if (timeout == null) { - timeout = 2000 - } - var width = "20em"; - if (message.length > 30) { - width = "30em"; - } - Swal.fire({ - text: message, - icon: "success", - width: width, - timer: timeout, - showConfirmButton: false - }); - }, - warn: function (message, callback) { - var width = "20em"; - if (message.length > 30) { - width = "30em"; - } - Swal.fire({ - text: message, - confirmButtonText: "确定", - buttonsStyling: false, - customClass: { - closeButton: "ui button", - cancelButton: "ui button", - confirmButton: "ui button primary" - }, - icon: "warning", - width: width, - onAfterClose: function () { - if (typeof (callback) == "function") { - setTimeout(function () { - callback(); - }); - } - } - }); - }, - confirm: function (message, callback) { - let width = "20em"; - if (message.length > 30) { - width = "30em"; - } - let config = { - confirmButtonText: "确定", - cancelButtonText: "取消", - showCancelButton: true, - showCloseButton: false, - buttonsStyling: false, - customClass: { - closeButton: "ui button", - cancelButton: "ui button", - confirmButton: "ui button primary" - }, - icon: "warning", - width: width, - preConfirm: function () { - if (typeof (callback) == "function") { - callback.call(Tea.Vue); - } - } - } - if (message.startsWith("html:")) { - config.html = message.substring(5) - } else { - config.text = message - } - Swal.fire(config); - }, - reload: function () { - window.location.reload() - } + Swal.fire(config); + }, + successToast: function (message, timeout) { + if (timeout == null) { + timeout = 2000 + } + var width = "20em"; + if (message.length > 30) { + width = "30em"; + } + Swal.fire({ + text: message, + icon: "success", + width: width, + timer: timeout, + showConfirmButton: false + }); + }, + warn: function (message, callback) { + var width = "20em"; + if (message.length > 30) { + width = "30em"; + } + Swal.fire({ + text: message, + confirmButtonText: "确定", + buttonsStyling: false, + customClass: { + closeButton: "ui button", + cancelButton: "ui button", + confirmButton: "ui button primary" + }, + icon: "warning", + width: width, + onAfterClose: function () { + if (typeof (callback) == "function") { + setTimeout(function () { + callback(); + }); + } + } + }); + }, + confirm: function (message, callback) { + let width = "20em"; + if (message.length > 30) { + width = "30em"; + } + let config = { + confirmButtonText: "确定", + cancelButtonText: "取消", + showCancelButton: true, + showCloseButton: false, + buttonsStyling: false, + customClass: { + closeButton: "ui button", + cancelButton: "ui button", + confirmButton: "ui button primary" + }, + icon: "warning", + width: width, + preConfirm: function () { + if (typeof (callback) == "function") { + callback.call(Tea.Vue); + } + } + } + if (message.startsWith("html:")) { + config.html = message.substring(5) + } else { + config.text = message + } + Swal.fire(config); + }, + reload: function () { + window.location.reload() + } }; diff --git a/web/views/@default/servers/server/stat/index.css b/web/views/@default/servers/server/stat/index.css index 3007cba5..35958bdb 100644 --- a/web/views/@default/servers/server/stat/index.css +++ b/web/views/@default/servers/server/stat/index.css @@ -1,4 +1,4 @@ .chart-box { - height: 20em; + height: 21em; } /*# sourceMappingURL=index.css.map */ \ No newline at end of file diff --git a/web/views/@default/servers/server/stat/index.html b/web/views/@default/servers/server/stat/index.html index 4116bc50..678c9277 100644 --- a/web/views/@default/servers/server/stat/index.html +++ b/web/views/@default/servers/server/stat/index.html @@ -7,24 +7,11 @@ {$template "/left_menu"}