😎优化请求日志页面

This commit is contained in:
zuohuaijun 2025-08-28 11:09:59 +08:00
parent 625af173ea
commit 1d62e2f6ce
3 changed files with 74 additions and 51 deletions

View File

@ -81,7 +81,7 @@
"vue-router": "^4.5.1",
"vue-signature-pad": "^3.0.2",
"vue3-tree-org": "^4.2.2",
"vxe-pc-ui": "^4.9.5",
"vxe-pc-ui": "^4.9.6",
"vxe-table": "^4.16.1",
"xe-utils": "^3.7.8",
"xlsx-js-style": "^1.2.0"
@ -96,7 +96,7 @@
"@typescript-eslint/eslint-plugin": "^8.41.0",
"@typescript-eslint/parser": "^8.41.0",
"@vitejs/plugin-vue": "^6.0.1",
"@vitejs/plugin-vue-jsx": "^5.1.0",
"@vitejs/plugin-vue-jsx": "^5.1.1",
"@vue/compiler-sfc": "^3.5.20",
"cli-progress": "^3.12.0",
"code-inspector-plugin": "^1.2.6",

View File

@ -8,42 +8,60 @@
</template>
<el-scrollbar height="calc(100vh - 250px)">
<el-form :model="data" label-width="auto">
<el-tabs v-model="state.selectedTabName">
<el-tab-pane label="请求信息">
<el-form-item label="客户端">
{{ data.httpClientName }}
</el-form-item>
<el-form-item label="接口描述">
{{ data.httpApiDesc }}
</el-form-item>
<el-form-item label="请求地址">
{{ data.requestUrl?.indexOf('?') == -1 ? data.requestUrl : data.requestUrl?.substring(0, data.requestUrl.indexOf('?')) }}
</el-form-item>
<el-form-item label="Query参数" v-if="data.requestUrl?.indexOf('?') != -1">
<el-row v-for="(value, key, index) in queryObject">
<span class="query-key">{{ key }}</span> = <span class="query-value">{{ value }}</span
>&
</el-row>
</el-form-item>
<el-form-item label="请求头">
<vue-json-pretty :data="data.requestHeaders" showLength showIcon showLineNumber showSelectController />
</el-form-item>
<el-form-item label="请求体">
<vue-json-pretty :data="data.requestBody" showLength showIcon showLineNumber showSelectController />
</el-form-item>
</el-tab-pane>
<el-tab-pane label="响应信息">
<el-form-item label="响应头">
<vue-json-pretty :data="data.responseHeaders" showLength showIcon showLineNumber showSelectController />
</el-form-item>
<el-form-item label="响应体">
<vue-json-pretty :data="data.responseBody" showLength showIcon showLineNumber showSelectController />
</el-form-item>
</el-tab-pane>
<el-tab-pane label="异常信息" v-if="data.exception">
<el-descriptions :column="3" :label-width="80" border>
<el-descriptions-item label="请求地址" :width="380">
{{ data.requestUrl?.indexOf('?') == -1 ? data.requestUrl : data.requestUrl?.substring(0, data.requestUrl.indexOf('?')) }}
</el-descriptions-item>
<el-descriptions-item :span="2" label="状态码">
{{ data.statusCode }}
</el-descriptions-item>
<el-descriptions-item label="客户端">
{{ data.httpClientName }}
</el-descriptions-item>
<el-descriptions-item :span="2" label="接口描述">
{{ data.httpApiDesc }}
</el-descriptions-item>
<el-descriptions-item label="开始时间">
{{ data.startTime }}
</el-descriptions-item>
<el-descriptions-item label="结束时间">
{{ data.endTime }}
</el-descriptions-item>
<el-descriptions-item label="耗时"> {{ data.elapsed }} ms </el-descriptions-item>
<el-descriptions-item label="创建人">
{{ data.createUserName }}
</el-descriptions-item>
<el-descriptions-item :span="2" label="创建时间">
{{ data.createTime }}
</el-descriptions-item>
<el-descriptions-item :span="3" label="请求头" class-name="row-line">
<vue-json-pretty :data="data.requestHeaders" showLength showIcon showLineNumber showSelectController />
</el-descriptions-item>
<el-descriptions-item :span="3" label="请求参数" class-name="row-line" v-if="data.requestUrl?.indexOf('?') != -1">
<el-row v-for="(value, key, index) in queryObject">
<span class="query-key">{{ key }}</span> = <span class="query-value">{{ value }}</span
>&
</el-row>
</el-descriptions-item>
<el-descriptions-item :span="3" label="请求体" class-name="row-line">
<vue-json-pretty :data="data.requestBody" showLength showIcon showLineNumber showSelectController />
</el-descriptions-item>
<el-descriptions-item :span="3" label="请求明文" class-name="row-line" v-if="data.requestBodyPlaintext">
<vue-json-pretty :data="data.requestBodyPlaintext" showLength showIcon showLineNumber showSelectController />
</el-descriptions-item>
<el-descriptions-item :span="3" label="响应头" class-name="row-line">
<vue-json-pretty :data="data.responseHeaders" showLength showIcon showLineNumber showSelectController />
</el-descriptions-item>
<el-descriptions-item :span="3" label="响应体" class-name="row-line">
<vue-json-pretty :data="data.responseBody" showLength showIcon showLineNumber showSelectController />
</el-descriptions-item>
<el-descriptions-item :span="3" label="响应明文" class-name="row-line" v-if="data.responseBodyPlaintext">
<vue-json-pretty :data="data.responseBodyPlaintext" showLength showIcon showLineNumber showSelectController />
</el-descriptions-item>
<el-descriptions-item :span="3" label="异常信息" class-name="row-line" v-if="data.exception">
<vue-json-pretty :data="data.exception" showLength showIcon showLineNumber showSelectController />
</el-tab-pane>
</el-tabs>
</el-descriptions-item>
</el-descriptions>
</el-form>
</el-scrollbar>
<template #footer>
@ -52,27 +70,27 @@
</el-dialog>
</template>
<!-- 远程请求日志 -->
<script lang="ts" setup>
import { ref, reactive, computed } from 'vue';
import { StringToObj } from '/@/utils/json-utils';
import { SysLogHttp } from '/@/api-services/system/models';
import VueJsonPretty from 'vue-json-pretty';
const data = ref<SysLogHttp>({});
const state = reactive({
visible: false,
selectedTabName: '0',
});
const data = ref<SysLogHttp>({});
const openDialog = (row: any) => {
state.visible = true;
state.selectedTabName = '0';
Object.assign(data.value, row);
data.value.requestUrl = StringToObj(row.requestUrl);
data.value.requestHeaders = StringToObj(row.requestHeaders);
data.value.requestBody = StringToObj(row.requestBody);
data.value.requestBodyPlaintext = StringToObj(row.requestBodyPlaintext);
data.value.responseHeaders = StringToObj(row.responseHeaders);
data.value.responseBody = StringToObj(row.responseBody);
data.value.responseBodyPlaintext = StringToObj(row.responseBodyPlaintext);
data.value.exception = StringToObj(row.exception);
};
@ -90,4 +108,7 @@ defineExpose({
.query-key {
color: #d55fde;
}
:deep(td.row-line) {
border-bottom: 1.5px solid #dadadd !important;
}
</style>

View File

@ -3,7 +3,6 @@
<el-card shadow="hover" :body-style="{ padding: '5px 5px 0 5px' }">
<scEcharts v-if="echartsOption.series.data" height="200px" :option="echartsOption" @clickData="clickData"></scEcharts>
</el-card>
<el-card shadow="hover" :body-style="{ padding: '5px', display: 'flex', width: '100%', height: '100%', alignItems: 'start' }">
<el-form :model="state.queryParams" ref="queryForm" :show-message="false" :inlineMessage="true" label-width="auto" style="flex: 1 1 0%">
<el-row :gutter="10">
@ -122,21 +121,23 @@
</div>
</template>
<!-- 请求日志 -->
<!-- 远程请求日志 -->
<script lang="ts" setup name="sysLogHttp">
import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { Local } from '/@/utils/storage';
import { getAPI } from '/@/utils/axios-utils';
import { useVxeTable } from '/@/hooks/useVxeTableOptionsHook';
import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
import { VxeGridInstance, VxeGridListeners, VxeGridPropTypes } from 'vxe-table';
import { PageLogHttpInput, PageLogHttpOutput } from '/@/api-services/system/models';
import { SysLogHttpApi } from '/@/api-services/system/api';
import ModifyRecord from '/@/components/table/modifyRecord.vue';
import commonFunction from '/@/utils/commonFunction';
import logDetail from './component/logDetail.vue';
import 'vue-json-pretty/lib/styles.css';
import logDetail from './component/logDetail.vue';
import ModifyRecord from '/@/components/table/modifyRecord.vue';
import { getAPI } from '/@/utils/axios-utils';
import { SysLogHttpApi } from '/@/api-services/system/api';
import { PageLogHttpInput, PageLogHttpOutput } from '/@/api-services/system/models';
const scEcharts = defineAsyncComponent(() => import('/@/components/scEcharts/index.vue'));
const commonFun = commonFunction();
@ -163,11 +164,11 @@ const options = useVxeTable<PageLogHttpOutput>(
// { type: 'checkbox', width: 40, fixed: 'left' },
{ field: 'seq', type: 'seq', title: '序号', width: 60, fixed: 'left' },
{ field: 'createTime', title: '创建时间', minWidth: 150, showOverflow: 'tooltip' },
{ field: 'httpApiDesc', title: '接口描述', minWidth: 150, showOverflow: 'tooltip' },
{ field: 'httpClientName', title: '客户端', minWidth: 110, showOverflow: 'tooltip' },
{ field: 'actionName', title: '模块名', minWidth: 110, showOverflow: 'tooltip' },
{ field: 'httpMethod', title: '请求方式', minWidth: 60, showOverflow: 'tooltip' },
{ field: 'isSuccessStatusCode', title: '是否成功', minWidth: 60, showOverflow: 'tooltip', slots: { default: 'row_isSuccessStatusCode' } },
{ field: 'httpApiDesc', title: '接口描述', minWidth: 150, showOverflow: 'tooltip' },
{ field: 'requestUrl', title: '请求地址', minWidth: 150, align: 'left', showOverflow: 'tooltip', slots: { default: 'row_requestUrl' } },
{ field: 'requestHeaders', title: '请求头', minWidth: 150, showOverflow: 'tooltip' },
{ field: 'requestBody', title: '请求体', minWidth: 150, showOverflow: 'tooltip', slots: { default: 'row_requestBody' } },
@ -316,6 +317,7 @@ const clickData = (e: any) => {
state.queryParams.createTimeRange.push(new Date(endTime));
xGrid.value?.commitProxy('query');
};
//
const getYearDayStatsData = async () => {
let data = [] as any;
@ -350,4 +352,4 @@ const gridEvents: VxeGridListeners<PageLogHttpOutput> = {
};
</script>
<style lang="scss" scoped></style>
<style lang="less" scoped></style>