This commit is contained in:
扶桑花间 2025-08-27 20:10:28 +08:00
parent 28de61792e
commit 18d0d9fef9
2 changed files with 29 additions and 128 deletions

View File

@ -9,4 +9,5 @@ enum UserLoginEnum: int
case STATUS_DISABLED = 21; // 用户已被禁用 case STATUS_DISABLED = 21; // 用户已被禁用
case LOGIN_EXCEPTION = 31; // 登录异常 case LOGIN_EXCEPTION = 31; // 登录异常
case LOGIN_SUCCESS = 99; // 登录成功 case LOGIN_SUCCESS = 99; // 登录成功
case LOGIN_EXIT = 98; //退出登录
} }

View File

@ -13,19 +13,9 @@
:where="defaultWhere" :where="defaultWhere"
cache-key="systemLoginRecordTable" cache-key="systemLoginRecordTable"
> >
<template #toolbar>
<el-button
type="primary"
class="ele-btn-icon"
:icon="DownloadOutlined"
@click="exportData"
>
导出
</el-button>
</template>
<template #loginType="{ row }"> <template #loginType="{ row }">
<el-tag <el-tag
v-if="row.loginType === 0" v-if="row.loginType === 99"
size="small" size="small"
type="success" type="success"
:disable-transitions="true" :disable-transitions="true"
@ -33,15 +23,7 @@
登录成功 登录成功
</el-tag> </el-tag>
<el-tag <el-tag
v-else-if="row.loginType === 1" v-else-if="row.loginType === 98"
size="small"
type="danger"
:disable-transitions="true"
>
登录失败
</el-tag>
<el-tag
v-else-if="row.loginType === 2"
size="small" size="small"
type="info" type="info"
:disable-transitions="true" :disable-transitions="true"
@ -49,12 +31,12 @@
退出登录 退出登录
</el-tag> </el-tag>
<el-tag <el-tag
v-else-if="row.loginType === 3" v-else-if="[11, 12, 21, 31].indexOf(row.loginType) != -1"
size="small" size="small"
type="warning" type="danger"
:disable-transitions="true" :disable-transitions="true"
> >
刷新TOKEN 登录失败 - {{ row.loginType }}
</el-tag> </el-tag>
</template> </template>
</ele-pro-table> </ele-pro-table>
@ -64,19 +46,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive } from 'vue'; import { ref, reactive } from 'vue';
import { EleMessage } from 'ele-admin-plus';
import type { EleProTable } from 'ele-admin-plus'; import type { EleProTable } from 'ele-admin-plus';
import type { import type {
DatasourceFunction, DatasourceFunction,
Columns Columns
} from 'ele-admin-plus/es/ele-pro-table/types'; } from 'ele-admin-plus/es/ele-pro-table/types';
import ExcelJS from 'exceljs';
import { download } from '@/utils/common';
import { DownloadOutlined } from '@/components/icons';
import LoginRecordSearch from './components/login-record-search.vue'; import LoginRecordSearch from './components/login-record-search.vue';
import { import {
pageLoginRecords, pageLoginRecords,
listLoginRecords
} from '@/api/system/login-record'; } from '@/api/system/login-record';
import type { LoginRecordParam } from '@/api/system/login-record/model'; import type { LoginRecordParam } from '@/api/system/login-record/model';
@ -97,43 +74,31 @@
type: 'index', type: 'index',
columnKey: 'index', columnKey: 'index',
width: 50, width: 50,
align: 'center' /* , align: 'center'
fixed: 'left' */
}, },
{ {
prop: 'username', prop: 'username',
label: '账号', label: '账号',
sortable: 'custom', width: 160
minWidth: 110
},
{
prop: 'nickname',
label: '用户名',
sortable: 'custom',
minWidth: 110
}, },
{ {
prop: 'ip', prop: 'ip',
label: 'IP地址', label: 'IP地址',
sortable: 'custom', width: 170
minWidth: 110
}, },
{ {
prop: 'device', prop: 'device',
label: '设备型号', label: '设备型号',
sortable: 'custom',
minWidth: 110 minWidth: 110
}, },
{ {
prop: 'os', prop: 'os',
label: '操作系统', label: '操作系统',
sortable: 'custom',
minWidth: 110 minWidth: 110
}, },
{ {
prop: 'browser', prop: 'browser',
label: '浏览器', label: '浏览器',
sortable: 'custom',
minWidth: 110 minWidth: 110
}, },
{ {
@ -144,33 +109,38 @@
slot: 'loginType', slot: 'loginType',
filters: [ filters: [
{ {
text: '登录成功', text: '用户名错误',
value: '0' value: '11'
}, },
{ {
text: '登录失败', text: '密码错误',
value: '1' value: '12'
},
{
text: '用户已禁用',
value: '21'
},
{
text: '登录异常',
value: '31'
},
{
text: '登录成功',
value: '99'
}, },
{ {
text: '退出登录', text: '退出登录',
value: '2' value: '98'
},
{
text: '刷新TOKEN',
value: '3'
} }
], ],
filterMultiple: false, filterMultiple: false,
align: 'center', align: 'center'
formatter: (row) =>
['登录成功', '登录失败', '退出登录', '刷新TOKEN'][row.loginType]
}, },
{ {
prop: 'comments', prop: 'comments',
label: '备注', label: '备注',
sortable: 'custom', minWidth: 210,
minWidth: 110, align: 'left'
align: 'center'
}, },
{ {
prop: 'createTime', prop: 'createTime',
@ -195,74 +165,4 @@
const reload = (where?: LoginRecordParam) => { const reload = (where?: LoginRecordParam) => {
tableRef.value?.reload?.({ page: 1, where }); tableRef.value?.reload?.({ page: 1, where });
}; };
/** 导出数据 */
const exportData = () => {
//
const loading = EleMessage.loading({
message: '请求中..',
plain: true
});
tableRef.value?.fetch?.(({ where, orders, filters }) => {
listLoginRecords({ ...where, ...orders, ...filters })
.then((data) => {
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('Sheet1');
sheet.addRow([
'账号',
'用户名',
'IP地址',
'设备型号',
'操作系统',
'浏览器',
'操作类型',
'备注',
'登录时间'
]);
data.forEach((d) => {
sheet.addRow([
d.username,
d.nickname,
d.ip,
d.device,
d.os,
d.browser,
['登录成功', '登录失败', '退出登录', '刷新TOKEN'][d.loginType],
d.comments,
d.createTime
]);
});
//
[16, 16, 22, 22, 18, 20, 14, 16, 24].forEach((width, index) => {
sheet.getColumn(index + 1).width = width;
});
//
sheet.eachRow({ includeEmpty: true }, (row, rowIndex) => {
row.height = 20;
row.eachCell({ includeEmpty: true }, (cell) => {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
};
cell.alignment = {
vertical: 'middle',
horizontal: 'center'
};
cell.font = { size: 12, bold: rowIndex === 1 };
});
});
//
workbook.xlsx.writeBuffer().then((data) => {
download(data, '登录日志.xlsx');
loading.close();
});
})
.catch((e) => {
loading.close();
EleMessage.error({ message: e.message, plain: true });
});
});
};
</script> </script>