feat(ops): 前端集成实时流量功能

- 添加实时流量API调用方法
- 优化OpsDashboard组件代码
This commit is contained in:
IanShaw027
2026-01-12 14:18:16 +08:00
parent 62771583e7
commit 5443efd7d7
2 changed files with 40 additions and 78 deletions

View File

@@ -362,6 +362,45 @@ export async function getAccountAvailabilityStats(platform?: string, groupId?: n
return data
}
export interface OpsRateSummary {
current: number
peak: number
avg: number
}
export interface OpsRealtimeTrafficSummary {
window: string
start_time: string
end_time: string
platform: string
group_id?: number | null
qps: OpsRateSummary
tps: OpsRateSummary
}
export interface OpsRealtimeTrafficSummaryResponse {
enabled: boolean
summary: OpsRealtimeTrafficSummary | null
timestamp?: string
}
export async function getRealtimeTrafficSummary(
window: string,
platform?: string,
groupId?: number | null
): Promise<OpsRealtimeTrafficSummaryResponse> {
const params: Record<string, any> = { window }
if (platform) {
params.platform = platform
}
if (typeof groupId === 'number' && groupId > 0) {
params.group_id = groupId
}
const { data } = await apiClient.get<OpsRealtimeTrafficSummaryResponse>('/admin/ops/realtime-traffic', { params })
return data
}
/**
* Subscribe to realtime QPS updates via WebSocket.
*
@@ -957,6 +996,7 @@ export const opsAPI = {
getErrorDistribution,
getConcurrencyStats,
getAccountAvailabilityStats,
getRealtimeTrafficSummary,
subscribeQPS,
listErrorLogs,
getErrorLogDetail,

View File

@@ -13,11 +13,6 @@
<OpsDashboardHeader
v-else-if="opsEnabled"
:overview="overview"
:ws-status="wsStatus"
:ws-reconnect-in-ms="wsReconnectInMs"
:ws-has-data="wsHasData"
:real-time-qps="realTimeQPS"
:real-time-tps="realTimeTPS"
:platform="platform"
:group-id="groupId"
:time-range="timeRange"
@@ -116,8 +111,6 @@ import AppLayout from '@/components/layout/AppLayout.vue'
import BaseDialog from '@/components/common/BaseDialog.vue'
import {
opsAPI,
OPS_WS_CLOSE_CODES,
type OpsWSStatus,
type OpsDashboardOverview,
type OpsErrorDistributionResponse,
type OpsErrorTrendResponse,
@@ -174,14 +167,6 @@ const QUERY_KEYS = {
const isApplyingRouteQuery = ref(false)
const isSyncingRouteQuery = ref(false)
// WebSocket for realtime QPS/TPS
const realTimeQPS = ref(0)
const realTimeTPS = ref(0)
const wsStatus = ref<OpsWSStatus>('closed')
const wsReconnectInMs = ref<number | null>(null)
const wsHasData = ref(false)
let unsubscribeQPS: (() => void) | null = null
let dashboardFetchController: AbortController | null = null
let dashboardFetchSeq = 0
@@ -201,50 +186,6 @@ function abortDashboardFetch() {
}
}
function stopQPSSubscription(options?: { resetMetrics?: boolean }) {
wsStatus.value = 'closed'
wsReconnectInMs.value = null
if (unsubscribeQPS) unsubscribeQPS()
unsubscribeQPS = null
if (options?.resetMetrics) {
realTimeQPS.value = 0
realTimeTPS.value = 0
wsHasData.value = false
}
}
function startQPSSubscription() {
stopQPSSubscription()
unsubscribeQPS = opsAPI.subscribeQPS(
(payload) => {
if (payload && typeof payload === 'object' && payload.type === 'qps_update' && payload.data) {
realTimeQPS.value = payload.data.qps || 0
realTimeTPS.value = payload.data.tps || 0
wsHasData.value = true
}
},
{
onStatusChange: (status) => {
wsStatus.value = status
if (status === 'connected') wsReconnectInMs.value = null
},
onReconnectScheduled: ({ delayMs }) => {
wsReconnectInMs.value = delayMs
},
onFatalClose: (event) => {
// Server-side feature flag says realtime is disabled; keep UI consistent and avoid reconnect loops.
if (event && event.code === OPS_WS_CLOSE_CODES.REALTIME_DISABLED) {
adminSettingsStore.setOpsRealtimeMonitoringEnabledLocal(false)
stopQPSSubscription({ resetMetrics: true })
}
},
// QPS updates may be sparse in idle periods; keep the timeout conservative.
staleTimeoutMs: 180_000
}
)
}
const readQueryString = (key: string): string => {
const value = route.query[key]
if (typeof value === 'string') return value
@@ -626,12 +567,6 @@ onMounted(async () => {
// Load thresholds configuration
loadThresholds()
if (adminSettingsStore.opsRealtimeMonitoringEnabled) {
startQPSSubscription()
} else {
stopQPSSubscription({ resetMetrics: true })
}
if (opsEnabled.value) {
await fetchData()
}
@@ -648,19 +583,6 @@ async function loadThresholds() {
}
onUnmounted(() => {
stopQPSSubscription()
abortDashboardFetch()
})
watch(
() => adminSettingsStore.opsRealtimeMonitoringEnabled,
(enabled) => {
if (!opsEnabled.value) return
if (enabled) {
startQPSSubscription()
} else {
stopQPSSubscription({ resetMetrics: true })
}
}
)
</script>