diff --git a/server/admin/api_group.go b/server/admin/api_group.go index dd440e1..f5975c1 100644 --- a/server/admin/api_group.go +++ b/server/admin/api_group.go @@ -47,6 +47,16 @@ func GroupNames(w http.ResponseWriter, r *http.Request) { RespSucess(w, data) } +func GroupNamesIds(w http.ResponseWriter, r *http.Request) { + var names = dbdata.GetGroupNamesIds() + data := map[string]interface{}{ + "count": len(names), + "page_size": 0, + "datas": names, + } + RespSucess(w, data) +} + func GroupDetail(w http.ResponseWriter, r *http.Request) { _ = r.ParseForm() idS := r.FormValue("id") diff --git a/server/admin/server.go b/server/admin/server.go index 482ddf0..a663ada 100644 --- a/server/admin/server.go +++ b/server/admin/server.go @@ -62,6 +62,7 @@ func StartAdmin() { r.HandleFunc("/group/list", GroupList) r.HandleFunc("/group/names", GroupNames) + r.HandleFunc("/group/names_ids", GroupNamesIds) r.HandleFunc("/group/detail", GroupDetail) r.HandleFunc("/group/set", GroupSet) r.HandleFunc("/group/del", GroupDel) diff --git a/server/dbdata/group.go b/server/dbdata/group.go index 7e731cf..97fa740 100644 --- a/server/dbdata/group.go +++ b/server/dbdata/group.go @@ -32,6 +32,11 @@ type ValData struct { Note string `json:"note"` } +type GroupNameId struct { + Id int `json:"id"` + Name string `json:"name"` +} + // type Group struct { // Id int `json:"id" xorm:"pk autoincr not null"` // Name string `json:"name" xorm:"varchar(60) not null unique"` @@ -64,6 +69,20 @@ func GetGroupNames() []string { return names } +func GetGroupNamesIds() []GroupNameId { + var datas []Group + err := Find(&datas, 0, 0) + if err != nil { + base.Error(err) + return nil + } + var names []GroupNameId + for _, v := range datas { + names = append(names, GroupNameId{Id: v.Id, Name: v.Name}) + } + return names +} + func SetGroup(g *Group) error { var err error if g.Name == "" { diff --git a/server/dbdata/group_test.go b/server/dbdata/group_test.go index 8b79b60..fc59234 100644 --- a/server/dbdata/group_test.go +++ b/server/dbdata/group_test.go @@ -63,4 +63,10 @@ func TestGetGroupNames(t *testing.T) { for _, v := range gs { ast.Equal(true, utils.InArrStr(gAll, v)) } + + gni := GetGroupNamesIds() + for _, v := range gni { + ast.NotEqual(0, v.Id) + ast.Equal(true, utils.InArrStr(gAll, v.Name)) + } } diff --git a/server/dbdata/statsinfo_test.go b/server/dbdata/statsinfo_test.go new file mode 100644 index 0000000..a49d64e --- /dev/null +++ b/server/dbdata/statsinfo_test.go @@ -0,0 +1,55 @@ +package dbdata + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStatsInfo(t *testing.T) { + ast := assert.New(t) + + preIpData() + defer closeIpdata() + + ast.True(StatsInfoIns.ValidAction("online")) + ast.False(StatsInfoIns.ValidAction("diskio")) + ast.True(StatsInfoIns.ValidScope("30d")) + ast.False(StatsInfoIns.ValidScope("60d")) + + up := uint32(100) + down := uint32(300) + upGroups := map[int]uint32{1: up} + downGroups := map[int]uint32{1: down} + numGroups := map[int]int{1: 5} + // online + numData, _ := json.Marshal(numGroups) + so := &StatsOnline{Num: 1, NumGroups: string(numData)} + // network + upData, _ := json.Marshal(upGroups) + downData, _ := json.Marshal(downGroups) + sn := &StatsNetwork{Up: up, Down: down, UpGroups: string(upData), DownGroups: string(downData)} + // cpu + sc := &StatsCpu{Percent: 0.3} + // mem + sm := &StatsMem{Percent: 24.50} + + StatsInfoIns.SetRealTime("online", so) + StatsInfoIns.GetRealTime("online") + StatsInfoIns.SaveStatsInfo(so, sn, sc, sm) + + var err error + _, err = StatsInfoIns.GetData("online", "1h") + ast.Nil(err) + + _, err = StatsInfoIns.GetData("network", "1h") + ast.Nil(err) + + _, err = StatsInfoIns.GetData("cpu", "1h") + ast.Nil(err) + + _, err = StatsInfoIns.GetData("mem", "1h") + ast.Nil(err) + +} diff --git a/server/sessdata/statsinfo.go b/server/sessdata/statsinfo.go index 5a583b4..8c2a636 100644 --- a/server/sessdata/statsinfo.go +++ b/server/sessdata/statsinfo.go @@ -22,9 +22,9 @@ func saveStatsInfo() { for range tick.C { up := uint32(0) down := uint32(0) - upGroups := make(map[string]uint32) - downGroups := make(map[string]uint32) - numGroups := make(map[string]int) + upGroups := make(map[int]uint32) + downGroups := make(map[int]uint32) + numGroups := make(map[int]int) onlineNum := 0 sessMux.Lock() for _, v := range sessions { @@ -32,12 +32,16 @@ func saveStatsInfo() { if v.IsActive { // 在线人数 onlineNum += 1 - numGroups[v.Group] += 1 + numGroups[v.CSess.Group.Id] += 1 // 网络吞吐 userUp := atomic.LoadUint32(&v.CSess.BandwidthUpPeriod) userDown := atomic.LoadUint32(&v.CSess.BandwidthDownPeriod) - upGroups[v.Group] += userUp - downGroups[v.Group] += userDown + if userUp > 0 { + upGroups[v.CSess.Group.Id] += userUp + } + if userDown > 0 { + downGroups[v.CSess.Group.Id] += userDown + } up += userUp down += userDown } diff --git a/web/src/pages/Home.vue b/web/src/pages/Home.vue index a0e0f49..6f8c9bd 100644 --- a/web/src/pages/Home.vue +++ b/web/src/pages/Home.vue @@ -46,6 +46,12 @@ +
+ + + + +
实时 @@ -58,6 +64,12 @@ +
+ + + + +
实时 @@ -119,6 +131,7 @@ export default { group: 0, ip_map: 0, }, + groupNames:[], lineChart: { online: { title: '用户在线数', @@ -160,7 +173,11 @@ export default { network : "rt", cpu : "rt", mem : "rt" - }, + }, + lineChartGroup : { + online: "", + network: "", + } } }, created() { @@ -169,6 +186,7 @@ export default { }, mounted() { this.getData() + this.getGroups() this.getAllStats() const chartsTimer = setInterval(() => { this.getAllStats() @@ -219,15 +237,22 @@ export default { formatOnline(data) { let timeFormat = this.getTimeFormat(data.scope) let chartData = this.lineChart[data.action] - let datas = data.datas + let chooseGroup = this.lineChartGroup[data.action] + let datas = data.datas + let xnum = 0 chartData.xname = [] chartData.xdata["在线人数"] = [] for(var i=0; i 0) { + let num_groups = JSON.parse(datas[i].num_groups) + xnum = ! num_groups[chooseGroup] ? 0 : num_groups[chooseGroup] + } + chartData.xdata["在线人数"][i] = xnum } // 实时更新在线数 - if (data.scope == "rt") { + if (data.scope == "rt" && chooseGroup == "") { this.counts.online = datas[datas.length - 1].num } this.lineChart[data.action] = chartData @@ -235,14 +260,28 @@ export default { formatNetwork(data) { let timeFormat = this.getTimeFormat(data.scope) let chartData = this.lineChart[data.action] - let datas = data.datas + let chooseGroup = this.lineChartGroup[data.action] + let datas = data.datas + let xnumUp = 0, xnumDown = 0 chartData.xname = [] chartData.xdata["上行流量"] = [] chartData.xdata["下行流量"] = [] for(var i=0; i 0) { + let upGroups = JSON.parse(datas[i].up_groups) + xnumUp = ! upGroups[chooseGroup] ? 0 : upGroups[chooseGroup] + } + if (xnumDown > 0) { + let downGroups = JSON.parse(datas[i].down_groups) + xnumDown = ! downGroups[chooseGroup] ? 0 : downGroups[chooseGroup] + } + } + chartData.xdata["上行流量"][i] = this.toMbps(xnumUp) + chartData.xdata["下行流量"][i] = this.toMbps(xnumDown) } this.lineChart[data.action] = chartData }, @@ -301,6 +340,23 @@ export default { jump(path) { this.$router.push(path); }, + getGroups() { + axios.get('/group/names_ids', {}).then(resp => { + var data = resp.data.data + var groupNames = [] + groupNames[0] = {text:"全部", value:""} + for(var i=0; i { + this.$message.error('哦,请求出错'); + console.log(error); + }); + }, + lineChartGroupChange(action) { + this.getStatsData(action, this.lineChartScope[action]); + } }, } @@ -309,6 +365,7 @@ export default { .panel-group { margin-bottom: 20px; } + .card-panel { display: flex; border-radius: 12px; @@ -368,4 +425,17 @@ export default { right: 5px; top: 5px; } + +.chart-group-name { + position: absolute; + left: 110px; + top: 5px; + width: 130px; + font-size: 10px; +} + +/deep/ .el-radio-button--mini .el-radio-button__inner { + padding: 7px 8px; + font-size: 10px; +}