fix: optimize summary count query and refine row keys for external api logs
This commit is contained in:
@@ -547,8 +547,10 @@ export const externalApiLogsApi = {
|
||||
status_code?: number
|
||||
path?: string
|
||||
}) => api.get<{ total: number }>('/api/external-api-logs/count', { params }),
|
||||
summary: (params?: { slow_ms?: number }) =>
|
||||
summary: (params?: { slow_ms?: number; hours?: number; limit?: number; offset?: number }) =>
|
||||
api.get<ExternalApiLogSummaryItem[]>('/api/external-api-logs/summary', { params }),
|
||||
summaryCount: (params?: { slow_ms?: number; hours?: number }) =>
|
||||
api.get<{ total: number }>('/api/external-api-logs/summary/count', { params }),
|
||||
}
|
||||
|
||||
// ——— Auth Capture ———
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="code-font">
|
||||
<tr v-for="row in summary" :key="row.path + row.method + row.direction" class="hover-row">
|
||||
<tr v-for="row in summary" :key="`${row.path}_${row.method}_${row.direction}_${row.target_type}_${row.target_id ?? row.target_name ?? ''}`" class="hover-row">
|
||||
<td>
|
||||
<span class="direction-tag" :class="row.direction">
|
||||
<svg v-if="row.direction === 'upstream'" class="direction-icon" viewBox="0 0 24 24" width="10" height="10" stroke="currentColor" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 4px; display: inline-block; vertical-align: middle;"><line x1="7" y1="17" x2="17" y2="7"></line><polyline points="7 7 17 7 17 17"></polyline></svg>
|
||||
@@ -90,6 +90,35 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 慢接口汇总分页器 -->
|
||||
<div class="pagination-container" v-if="summaryTotalRecords > 0">
|
||||
<div class="pagination-left">
|
||||
<span>共 <span class="highlight-text">{{ summaryTotalRecords }}</span> 个分组</span>
|
||||
<div class="page-size-selector">
|
||||
<span>每页</span>
|
||||
<select v-model="summaryPageSize" @change="handleSummaryPageSizeChange" class="page-size-select">
|
||||
<option :value="10">10</option>
|
||||
<option :value="20">20</option>
|
||||
<option :value="50">50</option>
|
||||
<option :value="100">100</option>
|
||||
</select>
|
||||
<span>条</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pagination-right">
|
||||
<button :disabled="summaryOffset === 0 || summaryLoading" @click="summaryPrevPage" class="page-btn">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
<span>上一页</span>
|
||||
</button>
|
||||
<span class="page-indicator">第 {{ summaryCurrentPage }} 页</span>
|
||||
<button :disabled="!summaryHasNextPage || summaryLoading" @click="summaryNextPage" class="page-btn">
|
||||
<span>下一页</span>
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 接口调用记录 -->
|
||||
@@ -347,6 +376,14 @@ const pageSize = ref(10)
|
||||
const hasNextPage = ref(false)
|
||||
const totalRecords = ref(0)
|
||||
const currentPage = computed(() => Math.floor(offset.value / pageSize.value) + 1)
|
||||
|
||||
// Slow summary pagination state (independent from list pagination)
|
||||
const summaryOffset = ref(0)
|
||||
const summaryPageSize = ref(10)
|
||||
const summaryTotalRecords = ref(0)
|
||||
const summaryHasNextPage = computed(() => summaryOffset.value + summaryPageSize.value < summaryTotalRecords.value)
|
||||
const summaryCurrentPage = computed(() => Math.floor(summaryOffset.value / summaryPageSize.value) + 1)
|
||||
|
||||
const slowThreshold = 3000
|
||||
|
||||
// In-app Notification System
|
||||
@@ -489,13 +526,36 @@ async function loadList(silent = false) {
|
||||
async function loadSummary(silent = false) {
|
||||
if (!silent) summaryLoading.value = true
|
||||
try {
|
||||
const res = await externalApiLogsApi.summary({ slow_ms: slowThreshold })
|
||||
const [res, countRes] = await Promise.all([
|
||||
externalApiLogsApi.summary({
|
||||
slow_ms: slowThreshold,
|
||||
limit: summaryPageSize.value,
|
||||
offset: summaryOffset.value,
|
||||
}),
|
||||
externalApiLogsApi.summaryCount({ slow_ms: slowThreshold }),
|
||||
])
|
||||
summary.value = res.data
|
||||
summaryTotalRecords.value = countRes.data.total
|
||||
} finally {
|
||||
if (!silent) summaryLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function summaryPrevPage() {
|
||||
summaryOffset.value = Math.max(0, summaryOffset.value - summaryPageSize.value)
|
||||
loadSummary()
|
||||
}
|
||||
|
||||
function summaryNextPage() {
|
||||
summaryOffset.value += summaryPageSize.value
|
||||
loadSummary()
|
||||
}
|
||||
|
||||
function handleSummaryPageSizeChange() {
|
||||
summaryOffset.value = 0
|
||||
loadSummary()
|
||||
}
|
||||
|
||||
function handleFilterChange() {
|
||||
offset.value = 0
|
||||
loadList()
|
||||
|
||||
Reference in New Issue
Block a user