diff --git a/web/public/js/components.js b/web/public/js/components.js index 27efaa07..64134d4d 100755 --- a/web/public/js/components.js +++ b/web/public/js/components.js @@ -1,3 +1,213 @@ +Vue.component("traffic-map-box", { + props: ["v-stats", "v-is-attack"], + mounted: function () { + this.render() + }, + data: function () { + let maxPercent = 0 + let isAttack = this.vIsAttack + this.vStats.forEach(function (v) { + let percent = parseFloat(v.percent) + if (percent > maxPercent) { + maxPercent = percent + } + + v.formattedCountRequests = teaweb.formatCount(v.countRequests) + "次" + v.formattedCountAttackRequests = teaweb.formatCount(v.countAttackRequests) + "次" + }) + + if (maxPercent < 100) { + maxPercent *= 1.2 // 不要让某一项100% + } + + return { + isAttack: isAttack, + stats: this.vStats, + chart: null, + minOpacity: 0.2, + maxPercent: maxPercent, + selectedCountryName: "" + } + }, + methods: { + render: function () { + this.chart = teaweb.initChart(document.getElementById("traffic-map-box")); + let that = this + this.chart.setOption({ + backgroundColor: "white", + grid: { + top: 0, + bottom: 0, + left: 0, + right: 0 + }, + roam: true, + tooltip: { + trigger: "item" + }, + series: [{ + type: "map", + map: "world", + zoom: 1.2, + selectedMode: false, + itemStyle: { + areaColor: "#E9F0F9", + borderColor: "#DDD" + }, + emphasis: { + itemStyle: { + areaColor: "#8B9BD3", + opacity: 1.0 + } + }, + //select: {itemStyle:{ areaColor: "#8B9BD3", opacity: 0.8 }}, + tooltip: { + formatter: function (args) { + let name = args.name + let stat = null + that.stats.forEach(function (v) { + if (v.name == name) { + stat = v + } + }) + + if (stat != null) { + return name + "
流量:" + stat.formattedBytes + "
流量占比:" + stat.percent + "%
请求数:" + stat.formattedCountRequests + "
攻击数:" + stat.formattedCountAttackRequests + } + return name + } + }, + data: this.stats.map(function (v) { + let opacity = parseFloat(v.percent) / that.maxPercent + if (opacity < that.minOpacity) { + opacity = that.minOpacity + } + let fullOpacity = opacity * 3 + if (fullOpacity > 1) { + fullOpacity = 1 + } + let isAttack = that.vIsAttack + let bgColor = "#276AC6" + if (isAttack) { + bgColor = "#B03A5B" + } + + return { + name: v.name, + value: v.bytes, + percent: parseFloat(v.percent), + itemStyle: { + areaColor: bgColor, + opacity: opacity + }, + emphasis: { + itemStyle: { + areaColor: bgColor, + opacity: fullOpacity + } + }, + label: { + show: false, + formatter: function (args) { + if (args.name == that.selectedCountryName) { + return args.name + } + return "" + }, + fontSize: "10px", + color: "#fff", + backgroundColor: "#8B9BD3", + padding: [2, 2, 2, 2] + } + } + }), + nameMap: window.WorldCountriesMap + }] + }) + this.chart.resize() + }, + select: function (countryName) { + if (this.chart == null) { + return + } + let option = this.chart.getOption() + let that = this + option.series[0].data.forEach(function (v) { + let opacity = v.percent / that.maxPercent + if (opacity < that.minOpacity) { + opacity = that.minOpacity + } + + if (v.name == countryName) { + if (v.isSelected) { + v.itemStyle.opacity = opacity + v.isSelected = false + v.label.show = false + that.selectedCountryName = "" + return + } + v.isSelected = true + that.selectedCountryName = countryName + opacity *= 3 + if (opacity > 1) { + opacity = 1 + } + + // 至少是0.5,让用户能够看清 + if (opacity < 0.5) { + opacity = 0.5 + } + v.itemStyle.opacity = opacity + v.label.show = true + } else { + v.itemStyle.opacity = opacity + v.isSelected = false + v.label.show = false + } + }) + this.chart.setOption(option) + } + }, + template: `
+ + + + + +
+
+
+
+ + + + + + + + + + + + + + + + +
国家/地区排行
暂无数据
+
+
+
+
{{stat.name}}
+
{{stat.percent}}% + {{stat.formattedCountAttackRequests}} + ({{stat.formattedBytes}})
+
+
+
+
` +}) + // 显示节点的多个集群 Vue.component("node-clusters-labels", { props: ["v-primary-cluster", "v-secondary-clusters", "size"], @@ -2951,7 +3161,7 @@ Vue.component("metric-chart", { template: `

{{chart.name}} ({{valueTypeName}})

-
+
` }) @@ -4397,8 +4607,10 @@ Vue.component("http-firewall-actions-box", { var defaultPageBody = ` +403 Forbidden -403 Forbidden +

403 Forbidden

+
Request ID: \${requestId}.
` @@ -5592,10 +5804,10 @@ Vue.component("http-pages-and-shutdown-box", { -

网站升级中

+

网站升级中

为了给您提供更好的服务,我们正在升级网站,请稍后重新访问。

- +
Request ID: \${requestId}, Powered by GoEdge.
` @@ -6109,7 +6321,7 @@ Vue.component("http-access-log-box", { template: `
[{{accessLog.node.name}}节点] [服务] - [{{accessLog.region}}] {{accessLog.remoteAddr}} [{{accessLog.timeLocal}}] "{{accessLog.requestMethod}} {{accessLog.scheme}}://{{accessLog.host}}{{accessLog.requestURI}} {{accessLog.proto}}" {{accessLog.status}} cache hit waf {{accessLog.firewallActions}} - {{tag}} - 耗时:{{formatCost(accessLog.requestTime)}} ms   ({{accessLog.humanTime}}) + [{{accessLog.region}}] {{accessLog.remoteAddr}} [{{accessLog.timeLocal}}] "{{accessLog.requestMethod}} {{accessLog.scheme}}://{{accessLog.host}}{{accessLog.requestURI}} {{accessLog.proto}}" {{accessLog.status}} cache hit waf {{accessLog.firewallActions}} - {{tag}} - 耗时:{{formatCost(accessLog.requestTime)}} ms   ({{accessLog.humanTime}})  
` }) @@ -8576,7 +8788,9 @@ Vue.component("traffic-limit-config-box", { Traffic Limit Exceeded Warning -The site traffic has exceeded the limit. Please contact with the site administrator. +

Traffic Limit Exceeded Warning

+

The site traffic has exceeded the limit. Please contact with the site administrator.

+
Request ID: \${requestId}.
` @@ -8905,16 +9119,19 @@ Vue.component("ip-item-text", { }) Vue.component("ip-box", { - props: [], + props: ["v-ip"], methods: { popup: function () { - let e = this.$refs.container - let text = e.innerText - if (text == null) { - text = e.textContent + let ip = this.vIp + if (ip == null || ip.length == 0) { + let e = this.$refs.container + ip = e.innerText + if (ip == null) { + ip = e.textContent + } } - teaweb.popup("/servers/ipbox?ip=" + text, { + teaweb.popup("/servers/ipbox?ip=" + ip, { width: "50em", height: "30em" }) @@ -9726,6 +9943,7 @@ Vue.component("datetime-input", { this.timestamp = Math.floor(date.getTime() / 1000) }, leadingZero: function (s, l) { + s = s.toString() if (l <= s.length) { return s } @@ -9733,6 +9951,18 @@ Vue.component("datetime-input", { s = "0" + s } return s + }, + resultTimestamp: function () { + return this.timestamp + }, + nextDays: function (days) { + let date = new Date() + date.setTime(date.getTime() + days * 86400 * 1000) + this.day = date.getFullYear() + "-" + this.leadingZero(date.getMonth() + 1, 2) + "-" + this.leadingZero(date.getDate(), 2) + this.hour = this.leadingZero(date.getHours(), 2) + this.minute = this.leadingZero(date.getMinutes(), 2) + this.second = this.leadingZero(date.getSeconds(), 2) + this.change() } }, template: `
@@ -9747,6 +9977,7 @@ Vue.component("datetime-input", {
:
+

常用时间:  1天  |  3天  |  一周  |  30天 

` }) diff --git a/web/public/js/components/maps/traffic-map-box.js b/web/public/js/components/maps/traffic-map-box.js index 31aaa5b9..8a5a3fa6 100644 --- a/web/public/js/components/maps/traffic-map-box.js +++ b/web/public/js/components/maps/traffic-map-box.js @@ -52,7 +52,7 @@ Vue.component("traffic-map-box", { selectedMode: false, itemStyle: { areaColor: "#E9F0F9", - borderColor: "#999" + borderColor: "#DDD" }, emphasis: { itemStyle: {