mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-04 21:50:28 +08:00
商业版WAF看板增加地图
This commit is contained in:
@@ -5,11 +5,15 @@ Vue.component("traffic-map-box", {
|
|||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
let maxPercent = 0
|
let maxPercent = 0
|
||||||
|
let isAttack = this.vIsAttack
|
||||||
this.vStats.forEach(function (v) {
|
this.vStats.forEach(function (v) {
|
||||||
let percent = parseFloat(v.percent)
|
let percent = parseFloat(v.percent)
|
||||||
if (percent > maxPercent) {
|
if (percent > maxPercent) {
|
||||||
maxPercent = percent
|
maxPercent = percent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v.formattedCountRequests = teaweb.formatCount(v.countRequests) + "次"
|
||||||
|
v.formattedCountAttackRequests = teaweb.formatCount(v.countAttackRequests) + "次"
|
||||||
})
|
})
|
||||||
|
|
||||||
if (maxPercent < 100) {
|
if (maxPercent < 100) {
|
||||||
@@ -17,10 +21,12 @@ Vue.component("traffic-map-box", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
isAttack: isAttack,
|
||||||
stats: this.vStats,
|
stats: this.vStats,
|
||||||
chart: null,
|
chart: null,
|
||||||
minOpacity: 0.2,
|
minOpacity: 0.2,
|
||||||
maxPercent: maxPercent
|
maxPercent: maxPercent,
|
||||||
|
selectedCountryName: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -29,7 +35,12 @@ Vue.component("traffic-map-box", {
|
|||||||
let that = this
|
let that = this
|
||||||
this.chart.setOption({
|
this.chart.setOption({
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
grid: {top: 0, bottom: 0, left: 0, right: 0},
|
grid: {
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0
|
||||||
|
},
|
||||||
roam: true,
|
roam: true,
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: "item"
|
trigger: "item"
|
||||||
@@ -50,12 +61,6 @@ Vue.component("traffic-map-box", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
//select: {itemStyle:{ areaColor: "#8B9BD3", opacity: 0.8 }},
|
//select: {itemStyle:{ areaColor: "#8B9BD3", opacity: 0.8 }},
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
formatter: function (args) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
tooltip: {
|
||||||
formatter: function (args) {
|
formatter: function (args) {
|
||||||
let name = args.name
|
let name = args.name
|
||||||
@@ -67,7 +72,7 @@ Vue.component("traffic-map-box", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (stat != null) {
|
if (stat != null) {
|
||||||
return name + "<br/>流量:" + stat.formattedBytes + "<br/>请求数:" + teaweb.formatNumber(stat.countRequests) + "<br/>流量占比:" + stat.percent + "%"
|
return name + "<br/>流量:" + stat.formattedBytes + "<br/>流量占比:" + stat.percent + "%<br/>请求数:" + stat.formattedCountRequests + "<br/>攻击数:" + stat.formattedCountAttackRequests
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
@@ -81,11 +86,12 @@ Vue.component("traffic-map-box", {
|
|||||||
if (fullOpacity > 1) {
|
if (fullOpacity > 1) {
|
||||||
fullOpacity = 1
|
fullOpacity = 1
|
||||||
}
|
}
|
||||||
let isAttack = this.vIsAttack
|
let isAttack = that.vIsAttack
|
||||||
let bgColor = "#276AC6"
|
let bgColor = "#276AC6"
|
||||||
if (isAttack) {
|
if (isAttack) {
|
||||||
bgColor = "#B03A5B"
|
bgColor = "#B03A5B"
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: v.name,
|
name: v.name,
|
||||||
value: v.bytes,
|
value: v.bytes,
|
||||||
@@ -99,6 +105,19 @@ Vue.component("traffic-map-box", {
|
|||||||
areaColor: bgColor,
|
areaColor: bgColor,
|
||||||
opacity: fullOpacity
|
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]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -123,9 +142,12 @@ Vue.component("traffic-map-box", {
|
|||||||
if (v.isSelected) {
|
if (v.isSelected) {
|
||||||
v.itemStyle.opacity = opacity
|
v.itemStyle.opacity = opacity
|
||||||
v.isSelected = false
|
v.isSelected = false
|
||||||
|
v.label.show = false
|
||||||
|
that.selectedCountryName = ""
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
v.isSelected = true
|
v.isSelected = true
|
||||||
|
that.selectedCountryName = countryName
|
||||||
opacity *= 3
|
opacity *= 3
|
||||||
if (opacity > 1) {
|
if (opacity > 1) {
|
||||||
opacity = 1
|
opacity = 1
|
||||||
@@ -136,9 +158,11 @@ Vue.component("traffic-map-box", {
|
|||||||
opacity = 0.5
|
opacity = 0.5
|
||||||
}
|
}
|
||||||
v.itemStyle.opacity = opacity
|
v.itemStyle.opacity = opacity
|
||||||
|
v.label.show = true
|
||||||
} else {
|
} else {
|
||||||
v.itemStyle.opacity = opacity
|
v.itemStyle.opacity = opacity
|
||||||
v.isSelected = false
|
v.isSelected = false
|
||||||
|
v.label.show = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.chart.setOption(option)
|
this.chart.setOption(option)
|
||||||
@@ -166,11 +190,13 @@ Vue.component("traffic-map-box", {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(stat, index) in stats.slice(0, 10)">
|
<tr v-for="(stat, index) in stats.slice(0, 10)">
|
||||||
<td @click.prevent="select(stat.name)" style="cursor: pointer" colspan="2">
|
<td @click.prevent="select(stat.name)" style="cursor: pointer" colspan="2">
|
||||||
<div class="ui progress bar blue" style="margin-bottom: 0.3em">
|
<div class="ui progress bar" :class="{red: vIsAttack, blue:!vIsAttack}" style="margin-bottom: 0.3em">
|
||||||
<div class="bar" style="min-width: 0; height: 4px;" :style="{width: stat.percent + '%'}"></div>
|
<div class="bar" style="min-width: 0; height: 4px;" :style="{width: stat.percent + '%'}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div>{{stat.name}}</div>
|
<div>{{stat.name}}</div>
|
||||||
<div><span class="grey">{{stat.percent}}% </span><span class="small grey">({{stat.formattedBytes}})</span></div>
|
<div><span class="grey">{{stat.percent}}% </span>
|
||||||
|
<span class="small grey" v-if="isAttack">{{stat.formattedCountAttackRequests}}</span>
|
||||||
|
<span class="small grey" v-if="!isAttack">({{stat.formattedBytes}})</span></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -30,6 +30,12 @@
|
|||||||
.chart-box {
|
.chart-box {
|
||||||
height: 14em;
|
height: 14em;
|
||||||
}
|
}
|
||||||
|
.traffic-map-box {
|
||||||
|
height: 16em;
|
||||||
|
}
|
||||||
|
.traffic-map-box div::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
.color-span {
|
.color-span {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sources":["waf.less"],"names":[],"mappings":"AAAA,GAAG,QACF;EACC,kBAAA;EACA,UAAA;EACA,UAAA;;AAIF;EACC,0BAAA;EACA,2BAAA;;AAFD,KAIC;EACC,kBAAA;EACA,4BAAA;;AANF,KAIC,QAIC,IAAG;EACF,iBAAA;;AATH,KAIC,QAIC,IAAG,MAGF;EACC,cAAA;EACA,mBAAA;;AAbJ,KAkBC,QAAO;EACN,eAAA;;AAnBF,KAsBC,GACC;EACC,aAAA;;AAxBH,KA4BC,QAAO,MACN;EACC,eAAA;;AAKH;EACC,YAAA;;AAGD;EACC,gBAAA;EACA,YAAA;;AAGD,EAAE,OACD;EACC,iBAAA;EACA,YAAA","file":"waf.css"}
|
{"version":3,"sources":["waf.less"],"names":[],"mappings":"AAAA,GAAG,QACF;EACC,kBAAA;EACA,UAAA;EACA,UAAA;;AAIF;EACC,0BAAA;EACA,2BAAA;;AAFD,KAIC;EACC,kBAAA;EACA,4BAAA;;AANF,KAIC,QAIC,IAAG;EACF,iBAAA;;AATH,KAIC,QAIC,IAAG,MAGF;EACC,cAAA;EACA,mBAAA;;AAbJ,KAkBC,QAAO;EACN,eAAA;;AAnBF,KAsBC,GACC;EACC,aAAA;;AAxBH,KA4BC,QAAO,MACN;EACC,eAAA;;AAKH;EACC,YAAA;;AAGD;EACC,YAAA;;AADD,gBAGC,IAAG;EACF,UAAA;;AAIF;EACC,gBAAA;EACA,YAAA;;AAGD,EAAE,OACD;EACC,iBAAA;EACA,YAAA","file":"waf.css"}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
{$layout}
|
{$layout}
|
||||||
|
|
||||||
|
{$var "header"}
|
||||||
|
<!-- world map -->
|
||||||
|
<script type="text/javascript" src="/js/echarts/echarts.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/world.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/world-countries-map.js"></script>
|
||||||
|
{$end}
|
||||||
|
|
||||||
{$template "menu"}
|
{$template "menu"}
|
||||||
{$template "/echarts"}
|
|
||||||
|
|
||||||
<div class="ui four columns grid">
|
<div class="ui four columns grid">
|
||||||
<div class="ui column">
|
<div class="ui column">
|
||||||
@@ -24,6 +31,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 流量地图 -->
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
<div class="traffic-map-box" v-if="!isLoading">
|
||||||
|
<traffic-map-box :v-stats="topCountryStats" :v-is-attack="true"></traffic-map-box>
|
||||||
|
</div>
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
<!-- 最近日志 -->
|
<!-- 最近日志 -->
|
||||||
<div v-if="accessLogs.length > 0">
|
<div v-if="accessLogs.length > 0">
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ Tea.context(function () {
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
|
|
||||||
this.$delay(function () {
|
this.$delay(function () {
|
||||||
let that = this
|
|
||||||
|
|
||||||
this.board.countDailyBlocks = teaweb.formatCount(this.board.countDailyBlocks)
|
this.board.countDailyBlocks = teaweb.formatCount(this.board.countDailyBlocks)
|
||||||
this.board.countDailyCaptcha = teaweb.formatCount(this.board.countDailyCaptcha)
|
this.board.countDailyCaptcha = teaweb.formatCount(this.board.countDailyCaptcha)
|
||||||
this.board.countDailyLogs = teaweb.formatCount(this.board.countDailyLogs)
|
this.board.countDailyLogs = teaweb.formatCount(this.board.countDailyLogs)
|
||||||
|
|||||||
@@ -45,6 +45,14 @@
|
|||||||
height: 14em;
|
height: 14em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.traffic-map-box {
|
||||||
|
height: 16em;
|
||||||
|
|
||||||
|
div::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.color-span {
|
.color-span {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
|
|||||||
Reference in New Issue
Block a user