优化:聚合日志相关 API,封装 date-range-picker 组件并优化部分细节
This commit is contained in:
parent
d8debf5481
commit
8cf15fd4a8
@ -45,6 +45,8 @@ export default function configStyleImportPlugin() {
|
|||||||
'option',
|
'option',
|
||||||
'optgroup',
|
'optgroup',
|
||||||
'icon',
|
'icon',
|
||||||
|
'dsubmenu',
|
||||||
|
'dgroup',
|
||||||
];
|
];
|
||||||
// List of components that need to map imported styles
|
// List of components that need to map imported styles
|
||||||
// 需要映射引入样式的组件列表
|
// 需要映射引入样式的组件列表
|
||||||
|
99
continew-admin-ui/src/api/monitor/log.ts
Normal file
99
continew-admin-ui/src/api/monitor/log.ts
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
export interface LogRecord {
|
||||||
|
logId: string;
|
||||||
|
clientIp: string;
|
||||||
|
location: string;
|
||||||
|
browser: string;
|
||||||
|
createTime: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginLogRecord extends LogRecord {
|
||||||
|
description: string;
|
||||||
|
status: number;
|
||||||
|
errorMsg: string;
|
||||||
|
createUserString: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationLogRecord extends LogRecord {
|
||||||
|
description: string;
|
||||||
|
status: number;
|
||||||
|
errorMsg: string;
|
||||||
|
createUserString: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogRecord extends LogRecord {
|
||||||
|
statusCode: number;
|
||||||
|
requestMethod: string;
|
||||||
|
requestUrl: string;
|
||||||
|
elapsedTime: number;
|
||||||
|
exceptionDetail?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogDetailRecord extends SystemLogRecord {
|
||||||
|
requestHeaders: string;
|
||||||
|
requestBody: string;
|
||||||
|
responseHeaders: string;
|
||||||
|
responseBody: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginLogParams extends Partial<LoginLogRecord> {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
sort: Array<string>;
|
||||||
|
}
|
||||||
|
export interface LoginLogListRes {
|
||||||
|
list: LoginLogRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
export function queryLoginLogList(params: LoginLogParams) {
|
||||||
|
return axios.get<LoginLogListRes>('/monitor/log/login', {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OperationLogParams extends Partial<OperationLogRecord> {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
sort: Array<string>;
|
||||||
|
uid?: string;
|
||||||
|
}
|
||||||
|
export interface OperationLogListRes {
|
||||||
|
list: OperationLogRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
export function queryOperationLogList(params: OperationLogParams) {
|
||||||
|
return axios.get<OperationLogListRes>('/monitor/log/operation', {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogParams extends Partial<SystemLogRecord> {
|
||||||
|
page: number;
|
||||||
|
size: number;
|
||||||
|
sort: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemLogListRes {
|
||||||
|
list: SystemLogRecord[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
export function querySystemLogList(params: SystemLogParams) {
|
||||||
|
return axios.get<SystemLogListRes>('/monitor/log/system', {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function querySystemLogDetail(logId: string) {
|
||||||
|
return axios.get<SystemLogDetailRecord>(`/monitor/log/system/${logId}`);
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import qs from 'query-string';
|
|
||||||
|
|
||||||
export interface LoginLogRecord {
|
|
||||||
logId: string;
|
|
||||||
status: number;
|
|
||||||
clientIp: string;
|
|
||||||
location: string;
|
|
||||||
browser: string;
|
|
||||||
errorMsg: string;
|
|
||||||
createUserString: string;
|
|
||||||
createTime: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LoginLogParams extends Partial<LoginLogRecord> {
|
|
||||||
page: number;
|
|
||||||
size: number;
|
|
||||||
sort: Array<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LoginLogListRes {
|
|
||||||
list: LoginLogRecord[];
|
|
||||||
total: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function queryLoginLogList(params: LoginLogParams) {
|
|
||||||
return axios.get<LoginLogListRes>('/monitor/log/login', {
|
|
||||||
params,
|
|
||||||
paramsSerializer: (obj) => {
|
|
||||||
return qs.stringify(obj);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import qs from 'query-string';
|
|
||||||
|
|
||||||
export interface OperationLogRecord {
|
|
||||||
logId: string;
|
|
||||||
description: string;
|
|
||||||
status: number;
|
|
||||||
clientIp: string;
|
|
||||||
location: string;
|
|
||||||
browser: string;
|
|
||||||
errorMsg: string;
|
|
||||||
createUserString: string;
|
|
||||||
createTime: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OperationLogParams extends Partial<OperationLogRecord> {
|
|
||||||
page: number;
|
|
||||||
size: number;
|
|
||||||
sort: Array<string>;
|
|
||||||
uid?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OperationLogListRes {
|
|
||||||
list: OperationLogRecord[];
|
|
||||||
total: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function queryOperationLogList(params: OperationLogParams) {
|
|
||||||
return axios.get<OperationLogListRes>('/monitor/log/operation', {
|
|
||||||
params,
|
|
||||||
paramsSerializer: (obj) => {
|
|
||||||
return qs.stringify(obj);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import qs from 'query-string';
|
|
||||||
|
|
||||||
export interface SystemLogRecord {
|
|
||||||
logId: string;
|
|
||||||
statusCode: number;
|
|
||||||
requestMethod: string;
|
|
||||||
requestUrl: string;
|
|
||||||
elapsedTime: number;
|
|
||||||
clientIp: string;
|
|
||||||
location: string;
|
|
||||||
browser: string;
|
|
||||||
errorMsg: string;
|
|
||||||
exceptionDetail?: string;
|
|
||||||
createUserString: string;
|
|
||||||
createTime: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SystemLogParams extends Partial<SystemLogRecord> {
|
|
||||||
page: number;
|
|
||||||
size: number;
|
|
||||||
sort: Array<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SystemLogListRes {
|
|
||||||
list: SystemLogRecord[];
|
|
||||||
total: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function querySystemLogList(params: SystemLogParams) {
|
|
||||||
return axios.get<SystemLogListRes>('/monitor/log/system', {
|
|
||||||
params,
|
|
||||||
paramsSerializer: (obj) => {
|
|
||||||
return qs.stringify(obj);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SystemLogDetailRecord {
|
|
||||||
logId: string;
|
|
||||||
description: string;
|
|
||||||
requestUrl: string;
|
|
||||||
requestMethod: string;
|
|
||||||
requestHeaders: string;
|
|
||||||
requestBody: string;
|
|
||||||
statusCode: number;
|
|
||||||
responseHeaders: string;
|
|
||||||
responseBody: string;
|
|
||||||
elapsedTime: number;
|
|
||||||
clientIp: string;
|
|
||||||
location: string;
|
|
||||||
browser: string;
|
|
||||||
createUserString: string;
|
|
||||||
createTime: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function querySystemLogDetail(logId: string) {
|
|
||||||
return axios.get<SystemLogDetailRecord>(`/monitor/log/system/${logId}`);
|
|
||||||
}
|
|
79
continew-admin-ui/src/components/date-range-picker/index.vue
Normal file
79
continew-admin-ui/src/components/date-range-picker/index.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<a-range-picker
|
||||||
|
style="width: 100%"
|
||||||
|
:shortcuts="shortcuts"
|
||||||
|
shortcuts-position="left"
|
||||||
|
:format="format"
|
||||||
|
:show-time="showTime"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, PropType } from 'vue';
|
||||||
|
import { ShortcutType } from '@arco-design/web-vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
format: {
|
||||||
|
type: String,
|
||||||
|
default: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
},
|
||||||
|
showTime: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: Array as PropType<string[]>,
|
||||||
|
default: (): string[] => ['开始时间', '结束时间'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const shortcuts = computed<ShortcutType[]>(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: '今天',
|
||||||
|
value: (): Date[] => [
|
||||||
|
dayjs().startOf('day').toDate(),
|
||||||
|
dayjs().toDate()
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '昨天',
|
||||||
|
value: (): Date[] => [
|
||||||
|
dayjs().subtract(1, 'day').startOf('day').toDate(),
|
||||||
|
dayjs().subtract(1, 'day').endOf('day').toDate()
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '本周',
|
||||||
|
value: (): Date[] => [
|
||||||
|
dayjs().startOf('week').add(1, 'day').toDate(),
|
||||||
|
dayjs().toDate()
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '本月',
|
||||||
|
value: (): Date[] => [
|
||||||
|
dayjs().startOf('month').toDate(),
|
||||||
|
dayjs().toDate()
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '本年',
|
||||||
|
value: (): Date[] => [
|
||||||
|
dayjs().startOf('year').toDate(),
|
||||||
|
dayjs().toDate()
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DateRangePicker',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less"></style>
|
@ -11,6 +11,7 @@ import {
|
|||||||
} from 'echarts/components';
|
} from 'echarts/components';
|
||||||
import Chart from './chart/index.vue';
|
import Chart from './chart/index.vue';
|
||||||
import Breadcrumb from './breadcrumb/index.vue';
|
import Breadcrumb from './breadcrumb/index.vue';
|
||||||
|
import DateRangePicker from './date-range-picker/index.vue';
|
||||||
|
|
||||||
// Manually introduce ECharts modules to reduce packing size
|
// Manually introduce ECharts modules to reduce packing size
|
||||||
|
|
||||||
@ -31,5 +32,6 @@ export default {
|
|||||||
install(Vue: App) {
|
install(Vue: App) {
|
||||||
Vue.component('Chart', Chart);
|
Vue.component('Chart', Chart);
|
||||||
Vue.component('Breadcrumb', Breadcrumb);
|
Vue.component('Breadcrumb', Breadcrumb);
|
||||||
|
Vue.component('DateRangePicker', DateRangePicker);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -25,12 +25,7 @@
|
|||||||
field="createTime"
|
field="createTime"
|
||||||
hide-label
|
hide-label
|
||||||
>
|
>
|
||||||
<a-range-picker
|
<date-range-picker v-model="queryFormData.createTime" />
|
||||||
v-model="queryFormData.createTime"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
show-time
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-button type="primary" @click="toQuery">
|
<a-button type="primary" @click="toQuery">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -85,7 +80,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, reactive } from 'vue';
|
import { computed, ref, reactive } from 'vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { queryLoginLogList, LoginLogRecord, LoginLogParams } from '@/api/monitor/login-log';
|
import { queryLoginLogList, LoginLogRecord, LoginLogParams } from '@/api/monitor/log';
|
||||||
import { Pagination } from '@/types/global';
|
import { Pagination } from '@/types/global';
|
||||||
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
||||||
@ -135,9 +130,10 @@
|
|||||||
title: '登录状态',
|
title: '登录状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
slotName: 'status',
|
slotName: 'status',
|
||||||
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '登录IP',
|
title: '登录 IP',
|
||||||
dataIndex: 'clientIp',
|
dataIndex: 'clientIp',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -153,6 +149,8 @@
|
|||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
const fetchData = async (
|
const fetchData = async (
|
||||||
params: LoginLogParams = { page: 1, size: 10, sort: ['createTime,desc'] }
|
params: LoginLogParams = { page: 1, size: 10, sort: ['createTime,desc'] }
|
||||||
) => {
|
) => {
|
||||||
@ -162,8 +160,6 @@
|
|||||||
renderData.value = data.list;
|
renderData.value = data.list;
|
||||||
pagination.current = params.page;
|
pagination.current = params.page;
|
||||||
pagination.total = data.total;
|
pagination.total = data.total;
|
||||||
} catch (err) {
|
|
||||||
// you can report use errorHandler or other
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,7 @@
|
|||||||
field="createTime"
|
field="createTime"
|
||||||
hide-label
|
hide-label
|
||||||
>
|
>
|
||||||
<a-range-picker
|
<date-range-picker v-model="queryFormData.createTime" />
|
||||||
v-model="queryFormData.createTime"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
show-time
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-button type="primary" @click="toQuery">
|
<a-button type="primary" @click="toQuery">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -97,7 +92,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, reactive } from 'vue';
|
import { computed, ref, reactive } from 'vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { queryOperationLogList, OperationLogRecord, OperationLogParams } from '@/api/monitor/operation-log';
|
import { queryOperationLogList, OperationLogRecord, OperationLogParams } from '@/api/monitor/log';
|
||||||
import { Pagination } from '@/types/global';
|
import { Pagination } from '@/types/global';
|
||||||
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
import type { SelectOptionData } from '@arco-design/web-vue/es/select/interface';
|
||||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
||||||
@ -152,9 +147,10 @@
|
|||||||
title: '操作状态',
|
title: '操作状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
slotName: 'status',
|
slotName: 'status',
|
||||||
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作IP',
|
title: '操作 IP',
|
||||||
dataIndex: 'clientIp',
|
dataIndex: 'clientIp',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -166,6 +162,8 @@
|
|||||||
dataIndex: 'browser',
|
dataIndex: 'browser',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 查询列表
|
||||||
const fetchData = async (
|
const fetchData = async (
|
||||||
params: OperationLogParams = { page: 1, size: 10, sort: ['createTime,desc'] }
|
params: OperationLogParams = { page: 1, size: 10, sort: ['createTime,desc'] }
|
||||||
) => {
|
) => {
|
||||||
@ -175,8 +173,6 @@
|
|||||||
renderData.value = data.list;
|
renderData.value = data.list;
|
||||||
pagination.current = params.page;
|
pagination.current = params.page;
|
||||||
pagination.total = data.total;
|
pagination.total = data.total;
|
||||||
} catch (err) {
|
|
||||||
// you can report use errorHandler or other
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,7 @@
|
|||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form ref="queryFormRef" :model="queryFormData" layout="inline">
|
<a-form ref="queryFormRef" :model="queryFormData" layout="inline">
|
||||||
<a-form-item field="createTime" hide-label>
|
<a-form-item field="createTime" hide-label>
|
||||||
<a-range-picker
|
<date-range-picker v-model="queryFormData.createTime" />
|
||||||
v-model="queryFormData.createTime"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
show-time
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-button type="primary" @click="toQuery">
|
<a-button type="primary" @click="toQuery">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -88,7 +83,7 @@
|
|||||||
<template #title>日志详情</template>
|
<template #title>日志详情</template>
|
||||||
<div style="margin: 10px 0 0 10px">
|
<div style="margin: 10px 0 0 10px">
|
||||||
<a-descriptions title="基础信息" :column="2" bordered>
|
<a-descriptions title="基础信息" :column="2" bordered>
|
||||||
<a-descriptions-item label="客户端IP">
|
<a-descriptions-item label="客户端 IP">
|
||||||
<a-skeleton v-if="detailLoading" :animation="true">
|
<a-skeleton v-if="detailLoading" :animation="true">
|
||||||
<a-skeleton-line :widths="['200px']" :rows="1" />
|
<a-skeleton-line :widths="['200px']" :rows="1" />
|
||||||
</a-skeleton>
|
</a-skeleton>
|
||||||
@ -100,7 +95,7 @@
|
|||||||
</a-skeleton>
|
</a-skeleton>
|
||||||
<span v-else>{{ renderDetailData.browser }}</span>
|
<span v-else>{{ renderDetailData.browser }}</span>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="IP归属地">
|
<a-descriptions-item label="IP 归属地">
|
||||||
<a-skeleton v-if="detailLoading" :animation="true">
|
<a-skeleton v-if="detailLoading" :animation="true">
|
||||||
<a-skeleton-line :widths="['200px']" :rows="1" />
|
<a-skeleton-line :widths="['200px']" :rows="1" />
|
||||||
</a-skeleton>
|
</a-skeleton>
|
||||||
@ -149,7 +144,7 @@
|
|||||||
</a-skeleton>
|
</a-skeleton>
|
||||||
<span v-else>{{ renderDetailData.requestMethod }}</span>
|
<span v-else>{{ renderDetailData.requestMethod }}</span>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="请求URL" :span="2">
|
<a-descriptions-item label="请求 URL" :span="2">
|
||||||
<a-skeleton v-if="detailLoading" :animation="true">
|
<a-skeleton v-if="detailLoading" :animation="true">
|
||||||
<a-skeleton-line :rows="1" />
|
<a-skeleton-line :rows="1" />
|
||||||
</a-skeleton>
|
</a-skeleton>
|
||||||
@ -201,7 +196,6 @@
|
|||||||
<a-space v-else>
|
<a-space v-else>
|
||||||
<VueJsonPretty
|
<VueJsonPretty
|
||||||
v-if="renderDetailData.requestHeaders"
|
v-if="renderDetailData.requestHeaders"
|
||||||
:path="'res'"
|
|
||||||
:data="JSON.parse(renderDetailData.requestHeaders)"
|
:data="JSON.parse(renderDetailData.requestHeaders)"
|
||||||
:show-length="true" />
|
:show-length="true" />
|
||||||
<span v-else>无</span>
|
<span v-else>无</span>
|
||||||
@ -237,7 +231,7 @@
|
|||||||
querySystemLogList,
|
querySystemLogList,
|
||||||
SystemLogRecord,
|
SystemLogRecord,
|
||||||
SystemLogParams,
|
SystemLogParams,
|
||||||
} from '@/api/monitor/system-log';
|
} from '@/api/monitor/log';
|
||||||
import { Pagination } from '@/types/global';
|
import { Pagination } from '@/types/global';
|
||||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
||||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
import { FormInstance } from '@arco-design/web-vue/es/form';
|
||||||
@ -253,7 +247,6 @@
|
|||||||
const renderData = ref<SystemLogRecord[]>([]);
|
const renderData = ref<SystemLogRecord[]>([]);
|
||||||
const renderDetailData = ref<SystemLogDetailRecord>({
|
const renderDetailData = ref<SystemLogDetailRecord>({
|
||||||
logId: '',
|
logId: '',
|
||||||
description: '',
|
|
||||||
requestUrl: '',
|
requestUrl: '',
|
||||||
requestMethod: '',
|
requestMethod: '',
|
||||||
requestHeaders: '',
|
requestHeaders: '',
|
||||||
@ -265,7 +258,6 @@
|
|||||||
clientIp: '',
|
clientIp: '',
|
||||||
location: '',
|
location: '',
|
||||||
browser: '',
|
browser: '',
|
||||||
createUserString: '',
|
|
||||||
createTime: '',
|
createTime: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -290,22 +282,24 @@
|
|||||||
title: '状态码',
|
title: '状态码',
|
||||||
dataIndex: 'statusCode',
|
dataIndex: 'statusCode',
|
||||||
slotName: 'statusCode',
|
slotName: 'statusCode',
|
||||||
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '请求方式',
|
title: '请求方式',
|
||||||
dataIndex: 'requestMethod',
|
dataIndex: 'requestMethod',
|
||||||
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '请求URI',
|
title: '请求 URI',
|
||||||
dataIndex: 'requestUrl',
|
dataIndex: 'requestUrl',
|
||||||
slotName: 'requestUrl',
|
slotName: 'requestUrl',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '客户端IP',
|
title: '客户端 IP',
|
||||||
dataIndex: 'clientIp',
|
dataIndex: 'clientIp',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'IP归属地',
|
title: 'IP 归属地',
|
||||||
dataIndex: 'location',
|
dataIndex: 'location',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -316,6 +310,7 @@
|
|||||||
title: '请求耗时',
|
title: '请求耗时',
|
||||||
dataIndex: 'elapsedTime',
|
dataIndex: 'elapsedTime',
|
||||||
slotName: 'elapsedTime',
|
slotName: 'elapsedTime',
|
||||||
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
@ -324,6 +319,7 @@
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
slotName: 'operations',
|
slotName: 'operations',
|
||||||
|
align: 'center',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -42,10 +42,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, reactive } from "vue";
|
import { computed, ref, reactive } from 'vue';
|
||||||
import { useLoginStore } from '@/store';
|
import { useLoginStore } from '@/store';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { queryOperationLogList, OperationLogRecord, OperationLogParams } from '@/api/monitor/operation-log';
|
import { queryOperationLogList, OperationLogRecord, OperationLogParams } from '@/api/monitor/log';
|
||||||
import { Pagination } from '@/types/global';
|
import { Pagination } from '@/types/global';
|
||||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
||||||
|
|
||||||
@ -78,9 +78,10 @@
|
|||||||
title: '操作状态',
|
title: '操作状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
slotName: 'status',
|
slotName: 'status',
|
||||||
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作IP',
|
title: '操作 IP',
|
||||||
dataIndex: 'clientIp',
|
dataIndex: 'clientIp',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -31,35 +31,53 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import top.charles7c.cnadmin.common.model.query.PageQuery;
|
import top.charles7c.cnadmin.common.model.query.PageQuery;
|
||||||
import top.charles7c.cnadmin.common.model.vo.PageInfo;
|
import top.charles7c.cnadmin.common.model.vo.PageInfo;
|
||||||
import top.charles7c.cnadmin.common.model.vo.R;
|
import top.charles7c.cnadmin.common.model.vo.R;
|
||||||
|
import top.charles7c.cnadmin.monitor.model.query.LoginLogQuery;
|
||||||
|
import top.charles7c.cnadmin.monitor.model.query.OperationLogQuery;
|
||||||
import top.charles7c.cnadmin.monitor.model.query.SystemLogQuery;
|
import top.charles7c.cnadmin.monitor.model.query.SystemLogQuery;
|
||||||
|
import top.charles7c.cnadmin.monitor.model.vo.LoginLogVO;
|
||||||
|
import top.charles7c.cnadmin.monitor.model.vo.OperationLogVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.SystemLogDetailVO;
|
import top.charles7c.cnadmin.monitor.model.vo.SystemLogDetailVO;
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.SystemLogVO;
|
import top.charles7c.cnadmin.monitor.model.vo.SystemLogVO;
|
||||||
import top.charles7c.cnadmin.monitor.service.LogService;
|
import top.charles7c.cnadmin.monitor.service.LogService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统日志 API
|
* 日志管理 API
|
||||||
*
|
*
|
||||||
* @author Charles7c
|
* @author Charles7c
|
||||||
* @since 2023/1/17 23:27
|
* @since 2023/1/18 23:55
|
||||||
*/
|
*/
|
||||||
@Tag(name = "操作日志 API")
|
@Tag(name = "日志管理 API")
|
||||||
@Validated
|
@Validated
|
||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RequestMapping(value = "/monitor/log/system", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/monitor/log", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public class SystemLogController {
|
public class LogController {
|
||||||
|
|
||||||
private final LogService logService;
|
private final LogService logService;
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询登录日志列表")
|
||||||
|
@GetMapping("/login")
|
||||||
|
public R<PageInfo<LoginLogVO>> list(@Validated LoginLogQuery query, @Validated PageQuery pageQuery) {
|
||||||
|
PageInfo<LoginLogVO> pageInfo = logService.list(query, pageQuery);
|
||||||
|
return R.ok(pageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询操作日志列表")
|
||||||
|
@GetMapping("/operation")
|
||||||
|
public R<PageInfo<OperationLogVO>> list(@Validated OperationLogQuery query, @Validated PageQuery pageQuery) {
|
||||||
|
PageInfo<OperationLogVO> pageInfo = logService.list(query, pageQuery);
|
||||||
|
return R.ok(pageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary = "分页查询系统日志列表")
|
@Operation(summary = "分页查询系统日志列表")
|
||||||
@GetMapping
|
@GetMapping("/system")
|
||||||
public R<PageInfo<SystemLogVO>> list(@Validated SystemLogQuery query, @Validated PageQuery pageQuery) {
|
public R<PageInfo<SystemLogVO>> list(@Validated SystemLogQuery query, @Validated PageQuery pageQuery) {
|
||||||
PageInfo<SystemLogVO> pageInfo = logService.list(query, pageQuery);
|
PageInfo<SystemLogVO> pageInfo = logService.list(query, pageQuery);
|
||||||
return R.ok(pageInfo);
|
return R.ok(pageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "系统日志列表")
|
@Operation(summary = "查看系统日志详情")
|
||||||
@GetMapping("/{logId}")
|
@GetMapping("/system/{logId}")
|
||||||
public R<SystemLogDetailVO> detail(@PathVariable Long logId) {
|
public R<SystemLogDetailVO> detail(@PathVariable Long logId) {
|
||||||
SystemLogDetailVO detailVO = logService.detail(logId);
|
SystemLogDetailVO detailVO = logService.detail(logId);
|
||||||
return R.ok(detailVO);
|
return R.ok(detailVO);
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package top.charles7c.cnadmin.webapi.controller.monitor;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.model.query.PageQuery;
|
|
||||||
import top.charles7c.cnadmin.common.model.vo.PageInfo;
|
|
||||||
import top.charles7c.cnadmin.common.model.vo.R;
|
|
||||||
import top.charles7c.cnadmin.monitor.model.query.LoginLogQuery;
|
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.LoginLogVO;
|
|
||||||
import top.charles7c.cnadmin.monitor.service.LogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录日志 API
|
|
||||||
*
|
|
||||||
* @author Charles7c
|
|
||||||
* @since 2023/1/16 23:17
|
|
||||||
*/
|
|
||||||
@Tag(name = "登录日志 API")
|
|
||||||
@Validated
|
|
||||||
@RestController
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RequestMapping(value = "/monitor/log/login", produces = MediaType.APPLICATION_JSON_VALUE)
|
|
||||||
public class LoginLogController {
|
|
||||||
|
|
||||||
private final LogService logService;
|
|
||||||
|
|
||||||
@Operation(summary = "分页查询登录日志列表")
|
|
||||||
@GetMapping
|
|
||||||
public R<PageInfo<LoginLogVO>> list(@Validated LoginLogQuery query, @Validated PageQuery pageQuery) {
|
|
||||||
PageInfo<LoginLogVO> pageInfo = logService.list(query, pageQuery);
|
|
||||||
return R.ok(pageInfo);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package top.charles7c.cnadmin.webapi.controller.monitor;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.model.query.PageQuery;
|
|
||||||
import top.charles7c.cnadmin.common.model.vo.PageInfo;
|
|
||||||
import top.charles7c.cnadmin.common.model.vo.R;
|
|
||||||
import top.charles7c.cnadmin.monitor.model.query.OperationLogQuery;
|
|
||||||
import top.charles7c.cnadmin.monitor.model.vo.OperationLogVO;
|
|
||||||
import top.charles7c.cnadmin.monitor.service.LogService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 操作日志 API
|
|
||||||
*
|
|
||||||
* @author Charles7c
|
|
||||||
* @since 2023/1/14 18:09
|
|
||||||
*/
|
|
||||||
@Tag(name = "操作日志 API")
|
|
||||||
@Validated
|
|
||||||
@RestController
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RequestMapping(value = "/monitor/log/operation", produces = MediaType.APPLICATION_JSON_VALUE)
|
|
||||||
public class OperationLogController {
|
|
||||||
|
|
||||||
private final LogService logService;
|
|
||||||
|
|
||||||
@Operation(summary = "分页查询操作日志列表")
|
|
||||||
@GetMapping
|
|
||||||
public R<PageInfo<OperationLogVO>> list(@Validated OperationLogQuery query, @Validated PageQuery pageQuery) {
|
|
||||||
PageInfo<OperationLogVO> pageInfo = logService.list(query, pageQuery);
|
|
||||||
return R.ok(pageInfo);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user