From cfecc8d113053f58ec93897b95eaec92a410249a Mon Sep 17 00:00:00 2001
From: spongehah <2635879218@qq.com>
Date: Mon, 24 Aug 2026 11:24:51 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E8=BF=90=E7=BB=B4=E7=9B=91=E6=8E=A7?=
=?UTF-8?q?=E9=94=99=E8=AF=AF=E8=AF=A6=E6=83=85=E6=94=AF=E6=8C=81=E8=BF=94?=
=?UTF-8?q?=E5=9B=9E=E5=88=97=E8=A1=A8=E5=B9=B6=E4=BF=9D=E7=95=99=E7=AD=9B?=
=?UTF-8?q?=E9=80=89=E7=8A=B6=E6=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
进入单条错误详情后新增"返回列表"按钮,可回到来源明细列表并保留
筛选/分页状态,避免只能退出到运维监控总览后重新筛选。记录来源列表
类型,返回时跳过列表重开时的筛选重置。
---
frontend/src/i18n/locales/en/admin/ops.ts | 1 +
frontend/src/i18n/locales/zh/admin/ops.ts | 1 +
frontend/src/views/admin/ops/OpsDashboard.vue | 33 ++++++++++++++++++-
.../ops/components/OpsErrorDetailModal.vue | 17 ++++++++++
.../ops/components/OpsErrorDetailsModal.vue | 2 ++
.../ops/components/OpsRequestDetailsModal.vue | 3 +-
6 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/frontend/src/i18n/locales/en/admin/ops.ts b/frontend/src/i18n/locales/en/admin/ops.ts
index fe6a7a28bb..4bb48c64da 100644
--- a/frontend/src/i18n/locales/en/admin/ops.ts
+++ b/frontend/src/i18n/locales/en/admin/ops.ts
@@ -307,6 +307,7 @@ export default {
title: 'Error Detail',
titleWithId: 'Error #{id}',
noErrorSelected: 'No error selected.',
+ backToList: 'Back to List',
resolution: 'Resolved:',
failedToUpdateResolvedStatus: 'Failed to update resolved status',
classificationKeys: {
diff --git a/frontend/src/i18n/locales/zh/admin/ops.ts b/frontend/src/i18n/locales/zh/admin/ops.ts
index 1e521c8914..3e568e1dd7 100644
--- a/frontend/src/i18n/locales/zh/admin/ops.ts
+++ b/frontend/src/i18n/locales/zh/admin/ops.ts
@@ -307,6 +307,7 @@ export default {
title: '错误详情',
titleWithId: '错误 #{id}',
noErrorSelected: '未选择错误。',
+ backToList: '返回列表',
resolution: '已解决:',
failedToUpdateResolvedStatus: '更新解决状态失败',
classificationKeys: {
diff --git a/frontend/src/views/admin/ops/OpsDashboard.vue b/frontend/src/views/admin/ops/OpsDashboard.vue
index cd5c672963..dc482ab074 100644
--- a/frontend/src/views/admin/ops/OpsDashboard.vue
+++ b/frontend/src/views/admin/ops/OpsDashboard.vue
@@ -119,11 +119,12 @@
:platform="platform"
:group-id="groupId"
:error-type="errorDetailsType"
+ :resume-state="resumeListState"
@update:show="showErrorDetails = $event"
@openErrorDetail="openError"
/>
-
+
@@ -377,6 +379,13 @@ const requestDetailsPreset = ref({
sort: 'created_at_desc'
})
+// 记录单条错误详情来自哪个列表,便于"返回列表"时重新打开对应弹窗并保留状态。
+type DetailReturnTarget = 'errorList' | 'requestList' | null
+const detailReturnTarget = ref(null)
+
+// 从详情返回时,列表弹窗应保留上一次的筛选/分页状态而非重置。
+const resumeListState = ref(false)
+
const showSettingsDialog = ref(false)
const showAlertRulesCard = ref(false)
@@ -508,12 +517,34 @@ function onQueryModeChange(v: string | number | boolean | null) {
function openError(id: number) {
selectedErrorId.value = id
+ // 记录来源列表,便于详情页"返回列表"。
+ detailReturnTarget.value = showRequestDetails.value ? 'requestList' : showErrorDetails.value ? 'errorList' : null
// Ensure only one modal visible at a time.
showErrorDetails.value = false
showRequestDetails.value = false
showErrorModal.value = true
}
+// 从单条错误详情返回其来源列表,重新打开关联弹窗(保留筛选/分页状态)。
+function handleBackToList() {
+ const target = detailReturnTarget.value
+ resumeListState.value = true
+ if (target === 'requestList') {
+ showErrorModal.value = false
+ showErrorDetails.value = false
+ showRequestDetails.value = true
+ } else if (target === 'errorList') {
+ showErrorModal.value = false
+ showRequestDetails.value = false
+ showErrorDetails.value = true
+ }
+ detailReturnTarget.value = null
+ // 子组件 watch 在本次 show 变化中消费 resumeState 后复位,保证下次手动打开仍会重置筛选。
+ window.setTimeout(() => {
+ resumeListState.value = false
+ }, 0)
+}
+
function buildApiParams() {
const params: any = {
platform: platform.value || undefined,
diff --git a/frontend/src/views/admin/ops/components/OpsErrorDetailModal.vue b/frontend/src/views/admin/ops/components/OpsErrorDetailModal.vue
index 407c671ca9..8b0dc388f8 100644
--- a/frontend/src/views/admin/ops/components/OpsErrorDetailModal.vue
+++ b/frontend/src/views/admin/ops/components/OpsErrorDetailModal.vue
@@ -211,6 +211,16 @@
+
+
+
@@ -228,10 +238,12 @@ interface Props {
show: boolean
errorId: number | null
errorType?: 'request' | 'upstream'
+ backToList?: boolean
}
interface Emits {
(e: 'update:show', value: boolean): void
+ (e: 'back'): void
}
const props = defineProps()
@@ -363,6 +375,11 @@ function close() {
emit('update:show', false)
}
+function goBack() {
+ emit('update:show', false)
+ emit('back')
+}
+
function prettyJSON(raw?: string): string {
if (!raw) return 'N/A'
try {
diff --git a/frontend/src/views/admin/ops/components/OpsErrorDetailsModal.vue b/frontend/src/views/admin/ops/components/OpsErrorDetailsModal.vue
index 0c513a5f1d..e97e919f6a 100644
--- a/frontend/src/views/admin/ops/components/OpsErrorDetailsModal.vue
+++ b/frontend/src/views/admin/ops/components/OpsErrorDetailsModal.vue
@@ -15,6 +15,7 @@ interface Props {
platform?: string
groupId?: number | null
errorType: 'request' | 'upstream'
+ resumeState?: boolean
}
const props = defineProps()
@@ -167,6 +168,7 @@ watch(
() => props.show,
(open) => {
if (!open) return
+ if (props.resumeState) return
page.value = 1
pageSize.value = 10
resetFilters()
diff --git a/frontend/src/views/admin/ops/components/OpsRequestDetailsModal.vue b/frontend/src/views/admin/ops/components/OpsRequestDetailsModal.vue
index 33ce058149..2d8e885a0c 100644
--- a/frontend/src/views/admin/ops/components/OpsRequestDetailsModal.vue
+++ b/frontend/src/views/admin/ops/components/OpsRequestDetailsModal.vue
@@ -23,6 +23,7 @@ interface Props {
preset: OpsRequestDetailsPreset
platform?: string
groupId?: number | null
+ resumeState?: boolean
}
const props = defineProps()
@@ -98,6 +99,7 @@ watch(
() => props.modelValue,
(open) => {
if (open) {
+ if (props.resumeState) return
page.value = 1
pageSize.value = 10
fetchData()
@@ -142,7 +144,6 @@ async function handleCopyRequestId(requestId: string) {
function openErrorDetail(errorId: number | null | undefined) {
if (!errorId) return
- close()
emit('openErrorDetail', errorId)
}