mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-11-15 14:03:36 +08:00
105
src/views/monitor/logs/system/detail.vue
Normal file
105
src/views/monitor/logs/system/detail.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<script setup lang="tsx">
|
||||
import { ref } from "vue";
|
||||
import "vue-json-pretty/lib/styles.css";
|
||||
import VueJsonPretty from "vue-json-pretty";
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
label: "IP 地址",
|
||||
prop: "ip"
|
||||
},
|
||||
{
|
||||
label: "地点",
|
||||
prop: "address"
|
||||
},
|
||||
{
|
||||
label: "操作系统",
|
||||
prop: "system"
|
||||
},
|
||||
{
|
||||
label: "浏览器类型",
|
||||
prop: "browser"
|
||||
},
|
||||
{
|
||||
label: "所属模块",
|
||||
prop: "module"
|
||||
},
|
||||
{
|
||||
label: "请求时间",
|
||||
prop: "requestTime"
|
||||
},
|
||||
{
|
||||
label: "请求方法",
|
||||
prop: "method"
|
||||
},
|
||||
{
|
||||
label: "请求耗时",
|
||||
prop: "takesTime"
|
||||
},
|
||||
{
|
||||
label: "请求接口",
|
||||
prop: "url",
|
||||
copy: true
|
||||
},
|
||||
{
|
||||
label: "TraceId",
|
||||
prop: "traceId",
|
||||
copy: true
|
||||
}
|
||||
];
|
||||
|
||||
const dataList = ref([
|
||||
{
|
||||
title: "响应头",
|
||||
name: "responseHeaders",
|
||||
data: (props.data[0] as any).responseHeaders
|
||||
},
|
||||
{
|
||||
title: "响应体",
|
||||
name: "responseBody",
|
||||
data: (props.data[0] as any).responseBody
|
||||
},
|
||||
{
|
||||
title: "请求头",
|
||||
name: "requestHeaders",
|
||||
data: (props.data[0] as any).requestHeaders
|
||||
},
|
||||
{
|
||||
title: "请求体",
|
||||
name: "requestBody",
|
||||
data: (props.data[0] as any).requestBody
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-scrollbar>
|
||||
<PureDescriptions
|
||||
border
|
||||
:data="props.data"
|
||||
:columns="columns"
|
||||
:column="5"
|
||||
/>
|
||||
</el-scrollbar>
|
||||
<el-tabs :modelValue="'responseBody'" type="border-card" class="mt-4">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
:name="item.name"
|
||||
:label="item.title"
|
||||
>
|
||||
<el-scrollbar max-height="calc(100vh - 240px)">
|
||||
<vue-json-pretty v-model:data="item.data" />
|
||||
</el-scrollbar>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,9 +1,11 @@
|
||||
import dayjs from "dayjs";
|
||||
import Detail from "./detail.vue";
|
||||
import { message } from "@/utils/message";
|
||||
import { getSystemLogsList } from "@/api/system";
|
||||
import { addDialog } from "@/components/ReDialog";
|
||||
import type { PaginationProps } from "@pureadmin/table";
|
||||
import { type Ref, reactive, ref, onMounted, toRaw } from "vue";
|
||||
import { getKeyList, useCopyToClipboard } from "@pureadmin/utils";
|
||||
import { getSystemLogsList, getSystemLogsDetail } from "@/api/system";
|
||||
import Info from "@iconify-icons/ri/question-line";
|
||||
|
||||
export function useRole(tableRef: Ref) {
|
||||
@@ -126,12 +128,12 @@ export function useRole(tableRef: Ref) {
|
||||
minWidth: 180,
|
||||
formatter: ({ requestTime }) =>
|
||||
dayjs(requestTime).format("YYYY-MM-DD HH:mm:ss")
|
||||
},
|
||||
{
|
||||
label: "操作",
|
||||
fixed: "right",
|
||||
slot: "operation"
|
||||
}
|
||||
// {
|
||||
// label: "操作",
|
||||
// fixed: "right",
|
||||
// slot: "operation"
|
||||
// }
|
||||
];
|
||||
|
||||
function handleSizeChange(val: number) {
|
||||
@@ -157,7 +159,8 @@ export function useRole(tableRef: Ref) {
|
||||
}
|
||||
|
||||
/** 拷贝请求接口,表格单元格被双击时触发 */
|
||||
function handleCellDblclick({ url }) {
|
||||
function handleCellDblclick({ url }, { property }) {
|
||||
if (property !== "url") return;
|
||||
update(url);
|
||||
copied.value
|
||||
? message(`${url} 已拷贝`, { type: "success" })
|
||||
@@ -185,6 +188,20 @@ export function useRole(tableRef: Ref) {
|
||||
onSearch();
|
||||
}
|
||||
|
||||
function onDetail(row) {
|
||||
getSystemLogsDetail({ id: row.id }).then(res => {
|
||||
addDialog({
|
||||
title: "系统日志详情",
|
||||
fullscreen: true,
|
||||
hideFooter: true,
|
||||
contentRenderer: () => Detail,
|
||||
props: {
|
||||
data: [res]
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function onSearch() {
|
||||
loading.value = true;
|
||||
const { data } = await getSystemLogsList(toRaw(form));
|
||||
@@ -216,6 +233,7 @@ export function useRole(tableRef: Ref) {
|
||||
pagination,
|
||||
selectedNum,
|
||||
onSearch,
|
||||
onDetail,
|
||||
clearAll,
|
||||
resetForm,
|
||||
onbatchDel,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getPickerShortcuts } from "../../utils";
|
||||
import { PureTableBar } from "@/components/RePureTableBar";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
|
||||
import View from "@iconify-icons/ep/view";
|
||||
import Delete from "@iconify-icons/ep/delete";
|
||||
import Refresh from "@iconify-icons/ep/refresh";
|
||||
|
||||
@@ -23,6 +24,7 @@ const {
|
||||
pagination,
|
||||
selectedNum,
|
||||
onSearch,
|
||||
onDetail,
|
||||
clearAll,
|
||||
resetForm,
|
||||
onbatchDel,
|
||||
@@ -133,7 +135,20 @@ const {
|
||||
@page-size-change="handleSizeChange"
|
||||
@page-current-change="handleCurrentChange"
|
||||
@cell-dblclick="handleCellDblclick"
|
||||
/>
|
||||
>
|
||||
<template #operation="{ row }">
|
||||
<el-button
|
||||
class="reset-margin !outline-none"
|
||||
link
|
||||
type="primary"
|
||||
:size="size"
|
||||
:icon="useRenderIcon(View)"
|
||||
@click="onDetail(row)"
|
||||
>
|
||||
详情
|
||||
</el-button>
|
||||
</template>
|
||||
</pure-table>
|
||||
</template>
|
||||
</PureTableBar>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user