From 838592253a98d3fef281e84b0d3ab7ddff6b8e2c Mon Sep 17 00:00:00 2001
From: dap1 <15891557205@163.com>
Date: Sat, 10 Jun 2023 13:04:32 +0800
Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E6=93=8D=E4=BD=9C=E6=97=A5?=
=?UTF-8?q?=E6=9C=9F=E8=AF=A6=E6=83=85=E6=9F=A5=E7=9C=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/Table/src/hooks/useRender.ts | 20 +++
src/views/system/operatelog/LogInfoModal.vue | 27 ++++
src/views/system/operatelog/index.vue | 31 ++++-
.../system/operatelog/operateLog.data.ts | 120 ++++++++++++++++--
4 files changed, 183 insertions(+), 15 deletions(-)
create mode 100644 src/views/system/operatelog/LogInfoModal.vue
diff --git a/src/components/Table/src/hooks/useRender.ts b/src/components/Table/src/hooks/useRender.ts
index a7e4eb1a..af1bc4a4 100644
--- a/src/components/Table/src/hooks/useRender.ts
+++ b/src/components/Table/src/hooks/useRender.ts
@@ -5,6 +5,7 @@ import { isArray, isString } from '@/utils/is'
import { DictTag } from '@/components/DictTag'
import { Icon } from '@/components/Icon'
import TableImg from '../components/TableImg.vue'
+import { JsonPreview } from '@/components/CodeEditor'
export const useRender = {
/**
@@ -112,5 +113,24 @@ export const useRender = {
if (text) {
return h(Icon, { icon: text })
}
+ },
+ /**
+ * 使用JsonPreview组件 方便预览JSON
+ * @param json json字符串/obj
+ * @returns 能转为json返回JsonPreview 否则返回自身
+ */
+ renderJsonPreview: (json: any) => {
+ if (!json) return ''
+ if (typeof json === 'object') {
+ return h(JsonPreview, { data: json })
+ }
+ if (typeof json === 'string') {
+ try {
+ const data = JSON.parse(json)
+ return h(JsonPreview, { data })
+ } catch (e) {
+ return json
+ }
+ }
}
}
diff --git a/src/views/system/operatelog/LogInfoModal.vue b/src/views/system/operatelog/LogInfoModal.vue
new file mode 100644
index 00000000..63d1971b
--- /dev/null
+++ b/src/views/system/operatelog/LogInfoModal.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/operatelog/index.vue b/src/views/system/operatelog/index.vue
index c5f28a83..93fbd163 100644
--- a/src/views/system/operatelog/index.vue
+++ b/src/views/system/operatelog/index.vue
@@ -4,16 +4,32 @@
{{ t('action.export') }}
+
+
+
+
+
+
diff --git a/src/views/system/operatelog/operateLog.data.ts b/src/views/system/operatelog/operateLog.data.ts
index 8e0473c4..d509b9e3 100644
--- a/src/views/system/operatelog/operateLog.data.ts
+++ b/src/views/system/operatelog/operateLog.data.ts
@@ -1,5 +1,6 @@
import { BasicColumn, FormSchema, useRender } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import { DescItem } from '@/components/Description/index'
export const columns: BasicColumn[] = [
{
@@ -10,7 +11,7 @@ export const columns: BasicColumn[] = [
{
title: '操作模块',
dataIndex: 'module',
- width: 120
+ width: 200
},
{
title: '操作名',
@@ -20,7 +21,7 @@ export const columns: BasicColumn[] = [
{
title: '操作类型',
dataIndex: 'type',
- width: 180,
+ width: 120,
customRender: ({ text }) => {
return useRender.renderDict(text, DICT_TYPE.SYSTEM_OPERATE_TYPE)
}
@@ -30,10 +31,14 @@ export const columns: BasicColumn[] = [
dataIndex: 'userNickname',
width: 120
},
+ // {
+ // title: 'userAgent',
+ // dataIndex: 'userAgent',
+ // width: 400
+ // },
{
- title: 'userAgent',
- dataIndex: 'userAgent',
- width: 400
+ title: '请求路径',
+ dataIndex: 'requestUrl'
},
{
title: '操作结果',
@@ -43,14 +48,6 @@ export const columns: BasicColumn[] = [
return useRender.renderTag(text === 0 ? '成功' : '失败', text === 0 ? '#87d068' : '#f50')
}
},
- {
- title: '操作日期',
- dataIndex: 'startTime',
- width: 180,
- customRender: ({ text }) => {
- return useRender.renderDate(text)
- }
- },
{
title: '执行时长',
dataIndex: 'duration',
@@ -58,6 +55,14 @@ export const columns: BasicColumn[] = [
customRender: ({ text }) => {
return useRender.renderText(text, 'ms')
}
+ },
+ {
+ title: '操作日期',
+ dataIndex: 'startTime',
+ width: 180,
+ customRender: ({ text }) => {
+ return useRender.renderDate(text)
+ }
}
]
@@ -102,3 +107,92 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 8 }
}
]
+
+const httpMethods = [
+ { value: 'GET', color: '#108ee9' },
+ { value: 'POST', color: '#2db7f5' },
+ { value: 'PUT', color: 'warning' },
+ { value: 'DELETE', color: '#f50' }
+]
+
+export const infoSchema: DescItem[] = [
+ {
+ field: 'module',
+ label: '操作模块'
+ },
+ {
+ field: 'name',
+ label: '操作名'
+ },
+ {
+ field: 'userNickname',
+ label: '操作人',
+ render(_, data) {
+ const { userNickname, userId } = data
+ return useRender.renderText(userNickname, 'uid: ' + userId)
+ }
+ },
+ {
+ field: 'resultCode',
+ label: '请求结果',
+ render(value) {
+ return useRender.renderTag(value === 0 ? '成功' : '失败', value === 0 ? '#87d068' : '#f50')
+ }
+ },
+ {
+ field: 'resultMsg',
+ label: '响应信息',
+ show(data) {
+ return data && data.resultMsg && data.resultMsg !== ''
+ }
+ },
+ {
+ field: 'userIp',
+ label: '请求ip'
+ },
+ {
+ field: 'startTime',
+ label: '请求时间',
+ render(value) {
+ return useRender.renderDate(value)
+ }
+ },
+ {
+ field: 'requestUrl',
+ label: '请求路径'
+ },
+ {
+ field: 'requestMethod',
+ label: '请求方法',
+ render(value) {
+ const current = httpMethods.find((item) => item.value === value.toUpperCase())
+ if (current) {
+ return useRender.renderTag(value, current.color)
+ }
+ return value
+ }
+ },
+ {
+ field: 'javaMethod',
+ label: '操作方法',
+ labelMinWidth: 80
+ },
+ {
+ field: 'javaMethodArgs',
+ label: '请求参数',
+ render(value) {
+ return useRender.renderJsonPreview(value)
+ }
+ },
+ {
+ field: 'userAgent',
+ label: 'userAgent'
+ },
+ {
+ field: 'duration',
+ label: '请求耗时',
+ render(value) {
+ return useRender.renderText(value, 'ms')
+ }
+ }
+]
From 02d0c92e8993f2f0c2bee36fb2f1914b6410f7f8 Mon Sep 17 00:00:00 2001
From: dap1 <15891557205@163.com>
Date: Sat, 10 Jun 2023 13:47:57 +0800
Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=E5=AD=97=E5=85=B8=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE=E4=BF=AE=E6=94=B9=E6=94=AF=E6=8C=81=E9=A2=84=E8=A7=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/system/dict/dict.data.ts | 126 ++++++++++++++++-------------
1 file changed, 71 insertions(+), 55 deletions(-)
diff --git a/src/views/system/dict/dict.data.ts b/src/views/system/dict/dict.data.ts
index b1173b99..1d21ed9e 100644
--- a/src/views/system/dict/dict.data.ts
+++ b/src/views/system/dict/dict.data.ts
@@ -1,6 +1,74 @@
import { BasicColumn, FormSchema, useRender } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+const options = [
+ {
+ value: '',
+ label: '无'
+ },
+ {
+ value: 'processing',
+ label: '主要'
+ },
+ {
+ value: 'success',
+ label: '成功'
+ },
+ {
+ value: 'default',
+ label: '默认'
+ },
+ {
+ value: 'warning',
+ label: '警告'
+ },
+ {
+ value: 'error',
+ label: '危险'
+ },
+ {
+ value: 'pink',
+ label: 'pink'
+ },
+ {
+ value: 'red',
+ label: 'red'
+ },
+ {
+ value: 'orange',
+ label: 'orange'
+ },
+ {
+ value: 'green',
+ label: 'green'
+ },
+ {
+ value: 'cyan',
+ label: 'cyan'
+ },
+ {
+ value: 'blue',
+ label: 'blue'
+ },
+ {
+ value: 'purple',
+ label: 'purple'
+ }
+]
+
+function previewOptions() {
+ return options.map((option) => {
+ const { value, label } = option
+ if (value === '') {
+ return option
+ }
+ return {
+ label: useRender.renderTag(label, value),
+ value
+ }
+ })
+}
+
export const dataColumns: BasicColumn[] = [
{
title: '字典编码',
@@ -119,67 +187,15 @@ export const dataFormSchema: FormSchema[] = [
field: 'colorType',
component: 'Select',
componentProps: {
- options: [
- {
- value: '',
- label: '空'
- },
- {
- value: 'processing',
- label: '主要'
- },
- {
- value: 'success',
- label: '成功'
- },
- {
- value: 'default',
- label: '默认'
- },
- {
- value: 'warning',
- label: '警告'
- },
- {
- value: 'error',
- label: '危险'
- },
- {
- value: 'pink',
- label: 'pink'
- },
- {
- value: 'red',
- label: 'red'
- },
- {
- value: 'orange',
- label: 'orange'
- },
- {
- value: 'green',
- label: 'green'
- },
- {
- value: 'cyan',
- label: 'cyan'
- },
- {
- value: 'blue',
- label: 'blue'
- },
- {
- value: 'purple',
- label: 'purple'
- }
- ]
+ options: previewOptions()
}
},
{
label: 'CSS Class',
field: 'cssClass',
component: 'Input',
- helpMessage: '输入hex模式的颜色,例如#108ee9'
+ helpMessage: '输入hex模式的颜色, 例如#108ee9',
+ rules: [{ required: false, message: '输入正确的16进制颜色', pattern: /^#([0-9a-fA-F]{3}){1,2}$/, trigger: 'blur' }]
},
{
label: '备注',
From dae144ccf9ad27f7599a97463924562d8cbf5cf6 Mon Sep 17 00:00:00 2001
From: dap1 <15891557205@163.com>
Date: Sat, 10 Jun 2023 20:03:00 +0800
Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=E4=B8=80=E4=BA=9B=E6=97=A5?=
=?UTF-8?q?=E5=BF=97=E7=9A=84=E8=AF=A6=E6=83=85=E6=9F=A5=E7=9C=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../infra/apiAccessLog/AccessLogModal.vue | 27 ++++
.../infra/apiAccessLog/apiAccessLog.data.ts | 104 ++++++++++++-
src/views/infra/apiAccessLog/index.vue | 31 +++-
src/views/infra/apiErrorLog/ErrorLogModal.vue | 27 ++++
.../infra/apiErrorLog/apiErrorLog.data.ts | 139 ++++++++++++++++++
src/views/infra/apiErrorLog/index.vue | 15 +-
.../system/operatelog/operateLog.data.ts | 25 ++--
7 files changed, 353 insertions(+), 15 deletions(-)
create mode 100644 src/views/infra/apiAccessLog/AccessLogModal.vue
create mode 100644 src/views/infra/apiErrorLog/ErrorLogModal.vue
diff --git a/src/views/infra/apiAccessLog/AccessLogModal.vue b/src/views/infra/apiAccessLog/AccessLogModal.vue
new file mode 100644
index 00000000..45a65715
--- /dev/null
+++ b/src/views/infra/apiAccessLog/AccessLogModal.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/infra/apiAccessLog/apiAccessLog.data.ts b/src/views/infra/apiAccessLog/apiAccessLog.data.ts
index 12bb65a2..eae52ff0 100644
--- a/src/views/infra/apiAccessLog/apiAccessLog.data.ts
+++ b/src/views/infra/apiAccessLog/apiAccessLog.data.ts
@@ -1,5 +1,7 @@
import { BasicColumn, FormSchema, useRender } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import { DescItem } from '@/components/Description/index'
+import { h } from 'vue'
export const columns: BasicColumn[] = [
{
@@ -58,7 +60,7 @@ export const columns: BasicColumn[] = [
ellipsis: true,
customRender: ({ record }) => {
const success = record.resultCode === 0
- return useRender.renderTag(success ? '成功' : '失败(' + record.resultMsg + ')', success ? '#87d068' : '#f50')
+ return useRender.renderTag(success ? '成功' : '失败', success ? '#87d068' : '#f50')
}
}
]
@@ -110,3 +112,103 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 8 }
}
]
+
+const httpMethods = [
+ { value: 'GET', color: '#108ee9' },
+ { value: 'POST', color: '#2db7f5' },
+ { value: 'PUT', color: 'warning' },
+ { value: 'DELETE', color: '#f50' }
+]
+
+export const infoSchema: DescItem[] = [
+ {
+ label: '日志id',
+ field: 'id'
+ },
+ {
+ label: '链路id',
+ field: 'traceId',
+ show: (data) => data && data.traceId && data.traceId !== ''
+ },
+ {
+ label: '应用名称',
+ field: 'applicationName',
+ labelMinWidth: 100
+ },
+ {
+ field: 'userId',
+ label: '用户id',
+ render(value, data) {
+ const tag = useRender.renderDict(data.userType, DICT_TYPE.USER_TYPE)
+ const uidTag = useRender.renderTag('uid: ' + value)
+ return h('span', {}, [tag, uidTag])
+ }
+ },
+ {
+ field: 'resultCode',
+ label: '请求结果',
+ render(value) {
+ return useRender.renderTag(value === 0 ? '成功' : '失败', value === 0 ? '#87d068' : '#f50')
+ }
+ },
+ {
+ field: 'resultMsg',
+ label: '响应信息',
+ show(data) {
+ return data && data.resultMsg && data.resultMsg !== ''
+ },
+ render(value) {
+ return h('span', { style: { color: 'red', fontWeight: 'bold' } }, value)
+ }
+ },
+ {
+ field: 'userIp',
+ label: '请求ip'
+ },
+ {
+ field: 'userAgent',
+ label: 'userAgent'
+ },
+ {
+ field: 'beginTime',
+ label: '请求时间',
+ render(value) {
+ return useRender.renderDate(value)
+ }
+ },
+ {
+ field: 'requestUrl',
+ label: '请求路径',
+ render(_, data) {
+ if (!data) {
+ return ''
+ }
+ const { requestMethod, requestUrl } = data
+ const current = httpMethods.find((item) => item.value === requestMethod.toUpperCase())
+ const methodTag = current ? useRender.renderTag(requestMethod, current.color) : requestMethod
+ return h('span', {}, [methodTag, requestUrl])
+ }
+ },
+ {
+ field: 'beginTime',
+ label: '请求开始时间',
+ render(value) {
+ return useRender.renderDate(value)
+ }
+ },
+ {
+ field: 'endTime',
+ label: '请求结束时间',
+ render(value) {
+ return useRender.renderDate(value)
+ }
+ },
+ {
+ field: 'duration',
+ label: '请求耗时',
+ render(value) {
+ // 为0的话需要转为string 否则不会显示
+ return useRender.renderText(String(value), 'ms')
+ }
+ }
+]
diff --git a/src/views/infra/apiAccessLog/index.vue b/src/views/infra/apiAccessLog/index.vue
index ce222317..dd9ee2ec 100644
--- a/src/views/infra/apiAccessLog/index.vue
+++ b/src/views/infra/apiAccessLog/index.vue
@@ -6,16 +6,32 @@
{{ t('action.export') }}
+
+
+
+
+
+
+
+
diff --git a/src/views/infra/apiErrorLog/apiErrorLog.data.ts b/src/views/infra/apiErrorLog/apiErrorLog.data.ts
index f3191681..bdc55f71 100644
--- a/src/views/infra/apiErrorLog/apiErrorLog.data.ts
+++ b/src/views/infra/apiErrorLog/apiErrorLog.data.ts
@@ -1,5 +1,8 @@
import { BasicColumn, FormSchema, useRender } from '@/components/Table'
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import { Textarea } from 'ant-design-vue'
+import { h } from 'vue'
+import { DescItem } from '@/components/Description/index'
export const columns: BasicColumn[] = [
{
@@ -108,3 +111,139 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 8 }
}
]
+
+function renderText(value: string, color: string, bold = true) {
+ return h('span', { style: { color, fontWeight: bold ? 'bold' : 'normal' } }, value)
+}
+
+const httpMethods = [
+ { value: 'GET', color: '#108ee9' },
+ { value: 'POST', color: '#2db7f5' },
+ { value: 'PUT', color: 'warning' },
+ { value: 'DELETE', color: '#f50' }
+]
+
+export const infoSchema: DescItem[] = [
+ {
+ field: 'id',
+ label: '异常id'
+ },
+ {
+ field: 'traceId',
+ label: '链路ID',
+ show(data) {
+ return data && data.traceId && data.traceId !== ''
+ }
+ },
+ {
+ field: 'applicationName',
+ label: '应用名称',
+ labelMinWidth: 100
+ },
+ {
+ field: 'processStatus',
+ label: '处理状态',
+ render(_, data) {
+ const { processStatus, processUserId } = data
+ const tag = useRender.renderDict(processStatus, DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS)
+ if (!processUserId) {
+ return tag
+ }
+ const uidTag = useRender.renderTag('uid: ' + processUserId)
+ return h('span', {}, [tag, uidTag])
+ }
+ },
+ {
+ field: 'processTime',
+ label: '处理时间',
+ show(data) {
+ return data && data.processTime && data.processTime !== ''
+ },
+ render(value) {
+ return useRender.renderDate(value)
+ }
+ },
+ {
+ field: 'userId',
+ label: '用户id',
+ render(value, data) {
+ const tag = useRender.renderDict(data.userType, DICT_TYPE.USER_TYPE)
+ const uidTag = useRender.renderTag('uid: ' + value)
+ return h('span', {}, [tag, uidTag])
+ }
+ },
+ {
+ field: 'userIp',
+ label: 'ip地址'
+ },
+ {
+ field: 'requestUrl',
+ label: '请求地址',
+ render(_, data) {
+ if (data) {
+ const { requestMethod } = data
+ const current = httpMethods.find((item) => item.value === requestMethod)
+ const tag = current ? useRender.renderTag(requestMethod, current.color) : requestMethod
+ return h('span', {}, [tag, data.requestUrl])
+ }
+ }
+ },
+ {
+ field: 'requestParams',
+ label: '请求参数',
+ render(value) {
+ return useRender.renderJsonPreview(value)
+ }
+ },
+ {
+ field: 'userAgent',
+ label: 'userAgent'
+ },
+ {
+ field: 'exceptionTime',
+ label: '异常时间',
+ render(value) {
+ return useRender.renderDate(value)
+ }
+ },
+ {
+ field: 'exceptionClassName',
+ label: '异常类名/方法',
+ render(_, data) {
+ if (data) {
+ return renderText(data.exceptionClassName + ' / ' + data.exceptionMethodName, 'red')
+ }
+ }
+ },
+ {
+ field: 'exceptionMessage',
+ label: '异常信息',
+ render(value) {
+ return renderText(value, 'red')
+ }
+ },
+ {
+ field: 'exceptionFileName',
+ label: '异常文件名',
+ render(_, data) {
+ if (data) {
+ return useRender.renderText(data.exceptionFileName, 'Line: ' + data.exceptionLineNumber)
+ }
+ }
+ },
+ {
+ field: 'exceptionName',
+ label: '异常名称'
+ },
+ {
+ field: 'exceptionRootCauseMessage',
+ label: '异常信息'
+ },
+ {
+ field: 'exceptionStackTrace',
+ label: '异常堆栈',
+ render(value) {
+ return h(Textarea, { value, readonly: true, style: { minHeight: '300px' } })
+ }
+ }
+]
diff --git a/src/views/infra/apiErrorLog/index.vue b/src/views/infra/apiErrorLog/index.vue
index b018151c..ddd53998 100644
--- a/src/views/infra/apiErrorLog/index.vue
+++ b/src/views/infra/apiErrorLog/index.vue
@@ -10,6 +10,11 @@