This commit is contained in:
unknown
2026-02-04 20:27:13 +08:00
commit 3b042d1dad
9410 changed files with 1488147 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
.grid .small {
font-size: 0.8em !important;
}
.table-box {
width: 40em;
max-height: 40em;
overflow-y: auto;
}
.chart-box {
height: 20em;
margin-top: 1em;
}
/*# sourceMappingURL=index.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA,KAAM;EACL,gBAAA;;AAGD;EACC,WAAA;EACA,gBAAA;EACA,gBAAA;;AAGD;EACC,YAAA;EACA,eAAA","file":"index.css"}

View File

@@ -0,0 +1,97 @@
{$layout}
{$template "/echarts"}
<div style="margin-top: 0.6em"></div>
<form class="ui form">
<div class="ui fields inline">
<div class="ui field">
<datepicker name="dayFrom" placeholder="开始日期" v-model="dayFrom" @change="changeDayFrom"></datepicker>
</div>
<div class="ui field">
<datepicker name="dayTo" placeholder="结束日期" v-model="dayTo" @change="changeDayTo"></datepicker>
</div>
<div class="ui field">
<span v-if="servers.length == 0" class="disabled">暂无网站</span>
<div v-else>
<combo-box :v-items="servers" name="serverId" @change="changeServer" :placeholder="'全部网站服务(' + (servers.length-1) + ''"></combo-box>
</div>
</div>
<div class="ui field" v-if="serverId == 0 && regions.length > 0">
<select class="ui dropdown" name="regionId" v-model="regionId" @change="changeRegion">
<option value="0">所有区域</option>
<option v-for="region in regions" :value="region.id">{{region.name}}</option>
</select>
</div>
<div class="ui field">
<button class="ui button" type="button" @click.prevent="search">查询</button>
</div>
</div>
</form>
<div class="margin"></div>
<div class="ui message" v-if="isLoading">加载中...</div>
<div class="ui four columns grid counter-chart" v-if="result != null">
<div class="ui column">
<h4>带宽峰值</h4>
<div class="value">
<span>{{result.maxBandwidthBitsFormat[0]}}</span>
{{result.maxBandwidthBitsFormat[1]}}
<br/>
<span v-if="result.maxBandwidthTime.length > 0" class="small grey">{{result.maxBandwidthTime}}:00</span>
<span v-else>&nbsp;<!-- placeholder --></span>
</div>
</div>
<div class="ui column">
<h4>95th带宽</h4>
<div class="value">
<span>{{result.bandwidth95thBitsFormat[0]}}</span>
{{result.bandwidth95thBitsFormat[1]}}
</div>
</div>
<div class="ui column">
<h4>总流量</h4>
<div class="value">
<span>{{result.totalTrafficBytesFormat[0]}}</span>
{{result.totalTrafficBytesFormat[1]}}
</div>
</div>
<div class="ui column with-border">
<h4>总请求数</h4>
<div class="value"><span>{{result.totalTrafficRequests}}</span></div>
</div>
</div>
<!-- 查询结果 -->
<div v-if="result != null" style="margin-top: 0.6em">
<!-- 菜单 -->
<first-menu >
<menu-item :class="{active: tab == 'chart'}" @click.prevent="selectTab('chart')">图表 &nbsp;<i class="icon chart area small"></i></menu-item>
<menu-item :class="{active: tab == 'table'}" @click.prevent="selectTab('table')">表格 &nbsp;<i class="icon table small"></i></menu-item>
<span class="item disabled">|</span>
<menu-item :href="'.download?dayFrom=' + dayFrom + '&dayTo=' + dayTo + '&serverId=' + serverId" target="_blank">下载 <i class="icon download small"></i></menu-item>
<menu-item v-for="(r, index) in dayRanges" :class="{active: dayFrom == r.dayFrom && dayTo == r.dayTo, right: index == 0}" @click.prevent="selectDay(r.dayFrom, r.dayTo)">{{r.name}}</menu-item>
</first-menu>
<!-- 表格 -->
<div class="table-box scroll-box" v-if="result != null" v-show="tab == 'table'">
<table class="ui table selectable celled">
<thead>
<tr>
<th>时间</th>
<th>带宽Mbps</th>
<th>带宽Gbps</th>
</tr>
</thead>
<tr v-for="stat in result.bandwidthStats">
<td>{{stat.day.substring(0, 4)}}-{{stat.day.substring(4, 6)}}-{{stat.day.substring(6)}} {{stat.time.substring(0, 2)}}:{{stat.time.substring(2)}}</td>
<td>{{stat.mbps}}</td>
<td>{{stat.gbps}}</td>
</tr>
</table>
</div>
<!-- 图表 -->
<div class="chart-box" id="bandwidth-chart" v-show="result != null && tab == 'chart'"></div>
</div>

View File

@@ -0,0 +1,146 @@
Tea.context(function () {
this.servers = []
this.result = null
this.isLoading = false
this.regionId = 0
this.serverId = 0
this.$delay(function () {
this.$post(".serverOptions")
.params({})
.success(function (resp) {
this.servers = resp.data.servers
})
this.search()
})
this.changeDayFrom = function () {
this.search()
}
this.changeDayTo = function () {
this.search()
}
this.changeServer = function (result) {
if (result != null) {
this.serverId = result.value
this.search()
}
}
this.changeRegion = function () {
this.search()
}
this.search = function () {
this.isLoading = true
this.result = null
this.$post("$")
.params({
serverId: this.serverId,
regionId: this.regionId,
dayFrom: this.dayFrom,
dayTo: this.dayTo
})
.success(function (resp) {
let totalTrafficBytesFormat = teaweb.splitFormat(teaweb.formatBytes(resp.data.totalTrafficBytes))
let maxBandwidthBitsFormat = teaweb.splitFormat(teaweb.formatBits(resp.data.maxBandwidthBits))
let bandwidth95thBitsFormat = teaweb.splitFormat(teaweb.formatBits(resp.data.bandwidth95thBits))
this.result = {
bandwidthStats: resp.data.bandwidthStats,
reversedBandwidthStats: resp.data.bandwidthStats.$copy().reverse(),
maxBandwidthBitsFormat: maxBandwidthBitsFormat,
maxBandwidthTime: resp.data.maxBandwidthTime,
bandwidth95thBitsFormat: bandwidth95thBitsFormat,
totalTrafficBytesFormat: totalTrafficBytesFormat,
totalTrafficRequests: teaweb.formatCount(resp.data.totalTrafficRequests)
}
this.reloadChart(resp.data.bandwidthStats, resp.data.bandwidth95thBits)
})
.done(function () {
this.isLoading = false
})
}
/**
* tab set
*/
this.tab = "chart"
this.selectTab = function (tab) {
this.tab = tab
}
this.reloadChart = function (stats, nthBits) {
let box = document.getElementById("bandwidth-chart")
if (box == null || box.offsetHeight <= 0) {
this.$delay(function () {
this.reloadChart(stats, nthBits)
}, 100)
return
}
let axis = teaweb.bitsAxis(stats, function (stat) {
return stat.bits
})
teaweb.renderLineChart({
id: "bandwidth-chart",
values: stats,
axis: axis,
x: function (stat) {
return stat.day.substring(0, 4) + "-" + stat.day.substring(4, 6) + "-" + stat.day.substring(6) + " " + stat.time.substring(0, 2) + ":" + stat.time.substring(2)
},
xColor: function (text) {
let currentTime = new Date().format("Y-m-d H:i")
if (currentTime < text) {
return "#cccccc"
}
return "default"
},
value: function (stat) {
if (typeof(stat.isNull) == "boolean" && stat.isNull) {
return null
}
return stat.bits / axis.divider
},
tooltip: function (args, values) {
if (args.componentType == "markLine") {
return args.name
}
let index = args.dataIndex
let stat = values[index]
return stat.day.substring(0, 4) + "-" + stat.day.substring(4, 6) + "-" + stat.day.substring(6) + " " + stat.time.substring(0, 2) + ":" + stat.time.substring(2) + "<br/>带宽:" + teaweb.formatBits(values[index].bits)
},
left: 30,
right: 40,
cache: false,
markLine: {
precision: 4,
data: [{
name: this.percentile + "th",
yAxis: nthBits / axis.divider
}],
symbol: "none",
lineStyle: {
color: teaweb.chartColor("red")
}
}
})
}
/**
* select day
*/
this.selectDay = function (dayFrom, dayTo) {
this.dayFrom = dayFrom
this.dayTo = dayTo
this.search()
}
})

View File

@@ -0,0 +1,14 @@
.grid .small {
font-size: 0.8em!important;
}
.table-box {
width: 40em;
max-height: 40em;
overflow-y: auto;
}
.chart-box {
height: 20em;
margin-top: 1em;
}