-
+
{{ currentLog.username }}
-
-
-
{{ currentLog.module }}
-
-
{{ currentLog.action }}
+
+ {{ typeMap[currentLog.type] }}
+
-
-
+
+
+ {{ levelMap[currentLog.level] }}
+
-
+
+
{{ currentLog.duration || '-' }}ms
+
+
+
+
{{ currentLog.action }}
+
+
+
+ {{ currentLog.method }}
+ {{ currentLog.url }}
+
+
+
{{ currentLog.ip }}
-
-
-
{{ formatDate(currentLog.createdAt) }}
+
+
+
{{ currentLog.userAgent }}
+
+
+
+
{{ JSON.stringify(currentLog.requestData, null, 2) }}
+
+
+
+
{{ JSON.stringify(currentLog.responseData, null, 2) }}
-
-
-
-
{{ currentLog.content }}
-
-
-
-
{{ currentLog.params }}
-
-
-
-
{{ currentLog.response }}
-
-
-
-
{{ currentLog.userAgent }}
@@ -122,88 +152,112 @@ import PageHeader from '@/components/ui/PageHeader.vue'
import Breadcrumb from '@/components/ui/Breadcrumb.vue'
import Card from '@/components/ui/Card.vue'
import Button from '@/components/ui/Button.vue'
-import Input from '@/components/ui/Input.vue'
import Select from '@/components/ui/Select.vue'
-import DatePicker from '@/components/ui/DatePicker.vue'
import Table from '@/components/ui/Table.vue'
import Badge from '@/components/ui/Badge.vue'
import Modal from '@/components/ui/Modal.vue'
-import StatusIndicator from '@/components/ui/StatusIndicator.vue'
+import SearchBar from '@/components/ui/SearchBar.vue'
+import DatePicker from '@/components/ui/DatePicker.vue'
const loading = ref(false)
const showDetailModal = ref(false)
-const currentLog = ref(null)
+const searchQuery = ref('')
+const filterType = ref('')
+const filterLevel = ref('')
+const dateRange = ref([])
const page = ref(1)
const pageSize = ref(10)
const total = ref(0)
-const filters = reactive({
- keyword: '',
- module: '',
- action: '',
- startDate: '',
- endDate: ''
-})
+const levelMap = {
+ info: '信息',
+ warning: '警告',
+ error: '错误',
+ debug: '调试'
+}
+
+const typeMap = {
+ login: '登录',
+ logout: '登出',
+ create: '创建',
+ update: '更新',
+ delete: '删除',
+ view: '查看',
+ export: '导出',
+ import: '导入',
+ other: '其他'
+}
const columns = [
{ key: 'id', label: 'ID', width: '80px' },
- { key: 'username', label: '操作用户' },
- { key: 'module', label: '操作模块' },
- { key: 'action', label: '操作类型' },
- { key: 'content', label: '操作内容' },
- { key: 'ip', label: 'IP地址' },
- { key: 'status', label: '状态' },
+ { key: 'level', label: '级别' },
+ { key: 'username', label: '操作人' },
+ { key: 'type', label: '类型' },
+ { key: 'action', label: '操作内容', width: '300px' },
+ { key: 'ip', label: 'IP 地址' },
+ { key: 'duration', label: '耗时' },
{ key: 'createdAt', label: '操作时间' }
]
const logs = ref([
- { id: 1, username: 'admin', module: '用户管理', action: '登录', content: '用户登录系统', ip: '192.168.1.100', status: 'success', createdAt: '2024-01-15 10:30:00', params: '{}', response: '{}', userAgent: 'Mozilla/5.0...' },
- { id: 2, username: 'admin', module: '用户管理', action: '新增', content: '新增用户:user1', ip: '192.168.1.100', status: 'success', createdAt: '2024-01-15 10:35:00', params: '{}', response: '{}', userAgent: 'Mozilla/5.0...' },
- { id: 3, username: 'admin', module: '系统配置', action: '修改', content: '修改系统配置', ip: '192.168.1.100', status: 'success', createdAt: '2024-01-15 11:00:00', params: '{}', response: '{}', userAgent: 'Mozilla/5.0...' },
- { id: 4, username: 'user1', module: '金融分析', action: '查询', content: '查询股票数据', ip: '192.168.1.101', status: 'success', createdAt: '2024-01-15 14:20:00', params: '{}', response: '{}', userAgent: 'Mozilla/5.0...' },
- { id: 5, username: 'user1', module: '用户管理', action: '登录', content: '用户登录系统', ip: '192.168.1.101', status: 'failed', createdAt: '2024-01-15 14:15:00', params: '{}', response: '{}', userAgent: 'Mozilla/5.0...' }
+ { id: 1, level: 'info', type: 'login', username: 'admin', action: '登录系统', ip: '192.168.1.100', duration: 120, method: 'POST', url: '/api/v1/auth/login', createdAt: '2024-01-15 10:30:00' },
+ { id: 2, level: 'info', type: 'create', username: 'admin', action: '创建用户 test', ip: '192.168.1.100', duration: 250, method: 'POST', url: '/api/v1/admin/users', createdAt: '2024-01-15 10:35:00' },
+ { id: 3, level: 'warning', type: 'update', username: 'user1', action: '更新配置信息', ip: '192.168.1.101', duration: 180, method: 'PUT', url: '/api/v1/admin/configs/1', createdAt: '2024-01-15 11:00:00' },
+ { id: 4, level: 'error', type: 'delete', username: 'admin', action: '删除角色失败 - 权限不足', ip: '192.168.1.100', duration: 50, method: 'DELETE', url: '/api/v1/admin/roles/1', createdAt: '2024-01-15 11:15:00' },
+ { id: 5, level: 'info', type: 'export', username: 'user2', action: '导出股票数据', ip: '192.168.1.102', duration: 3500, method: 'GET', url: '/api/v1/finance/stocks/export', createdAt: '2024-01-15 11:30:00' }
])
-const moduleOptions = [
- { value: 'user', label: '用户管理' },
- { value: 'role', label: '角色管理' },
- { value: 'config', label: '系统配置' },
- { value: 'finance', label: '金融分析' },
- { value: 'weather', label: '气象分析' }
-]
-
-const actionOptions = [
+const typeOptions = [
+ { value: '', label: '全部类型' },
{ value: 'login', label: '登录' },
- { value: 'create', label: '新增' },
- { value: 'update', label: '修改' },
+ { value: 'logout', label: '登出' },
+ { value: 'create', label: '创建' },
+ { value: 'update', label: '更新' },
{ value: 'delete', label: '删除' },
- { value: 'query', label: '查询' }
+ { value: 'view', label: '查看' },
+ { value: 'export', label: '导出' },
+ { value: 'import', label: '导入' },
+ { value: 'other', label: '其他' }
+]
+
+const levelOptions = [
+ { value: '', label: '全部级别' },
+ { value: 'info', label: '信息' },
+ { value: 'warning', label: '警告' },
+ { value: 'error', label: '错误' },
+ { value: 'debug', label: '调试' }
]
+const currentLog = ref(null)
+
const formatDate = (date) => {
if (!date) return '-'
return new Date(date).toLocaleString('zh-CN')
}
-const getModuleVariant = (module) => {
+const getLevelBadgeVariant = (level) => {
const variants = {
- '用户管理': 'primary',
- '角色管理': 'success',
- '系统配置': 'warning',
- '金融分析': 'danger'
+ info: 'primary',
+ warning: 'warning',
+ error: 'danger',
+ debug: 'secondary'
}
- return variants[module] || 'secondary'
+ return variants[level] || 'secondary'
}
-const getActionVariant = (action) => {
+const getTypeBadgeVariant = (type) => {
const variants = {
- '登录': 'primary',
- '新增': 'success',
- '修改': 'warning',
- '删除': 'danger',
- '查询': 'secondary'
+ login: 'success',
+ logout: 'secondary',
+ create: 'primary',
+ update: 'warning',
+ delete: 'danger',
+ view: 'info',
+ export: 'success',
+ import: 'success',
+ other: 'secondary'
}
- return variants[action] || 'secondary'
+ return variants[type] || 'secondary'
}
const handleSearch = () => {
@@ -211,19 +265,9 @@ const handleSearch = () => {
loadLogs()
}
-const resetFilters = () => {
- Object.assign(filters, {
- keyword: '',
- module: '',
- action: '',
- startDate: '',
- endDate: ''
- })
- handleSearch()
-}
-
-const handlePageChange = ({ page: newPage }) => {
+const handlePageChange = ({ page: newPage, pageSize: newSize }) => {
page.value = newPage
+ pageSize.value = newSize
loadLogs()
}
@@ -238,12 +282,23 @@ const loadLogs = async () => {
}
const viewDetail = (log) => {
- currentLog.value = log
+ currentLog.value = {
+ ...log,
+ requestData: { username: 'admin' },
+ responseData: { code: 200, message: 'success' },
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
+ }
showDetailModal.value = true
}
-const exportLogs = () => {
- alert('日志导出中...')
+const handleExport = () => {
+ alert('正在导出日志...')
+}
+
+const handleClear = () => {
+ if (confirm('确定要清理 30 天前的日志吗?')) {
+ alert('日志已清理')
+ }
}
onMounted(() => {
diff --git a/frontend/src/pages/system/PermissionList.vue b/frontend/src/pages/system/PermissionList.vue
index da2be90f..ad6a8f36 100644
--- a/frontend/src/pages/system/PermissionList.vue
+++ b/frontend/src/pages/system/PermissionList.vue
@@ -1,6 +1,6 @@
-
+