refactor: remove oper-log module

This commit is contained in:
chansee97 2026-01-15 23:04:53 +08:00
parent 21b6b5874d
commit 67651d7a3f
6 changed files with 16 additions and 579 deletions

View File

@ -47,27 +47,27 @@
"sizecheck": "npx vite-bundle-visualizer"
},
"dependencies": {
"@vueuse/core": "^13.7.0",
"@vueuse/core": "^14.1.0",
"alova": "^3.3.4",
"array-to-tree": "^3.3.2",
"colord": "^2.9.3",
"echarts": "^6.0.0",
"md-editor-v3": "^5.6.1",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.5.0",
"pro-naive-ui": "^3.1.1",
"pinia": "^3.0.4",
"pinia-plugin-persistedstate": "^4.7.1",
"pro-naive-ui": "^3.2.0",
"quill": "^2.0.3",
"radash": "^12.1.1",
"vue": "^3.5.20",
"vue-draggable-plus": "^0.6.0",
"vue-i18n": "^11.1.11",
"vue-router": "^4.5.1"
"vue": "^3.5.26",
"vue-draggable-plus": "^0.6.1",
"vue-i18n": "^11.2.8",
"vue-router": "^4.6.4"
},
"devDependencies": {
"@antfu/eslint-config": "^5.0.0",
"@iconify-json/icon-park-outline": "^1.2.2",
"@iconify/vue": "^5.0.0",
"@types/node": "^24.1.0",
"@types/node": "^25.0.8",
"@vitejs/plugin-vue": "^6.0.1",
"@vitejs/plugin-vue-jsx": "^5.0.1",
"eslint": "^9.29.0",
@ -78,15 +78,15 @@
"simple-git-hooks": "^2.13.1",
"typescript": "^5.8.3",
"unocss": "^66.3.3",
"unplugin-auto-import": "^19.3.0",
"unplugin-icons": "^22.2.0",
"unplugin-vue-components": "^28.8.0",
"vite": "^7.0.6",
"unplugin-auto-import": "^21.0.0",
"unplugin-icons": "^23.0.1",
"unplugin-vue-components": "^31.0.0",
"vite": "^7.3.1",
"vite-bundle-visualizer": "^1.2.1",
"vite-plugin-auto-proxy": "^1.0.1",
"vite-plugin-auto-proxy": "^1.0.2",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-vue-devtools": "8.0.0",
"vue-tsc": "^3.0.5"
"vite-plugin-vue-devtools": "8.0.5",
"vue-tsc": "^3.2.2"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"

View File

@ -1,31 +0,0 @@
import { request } from '@/utils/alova'
export interface OperLogQueryParams extends Api.PageParams {
}
/**
*
*/
export function getOperLogPage(params: OperLogQueryParams) {
return request.Get<Api.ListResponse<Entity.OperLog>>('/oper-log', { params })
}
/**
*
*/
export function getOperLogDetail(id: number) {
return request.Get<Entity.OperLog>(`/oper-log/${id}`)
}
/**
*
*/
export function deleteOperLog(ids: string) {
return request.Delete(`/oper-log/${ids}`)
}
/**
*
*/
export function clearOperLog() {
return request.Delete('/oper-log/clean')
}

View File

@ -1,75 +0,0 @@
declare namespace Entity {
/**
*
*/
interface OperLog {
/**
*
*/
id: number
/**
*
*/
title: string
/**
*
*/
method: string
/**
*
*/
requestMethod: string
/**
*
*/
operName: string
/**
*
*/
deptName: string
/**
* URL
*/
operUrl: string
/**
*
*/
operIp: string
/**
*
*/
operLocation: string
/**
*
*/
browser: string
/**
*
*/
os: string
/**
*
*/
operParam: string
/**
*
*/
jsonResult: string
/**
* 0 1
*/
status: number
/**
*
*/
errorMsg: string
/**
*
*/
costTime: string
/**
*
*/
operTime: Date
}
}

View File

@ -1,168 +0,0 @@
import type { DataTableColumns } from 'naive-ui'
import { NButton, NSpace, NTag } from 'naive-ui'
import type { ProSearchFormColumns } from 'pro-naive-ui'
import { renderProCopyableText } from 'pro-naive-ui'
// 操作日志搜索表单数据类型
export interface OperationLogSearchFormData {
operUrl?: string
title?: string
operName?: string
businessType?: number
status?: 0 | 1
operTime?: [string, string]
}
// 操作日志搜索表单列配置
export const searchColumns: ProSearchFormColumns<OperationLogSearchFormData> = [
{
title: '操作地址',
path: 'operUrl',
field: 'input',
fieldProps: {
clearable: true,
},
},
{
title: '系统模块',
path: 'title',
field: 'input',
fieldProps: {
clearable: true,
},
},
{
title: '操作人员',
path: 'operName',
field: 'input',
fieldProps: {
clearable: true,
},
},
{
title: '状态',
path: 'status',
field: 'select',
fieldProps: {
clearable: true,
options: [
{ label: '正常', value: 0 },
{ label: '异常', value: 1 },
],
},
},
{
title: '操作时间',
path: 'operTime',
field: 'date-time-range',
fieldProps: {
clearable: true,
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
defaultTime: ['00:00:00', '23:59:59'],
},
},
]
// 表格列配置
export function createTableColumns(options: {
onView: (row: Entity.OperLog) => void
onDelete: (operId: number) => void
}): DataTableColumns<Entity.OperLog> {
const { onView, onDelete } = options
return [
{
type: 'selection',
width: 55,
align: 'center',
},
{
title: '系统模块',
key: 'title',
width: 150,
align: 'center',
ellipsis: {
tooltip: true,
},
},
{
title: '操作人员',
key: 'operName',
width: 120,
align: 'center',
ellipsis: {
tooltip: true,
},
},
{
title: '主机地址',
key: 'operIp',
width: 130,
align: 'center',
render: row => renderProCopyableText(row.operIp),
},
{
title: '操作地点',
key: 'operLocation',
width: 150,
align: 'center',
ellipsis: {
tooltip: true,
},
},
{
title: '操作状态',
key: 'status',
width: 100,
align: 'center',
render: (row) => {
return (
<NTag type={row.status === 0 ? 'success' : 'error'} bordered={false}>
{row.status === 0 ? '正常' : '异常'}
</NTag>
)
},
},
{
title: '操作日期',
key: 'operTime',
width: 180,
align: 'center',
},
{
title: '消耗时间',
key: 'costTime',
width: 100,
align: 'center',
render: row => `${row.costTime}`,
},
{
title: '操作',
key: 'actions',
width: 150,
align: 'center',
fixed: 'right',
render: (row) => {
return (
<NSpace justify="center">
<NButton
text
type="primary"
onClick={() => onView(row)}
>
</NButton>
<NButton
text
type="error"
onClick={() => onDelete(row.id)}
>
</NButton>
</NSpace>
)
},
},
]
}

View File

@ -1,119 +0,0 @@
<script setup lang="ts">
import { useBoolean } from '@/hooks'
const { bool: visible, setTrue: showModal, setFalse: hideModal } = useBoolean(false)
const operationLog = ref<Entity.OperLog | null>(null)
//
function openModal(row: Entity.OperLog) {
operationLog.value = row
showModal()
}
//
function closeModal() {
hideModal()
operationLog.value = null
}
defineExpose({
openModal,
})
</script>
<template>
<n-modal
v-model:show="visible"
preset="card"
title="操作日志详细"
class="w-4/5 max-w-4xl"
:mask-closable="false"
>
<div v-if="operationLog" class="space-y-4">
<!-- 基本信息 -->
<n-card title="基本信息" size="small">
<n-descriptions :column="3" label-placement="left" size="small">
<n-descriptions-item label="日志编号">
{{ operationLog.id }}
</n-descriptions-item>
<n-descriptions-item label="系统模块">
{{ operationLog.title }}
</n-descriptions-item>
<n-descriptions-item label="部门名称">
{{ operationLog.deptName || '-' }}
</n-descriptions-item>
<n-descriptions-item label="操作状态">
<n-tag size="small">
{{ operationLog.status === 0 ? '正常' : '异常' }}
</n-tag>
</n-descriptions-item>
<n-descriptions-item label="消耗时间">
{{ `${operationLog.costTime}ms` }}
</n-descriptions-item>
<n-descriptions-item label="操作时间">
{{ operationLog.operTime }}
</n-descriptions-item>
</n-descriptions>
</n-card>
<!-- 请求信息 -->
<n-card title="请求信息" size="small">
<n-descriptions :column="2" label-placement="left" size="small">
<n-descriptions-item label="调用方法" :span="2">
<n-text code>
{{ operationLog.method }}
</n-text>
</n-descriptions-item>
<n-descriptions-item label="请求地址">
<n-text code>
{{ operationLog.operUrl }}
</n-text>
</n-descriptions-item>
<n-descriptions-item label="请求方式">
<n-tag size="small">
{{ operationLog.requestMethod }}
</n-tag>
</n-descriptions-item>
<n-descriptions-item label="主机地址">
{{ operationLog.operIp }}
</n-descriptions-item>
<n-descriptions-item label="操作地点">
{{ operationLog.operLocation }}
</n-descriptions-item>
</n-descriptions>
</n-card>
<!-- 请求参数 -->
<pro-card title="请求参数" size="small" :show="false">
<n-scrollbar style="max-height: 200px">
<pre>{{ JSON.parse(operationLog.operParam) }}</pre>
</n-scrollbar>
</pro-card>
<!-- 返回结果 -->
<pro-card title="返回结果" size="small">
<n-scrollbar style="max-height: 200px">
<pre>{{ operationLog.jsonResult }}</pre>
</n-scrollbar>
</pro-card>
<!-- 异常信息 -->
<n-card v-if="operationLog.status === 1" title="异常信息" size="small">
<n-scrollbar style="max-height: 200px">
<n-text type="error">
{{ operationLog.errorMsg || '无异常信息' }}
</n-text>
</n-scrollbar>
</n-card>
</div>
<template #footer>
<div class="flex justify-end">
<n-button @click="closeModal">
关闭
</n-button>
</div>
</template>
</n-modal>
</template>

View File

@ -1,170 +0,0 @@
<script setup lang="tsx">
import { createProSearchForm, useNDataTable } from 'pro-naive-ui'
import {
clearOperLog,
deleteOperLog,
getOperLogPage,
} from '@/api/monitor/oper-log'
import type { OperLogQueryParams } from '@/api/monitor/oper-log'
import { createTableColumns, searchColumns } from './columns'
import type { OperationLogSearchFormData } from './columns'
//
import DetailModal from './components/DetailModal.vue'
//
const detailModalRef = ref()
//
const searchForm = createProSearchForm<OperationLogSearchFormData>({
defaultCollapsed: true,
initialValues: {
},
})
// 使useNDataTable
const {
table: {
tableProps,
},
search: {
proSearchFormProps,
searchLoading,
},
refresh,
} = useNDataTable(getList, {
form: searchForm,
})
//
const checkedRowKeys = ref<(number)[]>([])
/** 查询操作日志列表 */
interface Result {
total: number
list: Entity.OperLog[]
}
async function getList({ current, pageSize }: any, formData: OperationLogSearchFormData): Promise<Result> {
try {
const params: OperLogQueryParams = {
pageNum: current,
pageSize,
...formData,
}
return getOperLogPage(params).then(res => res.data)
}
catch (error) {
console.error('获取操作日志列表失败:', error)
return {
total: 0,
list: [],
}
}
}
/** 查看详情 */
function handleView(row: Entity.OperLog) {
detailModalRef.value?.openModal(row)
}
/** 删除操作日志 */
async function handleDelete(operId: number | number[]) {
const isBatch = Array.isArray(operId)
const ids = isBatch ? operId.join(',') : operId.toString()
window.$dialog.warning({
title: '确认删除',
content: isBatch
? `是否确认删除选中的 ${operId.length} 条操作日志?`
: '是否确认删除该条操作日志?',
positiveText: '确定删除',
negativeText: '取消',
onPositiveClick: async () => {
try {
await deleteOperLog(ids)
window.$message.success('删除成功')
if (isBatch) {
//
checkedRowKeys.value = []
}
refresh()
}
catch (error) {
console.error('删除操作日志失败:', error)
}
},
})
}
/** 清空操作日志 */
async function handleClean() {
window.$dialog.warning({
title: '确认清空',
content: '是否确认清空所有操作日志数据?此操作不可恢复!',
positiveText: '确定清空',
negativeText: '取消',
onPositiveClick: async () => {
try {
await clearOperLog()
window.$message.success('清空成功')
refresh()
}
catch (error) {
console.error('清空操作日志失败:', error)
}
},
})
}
//
const columns = createTableColumns({
onView: handleView,
onDelete: handleDelete,
})
</script>
<template>
<n-space vertical>
<n-card>
<pro-search-form
v-bind="proSearchFormProps"
:form="searchForm"
:columns="searchColumns"
/>
</n-card>
<!-- 数据表格 -->
<pro-data-table
v-bind="tableProps"
v-model:checked-row-keys="checkedRowKeys"
:columns="columns"
row-key="id"
:loading="searchLoading"
title=" "
>
<template #toolbar>
<n-flex>
<n-button
type="error"
:disabled="checkedRowKeys.length === 0"
@click="handleDelete(checkedRowKeys.map(id => Number(id)))"
>
<template #icon>
<icon-park-outline-delete />
</template>
删除
</n-button>
<n-button type="warning" @click="handleClean">
<template #icon>
<icon-park-outline-clear />
</template>
清空
</n-button>
</n-flex>
</template>
</pro-data-table>
<!-- 详情弹窗 -->
<DetailModal ref="detailModalRef" />
</n-space>
</template>