feat: 增加网页后台管理
This commit is contained in:
71
WebRTCSignalServerWeb/src/api/admin.ts
Normal file
71
WebRTCSignalServerWeb/src/api/admin.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import request from './request';
|
||||
|
||||
export type DeviceType = 'CONTROLLER' | 'CONTROLLED' | null;
|
||||
|
||||
export interface DeviceInfo {
|
||||
deviceId: string;
|
||||
deviceType: DeviceType;
|
||||
online: boolean;
|
||||
connectedAt: number | null;
|
||||
}
|
||||
|
||||
export interface DashboardData {
|
||||
serverStartTime: number;
|
||||
currentTime: number;
|
||||
uptimeMs: number;
|
||||
totalDevices: number;
|
||||
onlineDevices: number;
|
||||
offlineDevices: number;
|
||||
onlineControllers: number;
|
||||
onlineControlled: number;
|
||||
pendingConnections: number;
|
||||
metrics: {
|
||||
totalMessages: number;
|
||||
totalOffers: number;
|
||||
totalAnswers: number;
|
||||
totalRejected: number;
|
||||
totalRegistered: number;
|
||||
peakSessions: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PendingConnection {
|
||||
fromDeviceId: string;
|
||||
toDeviceId: string;
|
||||
createdAt: number;
|
||||
elapsedMs: number;
|
||||
}
|
||||
|
||||
export interface ServerConfig {
|
||||
dedupWindowMs: number;
|
||||
requestTimeoutMs: number;
|
||||
websocketEndpoint: string;
|
||||
serverPort: number;
|
||||
}
|
||||
|
||||
export function getDashboard(): Promise<DashboardData> {
|
||||
return request.get('/api/admin/dashboard') as unknown as Promise<DashboardData>;
|
||||
}
|
||||
|
||||
export function getDevices(type?: string): Promise<DeviceInfo[]> {
|
||||
return request.get('/api/admin/devices', { params: type ? { type } : {} }) as unknown as Promise<
|
||||
DeviceInfo[]
|
||||
>;
|
||||
}
|
||||
|
||||
export function getConnections(): Promise<PendingConnection[]> {
|
||||
return request.get('/api/admin/connections') as unknown as Promise<PendingConnection[]>;
|
||||
}
|
||||
|
||||
export function getConfig(): Promise<ServerConfig> {
|
||||
return request.get('/api/admin/config') as unknown as Promise<ServerConfig>;
|
||||
}
|
||||
|
||||
export function getHealth(): Promise<{ status: string }> {
|
||||
return request.get('/api/admin/health') as unknown as Promise<{ status: string }>;
|
||||
}
|
||||
|
||||
/** 校验令牌有效性(用于登录时验证)。 */
|
||||
export function verifyToken(token: string): Promise<unknown> {
|
||||
return request.get('/api/admin/health', { headers: { 'X-Admin-Token': token } });
|
||||
}
|
||||
33
WebRTCSignalServerWeb/src/api/request.ts
Normal file
33
WebRTCSignalServerWeb/src/api/request.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import axios from 'axios';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import router from '@/router';
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE || 'http://localhost:8080',
|
||||
timeout: 15000,
|
||||
});
|
||||
|
||||
request.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('admin_token');
|
||||
if (token) {
|
||||
config.headers['X-Admin-Token'] = token;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
request.interceptors.response.use(
|
||||
(resp) => resp.data,
|
||||
(error) => {
|
||||
const status = error.response?.status;
|
||||
if (status === 401) {
|
||||
localStorage.removeItem('admin_token');
|
||||
ElMessage.error('登录已失效,请重新登录');
|
||||
router.replace({ name: 'Login' });
|
||||
} else {
|
||||
ElMessage.error(error.response?.data?.message || error.message || '请求失败');
|
||||
}
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
|
||||
export default request;
|
||||
Reference in New Issue
Block a user