Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-csf-front
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
yuzhenWang
yd-csf-front
Commits
2d5a76fa
Commit
2d5a76fa
authored
Aug 03, 2026
by
jianan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
操作日志1
parent
53d4357f
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
345 additions
and
0 deletions
+345
-0
src/api/monitor/auditlog.js
+18
-0
src/views/monitor/auditlog/index.vue
+327
-0
No files found.
src/api/monitor/auditlog.js
0 → 100644
View file @
2d5a76fa
import
request
from
'@/utils/request'
// 审计日志分页查询
export
function
getAuditLogPage
(
data
)
{
return
request
({
url
:
'/csf/api/auditlog/log/page'
,
method
:
'post'
,
data
})
}
// 审计详情查询
export
function
getAuditLogDetail
(
requestId
)
{
return
request
({
url
:
'/csf/api/auditlog/log/detail?requestId='
+
requestId
,
method
:
'get'
})
}
src/views/monitor/auditlog/index.vue
0 → 100644
View file @
2d5a76fa
<
template
>
<div
class=
"app-container"
>
<CommonPage
:operationBtnList=
"operationBtnList"
:visibleDefaultButtons=
"visibleDefaultButtons"
:showSearchForm=
"true"
:show-pagination=
"true"
:total=
"pageTotal"
:current-page=
"currentPage"
:page-size=
"pageSize"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
>
<template
#
searchForm
>
<SearchForm
ref=
"searchFormRef"
:config=
"searchConfig"
/>
</
template
>
<
template
#
table
>
<el-table
:data=
"tableData"
v-loading=
"loading"
border
>
<el-table-column
prop=
"operTime"
label=
"操作时间"
width=
"170"
>
<template
#
default=
"scope"
>
<span>
{{
parseTime
(
scope
.
row
.
operTime
)
}}
</span>
</
template
>
</el-table-column>
<el-table-column
prop=
"module"
label=
"业务模块"
width=
"120"
:show-overflow-tooltip=
"true"
/>
<el-table-column
prop=
"businessType"
label=
"业务类型"
width=
"100"
>
<
template
#
default=
"scope"
>
<span>
{{
BUSINESS_TYPE_MAP
[
scope
.
row
.
businessType
]
||
scope
.
row
.
businessType
}}
</span>
</
template
>
</el-table-column>
<el-table-column
prop=
"content"
label=
"日志内容"
min-width=
"180"
:show-overflow-tooltip=
"true"
/>
<el-table-column
prop=
"operName"
label=
"操作人"
width=
"100"
/>
<el-table-column
prop=
"deptName"
label=
"部门"
width=
"120"
:show-overflow-tooltip=
"true"
/>
<el-table-column
prop=
"status"
label=
"状态"
width=
"80"
>
<
template
#
default=
"scope"
>
<el-tag
:type=
"scope.row.status === 0 ? 'success' : 'danger'"
size=
"small"
>
{{
scope
.
row
.
status
===
0
?
'成功'
:
'失败'
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"operIp"
label=
"操作IP"
width=
"140"
/>
<el-table-column
label=
"操作"
width=
"100"
fixed=
"right"
>
<
template
#
default=
"scope"
>
<el-button
link
type=
"primary"
icon=
"View"
@
click=
"handleView(scope.row)"
>
详情
</el-button>
</
template
>
</el-table-column>
</el-table>
</template>
</CommonPage>
<!-- 审计详情弹窗 -->
<el-dialog
title=
"审计详情"
v-model=
"dialogVisible"
width=
"1000px"
append-to-body
:close-on-click-modal=
"false"
>
<div
v-loading=
"detailLoading"
>
<!-- 操作日志基本信息 -->
<el-descriptions
v-if=
"detail.operLog"
title=
"基本信息"
:column=
"2"
border
style=
"margin-bottom: 20px"
>
<el-descriptions-item
label=
"业务模块"
>
{{ detail.operLog.module }}
</el-descriptions-item>
<el-descriptions-item
label=
"业务类型"
>
{{ BUSINESS_TYPE_MAP[detail.operLog.businessType] || detail.operLog.businessType }}
</el-descriptions-item>
<el-descriptions-item
label=
"操作人"
>
{{ detail.operLog.operName }}
</el-descriptions-item>
<el-descriptions-item
label=
"部门"
>
{{ detail.operLog.deptName }}
</el-descriptions-item>
<el-descriptions-item
label=
"操作时间"
>
{{ parseTime(detail.operLog.operTime) }}
</el-descriptions-item>
<el-descriptions-item
label=
"操作IP"
>
{{ detail.operLog.operIp }}
</el-descriptions-item>
<el-descriptions-item
label=
"请求URL"
:span=
"2"
>
{{ detail.operLog.operUrl }}
</el-descriptions-item>
<el-descriptions-item
label=
"日志内容"
:span=
"2"
>
{{ detail.operLog.content }}
</el-descriptions-item>
<el-descriptions-item
label=
"操作状态"
>
<el-tag
:type=
"detail.operLog.status === 0 ? 'success' : 'danger'"
size=
"small"
>
{{ detail.operLog.status === 0 ? '成功' : '失败' }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item
label=
"请求ID"
>
{{ detail.operLog.requestId }}
</el-descriptions-item>
<el-descriptions-item
label=
"请求参数"
:span=
"2"
>
<div
class=
"json-content"
>
{{ detail.operLog.operParam || '-' }}
</div>
</el-descriptions-item>
<el-descriptions-item
label=
"返回结果"
:span=
"2"
>
<div
class=
"json-content"
>
{{ detail.operLog.jsonResult || '-' }}
</div>
</el-descriptions-item>
<el-descriptions-item
v-if=
"detail.operLog.status === 1"
label=
"错误信息"
:span=
"2"
>
<span
style=
"color: #f56c6c"
>
{{ detail.operLog.errorMsg }}
</span>
</el-descriptions-item>
</el-descriptions>
<!-- 数据快照 -->
<
template
v-if=
"detail.snapshots && detail.snapshots.length > 0"
>
<h4
class=
"section-title"
>
数据快照(共
{{
detail
.
snapshots
.
length
}}
条)
</h4>
<el-table
:data=
"detail.snapshots"
border
size=
"small"
style=
"margin-bottom: 20px"
>
<el-table-column
prop=
"tableName"
label=
"表名"
width=
"150"
/>
<el-table-column
prop=
"recordId"
label=
"记录ID"
width=
"120"
/>
<el-table-column
label=
"变更前数据"
min-width=
"280"
>
<template
#
default=
"scope"
>
<pre
v-if=
"scope.row.beforeJson"
class=
"json-pre"
>
{{
formatJson
(
scope
.
row
.
beforeJson
)
}}
</pre>
<span
v-else
class=
"empty-hint"
>
- (新增)
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"变更后数据"
min-width=
"280"
>
<
template
#
default=
"scope"
>
<pre
v-if=
"scope.row.afterJson"
class=
"json-pre"
>
{{
formatJson
(
scope
.
row
.
afterJson
)
}}
</pre>
<span
v-else
class=
"empty-hint"
>
- (删除)
</span>
</
template
>
</el-table-column>
</el-table>
</template>
<!-- 字段变更明细 -->
<
template
v-if=
"detail.changes && detail.changes.length > 0"
>
<h4
class=
"section-title"
>
字段变更明细(共
{{
detail
.
changes
.
length
}}
条)
</h4>
<el-table
:data=
"detail.changes"
border
size=
"small"
>
<el-table-column
prop=
"tableName"
label=
"表名"
width=
"150"
/>
<el-table-column
prop=
"fieldComment"
label=
"字段名"
width=
"140"
/>
<el-table-column
label=
"变更类型"
width=
"80"
>
<template
#
default=
"scope"
>
<el-tag
:type=
"changeTypeTag(scope.row.changeType)"
size=
"small"
>
{{
scope
.
row
.
changeType
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"oldValue"
label=
"旧值"
min-width=
"200"
:show-overflow-tooltip=
"true"
/>
<el-table-column
prop=
"newValue"
label=
"新值"
min-width=
"200"
:show-overflow-tooltip=
"true"
/>
</el-table>
</template>
</div>
<
template
#
footer
>
<el-button
@
click=
"dialogVisible = false"
>
关 闭
</el-button>
</
template
>
</el-dialog>
</div>
</template>
<
script
setup
>
import
{
ref
,
reactive
}
from
'vue'
import
CommonPage
from
'@/components/commonPage'
import
SearchForm
from
'@/components/SearchForm/SearchForm.vue'
import
{
getAuditLogPage
,
getAuditLogDetail
}
from
'@/api/monitor/auditlog'
const
{
proxy
}
=
getCurrentInstance
()
// 业务类型映射
const
BUSINESS_TYPE_MAP
=
{
0
:
'其它'
,
1
:
'新增'
,
2
:
'修改'
,
3
:
'删除'
,
4
:
'授权'
,
5
:
'导出'
,
6
:
'导入'
,
7
:
'强退'
,
8
:
'生成代码'
,
9
:
'清空数据'
}
// 搜索表单配置
const
searchFormRef
=
ref
(
null
)
const
searchConfig
=
ref
([
{
type
:
'input'
,
prop
:
'module'
,
label
:
'业务模块'
,
placeholder
:
'请输入业务模块'
},
{
type
:
'input'
,
prop
:
'operName'
,
label
:
'操作人'
,
placeholder
:
'请输入操作人'
},
{
type
:
'select'
,
prop
:
'status'
,
label
:
'操作状态'
,
placeholder
:
'请选择'
,
options
:
[
{
label
:
'成功'
,
value
:
0
},
{
label
:
'失败'
,
value
:
1
}
]
},
{
type
:
'daterange'
,
prop
:
'operTimeRange'
,
label
:
'操作时间'
,
startPlaceholder
:
'开始时间'
,
endPlaceholder
:
'结束时间'
,
valueFormat
:
'YYYY-MM-DD HH:mm:ss'
}
])
// 表格数据
const
tableData
=
ref
([])
const
loading
=
ref
(
false
)
// 分页
const
currentPage
=
ref
(
1
)
const
pageSize
=
ref
(
10
)
const
pageTotal
=
ref
(
0
)
const
handleSizeChange
=
val
=>
{
pageSize
.
value
=
val
getList
()
}
const
handleCurrentChange
=
val
=>
{
currentPage
.
value
=
val
getList
()
}
// 获取列表数据
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
formData
=
searchFormRef
.
value
?.
getFormData
()
||
{}
const
params
=
{
...
formData
,
startTime
:
formData
.
operTimeRange
?
formData
.
operTimeRange
[
0
]
:
undefined
,
endTime
:
formData
.
operTimeRange
?
formData
.
operTimeRange
[
1
]
:
undefined
,
operTimeRange
:
undefined
,
pageNo
:
currentPage
.
value
,
pageSize
:
pageSize
.
value
}
const
response
=
await
getAuditLogPage
(
params
)
tableData
.
value
=
response
.
data
.
records
||
[]
pageTotal
.
value
=
response
.
data
.
total
||
0
}
finally
{
loading
.
value
=
false
}
}
getList
()
// 查询
const
handleQuery
=
()
=>
{
currentPage
.
value
=
1
getList
()
}
// 重置
const
handleReset
=
()
=>
{
searchFormRef
.
value
?.
resetForm
()
currentPage
.
value
=
1
getList
()
}
const
visibleDefaultButtons
=
ref
([
'reset'
,
'query'
])
const
operationBtnList
=
ref
([
{
key
:
'reset'
,
direction
:
'right'
,
click
:
handleReset
},
{
key
:
'query'
,
direction
:
'right'
,
click
:
handleQuery
}
])
// ========== 详情弹窗 ==========
const
dialogVisible
=
ref
(
false
)
const
detailLoading
=
ref
(
false
)
const
detail
=
reactive
({
operLog
:
null
,
snapshots
:
[],
changes
:
[]
})
const
handleView
=
async
(
row
)
=>
{
dialogVisible
.
value
=
true
detail
.
operLog
=
null
detail
.
snapshots
=
[]
detail
.
changes
=
[]
if
(
!
row
.
requestId
)
return
detailLoading
.
value
=
true
try
{
const
response
=
await
getAuditLogDetail
(
row
.
requestId
)
if
(
response
.
data
)
{
detail
.
operLog
=
response
.
data
.
operLog
||
null
detail
.
snapshots
=
response
.
data
.
snapshots
||
[]
detail
.
changes
=
response
.
data
.
changes
||
[]
}
}
finally
{
detailLoading
.
value
=
false
}
}
const
formatJson
=
(
jsonStr
)
=>
{
try
{
return
JSON
.
stringify
(
JSON
.
parse
(
jsonStr
),
null
,
2
)
}
catch
{
return
jsonStr
}
}
const
changeTypeTag
=
(
type
)
=>
{
switch
(
type
)
{
case
'ADD'
:
return
'success'
case
'MODIFY'
:
return
'warning'
case
'DELETE'
:
return
'danger'
default
:
return
'info'
}
}
</
script
>
<
style
scoped
>
.section-title
{
font-size
:
14px
;
font-weight
:
600
;
color
:
#303133
;
margin
:
0
0
12px
0
;
padding-left
:
8px
;
border-left
:
3px
solid
#409eff
;
}
.json-content
{
max-height
:
200px
;
overflow-y
:
auto
;
white-space
:
pre-wrap
;
word-break
:
break-all
;
font-size
:
12px
;
color
:
#606266
;
background
:
#f5f7fa
;
padding
:
8px
;
border-radius
:
4px
;
}
.json-pre
{
margin
:
0
;
padding
:
6px
8px
;
background
:
#f5f7fa
;
border-radius
:
4px
;
font-size
:
12px
;
line-height
:
1.5
;
max-height
:
200px
;
overflow
:
auto
;
white-space
:
pre-wrap
;
word-break
:
break-all
;
}
.empty-hint
{
color
:
#c0c4cc
;
font-size
:
12px
;
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment