Compare commits
No commits in common. 'ecf4129dfc1d03857dcc22c2c114bb4aa7515c20' and '7a5dde79ac181bc10adb8acdb56a143eac8114e4' have entirely different histories.
ecf4129dfc
...
7a5dde79ac
12 changed files with 19 additions and 567 deletions
@ -1,11 +0,0 @@ |
|||||||
import request from "@/api/request"; |
|
||||||
|
|
||||||
/** |
|
||||||
* 分页查询系统访问日志。 |
|
||||||
*/ |
|
||||||
export function listSystemLog(query) { |
|
||||||
return request.get({ |
|
||||||
url: "/systemLog", |
|
||||||
query, |
|
||||||
}); |
|
||||||
} |
|
||||||
@ -1,314 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="container"> |
|
||||||
<header class="mb-20"> |
|
||||||
<el-form :label-width="100"> |
|
||||||
<el-row :gutter="12"> |
|
||||||
<el-col :span="6"> |
|
||||||
<el-form-item label="请求人"> |
|
||||||
<el-input |
|
||||||
v-model="query.requester" |
|
||||||
placeholder="请输入登录名或姓名" |
|
||||||
clearable |
|
||||||
@keyup.enter="search" |
|
||||||
/> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="6"> |
|
||||||
<el-form-item label="接口地址"> |
|
||||||
<el-input |
|
||||||
v-model="query.requestUri" |
|
||||||
placeholder="请输入接口地址" |
|
||||||
clearable |
|
||||||
@keyup.enter="search" |
|
||||||
/> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="6"> |
|
||||||
<el-form-item label="访问方式"> |
|
||||||
<el-select |
|
||||||
v-model="query.requestMethod" |
|
||||||
placeholder="请选择访问方式" |
|
||||||
clearable |
|
||||||
> |
|
||||||
<el-option |
|
||||||
v-for="method in requestMethods" |
|
||||||
:key="method" |
|
||||||
:label="method" |
|
||||||
:value="method" |
|
||||||
/> |
|
||||||
</el-select> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="6"> |
|
||||||
<el-form-item label="来源IP"> |
|
||||||
<el-input |
|
||||||
v-model="query.sourceIp" |
|
||||||
placeholder="请输入来源IP" |
|
||||||
clearable |
|
||||||
@keyup.enter="search" |
|
||||||
/> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
<el-row :gutter="12"> |
|
||||||
<el-col :span="6"> |
|
||||||
<el-form-item label="执行结果"> |
|
||||||
<el-select |
|
||||||
v-model="query.status" |
|
||||||
placeholder="请选择执行结果" |
|
||||||
clearable |
|
||||||
> |
|
||||||
<el-option label="成功" :value="1" /> |
|
||||||
<el-option label="失败" :value="0" /> |
|
||||||
</el-select> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
<el-col :span="12"> |
|
||||||
<el-form-item label="日志时间"> |
|
||||||
<el-date-picker |
|
||||||
v-model="query.logTimeRange" |
|
||||||
type="datetimerange" |
|
||||||
value-format="YYYY-MM-DD HH:mm:ss" |
|
||||||
format="YYYY-MM-DD HH:mm:ss" |
|
||||||
range-separator="~" |
|
||||||
start-placeholder="开始时间" |
|
||||||
end-placeholder="结束时间" |
|
||||||
clearable |
|
||||||
/> |
|
||||||
</el-form-item> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-form> |
|
||||||
<div class="flex end"> |
|
||||||
<el-button type="primary" @click="search"> |
|
||||||
<template #icon> |
|
||||||
<icon name="el-icon-Search" /> |
|
||||||
</template> |
|
||||||
查询 |
|
||||||
</el-button> |
|
||||||
<el-button @click="reset">重置</el-button> |
|
||||||
</div> |
|
||||||
</header> |
|
||||||
|
|
||||||
<el-tabs v-model="activeTab" @tab-change="handleTabChange"> |
|
||||||
<el-tab-pane label="登录日志" name="login" /> |
|
||||||
<el-tab-pane label="操作日志" name="operation" /> |
|
||||||
</el-tabs> |
|
||||||
|
|
||||||
<div class="table-container"> |
|
||||||
<el-table :data="logs"> |
|
||||||
<el-table-column label="请求人" min-width="160"> |
|
||||||
<template #default="{ row }"> |
|
||||||
{{ formatRequester(row) }} |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column |
|
||||||
label="接口地址" |
|
||||||
prop="requestUri" |
|
||||||
min-width="220" |
|
||||||
show-overflow-tooltip |
|
||||||
/> |
|
||||||
<el-table-column |
|
||||||
label="访问方式" |
|
||||||
prop="requestMethod" |
|
||||||
width="100" |
|
||||||
align="center" |
|
||||||
/> |
|
||||||
<el-table-column |
|
||||||
label="来源IP" |
|
||||||
prop="sourceIp" |
|
||||||
min-width="140" |
|
||||||
show-overflow-tooltip |
|
||||||
/> |
|
||||||
<el-table-column label="请求参数" min-width="220"> |
|
||||||
<template #default="{ row }"> |
|
||||||
<span class="summary-text">{{ formatSummary(row.requestParams) }}</span> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="执行耗时" width="110" align="center"> |
|
||||||
<template #default="{ row }"> |
|
||||||
{{ row.executionTime }} ms |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column label="执行结果" width="100" align="center"> |
|
||||||
<template #default="{ row }"> |
|
||||||
<el-tag :type="row.status === 1 ? 'success' : 'danger'"> |
|
||||||
{{ row.status === 1 ? "成功" : "失败" }} |
|
||||||
</el-tag> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column |
|
||||||
label="日志时间" |
|
||||||
prop="logTime" |
|
||||||
width="180" |
|
||||||
/> |
|
||||||
<el-table-column label="操作" width="100" fixed="right"> |
|
||||||
<template #default="{ row }"> |
|
||||||
<el-button type="primary" link @click="showDetail(row)"> |
|
||||||
查看详情 |
|
||||||
</el-button> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</el-table> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div class="flex end mt-8"> |
|
||||||
<el-pagination |
|
||||||
v-model:page-size="query.size" |
|
||||||
v-model:current-page="query.current" |
|
||||||
:page-sizes="[10, 20, 50]" |
|
||||||
:total="total" |
|
||||||
layout="total, sizes, prev, pager, next" |
|
||||||
@size-change="handleSizeChange" |
|
||||||
@current-change="getList" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
<el-dialog v-model="detailVisible" title="系统日志详情" width="760px"> |
|
||||||
<el-descriptions :column="2" border> |
|
||||||
<el-descriptions-item label="请求人"> |
|
||||||
{{ formatRequester(activeLog) }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="日志时间"> |
|
||||||
{{ activeLog.logTime || "-" }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="接口地址" :span="2"> |
|
||||||
{{ activeLog.requestUri || "-" }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="访问方式"> |
|
||||||
{{ activeLog.requestMethod || "-" }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="来源IP"> |
|
||||||
{{ activeLog.sourceIp || "-" }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="执行耗时"> |
|
||||||
{{ activeLog.executionTime ?? 0 }} ms |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="执行结果"> |
|
||||||
<el-tag :type="activeLog.status === 1 ? 'success' : 'danger'"> |
|
||||||
{{ activeLog.status === 1 ? "成功" : "失败" }} |
|
||||||
</el-tag> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="请求参数" :span="2"> |
|
||||||
<pre class="detail-content">{{ activeLog.requestParams || "-" }}</pre> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item label="异常信息" :span="2"> |
|
||||||
<pre class="detail-content error-content">{{ activeLog.errorMessage || "-" }}</pre> |
|
||||||
</el-descriptions-item> |
|
||||||
</el-descriptions> |
|
||||||
<template #footer> |
|
||||||
<el-button @click="detailVisible = false">关闭</el-button> |
|
||||||
</template> |
|
||||||
</el-dialog> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup> |
|
||||||
import { listSystemLog } from "@/api/system/systemLog"; |
|
||||||
|
|
||||||
const requestMethods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]; |
|
||||||
|
|
||||||
const createDefaultQuery = () => ({ |
|
||||||
current: 1, |
|
||||||
size: 10, |
|
||||||
requester: undefined, |
|
||||||
requestUri: undefined, |
|
||||||
requestMethod: undefined, |
|
||||||
sourceIp: undefined, |
|
||||||
status: undefined, |
|
||||||
logTimeRange: [], |
|
||||||
}); |
|
||||||
|
|
||||||
const query = ref(createDefaultQuery()); |
|
||||||
const logs = ref([]); |
|
||||||
const total = ref(0); |
|
||||||
const detailVisible = ref(false); |
|
||||||
const activeLog = ref({}); |
|
||||||
const activeTab = ref("login"); |
|
||||||
|
|
||||||
/** |
|
||||||
* 将页面时间范围拆分成后端接收的开始、结束时间参数。 |
|
||||||
*/ |
|
||||||
function buildQueryParams() { |
|
||||||
const { logTimeRange, ...params } = query.value; |
|
||||||
params.logType = activeTab.value; |
|
||||||
if (logTimeRange?.length === 2) { |
|
||||||
params.startTime = logTimeRange[0]; |
|
||||||
params.endTime = logTimeRange[1]; |
|
||||||
} |
|
||||||
return params; |
|
||||||
} |
|
||||||
|
|
||||||
function getList() { |
|
||||||
listSystemLog(buildQueryParams()).then((data) => { |
|
||||||
logs.value = data.records; |
|
||||||
total.value = data.total; |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
function search() { |
|
||||||
query.value.current = 1; |
|
||||||
getList(); |
|
||||||
} |
|
||||||
|
|
||||||
function reset() { |
|
||||||
query.value = createDefaultQuery(); |
|
||||||
getList(); |
|
||||||
} |
|
||||||
|
|
||||||
function handleSizeChange() { |
|
||||||
query.value.current = 1; |
|
||||||
getList(); |
|
||||||
} |
|
||||||
|
|
||||||
function handleTabChange() { |
|
||||||
query.value.current = 1; |
|
||||||
getList(); |
|
||||||
} |
|
||||||
|
|
||||||
function formatRequester(row = {}) { |
|
||||||
if (row.nickName && row.userName) { |
|
||||||
return `${row.nickName}(${row.userName})`; |
|
||||||
} |
|
||||||
return row.nickName || row.userName || "匿名/外部调用"; |
|
||||||
} |
|
||||||
|
|
||||||
function formatSummary(value) { |
|
||||||
if (!value) { |
|
||||||
return "-"; |
|
||||||
} |
|
||||||
return value.length > 60 ? `${value.slice(0, 60)}...` : value; |
|
||||||
} |
|
||||||
|
|
||||||
function showDetail(row) { |
|
||||||
activeLog.value = row; |
|
||||||
detailVisible.value = true; |
|
||||||
} |
|
||||||
|
|
||||||
getList(); |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss" scoped> |
|
||||||
.summary-text { |
|
||||||
display: inline-block; |
|
||||||
max-width: 100%; |
|
||||||
overflow: hidden; |
|
||||||
text-overflow: ellipsis; |
|
||||||
white-space: nowrap; |
|
||||||
vertical-align: middle; |
|
||||||
} |
|
||||||
|
|
||||||
.detail-content { |
|
||||||
margin: 0; |
|
||||||
max-height: 260px; |
|
||||||
overflow: auto; |
|
||||||
white-space: pre-wrap; |
|
||||||
overflow-wrap: anywhere; |
|
||||||
font-family: inherit; |
|
||||||
line-height: 1.6; |
|
||||||
} |
|
||||||
|
|
||||||
.error-content { |
|
||||||
color: var(--el-color-danger); |
|
||||||
} |
|
||||||
</style> |
|
||||||
Loading…
Reference in new issue