feat(前端API): 实现运维监控 API 客户端

- 新增 ops API 客户端(ops.ts)
- 扩展 settings API 支持 ops 配置
- 更新 admin API 索引导出 ops 模块
- 扩展 API 客户端支持 WebSocket 连接
This commit is contained in:
IanShaw027
2026-01-09 20:58:33 +08:00
parent e846458009
commit 11d063e3c4
4 changed files with 970 additions and 4 deletions

View File

@@ -80,9 +80,45 @@ apiClient.interceptors.response.use(
return response
},
(error: AxiosError<ApiResponse<unknown>>) => {
// Request cancellation: keep the original axios cancellation error so callers can ignore it.
// Otherwise we'd misclassify it as a generic "network error".
if (error.code === 'ERR_CANCELED' || axios.isCancel(error)) {
return Promise.reject(error)
}
// Handle common errors
if (error.response) {
const { status, data } = error.response
const url = String(error.config?.url || '')
// Validate `data` shape to avoid HTML error pages breaking our error handling.
const apiData = (typeof data === 'object' && data !== null ? data : {}) as Record<string, any>
// Ops monitoring disabled: treat as feature-flagged 404, and proactively redirect away
// from ops pages to avoid broken UI states.
if (status === 404 && apiData.message === 'Ops monitoring is disabled') {
try {
localStorage.setItem('ops_monitoring_enabled_cached', 'false')
} catch {
// ignore localStorage failures
}
try {
window.dispatchEvent(new CustomEvent('ops-monitoring-disabled'))
} catch {
// ignore event failures
}
if (window.location.pathname.startsWith('/admin/ops')) {
window.location.href = '/admin/settings'
}
return Promise.reject({
status,
code: 'OPS_DISABLED',
message: apiData.message || error.message,
url
})
}
// 401: Unauthorized - clear token and redirect to login
if (status === 401) {
@@ -113,8 +149,8 @@ apiClient.interceptors.response.use(
// Return structured error
return Promise.reject({
status,
code: data?.code,
message: data?.message || error.message
code: apiData.code,
message: apiData.message || apiData.detail || error.message
})
}