重构:重构在线用户前端代码
This commit is contained in:
parent
b32a298b62
commit
e2dd4e36c7
@ -1,5 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from "axios";
|
||||||
import qs from 'query-string';
|
import qs from "query-string";
|
||||||
|
|
||||||
|
const BASE_URL = "/monitor/online/user";
|
||||||
|
|
||||||
export interface OnlineUserRecord {
|
export interface OnlineUserRecord {
|
||||||
token: string;
|
token: string;
|
||||||
@ -11,25 +13,26 @@ export interface OnlineUserRecord {
|
|||||||
loginTime: string;
|
loginTime: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnlineUserParams extends Partial<OnlineUserRecord> {
|
export interface OnlineUserParam extends Partial<OnlineUserRecord> {
|
||||||
page: number;
|
page: number;
|
||||||
size: number;
|
size: number;
|
||||||
sort: Array<string>;
|
sort: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnlineUserListRes {
|
export interface OnlineUserListRes {
|
||||||
list: OnlineUserRecord[];
|
list: OnlineUserRecord[];
|
||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOnlineUserList(params: OnlineUserParams) {
|
export function listOnlineUser(params: OnlineUserParam) {
|
||||||
return axios.get<OnlineUserListRes>('/monitor/online/user', {
|
return axios.get<OnlineUserListRes>(BASE_URL, {
|
||||||
params,
|
params,
|
||||||
paramsSerializer: (obj) => {
|
paramsSerializer: (obj) => {
|
||||||
return qs.stringify(obj);
|
return qs.stringify(obj);
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function kickout(token: string) {
|
export function kickout(token: string) {
|
||||||
return axios.delete(`/monitor/online/user/${token}`);
|
return axios.delete(`${BASE_URL}/${token}`);
|
||||||
}
|
}
|
@ -1,11 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-range-picker
|
<a-range-picker
|
||||||
style="width: 100%"
|
:placeholder="placeholder"
|
||||||
:shortcuts="shortcuts"
|
|
||||||
shortcuts-position="left"
|
|
||||||
:format="format"
|
:format="format"
|
||||||
:show-time="showTime"
|
:show-time="showTime"
|
||||||
:placeholder="placeholder"
|
:shortcuts="shortcuts"
|
||||||
|
shortcuts-position="left"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -2,65 +2,85 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<Breadcrumb :items="['menu.monitor', 'menu.online.user.list']" />
|
<Breadcrumb :items="['menu.monitor', 'menu.online.user.list']" />
|
||||||
<a-card class="general-card" :title="$t('menu.online.user.list')">
|
<a-card class="general-card" :title="$t('menu.online.user.list')">
|
||||||
<a-row style="margin-bottom: 15px">
|
<!-- 头部区域 -->
|
||||||
<a-col :span="24">
|
<div class="head-container">
|
||||||
<a-form ref="queryFormRef" :model="queryFormData" layout="inline">
|
<!-- 搜索栏 -->
|
||||||
|
<div class="query-container">
|
||||||
|
<a-form ref="queryRef" :model="queryParams" layout="inline">
|
||||||
<a-form-item field="nickname" hide-label>
|
<a-form-item field="nickname" hide-label>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="queryFormData.nickname"
|
v-model="queryParams.nickname"
|
||||||
placeholder="输入用户昵称搜索"
|
placeholder="输入用户昵称搜索"
|
||||||
allow-clear
|
allow-clear
|
||||||
style="width: 150px;"
|
style="width: 150px;"
|
||||||
@press-enter="toQuery"
|
@press-enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item field="loginTime" hide-label>
|
<a-form-item field="loginTime" hide-label>
|
||||||
<date-range-picker v-model="queryFormData.loginTime" />
|
<date-range-picker v-model="queryParams.loginTime" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-button type="primary" @click="toQuery">
|
<a-form-item hide-label>
|
||||||
<template #icon>
|
<a-space>
|
||||||
<icon-search />
|
<a-button type="primary" @click="handleQuery">
|
||||||
</template>
|
<template #icon><icon-search /></template>查询
|
||||||
查询
|
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button @click="resetQuery">
|
<a-button @click="resetQuery">
|
||||||
<template #icon>
|
<template #icon><icon-refresh /></template>重置
|
||||||
<icon-refresh />
|
|
||||||
</template>
|
|
||||||
重置
|
|
||||||
</a-button>
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-col>
|
</div>
|
||||||
</a-row>
|
</div>
|
||||||
|
|
||||||
|
<!-- 列表区域 -->
|
||||||
<a-table
|
<a-table
|
||||||
:columns="columns"
|
ref="tableRef"
|
||||||
:data="renderData"
|
row-key="token"
|
||||||
:pagination="paginationProps"
|
:loading="loading"
|
||||||
row-key="logId"
|
:pagination="{
|
||||||
|
showTotal: true,
|
||||||
|
showPageSize: true,
|
||||||
|
total: total,
|
||||||
|
current: queryParams.page,
|
||||||
|
}"
|
||||||
|
:data="onlineUserList"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
:stripe="true"
|
:stripe="true"
|
||||||
:loading="loading"
|
|
||||||
size="large"
|
size="large"
|
||||||
@page-change="handlePageChange"
|
@page-change="handlePageChange"
|
||||||
@page-size-change="handlePageSizeChange"
|
@page-size-change="handlePageSizeChange"
|
||||||
>
|
>
|
||||||
<template #index="{ rowIndex }">
|
<template #columns>
|
||||||
{{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
|
<a-table-column title="序号">
|
||||||
|
<template #cell="{ rowIndex }">
|
||||||
|
{{ rowIndex + 1 + (queryParams.page - 1) * queryParams.size }}
|
||||||
</template>
|
</template>
|
||||||
<template #nickname="{ record }">
|
</a-table-column>
|
||||||
|
<a-table-column title="用户昵称">
|
||||||
|
<template #cell="{ record }">
|
||||||
{{ record.nickname }}({{record.username}})
|
{{ record.nickname }}({{record.username}})
|
||||||
</template>
|
</template>
|
||||||
<template #operations="{ record }">
|
</a-table-column>
|
||||||
|
<a-table-column title="登录 IP" data-index="clientIp" />
|
||||||
|
<a-table-column title="登录地点" data-index="location" />
|
||||||
|
<a-table-column title="浏览器" data-index="browser" />
|
||||||
|
<a-table-column title="登录时间" data-index="loginTime" />
|
||||||
|
<a-table-column title="操作" align="center">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<a-popconfirm content="确定要强退该用户吗?" type="warning" @ok="handleKickout(record.token)">
|
||||||
<a-button
|
<a-button
|
||||||
v-permission="['admin']"
|
v-permission="['admin']"
|
||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
:title="currentToken === record.token ? '不能强退当前登录' : ''"
|
|
||||||
:disabled="currentToken === record.token"
|
:disabled="currentToken === record.token"
|
||||||
@click="handleClick(record.token)"
|
:title="currentToken === record.token ? '不能强退当前登录用户' : ''"
|
||||||
>
|
>
|
||||||
强退
|
<template #icon><icon-delete /></template>强退
|
||||||
</a-button>
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</a-card>
|
</a-card>
|
||||||
@ -68,116 +88,94 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, reactive } from 'vue';
|
import { getCurrentInstance, ref, toRefs, reactive } from 'vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import {
|
||||||
import { Message } from '@arco-design/web-vue';
|
listOnlineUser,
|
||||||
import { getOnlineUserList, OnlineUserRecord, OnlineUserParams, kickout } from '@/api/monitor/online';
|
OnlineUserRecord,
|
||||||
import { Pagination } from '@/types/global';
|
OnlineUserParam,
|
||||||
import { PaginationProps } from '@arco-design/web-vue';
|
kickout
|
||||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
} from '@/api/monitor/online';
|
||||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
|
|
||||||
const { loading, setLoading } = useLoading(true);
|
const { proxy } = getCurrentInstance() as any;
|
||||||
const currentToken = computed(() => getToken());
|
|
||||||
const queryFormRef = ref<FormInstance>();
|
|
||||||
const queryFormData = ref({
|
|
||||||
nickname: '',
|
|
||||||
loginTime: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 查询
|
const onlineUserList = ref<OnlineUserRecord[]>([]);
|
||||||
const toQuery = () => {
|
const total = ref(0);
|
||||||
fetchData({
|
const loading = ref(false);
|
||||||
page: pagination.current,
|
const currentToken = getToken();
|
||||||
size: pagination.pageSize,
|
|
||||||
|
const data = reactive({
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
nickname: undefined,
|
||||||
|
loginTime: undefined,
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
sort: ['createTime,desc'],
|
sort: ['createTime,desc'],
|
||||||
...queryFormData.value,
|
},
|
||||||
} as unknown as OnlineUserParams);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const resetQuery = async () => {
|
|
||||||
await queryFormRef.value?.resetFields();
|
|
||||||
await fetchData();
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderData = ref<OnlineUserRecord[]>([]);
|
|
||||||
const basePagination: Pagination = {
|
|
||||||
current: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
};
|
|
||||||
const pagination = reactive({
|
|
||||||
...basePagination,
|
|
||||||
});
|
});
|
||||||
const paginationProps = computed((): PaginationProps => {
|
const { queryParams } = toRefs(data);
|
||||||
return {
|
|
||||||
showTotal: true,
|
|
||||||
showPageSize: true,
|
|
||||||
total: pagination.total,
|
|
||||||
current: pagination.current,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const columns = computed<TableColumnData[]>(() => [
|
|
||||||
{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'index',
|
|
||||||
slotName: 'index',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '用户昵称',
|
|
||||||
dataIndex: 'nickname',
|
|
||||||
slotName: 'nickname',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '登录 IP',
|
|
||||||
dataIndex: 'clientIp',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '登录地点',
|
|
||||||
dataIndex: 'location',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '浏览器',
|
|
||||||
dataIndex: 'browser',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '登录时间',
|
|
||||||
dataIndex: 'loginTime',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
slotName: 'operations',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 分页查询列表
|
/**
|
||||||
const fetchData = async (
|
* 查询列表
|
||||||
params: OnlineUserParams = { page: 1, size: 10, sort: ['createTime,desc'] }
|
*
|
||||||
) => {
|
* @param params 查询参数
|
||||||
setLoading(true);
|
*/
|
||||||
try {
|
const getList = (params: OnlineUserParam = { ...queryParams.value }) => {
|
||||||
const { data } = await getOnlineUserList(params);
|
loading.value = true;
|
||||||
renderData.value = data.list;
|
listOnlineUser(params).then((res) => {
|
||||||
pagination.current = params.page;
|
onlineUserList.value = res.data.list;
|
||||||
pagination.total = data.total;
|
total.value = res.data.total;
|
||||||
} finally {
|
loading.value = false;
|
||||||
setLoading(false);
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
getList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 强退
|
||||||
|
*
|
||||||
|
* @param token Token
|
||||||
|
*/
|
||||||
|
const handleKickout = (token: string) => {
|
||||||
|
kickout(token).then((res) => {
|
||||||
|
getList();
|
||||||
|
proxy.$message.success(res.msg);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询
|
||||||
|
*/
|
||||||
|
const handleQuery = () => {
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置
|
||||||
|
*/
|
||||||
|
const resetQuery = () => {
|
||||||
|
proxy.$refs.queryRef.resetFields();
|
||||||
|
handleQuery();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换页码
|
||||||
|
*
|
||||||
|
* @param current 页码
|
||||||
|
*/
|
||||||
const handlePageChange = (current: number) => {
|
const handlePageChange = (current: number) => {
|
||||||
fetchData({ page: current, size: pagination.pageSize, sort: ['createTime,desc'] });
|
queryParams.value.page = current;
|
||||||
|
getList();
|
||||||
};
|
};
|
||||||
const handlePageSizeChange = (pageSize: number) => {
|
|
||||||
fetchData({ page: pagination.current, size: pageSize, sort: ['createTime,desc'] });
|
|
||||||
};
|
|
||||||
fetchData();
|
|
||||||
|
|
||||||
// 强退
|
/**
|
||||||
const handleClick = async (token: string) => {
|
* 切换每页条数
|
||||||
const res = await kickout(token);
|
*
|
||||||
if (res.success) Message.success(res.msg);
|
* @param pageSize 每页条数
|
||||||
|
*/
|
||||||
|
const handlePageSizeChange = (pageSize: number) => {
|
||||||
|
queryParams.value.size = pageSize;
|
||||||
|
getList();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -190,6 +188,9 @@
|
|||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.container {
|
.container {
|
||||||
padding: 0 20px 20px 20px;
|
padding: 0 20px 20px 20px;
|
||||||
|
.head-container {
|
||||||
|
margin-bottom: 16px
|
||||||
|
}
|
||||||
}
|
}
|
||||||
:deep(.arco-table-th) {
|
:deep(.arco-table-th) {
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
Loading…
Reference in New Issue
Block a user