🔨 用户锁定列表.
This commit is contained in:
@@ -60,10 +60,31 @@ export interface UserQueryResponse extends TableData {
|
|||||||
roles: Array<RoleQueryResponse>;
|
roles: Array<RoleQueryResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁定用户查询响应
|
||||||
|
*/
|
||||||
|
export interface LockedUserQueryResponse {
|
||||||
|
username: string;
|
||||||
|
address: string;
|
||||||
|
location: string;
|
||||||
|
userAgent: string;
|
||||||
|
expireTime: number;
|
||||||
|
loginTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解锁用户请求
|
||||||
|
*/
|
||||||
|
export interface UserUnlockRequest {
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户会话查询响应
|
* 用户会话查询响应
|
||||||
*/
|
*/
|
||||||
export interface UserSessionQueryResponse {
|
export interface UserSessionQueryResponse {
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
current: boolean;
|
current: boolean;
|
||||||
address: string;
|
address: string;
|
||||||
@@ -183,10 +204,31 @@ export function batchDeleteUser(idList: Array<number>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户会话列表
|
* 获取锁定的用户列表
|
||||||
|
*/
|
||||||
|
export function getLockedUserList() {
|
||||||
|
return axios.get<Array<LockedUserQueryResponse>>('/infra/system-user/locked/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解锁锁定的用户
|
||||||
|
*/
|
||||||
|
export function unlockLockedUser(request: UserUnlockRequest) {
|
||||||
|
return axios.put('/infra/system-user/locked/unlock', request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取全部用户会话列表
|
||||||
|
*/
|
||||||
|
export function getUsersSessionList() {
|
||||||
|
return axios.get<Array<UserSessionQueryResponse>>('/infra/system-user/session/users/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个用户会话列表
|
||||||
*/
|
*/
|
||||||
export function getUserSessionList(id: number) {
|
export function getUserSessionList(id: number) {
|
||||||
return axios.get<Array<UserSessionQueryResponse>>('/infra/system-user/session/list', { params: { id } });
|
return axios.get<Array<UserSessionQueryResponse>>('/infra/system-user/session/user/list', { params: { id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
137
orion-visor-ui/src/views/user/locked-user/index.vue
Normal file
137
orion-visor-ui/src/views/user/locked-user/index.vue
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layout-container">
|
||||||
|
<!-- 表格 -->
|
||||||
|
<a-card class="general-card table-card">
|
||||||
|
<template #title>
|
||||||
|
<!-- 左侧操作 -->
|
||||||
|
<div class="table-left-bar-handle">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="table-title">
|
||||||
|
锁定用户列表
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 右侧操作 -->
|
||||||
|
<div class="table-right-bar-handle">
|
||||||
|
<a-button type="primary" @click="fetchTableData">
|
||||||
|
查询
|
||||||
|
<template #icon>
|
||||||
|
<icon-search />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- table -->
|
||||||
|
<a-table row-key="id"
|
||||||
|
ref="tableRef"
|
||||||
|
class="table-resize"
|
||||||
|
:loading="loading"
|
||||||
|
:columns="columns"
|
||||||
|
:data="tableRenderData"
|
||||||
|
:pagination="false"
|
||||||
|
:bordered="false"
|
||||||
|
:column-resizable="true">
|
||||||
|
<!-- 用户名 -->
|
||||||
|
<template #username="{ record }">
|
||||||
|
<div style="display: contents;">
|
||||||
|
<!-- 用户名 -->
|
||||||
|
<span class="text-copy" @click="copy(record.username, true)">
|
||||||
|
{{ record.username }}
|
||||||
|
</span>
|
||||||
|
<!-- 当前会话 -->
|
||||||
|
<a-tag v-if="record.current"
|
||||||
|
size="small"
|
||||||
|
class="ml8"
|
||||||
|
color="green">
|
||||||
|
当前
|
||||||
|
</a-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- 登录IP -->
|
||||||
|
<template #address="{ record }">
|
||||||
|
<div style="display: contents;">
|
||||||
|
<span class="text-copy mr4" @click="copy(record.address, true)">
|
||||||
|
{{ record.address }}
|
||||||
|
</span>
|
||||||
|
<span>({{ record.location }})</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- 操作 -->
|
||||||
|
<template #handle="{ record }">
|
||||||
|
<div class="table-handle-wrapper">
|
||||||
|
<!-- 删除 -->
|
||||||
|
<a-popconfirm content="确定要解锁当前用户吗?"
|
||||||
|
position="left"
|
||||||
|
type="warning"
|
||||||
|
@ok="unlockUser(record)">
|
||||||
|
<a-button v-if="!record.current"
|
||||||
|
v-permission="['infra:system-user:management:unlock']"
|
||||||
|
type="text"
|
||||||
|
size="mini"
|
||||||
|
status="danger">
|
||||||
|
解锁
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'userLockedUser'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { LockedUserQueryResponse } from '@/api/user/user';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import useLoading from '@/hooks/loading';
|
||||||
|
import columns from './types/table.columns';
|
||||||
|
import { copy } from '@/hooks/copy';
|
||||||
|
import { getLockedUserList, unlockLockedUser } from '@/api/user/user';
|
||||||
|
|
||||||
|
const { loading, setLoading } = useLoading();
|
||||||
|
|
||||||
|
const tableRenderData = ref<Array<LockedUserQueryResponse>>([]);
|
||||||
|
|
||||||
|
// 解锁用户
|
||||||
|
const unlockUser = async (record: LockedUserQueryResponse) => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
// 解锁用户
|
||||||
|
await unlockLockedUser({
|
||||||
|
username: record.username,
|
||||||
|
});
|
||||||
|
Message.success('操作成功');
|
||||||
|
// 查询数据
|
||||||
|
await fetchTableData();
|
||||||
|
} catch (e) {
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
const fetchTableData = async () => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const { data } = await getLockedUserList();
|
||||||
|
tableRenderData.value = data;
|
||||||
|
} catch (e) {
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchTableData();
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import type { TableColumnData } from '@arco-design/web-vue';
|
||||||
|
import { dateFormat } from '@/utils';
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '序号',
|
||||||
|
dataIndex: 'seq',
|
||||||
|
slotName: 'seq',
|
||||||
|
width: 100,
|
||||||
|
align: 'left',
|
||||||
|
fixed: 'left',
|
||||||
|
default: true,
|
||||||
|
render: ({ rowIndex }) => {
|
||||||
|
return rowIndex + 1;
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
title: '用户名',
|
||||||
|
dataIndex: 'username',
|
||||||
|
slotName: 'username',
|
||||||
|
width: 188,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true,
|
||||||
|
default: true,
|
||||||
|
}, {
|
||||||
|
title: '登录IP',
|
||||||
|
dataIndex: 'address',
|
||||||
|
slotName: 'address',
|
||||||
|
minWidth: 228,
|
||||||
|
default: true,
|
||||||
|
}, {
|
||||||
|
title: 'userAgent',
|
||||||
|
dataIndex: 'userAgent',
|
||||||
|
slotName: 'userAgent',
|
||||||
|
minWidth: 328,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true,
|
||||||
|
default: true,
|
||||||
|
}, {
|
||||||
|
title: '登录时间',
|
||||||
|
dataIndex: 'loginTime',
|
||||||
|
slotName: 'loginTime',
|
||||||
|
align: 'center',
|
||||||
|
width: 180,
|
||||||
|
render: ({ record }) => {
|
||||||
|
return dateFormat(new Date(record.loginTime));
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
}, {
|
||||||
|
title: '解锁时间',
|
||||||
|
dataIndex: 'expireTime',
|
||||||
|
slotName: 'expireTime',
|
||||||
|
align: 'center',
|
||||||
|
width: 180,
|
||||||
|
render: ({ record }) => {
|
||||||
|
return dateFormat(new Date(record.expireTime));
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
}, {
|
||||||
|
title: '操作',
|
||||||
|
slotName: 'handle',
|
||||||
|
width: 108,
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'right',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
] as TableColumnData[];
|
||||||
|
|
||||||
|
export default columns;
|
||||||
Reference in New Issue
Block a user