mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-11-03 00:33:13 +00:00
feat: 运维监控错误详情支持返回列表并保留筛选状态
进入单条错误详情后新增"返回列表"按钮,可回到来源明细列表并保留 筛选/分页状态,避免只能退出到运维监控总览后重新筛选。记录来源列表 类型,返回时跳过列表重开时的筛选重置。
This commit is contained in:
6 files changed
+55
-2
No files matched your search
@@ -307,6 +307,7 @@ export default {
|
|||||||
title: 'Error Detail',
|
title: 'Error Detail',
|
||||||
titleWithId: 'Error #{id}',
|
titleWithId: 'Error #{id}',
|
||||||
noErrorSelected: 'No error selected.',
|
noErrorSelected: 'No error selected.',
|
||||||
|
backToList: 'Back to List',
|
||||||
resolution: 'Resolved:',
|
resolution: 'Resolved:',
|
||||||
failedToUpdateResolvedStatus: 'Failed to update resolved status',
|
failedToUpdateResolvedStatus: 'Failed to update resolved status',
|
||||||
classificationKeys: {
|
classificationKeys: {
|
||||||
|
|||||||
@@ -307,6 +307,7 @@ export default {
|
|||||||
title: '错误详情',
|
title: '错误详情',
|
||||||
titleWithId: '错误 #{id}',
|
titleWithId: '错误 #{id}',
|
||||||
noErrorSelected: '未选择错误。',
|
noErrorSelected: '未选择错误。',
|
||||||
|
backToList: '返回列表',
|
||||||
resolution: '已解决:',
|
resolution: '已解决:',
|
||||||
failedToUpdateResolvedStatus: '更新解决状态失败',
|
failedToUpdateResolvedStatus: '更新解决状态失败',
|
||||||
classificationKeys: {
|
classificationKeys: {
|
||||||
|
|||||||
@@ -119,11 +119,12 @@
|
|||||||
:platform="platform"
|
:platform="platform"
|
||||||
:group-id="groupId"
|
:group-id="groupId"
|
||||||
:error-type="errorDetailsType"
|
:error-type="errorDetailsType"
|
||||||
|
:resume-state="resumeListState"
|
||||||
@update:show="showErrorDetails = $event"
|
@update:show="showErrorDetails = $event"
|
||||||
@openErrorDetail="openError"
|
@openErrorDetail="openError"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<OpsErrorDetailModal v-model:show="showErrorModal" :error-id="selectedErrorId" :error-type="errorDetailsType" />
|
<OpsErrorDetailModal v-model:show="showErrorModal" :error-id="selectedErrorId" :error-type="errorDetailsType" :back-to-list="detailReturnTarget !== null" @back="handleBackToList" />
|
||||||
|
|
||||||
<OpsRequestDetailsModal
|
<OpsRequestDetailsModal
|
||||||
v-model="showRequestDetails"
|
v-model="showRequestDetails"
|
||||||
@@ -131,6 +132,7 @@
|
|||||||
:preset="requestDetailsPreset"
|
:preset="requestDetailsPreset"
|
||||||
:platform="platform"
|
:platform="platform"
|
||||||
:group-id="groupId"
|
:group-id="groupId"
|
||||||
|
:resume-state="resumeListState"
|
||||||
@openErrorDetail="openError"
|
@openErrorDetail="openError"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -377,6 +379,13 @@ const requestDetailsPreset = ref<OpsRequestDetailsPreset>({
|
|||||||
sort: 'created_at_desc'
|
sort: 'created_at_desc'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 记录单条错误详情来自哪个列表,便于"返回列表"时重新打开对应弹窗并保留状态。
|
||||||
|
type DetailReturnTarget = 'errorList' | 'requestList' | null
|
||||||
|
const detailReturnTarget = ref<DetailReturnTarget>(null)
|
||||||
|
|
||||||
|
// 从详情返回时,列表弹窗应保留上一次的筛选/分页状态而非重置。
|
||||||
|
const resumeListState = ref(false)
|
||||||
|
|
||||||
const showSettingsDialog = ref(false)
|
const showSettingsDialog = ref(false)
|
||||||
const showAlertRulesCard = ref(false)
|
const showAlertRulesCard = ref(false)
|
||||||
|
|
||||||
@@ -508,12 +517,34 @@ function onQueryModeChange(v: string | number | boolean | null) {
|
|||||||
|
|
||||||
function openError(id: number) {
|
function openError(id: number) {
|
||||||
selectedErrorId.value = id
|
selectedErrorId.value = id
|
||||||
|
// 记录来源列表,便于详情页"返回列表"。
|
||||||
|
detailReturnTarget.value = showRequestDetails.value ? 'requestList' : showErrorDetails.value ? 'errorList' : null
|
||||||
// Ensure only one modal visible at a time.
|
// Ensure only one modal visible at a time.
|
||||||
showErrorDetails.value = false
|
showErrorDetails.value = false
|
||||||
showRequestDetails.value = false
|
showRequestDetails.value = false
|
||||||
showErrorModal.value = true
|
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() {
|
function buildApiParams() {
|
||||||
const params: any = {
|
const params: any = {
|
||||||
platform: platform.value || undefined,
|
platform: platform.value || undefined,
|
||||||
|
|||||||
@@ -211,6 +211,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<template v-if="backToList" #footer>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
data-testid="error-detail-back-to-list"
|
||||||
|
@click="goBack"
|
||||||
|
>
|
||||||
|
{{ t('admin.ops.errorDetail.backToList') }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -228,10 +238,12 @@ interface Props {
|
|||||||
show: boolean
|
show: boolean
|
||||||
errorId: number | null
|
errorId: number | null
|
||||||
errorType?: 'request' | 'upstream'
|
errorType?: 'request' | 'upstream'
|
||||||
|
backToList?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:show', value: boolean): void
|
(e: 'update:show', value: boolean): void
|
||||||
|
(e: 'back'): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@@ -363,6 +375,11 @@ function close() {
|
|||||||
emit('update:show', false)
|
emit('update:show', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function goBack() {
|
||||||
|
emit('update:show', false)
|
||||||
|
emit('back')
|
||||||
|
}
|
||||||
|
|
||||||
function prettyJSON(raw?: string): string {
|
function prettyJSON(raw?: string): string {
|
||||||
if (!raw) return 'N/A'
|
if (!raw) return 'N/A'
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ interface Props {
|
|||||||
platform?: string
|
platform?: string
|
||||||
groupId?: number | null
|
groupId?: number | null
|
||||||
errorType: 'request' | 'upstream'
|
errorType: 'request' | 'upstream'
|
||||||
|
resumeState?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@@ -167,6 +168,7 @@ watch(
|
|||||||
() => props.show,
|
() => props.show,
|
||||||
(open) => {
|
(open) => {
|
||||||
if (!open) return
|
if (!open) return
|
||||||
|
if (props.resumeState) return
|
||||||
page.value = 1
|
page.value = 1
|
||||||
pageSize.value = 10
|
pageSize.value = 10
|
||||||
resetFilters()
|
resetFilters()
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ interface Props {
|
|||||||
preset: OpsRequestDetailsPreset
|
preset: OpsRequestDetailsPreset
|
||||||
platform?: string
|
platform?: string
|
||||||
groupId?: number | null
|
groupId?: number | null
|
||||||
|
resumeState?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@@ -98,6 +99,7 @@ watch(
|
|||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(open) => {
|
(open) => {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
if (props.resumeState) return
|
||||||
page.value = 1
|
page.value = 1
|
||||||
pageSize.value = 10
|
pageSize.value = 10
|
||||||
fetchData()
|
fetchData()
|
||||||
@@ -142,7 +144,6 @@ async function handleCopyRequestId(requestId: string) {
|
|||||||
|
|
||||||
function openErrorDetail(errorId: number | null | undefined) {
|
function openErrorDetail(errorId: number | null | undefined) {
|
||||||
if (!errorId) return
|
if (!errorId) return
|
||||||
close()
|
|
||||||
emit('openErrorDetail', errorId)
|
emit('openErrorDetail', errorId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user