feat(log): 三类日志列表加大小列,详情按 50KB 门槛切换在线预览/下载
build / build (push) Successful in 1m57s

- 推送/操作/开放接口日志列表各加"大小"列(payload_size/response_size,Utils.getFileSize 格式化)
- 详情弹窗:下载按钮常驻;Utils.canPreview(≤50KB) 才显示"在线预览",点击 fetch 复用各自 /Download/{id} 取原文渲染
- oapilog 详情从无条件内联改为同一套门槛逻辑
- utils 新增 PREVIEW_MAX_BYTES 与 canPreview
This commit is contained in:
chenxing
2026-09-18 09:24:38 +08:00
parent 628a914e19
commit d012a99e28
7 changed files with 209 additions and 6 deletions
+7
View File
@@ -156,6 +156,13 @@ const columns = [
align: 'right',
render: (h: any, { row }: any) => h('span', row.costMs != null ? `${row.costMs}` : '-'),
},
{
title: '请求体',
key: 'payloadSize',
width: 100,
align: 'right',
render: (h: any, { row }: any) => h('span', row.payloadSize != null && row.payloadSize > 0 ? Utils.getFileSize(row.payloadSize) : '-'),
},
{
title: '操作',
key: 'action',
+57 -2
View File
@@ -43,7 +43,12 @@
<span>{{ formatTime(row?.createdAt) }}</span>
</FormItem>
<FormItem label="请求体:">
<a v-if="row?.id" href="javascript:;" class="download-link" @click.prevent="handleDownload">下载请求体</a>
<template v-if="row?.id">
<a href="javascript:;" class="download-link" @click.prevent="handleDownload">下载请求体</a>
<a v-if="canPreview" href="javascript:;" class="download-link" style="margin-left: 12px"
@click.prevent="handlePreview">在线预览</a>
<span v-if="sizeText" class="sub-text">({{ sizeText }})</span>
</template>
<span v-else>-</span>
</FormItem>
</Form>
@@ -51,10 +56,17 @@
<Button type="primary" @click="show = false">确定</Button>
</template>
</Modal>
<Modal v-model="previewVisible" title="请求体预览" width="760" :mask-closable="true">
<pre class="json-pre">{{ previewText }}</pre>
<template #footer>
<Button @click="previewVisible = false">关闭</Button>
</template>
</Modal>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, ref } from 'vue';
import useCurrentInstance from '@/utils/hook/useCurrentInstance';
import Utils from '@/utils';
@@ -87,11 +99,40 @@ function onVisibleChange(val: boolean) {
const { $conf } = useCurrentInstance();
const previewVisible = ref(false);
const previewText = ref('');
const canPreview = computed(() => Utils.canPreview(props.row?.payloadSize));
const sizeText = computed(() =>
props.row?.payloadSize != null && props.row.payloadSize > 0 ? Utils.getFileSize(props.row.payloadSize) : ''
);
function handleDownload() {
if (!props.row?.id) return;
location.href = `${$conf.serviceHost}/api/push/Download/${props.row.id}`;
}
async function handlePreview() {
if (!props.row?.id) return;
previewText.value = '加载中…';
previewVisible.value = true;
try {
const res = await fetch(`${$conf.serviceHost}/api/push/Download/${props.row.id}`, { credentials: 'include' });
previewText.value = formatJson(await res.text());
} catch (e: any) {
previewText.value = '预览加载失败:' + (e?.message || e);
}
}
function formatJson(val: string): string {
if (!val) return '-';
try {
return JSON.stringify(JSON.parse(val), null, 2);
} catch {
return val;
}
}
function formatTime(val: any): string {
if (!val) return '-';
return Utils.dateFormat(val, 'yyyy-MM-dd HH:mm:ss');
@@ -135,4 +176,18 @@ function formatTime(val: any): string {
}
}
}
.json-pre {
margin: 0;
padding: 10px 12px;
background: #f7f8fa;
border: 1px solid #e8eaec;
border-radius: 4px;
max-height: 420px;
overflow: auto;
white-space: pre-wrap;
word-break: break-all;
font-size: 13px;
line-height: 1.6;
}
</style>