mirror of https://github.com/bjdgyc/anylink.git
新增在线用户的搜索和一键下线功能
This commit is contained in:
parent
a59e480b61
commit
096b6f8f08
|
@ -23,6 +23,8 @@ const (
|
|||
UserLogoutAdmin = 4 // 账号被管理员踢下线
|
||||
UserLogoutExpire = 5 // 账号过期被踢下线
|
||||
UserIdleTimeout = 6 // 用户空闲链接超时
|
||||
UserLogoutOneAdmin = 7 // 账号被管理员一键下线
|
||||
|
||||
)
|
||||
|
||||
type UserActLogProcess struct {
|
||||
|
@ -64,6 +66,7 @@ var (
|
|||
UserLogoutAdmin: "账号被管理员踢下线",
|
||||
UserLogoutExpire: "账号过期被踢下线",
|
||||
UserIdleTimeout: "用户空闲链接超时",
|
||||
UserLogoutOneAdmin: "账号被管理员一键下线",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -126,6 +129,9 @@ func (ua *UserActLogProcess) GetStatusOpsWithTag() interface{} {
|
|||
}
|
||||
|
||||
func (ua *UserActLogProcess) GetInfoOpsById(id uint8) string {
|
||||
if int(id) >= len(ua.InfoOps) {
|
||||
return "未知的信息类型"
|
||||
}
|
||||
return ua.InfoOps[id]
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"net"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/bjdgyc/anylink/pkg/utils"
|
||||
|
@ -42,33 +43,74 @@ func (o Onlines) Swap(i, j int) {
|
|||
}
|
||||
|
||||
func OnlineSess() []Online {
|
||||
return GetOnlineSess("", "", false)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: GetOnlineSess
|
||||
* @param search_cate 分类:用户名、登录组、MAC地址、IP地址、远端地址
|
||||
* @param search_text 关键字,模糊搜索
|
||||
* @param show_sleeper 是否显示休眠用户
|
||||
* @return []Online
|
||||
*/
|
||||
func GetOnlineSess(search_cate string, search_text string, show_sleeper bool) []Online {
|
||||
var datas Onlines
|
||||
if strings.TrimSpace(search_text) == "" {
|
||||
search_cate = ""
|
||||
}
|
||||
sessMux.Lock()
|
||||
defer sessMux.Unlock()
|
||||
for _, v := range sessions {
|
||||
v.mux.Lock()
|
||||
if v.IsActive {
|
||||
cSess := v.CSess
|
||||
if cSess == nil {
|
||||
cSess = &ConnSession{}
|
||||
}
|
||||
// 选择需要比较的字符串
|
||||
var compareText string
|
||||
switch search_cate {
|
||||
case "username":
|
||||
compareText = v.Username
|
||||
case "group":
|
||||
compareText = v.Group
|
||||
case "mac_addr":
|
||||
compareText = v.MacAddr
|
||||
case "ip":
|
||||
if cSess != nil {
|
||||
compareText = cSess.IpAddr.String()
|
||||
}
|
||||
case "remote_addr":
|
||||
if cSess != nil {
|
||||
compareText = cSess.RemoteAddr
|
||||
}
|
||||
}
|
||||
if search_cate != "" && !strings.Contains(compareText, search_text) {
|
||||
v.mux.Unlock()
|
||||
continue
|
||||
}
|
||||
|
||||
if show_sleeper || v.IsActive {
|
||||
val := Online{
|
||||
Token: v.Token,
|
||||
Ip: v.CSess.IpAddr,
|
||||
Ip: cSess.IpAddr,
|
||||
Username: v.Username,
|
||||
Group: v.Group,
|
||||
MacAddr: v.MacAddr,
|
||||
UniqueMac: v.UniqueMac,
|
||||
RemoteAddr: v.CSess.RemoteAddr,
|
||||
TunName: v.CSess.IfName,
|
||||
Mtu: v.CSess.Mtu,
|
||||
Client: v.CSess.Client,
|
||||
BandwidthUp: utils.HumanByte(v.CSess.BandwidthUpPeriod.Load()) + "/s",
|
||||
BandwidthDown: utils.HumanByte(v.CSess.BandwidthDownPeriod.Load()) + "/s",
|
||||
BandwidthUpAll: utils.HumanByte(v.CSess.BandwidthUpAll.Load()),
|
||||
BandwidthDownAll: utils.HumanByte(v.CSess.BandwidthDownAll.Load()),
|
||||
RemoteAddr: cSess.RemoteAddr,
|
||||
TunName: cSess.IfName,
|
||||
Mtu: cSess.Mtu,
|
||||
Client: cSess.Client,
|
||||
BandwidthUp: utils.HumanByte(cSess.BandwidthUpPeriod.Load()) + "/s",
|
||||
BandwidthDown: utils.HumanByte(cSess.BandwidthDownPeriod.Load()) + "/s",
|
||||
BandwidthUpAll: utils.HumanByte(cSess.BandwidthUpAll.Load()),
|
||||
BandwidthDownAll: utils.HumanByte(cSess.BandwidthDownAll.Load()),
|
||||
LastLogin: v.LastLogin,
|
||||
}
|
||||
datas = append(datas, val)
|
||||
}
|
||||
v.mux.Unlock()
|
||||
}
|
||||
sessMux.Unlock()
|
||||
sort.Sort(&datas)
|
||||
return datas
|
||||
}
|
||||
|
|
|
@ -464,7 +464,7 @@ func CloseSess(token string, code ...uint8) {
|
|||
sess.CSess.Close()
|
||||
return
|
||||
}
|
||||
AddUserActLogBySess(sess)
|
||||
AddUserActLogBySess(sess, code...)
|
||||
}
|
||||
|
||||
func CloseCSess(token string) {
|
||||
|
@ -501,7 +501,7 @@ func AddUserActLog(cs *ConnSession) {
|
|||
dbdata.UserActLogIns.Add(ua, cs.UserAgent)
|
||||
}
|
||||
|
||||
func AddUserActLogBySess(sess *Session) {
|
||||
func AddUserActLogBySess(sess *Session, code ...uint8) {
|
||||
ua := dbdata.UserActLog{
|
||||
Username: sess.Username,
|
||||
GroupName: sess.Group,
|
||||
|
@ -512,5 +512,8 @@ func AddUserActLogBySess(sess *Session) {
|
|||
Status: dbdata.UserLogout,
|
||||
}
|
||||
ua.Info = dbdata.UserActLogIns.GetInfoOpsById(dbdata.UserLogoutBanner)
|
||||
if len(code) > 0 {
|
||||
ua.Info = dbdata.UserActLogIns.GetInfoOpsById(code[0])
|
||||
}
|
||||
dbdata.UserActLogIns.Add(ua, sess.UserAgent)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,59 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form :inline="true">
|
||||
<el-form-item>
|
||||
<el-select
|
||||
v-model="searchCate"
|
||||
style="width: 86px;"
|
||||
@change="handleSearch">
|
||||
<el-option
|
||||
label="用户名"
|
||||
value="username">
|
||||
</el-option>
|
||||
<el-option
|
||||
label="登录组"
|
||||
value="group">
|
||||
</el-option>
|
||||
<el-option
|
||||
label="MAC地址"
|
||||
value="mac_addr">
|
||||
</el-option>
|
||||
<el-option
|
||||
label="IP地址"
|
||||
value="ip">
|
||||
</el-option>
|
||||
<el-option
|
||||
label="远端地址"
|
||||
value="remote_addr">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input
|
||||
v-model="searchText"
|
||||
placeholder="请输入搜索内容"
|
||||
@input="handleSearch">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
显示休眠用户:
|
||||
<el-switch
|
||||
v-model="showSleeper"
|
||||
@change="handleSearch">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="extra-small-button"
|
||||
type="danger"
|
||||
size="mini"
|
||||
:loading="loadingOneOffline"
|
||||
@click="handleOneOffline">
|
||||
一键下线
|
||||
</el-button>
|
||||
</el-form>
|
||||
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
:data="tableData"
|
||||
|
@ -20,7 +73,7 @@
|
|||
|
||||
<el-table-column
|
||||
prop="group"
|
||||
label="登陆组">
|
||||
label="登录组">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
|
@ -67,7 +120,6 @@
|
|||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="status"
|
||||
label="实时 上行/下行"
|
||||
width="220">
|
||||
<template slot-scope="scope">
|
||||
|
@ -77,7 +129,6 @@
|
|||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="status"
|
||||
label="总量 上行/下行"
|
||||
width="200">
|
||||
<template slot-scope="scope">
|
||||
|
@ -88,7 +139,7 @@
|
|||
|
||||
<el-table-column
|
||||
prop="last_login"
|
||||
label="登陆时间"
|
||||
label="登录时间"
|
||||
:formatter="tableDateFormat">
|
||||
</el-table-column>
|
||||
|
||||
|
@ -99,6 +150,7 @@
|
|||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
v-if="scope.row.remote_addr !== ''"
|
||||
@click="handleReline(scope.row)">重连
|
||||
</el-button>
|
||||
|
||||
|
@ -123,6 +175,7 @@
|
|||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { MessageBox } from 'element-ui';
|
||||
|
||||
export default {
|
||||
name: "Online",
|
||||
|
@ -147,6 +200,10 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
searchCate: 'username',
|
||||
searchText: '',
|
||||
showSleeper: false,
|
||||
loadingOneOffline: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -185,8 +242,43 @@ export default {
|
|||
handleEdit(a, row) {
|
||||
console.log(a, row)
|
||||
},
|
||||
handleOneOffline() {
|
||||
if (this.tableData === null || this.tableData.length === 0) {
|
||||
this.$message.error('错误:当前在线用户表为空,无法执行一键下线操作!');
|
||||
return;
|
||||
}
|
||||
MessageBox.confirm('当前搜索条件下的所有用户将会“下线”,你确定执行吗?', '危险', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'danger'
|
||||
}).then(() => {
|
||||
try {
|
||||
this.loadingOneOffline = true;
|
||||
this.getData();
|
||||
this.$message.success('操作成功');
|
||||
this.loadingOneOffline = false;
|
||||
// 清空当前表格
|
||||
this.tableData = [];
|
||||
} catch (error) {
|
||||
this.loadingOneOffline = false;
|
||||
this.$message.error('操作失败');
|
||||
}
|
||||
});
|
||||
},
|
||||
handleSearch() {
|
||||
this.getData();
|
||||
},
|
||||
getData() {
|
||||
axios.get('/user/online').then(resp => {
|
||||
axios.get('/user/online',
|
||||
{
|
||||
params: {
|
||||
search_cate: this.searchCate,
|
||||
search_text: this.searchText,
|
||||
show_sleeper: this.showSleeper,
|
||||
one_offline: this.loadingOneOffline
|
||||
}
|
||||
}
|
||||
).then(resp => {
|
||||
var data = resp.data.data
|
||||
console.log(data);
|
||||
this.tableData = data.datas;
|
||||
|
@ -201,5 +293,23 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
/deep/ .el-form .el-form-item__label,
|
||||
/deep/ .el-form .el-form-item__content,
|
||||
/deep/ .el-form .el-input,
|
||||
/deep/ .el-form .el-select,
|
||||
/deep/ .el-form .el-button,
|
||||
/deep/ .el-form .el-select-dropdown__item {
|
||||
font-size: 11px;
|
||||
}
|
||||
.el-select-dropdown .el-select-dropdown__item {
|
||||
font-size: 11px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
/deep/ .el-input__inner{
|
||||
height: 30px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.extra-small-button {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue