refactor(aiot-device): 规范整理设备 API 层和类型定义
- 按功能分区:摄像头管理、ROI 区域、算法管理、算法绑定、配置推送 - Camera 接口扩展完整字段(streamKey、createTime 等) - 新增 PageResult、MediaServer 类型定义 - getSnapUrl 改为 async,通过 query param 传递 access-token 支持认证截图 - 所有 API 函数添加精确的泛型返回类型 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,49 @@
|
||||
/**
|
||||
* AIoT 设备管理 API
|
||||
*
|
||||
* 所有请求通过 wvpRequestClient 发送到 WVP 视频平台后端,
|
||||
* 由 Vite 代理按路径分发并 rewrite:
|
||||
* /aiot/device/proxy/* → WVP /api/proxy/*
|
||||
* /aiot/device/user/* → WVP /api/user/*
|
||||
* /aiot/device/server/* → WVP /api/server/media_server/*
|
||||
* /aiot/device/* → WVP /api/ai/*
|
||||
*/
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
|
||||
import { wvpRequestClient } from '#/api/aiot/request';
|
||||
import { getWvpToken, wvpRequestClient } from '#/api/aiot/request';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
|
||||
// ==================== 类型定义 ====================
|
||||
|
||||
export namespace AiotDeviceApi {
|
||||
/** 分页响应结构 */
|
||||
export interface PageResult<T> {
|
||||
list: T[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
/** 摄像头(拉流代理) */
|
||||
export interface Camera {
|
||||
id?: number;
|
||||
type?: string; // 'default' | 'ffmpeg'
|
||||
app?: string;
|
||||
stream?: string;
|
||||
srcUrl?: string;
|
||||
timeout?: number;
|
||||
rtspType?: string; // '0'=TCP, '1'=UDP, '2'=Multicast
|
||||
enable?: boolean;
|
||||
enableAudio?: boolean;
|
||||
enableMp4?: boolean;
|
||||
enableDisableNoneReader?: boolean;
|
||||
relatesMediaServerId?: string;
|
||||
ffmpegCmdKey?: string;
|
||||
pulling?: boolean;
|
||||
mediaServerId?: string;
|
||||
streamKey?: string;
|
||||
createTime?: string;
|
||||
}
|
||||
|
||||
/** ROI 区域 */
|
||||
export interface Roi {
|
||||
id?: number;
|
||||
@@ -12,7 +51,7 @@ export namespace AiotDeviceApi {
|
||||
cameraId?: string;
|
||||
deviceId?: string;
|
||||
name?: string;
|
||||
roiType?: string; // rectangle | polygon
|
||||
roiType?: string; // 'rectangle' | 'polygon'
|
||||
coordinates?: string;
|
||||
color?: string;
|
||||
priority?: number;
|
||||
@@ -21,7 +60,7 @@ export namespace AiotDeviceApi {
|
||||
algorithms?: RoiAlgoBinding[];
|
||||
}
|
||||
|
||||
/** ROI 算法绑定(详情里的嵌套结构) */
|
||||
/** ROI 算法绑定(详情嵌套结构) */
|
||||
export interface RoiAlgoBinding {
|
||||
bind: AlgoBind;
|
||||
algorithm?: Algorithm;
|
||||
@@ -32,11 +71,11 @@ export namespace AiotDeviceApi {
|
||||
bindId?: string;
|
||||
roiId?: string;
|
||||
algoCode?: string;
|
||||
enabled?: number;
|
||||
enabled?: number; // 0 | 1
|
||||
params?: string;
|
||||
}
|
||||
|
||||
/** 算法 */
|
||||
/** 算法定义 */
|
||||
export interface Algorithm {
|
||||
id?: number;
|
||||
algoCode?: string;
|
||||
@@ -46,36 +85,38 @@ export namespace AiotDeviceApi {
|
||||
paramSchema?: string;
|
||||
}
|
||||
|
||||
/** 摄像头(拉流代理) */
|
||||
export interface Camera {
|
||||
id?: number;
|
||||
type?: string; // default | ffmpeg
|
||||
app?: string;
|
||||
stream?: string;
|
||||
srcUrl?: string;
|
||||
timeout?: number;
|
||||
rtspType?: string; // 0=TCP, 1=UDP, 2=Multicast
|
||||
enable?: boolean;
|
||||
enableAudio?: boolean;
|
||||
enableMp4?: boolean;
|
||||
enableDisableNoneReader?: boolean;
|
||||
relatesMediaServerId?: string;
|
||||
ffmpegCmdKey?: string;
|
||||
pulling?: boolean;
|
||||
mediaServerId?: string;
|
||||
/** 媒体服务器 */
|
||||
export interface MediaServer {
|
||||
id: string;
|
||||
ip: string;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 摄像头管理 API ====================
|
||||
// ==================== 摄像头管理 ====================
|
||||
|
||||
/** 获取摄像头列表 */
|
||||
/** 摄像头列表(分页) */
|
||||
export function getCameraList(params: {
|
||||
page: number;
|
||||
count: number;
|
||||
query?: string;
|
||||
pulling?: boolean;
|
||||
}) {
|
||||
return wvpRequestClient.get<any>('/aiot/device/proxy/list', { params });
|
||||
return wvpRequestClient.get<AiotDeviceApi.PageResult<AiotDeviceApi.Camera>>(
|
||||
'/aiot/device/proxy/list',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
/** 保存摄像头(新增/编辑,有 id 为编辑) */
|
||||
export function saveCamera(data: Partial<AiotDeviceApi.Camera>) {
|
||||
return wvpRequestClient.post('/aiot/device/proxy/save', data);
|
||||
}
|
||||
|
||||
/** 删除摄像头 */
|
||||
export function deleteCamera(id: number) {
|
||||
return wvpRequestClient.delete('/aiot/device/proxy/delete', {
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
/** 开始拉流 */
|
||||
@@ -88,26 +129,16 @@ export function stopCamera(id: number) {
|
||||
return wvpRequestClient.get('/aiot/device/proxy/stop', { params: { id } });
|
||||
}
|
||||
|
||||
/** 保存摄像头(新增/编辑) */
|
||||
export function saveCamera(data: Partial<AiotDeviceApi.Camera>) {
|
||||
return wvpRequestClient.post('/aiot/device/proxy/save', data);
|
||||
}
|
||||
|
||||
/** 删除摄像头 */
|
||||
export function deleteCamera(id: number) {
|
||||
return wvpRequestClient.delete('/aiot/device/proxy/delete', {
|
||||
params: { id },
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取在线媒体服务器列表 */
|
||||
/** 在线媒体服务器列表 */
|
||||
export function getMediaServerList() {
|
||||
return wvpRequestClient.get<any>('/aiot/device/server/online/list');
|
||||
return wvpRequestClient.get<AiotDeviceApi.MediaServer[]>(
|
||||
'/aiot/device/server/online/list',
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== ROI 区域管理 API ====================
|
||||
// ==================== ROI 区域管理 ====================
|
||||
|
||||
/** 获取 ROI 列表(分页) */
|
||||
/** ROI 列表(分页) */
|
||||
export function getRoiList(params: {
|
||||
page: number;
|
||||
count: number;
|
||||
@@ -115,22 +146,26 @@ export function getRoiList(params: {
|
||||
deviceId?: string;
|
||||
query?: string;
|
||||
}) {
|
||||
return wvpRequestClient.get<any>('/aiot/device/roi/list', { params });
|
||||
return wvpRequestClient.get<AiotDeviceApi.PageResult<AiotDeviceApi.Roi>>(
|
||||
'/aiot/device/roi/list',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取 ROI 详情 */
|
||||
/** ROI 详情(含算法绑定) */
|
||||
export function getRoiDetail(id: number) {
|
||||
return wvpRequestClient.get<any>(`/aiot/device/roi/${id}`);
|
||||
return wvpRequestClient.get<AiotDeviceApi.Roi>(`/aiot/device/roi/${id}`);
|
||||
}
|
||||
|
||||
/** 获取某摄像头的所有 ROI */
|
||||
/** 某摄像头的所有 ROI */
|
||||
export function getRoiByCameraId(cameraId: string) {
|
||||
return wvpRequestClient.get<any>('/aiot/device/roi/channel', {
|
||||
params: { cameraId },
|
||||
});
|
||||
return wvpRequestClient.get<AiotDeviceApi.Roi[]>(
|
||||
'/aiot/device/roi/channel',
|
||||
{ params: { cameraId } },
|
||||
);
|
||||
}
|
||||
|
||||
/** 保存 ROI */
|
||||
/** 保存 ROI(新增/编辑) */
|
||||
export function saveRoi(data: Partial<AiotDeviceApi.Roi>) {
|
||||
return wvpRequestClient.post('/aiot/device/roi/save', data);
|
||||
}
|
||||
@@ -140,12 +175,34 @@ export function deleteRoi(roiId: string) {
|
||||
return wvpRequestClient.delete(`/aiot/device/roi/delete/${roiId}`);
|
||||
}
|
||||
|
||||
/** 获取截图 URL */
|
||||
export function getSnapUrl(app: string, stream: string) {
|
||||
return `${apiURL}/aiot/device/roi/snap?app=${encodeURIComponent(app)}&stream=${encodeURIComponent(stream)}&t=${Date.now()}`;
|
||||
/**
|
||||
* 获取摄像头截图 URL
|
||||
* 截图接口需要认证,通过 query param 传递 access-token
|
||||
*/
|
||||
export async function getSnapUrl(
|
||||
app: string,
|
||||
stream: string,
|
||||
): Promise<string> {
|
||||
const token = await getWvpToken();
|
||||
return (
|
||||
`${apiURL}/aiot/device/roi/snap` +
|
||||
`?app=${encodeURIComponent(app)}` +
|
||||
`&stream=${encodeURIComponent(stream)}` +
|
||||
`&access-token=${encodeURIComponent(token)}` +
|
||||
`&t=${Date.now()}`
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== 算法绑定 API ====================
|
||||
// ==================== 算法管理 ====================
|
||||
|
||||
/** 算法列表 */
|
||||
export function getAlgorithmList() {
|
||||
return wvpRequestClient.get<AiotDeviceApi.Algorithm[]>(
|
||||
'/aiot/device/algorithm/list',
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== 算法绑定 ====================
|
||||
|
||||
/** 绑定算法到 ROI */
|
||||
export function bindAlgo(data: { roiId: string; algoCode: string }) {
|
||||
@@ -159,7 +216,7 @@ export function unbindAlgo(bindId: string) {
|
||||
});
|
||||
}
|
||||
|
||||
/** 更新算法参数 */
|
||||
/** 更新算法绑定参数 */
|
||||
export function updateAlgoParams(data: {
|
||||
bindId: string;
|
||||
params?: string;
|
||||
@@ -168,14 +225,7 @@ export function updateAlgoParams(data: {
|
||||
return wvpRequestClient.post('/aiot/device/roi/updateAlgoParams', data);
|
||||
}
|
||||
|
||||
// ==================== 算法管理 API ====================
|
||||
|
||||
/** 获取算法列表 */
|
||||
export function getAlgorithmList() {
|
||||
return wvpRequestClient.get<any>('/aiot/device/algorithm/list');
|
||||
}
|
||||
|
||||
// ==================== 配置推送 API ====================
|
||||
// ==================== 配置推送 ====================
|
||||
|
||||
/** 推送配置到边缘端 */
|
||||
export function pushConfig(cameraId: string) {
|
||||
@@ -184,9 +234,10 @@ export function pushConfig(cameraId: string) {
|
||||
});
|
||||
}
|
||||
|
||||
/** 导出配置 */
|
||||
/** 导出摄像头配置 JSON */
|
||||
export function exportConfig(cameraId: string) {
|
||||
return wvpRequestClient.get<any>('/aiot/device/config/export', {
|
||||
params: { cameraId },
|
||||
});
|
||||
return wvpRequestClient.get<Record<string, any>>(
|
||||
'/aiot/device/config/export',
|
||||
{ params: { cameraId } },
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user