捕梦者基础前端框架
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

247 lines
5.6 KiB

<template>
<ele-page>
<login-record-search :where="defaultWhere" @search="reload" />
<ele-card :body-style="{ paddingTop: '8px' }">
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:show-overflow-tooltip="true"
:highlight-current-row="true"
:export-config="{ fileName: '登录日志数据' }"
:where="defaultWhere"
cache-key="systemLoginRecordTable"
>
<template #toolbar>
<el-button
type="primary"
class="ele-btn-icon"
:icon="DownloadOutlined"
@click="exportData"
>
导出
</el-button>
</template>
<template #loginType="{ row }">
<el-tag
v-if="row.loginType === 0"
size="small"
type="success"
:disable-transitions="true"
>
登录成功
</el-tag>
<el-tag
v-else-if="row.loginType === 1"
size="small"
type="danger"
:disable-transitions="true"
>
登录失败
</el-tag>
<el-tag
v-else-if="row.loginType === 2"
size="small"
type="info"
:disable-transitions="true"
>
退出登录
</el-tag>
<el-tag
v-else-if="row.loginType === 3"
size="small"
type="warning"
:disable-transitions="true"
>
刷新TOKEN
</el-tag>
</template>
</ele-pro-table>
</ele-card>
</ele-page>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { EleMessage } from 'ele-admin-plus/es';
import type { EleProTable } from 'ele-admin-plus';
import type {
DatasourceFunction,
Columns
} from 'ele-admin-plus/es/ele-pro-table/types';
import { utils, writeFile } from 'xlsx';
import { DownloadOutlined } from '@/components/icons';
import LoginRecordSearch from './components/login-record-search.vue';
import {
pageLoginRecords,
listLoginRecords
} from '@/api/system/login-record';
import type { LoginRecordParam } from '@/api/system/login-record/model';
/** 默认搜索条件 */
const defaultWhere = reactive({
username: '',
nickname: ''
});
/** 表格实例 */
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
/** 表格列配置 */
const columns = ref<Columns>([
{
type: 'index',
columnKey: 'index',
width: 50,
align: 'center',
fixed: 'left'
},
{
prop: 'username',
label: '账号',
sortable: 'custom',
minWidth: 110
},
{
prop: 'nickname',
label: '用户名',
sortable: 'custom',
minWidth: 110
},
{
prop: 'ip',
label: 'IP地址',
sortable: 'custom',
minWidth: 110
},
{
prop: 'device',
label: '设备型号',
sortable: 'custom',
minWidth: 110
},
{
prop: 'os',
label: '操作系统',
sortable: 'custom',
minWidth: 110
},
{
prop: 'browser',
label: '浏览器',
sortable: 'custom',
minWidth: 110
},
{
prop: 'loginType',
label: '操作类型',
sortable: 'custom',
width: 130,
slot: 'loginType',
filters: [
{
text: '登录成功',
value: '0'
},
{
text: '登录失败',
value: '1'
},
{
text: '退出登录',
value: '2'
},
{
text: '刷新TOKEN',
value: '3'
}
],
filterMultiple: false
},
{
prop: 'comments',
label: '备注',
sortable: 'custom',
minWidth: 110
},
{
prop: 'createTime',
label: '登录时间',
sortable: 'custom',
minWidth: 110
}
]);
/** 表格数据源 */
const datasource: DatasourceFunction = ({
pages,
where,
orders,
filters
}) => {
return pageLoginRecords({ ...where, ...orders, ...filters, ...pages });
};
/** 刷新表格 */
const reload = (where?: LoginRecordParam) => {
tableRef.value?.reload?.({ page: 1, where });
};
/** 导出数据 */
const exportData = () => {
const array = [
[
'账号',
'用户名',
'IP地址',
'设备型号',
'操作系统',
'浏览器',
'操作类型',
'备注',
'登录时间'
]
];
// 请求查询全部接口
const loading = EleMessage.loading('请求中..');
tableRef.value?.fetch?.(({ where, orders, filters }) => {
listLoginRecords({ ...where, ...orders, ...filters })
.then((data) => {
loading.close();
data.forEach((d) => {
array.push([
d.username,
d.nickname,
d.ip,
d.device,
d.os,
d.browser,
['登录成功', '登录失败', '退出登录', '刷新TOKEN'][d.loginType],
d.comments,
d.createTime
]);
});
writeFile(
{
SheetNames: ['Sheet1'],
Sheets: {
Sheet1: utils.aoa_to_sheet(array)
}
},
'登录日志.xlsx'
);
})
.catch((e) => {
loading.close();
EleMessage.error(e.message);
});
});
};
</script>
<script lang="ts">
export default {
name: 'SystemLoginRecord'
};
</script>