XuqmGroup-Web/ops-platform/src/api/ops.ts
XuqmGroup ad734ff204 feat(system-logs): 两端平台新增服务日志查看页面
- tenant-platform: /system-logs 页面,私有化模式下侧边栏显示;支持服务切换、
  行数选择、刷新间隔配置(5s/10s/30s/1min)、自动滚动
- ops-platform: /system-logs 页面,始终可见;复用相同交互,通过 ROLE_OPS 接口获取日志

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:22:58 +08:00

292 行
7.2 KiB
TypeScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

import client from './client'
export interface TenantItem {
id: string
username: string
nickname: string
email: string
phone?: string
type: 'MAIN' | 'SUB'
status: 'ACTIVE' | 'DISABLED' | 'PENDING_EMAIL'
parentId?: string
createdAt: string
}
export interface TenantDetail extends TenantItem {
appCount: number
subAccountCount: number
activeServiceCount: number
apps: AppItem[]
}
export interface TenantPage {
content: TenantItem[]
total: number
totalPages: number
}
export interface DailyTrendItem {
date: string
count: number
}
export interface Statistics {
totalTenants: number
todayNew: number
activeApps: number
onlineUsers: number
dailyTrend: DailyTrendItem[]
serviceDistribution: Record<string, number>
}
export interface ServiceRequest {
id: string
appKey: string
platform: string
serviceType: string
status: 'PENDING' | 'APPROVED' | 'REJECTED'
applyReason?: string
reviewNote?: string
createdAt: string
reviewedAt?: string
tenant?: {
id: string
username: string
nickname: string
email: string
phone?: string
type: 'MAIN' | 'SUB'
status: 'ACTIVE' | 'DISABLED' | 'PENDING_EMAIL'
} | null
app?: {
id: string
appKey: string
name: string
packageName: string
iosBundleId?: string
harmonyBundleName?: string
tenantId: string
createdAt: string
} | null
}
export interface ServiceRequestPage {
content: ServiceRequest[]
total: number
totalPages: number
}
export interface AppItem {
id: string
appKey: string
appSecret: string
name: string
packageName: string
tenantId: string
tenantName?: string
createdAt: string
}
export interface FeatureServiceItem {
id: string
appKey: string
platform: string
serviceType: string
enabled: boolean
config?: string | null
createdAt: string
}
export interface AppDetail {
app: AppItem
tenant: TenantItem | null
services: FeatureServiceItem[]
serviceCount: number
enabledServiceCount: number
}
export interface AppPage {
content: AppItem[]
total: number
totalPages: number
}
export interface OpsLogItem {
id: string
tenantId: string
moduleType: string
resourceType: string
resourceId: string
action: string
operator: string
detailJson: string
createdAt: string
}
export interface OpsLogPage {
content: OpsLogItem[]
total: number
totalPages: number
}
export interface RiskRuleForm {
ipRateLimit: number
loginFailThreshold: number
loginLockMinutes: number
abnormalDetection: boolean
}
export interface SensitiveWord {
id: string
word: string
level: '高' | '中' | '低'
category: string
enabled: boolean
updatedAt: string
}
export interface SensitiveWordPage {
content: SensitiveWord[]
total: number
totalPages: number
}
export interface PushDeviceInfo {
id: string
vendor: string
tokenPreview: string
platform?: string
deviceId: string
brand?: string
model?: string
osVersion?: string
appVersion?: string
receivePush: boolean
lastLoginAt: string
updatedAt: string
}
export interface PushDiagnostics {
tokenType: 'PUSH' | 'IM' | 'UNKNOWN'
appKey?: string
userId?: string
online: boolean
lastSeenAt: number
canSendOfflineMessage: boolean
deliverableDevice?: PushDeviceInfo | null
deliverableDevices: PushDeviceInfo[]
devices: PushDeviceInfo[]
}
export interface PushDeviceLog {
id: string
appKey: string
userId: string
vendor: string
tokenPreview: string
platform?: string
deviceId: string
brand?: string
model?: string
osVersion?: string
appVersion?: string
receivePush: boolean
eventType: 'REGISTER' | 'UNREGISTER' | 'RECEIVE_PUSH_UPDATE'
createdAt: string
}
export interface PushDeviceLogPage {
content: PushDeviceLog[]
total: number
totalPages: number
}
export interface PushTestResult {
appKey: string
userId: string
sent: boolean
targetCount: number
targets: PushDeviceInfo[]
}
export const opsApi = {
listTenants: (keyword = '', page = 0, size = 20) =>
client.get<{ data: TenantPage }>('/ops/tenants', { params: { keyword, page, size } }),
toggleStatus: (id: string) =>
client.post(`/ops/tenants/${id}/toggle-status`),
getTenant: (id: string) =>
client.get<{ data: TenantDetail }>(`/ops/tenants/${id}`),
listTenantApps: (id: string) =>
client.get<{ data: AppItem[] }>(`/ops/tenants/${id}/apps`),
statistics: () =>
client.get<{ data: Statistics }>('/ops/statistics'),
listServiceRequests: (status = '', page = 0, size = 20) =>
client.get<{ data: ServiceRequestPage }>('/ops/service-requests', { params: { status, page, size } }),
approveRequest: (requestId: string, reviewNote = '', expiresAt?: string) =>
client.post<{ data: ServiceRequest }>(`/ops/service-requests/${requestId}/approve`, { reviewNote, expiresAt }),
rejectRequest: (requestId: string, reviewNote = '') =>
client.post<{ data: ServiceRequest }>(`/ops/service-requests/${requestId}/reject`, { reviewNote }),
listApps: (keyword = '', tenantId = '', page = 0, size = 20) =>
client.get<{ data: AppPage }>('/ops/apps', { params: { keyword, tenantId, page, size } }),
getApp: (id: string) =>
client.get<{ data: AppDetail }>(`/ops/apps/${id}`),
listAppServices: (id: string) =>
client.get<{ data: FeatureServiceItem[] }>(`/ops/apps/${id}/services`),
transferApp: (appKey: string, targetTenantId: string) =>
client.post(`/ops/apps/${appKey}/transfer`, { targetTenantId }),
listOperationLogs: (page = 0, size = 20) =>
client.get<{ data: OpsLogPage }>('/ops/operation-logs', { params: { page, size } }),
// 风控相关 APImock 实现,TODO接入后端
getRiskRules: () =>
client.get<{ data: RiskRuleForm }>('/ops/risk/rules'),
saveRiskRules: (rules: RiskRuleForm) =>
client.post('/ops/risk/rules', rules),
listSensitiveWords: (page = 0, size = 20) =>
client.get<{ data: SensitiveWordPage }>('/ops/risk/sensitive-words', { params: { page, size } }),
createSensitiveWord: (word: Omit<SensitiveWord, 'id' | 'updatedAt'>) =>
client.post<{ data: SensitiveWord }>('/ops/risk/sensitive-words', word),
updateSensitiveWord: (id: string, word: Partial<SensitiveWord>) =>
client.put<{ data: SensitiveWord }>(`/ops/risk/sensitive-words/${id}`, word),
toggleSensitiveWord: (id: string, enabled: boolean) =>
client.patch(`/ops/risk/sensitive-words/${id}/toggle`, { enabled }),
deleteSensitiveWord: (id: string) =>
client.delete(`/ops/risk/sensitive-words/${id}`),
searchPushByToken: (token: string, appKey = '') =>
client.get<{ data: PushDiagnostics }>('/ops/push/search', { params: { token, appKey } }),
listPushDeviceLogs: (appKey: string, userId: string, page = 0, size = 20) =>
client.get<{ data: PushDeviceLogPage }>('/ops/push/device-logs', { params: { appKey, userId, page, size } }),
sendPushTestOffline: (payload: { appKey: string; userId: string; title: string; body: string; payload?: string }) =>
client.post<{ data: PushTestResult }>('/ops/push/test-offline', payload),
getRunningServices: () =>
client.get<{ data: string[] }>('/ops/system/services'),
fetchServiceLogs: (service: string, lines: number) =>
client.get<string>(`/ops/system/logs/${encodeURIComponent(service)}`, {
params: { lines },
responseType: 'text',
}),
}