Files
wireguard-dashboard/web/src/views/workbench/index.vue
coward fa04d9c83a
All checks were successful
continuous-integration/drone/tag Build is passing
:art:首页控制面板的客户端链接列表新增右键刷新
2024-10-10 15:03:57 +08:00

298 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<AppPage :show-footer="true">
<div class="flex">
<n-card class="w-30%">
<div class="flex items-center">
<n-avatar round :size="60" :src="userStore.avatar" />
<div class="ml-20 flex-col">
<span class="text-20 opacity-80">Hello, {{ userStore.nickname }}</span>
<span class="mt-4 opacity-50">今日事今日毕</span>
</div>
</div>
<p class="mt-40 text-14 opacity-60">{{ dailyPoetry.content || '莫向外求,但从心觅,行有不得,反求诸己。' }}</p>
<p class="mt-32 text-right text-12 opacity-40"> {{ dailyPoetry.author || '佚名' }}</p>
</n-card>
<n-card class="ml-12 w-70%">
<n-data-table
remote
:columns="tableColumns"
:data="tableData.data"
:pagination="paginate"
/>
</n-card>
</div>
<n-card>
<n-data-table
remote
:columns="connectionsColumns"
:data="connectionsData.data"
:row-props="rowProps"
/>
<n-dropdown
placement="bottom-start"
trigger="manual"
size="small"
:x="xRef"
:y="yRef"
:options="rightMenuOpts"
@select="rowSelect"
@clickoutside="rowClick"
:show="showDropdownRef"
/>
</n-card>
</AppPage>
</template>
<script setup>
import { useUserStore } from '@/store'
import api from '@/views/workbench/api'
import { debounce, renderIcon } from '@/utils'
import { NTag } from 'naive-ui'
const userStore = useUserStore()
// 表格表头
const tableColumns = [
{
title: '用户名称',
key: 'username',
align: 'center',
titleAlign: 'center'
},
{
title: '客户端IP',
key: 'clientIP',
align: 'center',
titleAlign: 'center'
},
{
title: '请求方法',
key: 'method',
align: 'center',
titleAlign: 'center'
},
{
title: '请求主机',
key: 'host',
align: 'center',
titleAlign: 'center'
},
{
title: '请求地址',
key: 'uri',
align: 'center',
titleAlign: 'center'
},
{
title: '状态码',
key: 'statusCode',
align: 'center',
titleAlign: 'center'
},
{
title: '请求时间',
key: 'createdAt',
align: 'center',
titleAlign: 'center'
},
]
// 链接信息列表
const connectionsColumns = [
{
title: '客户端名称',
key: 'name',
align: 'center',
titleAlign: 'center'
},
{
title: '联系邮箱',
key: 'email',
align: 'center',
titleAlign: 'center'
},
{
title: '客户端IP',
key: 'ipAllocation',
align: 'center',
titleAlign: 'center'
},
{
title: '端点',
key: 'connectEndpoint',
align: 'center',
titleAlign: 'center'
},
{
title: '是否在线',
key: 'online',
align: 'center',
titleAlign: 'center',
render: (row) => {
switch (row.online) {
case true:
return h(NTag,{
type: 'info',
},{
default: () => '在线'
})
case false:
return h(NTag,{
type: 'warning',
},{
default: () => '离线'
})
}
}
},
{
title: '接受流量',
key: 'receiveBytes',
align: 'center',
titleAlign: 'center'
},
{
title: '传输流量',
key: 'transmitBytes',
align: 'center',
titleAlign: 'center'
},
{
title: '最后握手时间',
key: 'lastHandAt',
align: 'center',
titleAlign: 'center'
}
]
// 链接列表邮件刷新菜单
const rightMenuOpts = [
{
label: () => h('span',{ style: { color: 'green' }}, '刷新'),
key: "refresh",
icon: renderIcon('tabler:refresh',{ size: 14 })
}
]
// 右键菜单的设置
const showDropdownRef = ref(false);
const xRef = ref(0);
const yRef = ref(0);
// 右键菜单的基本位置逻辑
function rowProps(row) {
return {
onContextmenu: (e) => {
// $message.info(JSON.stringify(row, null, 2));
e.preventDefault();
showDropdownRef.value = false;
nextTick().then(() => {
showDropdownRef.value = true;
xRef.value = e.clientX;
yRef.value = e.clientY;
});
}
};
}
// 右键菜单的逻辑
function rowSelect(row) {
switch (row) {
case "refresh":
getClientConnections()
showDropdownRef.value = false
}
}
function rowClick() {
showDropdownRef.value = false
}
// 表格数据
const tableData = ref({
data: []
})
// 链接数据
const connectionsData = ref({
data: []
})
const dailyPoetry = ref({
author: '',
content: ''
})
// 页码控件
const paginate = reactive({
page: 1,
pageSize: 2,
itemCount: 0,
pageCount: 0,
onChange: (page) => {
paginate.page = page;
getLogsList()
}
})
// 获取操作日志列表
async function getLogsList() {
try {
const res = await api.logsList({
current: paginate.page,
size: paginate.pageSize,
})
if (res.data.code === 200) {
tableData.value.data = res.data.data.records;
paginate.itemCount = res.data.data.total;
paginate.pageCount = res.data.data.totalPage;
}
}catch (error) {
return error
}
}
// 每日诗词
const dailyPoe = debounce(() => {
getDailyPoetry()
},800)
// 获取每日诗词
function getDailyPoetry() {
try {
api.dailyPoetry().then(res => {
if (res.data.code === 200) {
dailyPoetry.value.author = res.data.data.author;
dailyPoetry.value.content = res.data.data.content;
}
})
}catch (error) {
return error
}
}
const connectionList = debounce(() => {
getClientConnections()
},300)
// 获取客户端链接列表
async function getClientConnections() {
try {
const res = await api.clientConnections()
if (res.data.code === 200) {
connectionsData.value.data = res.data.data;
}
}catch (e) {
return e
}
}
const initFunc = debounce(() => {
getClientConnections()
// dailyPoe()
// connectionList()
},500)
getLogsList()
initFunc()
</script>