# 告警管理系统 API 接口文档(Django 版) > 基础路径:`/api/v1` > 服务器地址:`http://192.168.28.32:8000` > 认证方式:Bearer Token(24h 有效期) > 统一响应信封:`{ "err": { "ec": 0, "dm": "ok" }, "ret": }` --- ## 目录 1. [认证接口](#1-认证接口) 2. [事件(告警)接口](#2-事件告警接口) 3. [摄像头接口](#3-摄像头接口) 4. [规则接口](#4-规则接口) 5. [算法接口](#5-算法接口) 6. [WebSocket 接口](#6-websocket-接口) 7. [通用响应格式](#7-通用响应格式) 8. [认证与 Token 管理](#8-认证与-token-管理) 9. [前端数据转换说明](#9-前端数据转换说明) 10. [完整调用示例](#10-完整调用示例) 11. [附录:前端 API 方法速查表](#11-附录前端-api-方法速查表) --- ## 1. 认证接口 --- ### 1.1 登录 - **方法**:`POST` - **路径**:`/auth/login` - **描述**:用户登录,获取 Token - **鉴权**:无(公开) **请求头**: ```http Content-Type: application/json Accept: application/json ``` **请求体(Body JSON)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `username` | `string` | 是 | 用户名 | | `password` | `string` | 是 | 密码 | | `cookieless` | `string` | 是 | `"True"` 或 `"False"` | ```json { "username": "admin", "password": "123456", "cookieless": "False" } ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { "token": "eyJhbGciOiJIUzI1NiIs..." } } ``` | 返回字段 | 类型 | 说明 | |---------|------|------| | `ret.token` | `string` | JWT Token,有效期 24h | **失败响应**: ```json { "err": { "ec": 1001, "dm": "用户名或密码错误" } } ``` --- ### 1.2 登出 - **方法**:`POST` - **路径**:`/auth/logout` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` **请求体**:无 **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": {} } ``` --- ### 1.3 添加用户 - **方法**:`POST` - **路径**:`/auth/adduser` - **鉴权**:Bearer Token(需管理员权限) **请求头**: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` **请求体(Body JSON)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `username` | `string` | 是 | 用户名 | | `password` | `string` | 是 | 密码 | | `email` | `string` | 否 | 邮箱,默认为空 | ```json { "username": "operator1", "password": "pass123456", "email": "" } ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": {} } ``` --- ### 1.4 删除用户 - **方法**:`POST` - **路径**:`/auth/rmuser` - **鉴权**:Bearer Token(需管理员权限) **请求头**: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` **请求体(Body JSON)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `username` | `string` | 是 | 要删除的用户名 | ```json { "username": "operator1" } ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": {} } ``` --- ### 1.5 获取所有用户 - **方法**:`GET` - **路径**:`/auth/allusers` - **鉴权**:Bearer Token(需管理员权限) **请求头**: ```http Authorization: Bearer Accept: application/json ``` **请求参数**:无 **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { "users": [ { "username": "admin", "email": "" }, { "username": "operator1", "email": "op1@example.com" } ] } } ``` | 返回字段 | 类型 | 说明 | |---------|------|------| | `ret.users` | `array` | 用户列表 | | `ret.users[].username` | `string` | 用户名 | | `ret.users[].email` | `string` | 邮箱 | --- ### 1.6 重置用户信息 - **方法**:`POST` - **路径**:`/auth/resetuser` - **鉴权**:Bearer Token(需管理员权限) **请求头**: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` **请求体(Body JSON)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `username` | `string` | 是 | 用户名 | | `password` | `string` | 是 | 新密码 | | `email` | `string` | 是 | 邮箱 | ```json { "username": "operator1", "password": "newpass123", "email": "op1@example.com" } ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": {} } ``` --- ## 2. 事件(告警)接口 --- ### 2.1 获取事件列表(分页) - **方法**:`GET` - **路径**:`/events` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **查询参数(Query)**: | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | `limit` | `number` | 否 | `20` | 每页条数 | | `offset` | `number` | 否 | `0` | 偏移量 | **请求示例**: ``` GET /api/v1/events?limit=20&offset=0 Authorization: Bearer ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { "count": 1617, "next": "http://192.168.28.32:8000/api/v1/events?limit=20&offset=20", "previous": null, "results": [ { "id": 90908, "camera_id": 1, "started_at": "2026-04-01T09:30:00Z", "ended_at": "2026-04-01T09:30:10Z", "mediums": [ { "id": 109656, "name": "snapshot", "file": "http://192.168.28.32:8000/media/mediums/2026/04/02/camera1_xxx.jpg", "event_id": 90908 } ], "camera": { "id": 1, "name": "421枪机", "uri": "rtsp://admin:1234qwer@192.168.28.102:554/Streaming/Channels/202", "mode": "on", "status": "online", "detect_params": { "threshold": 0.5 }, "default_params": {}, "rules": [ /* RuleItem[] 见规则结构 */ ], "should_push": false, "config_params": {}, "sampling": false, "note": {}, "snapshot": "http://192.168.28.32:8000/media/camera/camera1_snapshot.jpg", "remote_id": -1, "raw_address": "0b8342ec52e62d01dd3273f583d326ec", "ip": "admin:1234qwer@192.168.28.102:554", "port": 8082 }, "types": "wander", "types_bits": 0, "obj_types": {}, "uuid": "461aeb6e-10f3-4173-9b33-d540ce59511e", "status": "pending", "remark": null, "should_push": false, "metadata": {} } ] } } ``` **前端返回**: ```typescript { tableData: EventItem[], // ret.results totalItems: number // ret.count } ``` --- ### 2.2 按参数筛选事件列表 - **方法**:`GET` - **路径**:`/events` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **查询参数(Query)**: | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | `limit` | `number` | 否 | `20` | 每页条数 | | `offset` | `number` | 否 | `0` | 偏移量 | | `time_before` | `string` | 否 | — | 结束时间(ISO 8601) | | `time_after` | `string` | 否 | — | 开始时间(ISO 8601) | | `types` | `string` | 否 | — | 告警类型编码(如 `wander`) | | `camera_id` | `number` | 否 | — | 摄像头 ID | | `status` | `string` | 否 | — | 状态:`pending` / `closed` | **请求示例**: ``` GET /api/v1/events?limit=20&offset=0&time_after=2026-04-01T00%3A00%3A00Z&time_before=2026-04-02T00%3A00%3A00Z&types=wander&camera_id=1&status=pending Authorization: Bearer ``` **成功响应(200 OK)**:同 2.1 响应结构。 --- --- ### 2.3 获取单个事件详情 - **方法**:`GET` - **路径**:`/event/events/retrieves` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **查询参数(Query)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `id` | `number` | 是 | 事件 ID | **请求示例**: ``` GET /api/v1/event/events/retrieves?id=90908 Authorization: Bearer ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { "objects": [ { "id": 90908, "camera_id": 1, "started_at": "2026-04-01T09:30:00Z", "ended_at": "2026-04-01T09:30:10Z", "mediums": [ { "id": 109656, "name": "snapshot", "file": "http://192.168.28.32:8000/media/mediums/2026/04/02/camera1_xxx.jpg", "event_id": 90908 } ], "camera": { /* CameraItem 见摄像头结构 */ }, "types": "wander", "types_bits": 0, "obj_types": {}, "uuid": "461aeb6e-10f3-4173-9b33-d540ce59511e", "status": "pending", "remark": null, "should_push": false, "metadata": {} } ] } } ``` **前端取值**:`res.data.ret.objects[0]` --- ### 2.4 获取最新一条事件 - **方法**:内部调用 `getEvents(token, 1, 1)` - **路径**:`/events?limit=1&offset=0` - **鉴权**:Bearer Token **成功响应**:同 2.1,但 `results` 只有一条,`count` 为总条数。 --- ### 2.5 修改事件状态 - **方法**:`PATCH` - **路径**:`/events/{eventId}` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` **路径参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | `eventId` | `number` | 事件 ID | **请求体(Body JSON)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `status` | `string` | 是 | 状态值:`pending` / `closed` | | `remark` | `string` | 否 | 备注信息 | ```json { "status": "closed", "remark": "已处理完毕" } ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": {} } ``` --- ### 2.6 删除事件 - **方法**:`DELETE` - **路径**:`/event/events/{eventId}` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **路径参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | `eventId` | `number` | 事件 ID | **请求体**:无 **成功响应**:`204 No Content`(无 body) **失败响应**(如事件不存在): ```json { "err": { "ec": 404, "dm": "Not Found", "em": "Not found." } } ``` --- ### 2.7 事件对象完整结构(EventItem) ```typescript interface EventItem { id: number; // 告警 ID camera_id: number; // 摄像头 ID started_at: string; // 开始时间(ISO 8601) ended_at: string; // 结束时间(ISO 8601) types: string; // 告警类型编码(如 "wander") types_bits: number; // 类型位标记 obj_types: Record; // 目标类型 uuid: string; // 唯一标识 status: 'pending' | 'closed'; // 处理状态 remark: string | null; // 备注 should_push: boolean; // 是否推送 metadata: Record; // 元数据 // 多媒体 mediums: Array<{ id: number; name: string; // 如 "snapshot" file: string; // 图片 URL(已规范化) event_id: number; }>; // 关联摄像头 camera: CameraItem; } ``` --- ## 3. 摄像头接口 --- ### 3.1 获取摄像头列表 - **方法**:`GET` - **路径**:`/camera/cameras/get_all` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { "count": 10, "results": [ { "id": 1, "name": "421枪机", "uri": "rtsp://{camerastream}", "mode": "on", "status": "online", "detect_params": { "threshold": 0.5 }, "default_params": {}, "rules": [ { "id": 1, "unique_id": "1268f3f2-e0c5-47ea-aa1f-5b97b6dfb95d", "camera": 1, "name": "规则名称", "mode": "on", "algo": "rule-name", "params": {}, "params_base": "", "schedule": {}, "event_types": { "规则英文": "别名,中文映射" } } ], "should_push": false, "config_params": {}, "sampling": false, "note": {}, "snapshot": "URL***.jpg", "remote_id": -1, "raw_address": "0b8342ec52e62d01dd3273f583d326ec", "ip": "camera-url", "port": 8082 } ] } } ``` --- --- ### 3.2 获取单个摄像头详情 - **方法**:`GET` - **路径**:`/camera/cameras/{cameraId}` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **路径参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | `cameraId` | `number` | 摄像头 ID | **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { /* CameraItem */ } } ``` --- ### 3.3 更新摄像头信息 - **方法**:`PATCH` - **路径**:`/camera/cameras/{cameraId}` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` **路径参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | `cameraId` | `number` | 摄像头 ID | **请求体(Body JSON)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `name` | `string` | 否 | 摄像头名称 | | `mode` | `"on"` / `"off"` | 是 | 检测模式 | ```json { "name": "421枪机", "mode": "on" } ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { /* CameraItem */ } } ``` --- ### 3.4 启动摄像头视频流 - **方法**:`POST` - **路径**:`/camera/cameras/{cameraId}/start_stream` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **路径参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | `cameraId` | `number` | 摄像头 ID | **请求体**:无 **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { "port": 8094 } } ``` | 返回字段 | 类型 | 说明 | |---------|------|------| | `ret.port` | `number` | 动态分配的 WebSocket 端口,用于 JSMpeg 视频播放 | --- ### 3.5 停止摄像头视频流 - **方法**:`POST` - **路径**:`/camera/cameras/{cameraId}/stop_stream` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **路径参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | `cameraId` | `number` | 摄像头 ID | **请求体**:无 **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": {} } ``` --- ### 3.8 摄像头对象完整结构(CameraItem) ```typescript interface CameraItem { id: number; name: string; // 点位名称(如 "421枪机") uri: string; // RTSP 地址 mode: 'on' | 'off'; // 检测全局开关 status: 'online' | 'offline'; // 在线状态 detect_params: { threshold: number; // 检测阈值(如 0.5) }; default_params: Record; rules: RuleItem[]; // 关联规则列表 should_push: boolean; config_params: Record; sampling: boolean; note: Record; snapshot: string; // 快照图片 URL(已规范化) remote_id: number; raw_address: string; ip: string; port: number; } ``` **前端发送的 CameraData 类型**(用于 updateCamera): ```typescript interface CameraData { id?: number; name?: string; mode?: "on" | "off"; rules?: RuleData[] | {}; } ``` --- ## 4. 规则接口 --- ### 4.1 更新规则 - **方法**:`PATCH` - **路径**:`/rules/{ruleId}` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` **路径参数**: | 参数名 | 类型 | 说明 | |--------|------|------| | `ruleId` | `number` | 规则 ID | **请求体(Body JSON)**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `id` | `number` | 是 | 规则 ID | | `name` | `string` | 否 | 规则名称 | | `mode` | `"on"` / `"off"` / `"schedule"` | 否 | 规则模式 | | `schedule` | `object` | 否 | 时间段配置 | ```json { "id": 1, "name": "徘徊", "mode": "on", "schedule": {} } ``` **带时间段的请求**: ```json { "id": 1, "name": "未穿反光衣", "mode": "schedule", "schedule": { "type": "daily", "time_slots": [ [ 960, 1020 ] ] } } ``` **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { /* RuleItem */ } } ``` --- ### 4.2 规则对象完整结构(RuleItem) ```typescript interface RuleItem { id: number; unique_id: string; // UUID camera: number; // 关联摄像头 ID name: string; // 规则名称(如 "徘徊") mode: 'on' | 'off' | 'schedule'; algo: string; // 算法编码(如 "wander") params: Record; params_base: string; schedule: { type: string; // 如 "daily" time_slots?: Array<[number, number]>; } | {}; event_types: Record; // 如 { "wander": "人员徘徊" } } ``` --- ## 5. 算法接口 --- ### 5.1 获取算法列表 - **方法**:`GET` - **路径**:`/algorithms` - **鉴权**:Bearer Token **请求头**: ```http Authorization: Bearer Accept: application/json ``` **请求参数**:无 **成功响应(200 OK)**: ```json { "err": { "ec": 0, "dm": "ok" }, "ret": [ { "code_name": "wander", "name": "人员徘徊" }, { "code_name": "intrusion", "name": "入侵" }, { "code_name": "no_reflective_clothing", "name": "未佩戴反光衣" } ] } ``` | 返回字段 | 类型 | 说明 | |---------|------|------| | `ret[]` | `array` | 算法列表(无分页包装) | | `ret[].code_name` | `string` | 算法编码(如 `wander`) | | `ret[].name` | `string` | 算法中文名称(如 `人员徘徊`) | ### 5.2 算法映射表 ```typescript interface AlgorithmItem { code_name: string; // 算法编码(如 "wander") name: string; // 算法中文名称(如 "人员徘徊") } ``` 登录时自动拉取并构建 `Map` 映射,供全局以编码查中文名。 --- ## 6. WebSocket 接口 ### 6.1 事件监听通道 WebSocket - **地址**:`ws://192.168.28.32:8080/ws/event` - **代理地址(Vite 开发环境)**:`/ws/event` ### 6.2 推送消息格式 ```json { "id": 90908, "camera_id": 1, "started_at": "2026-04-01T09:30:00Z", "ended_at": "2026-04-01T09:30:10Z", "types": "wander", "status": "pending", "camera": { "id": 1, "name": "421枪机" }, "mediums": [ { "id": 109656, "name": "snapshot", "file": "http://192.168.28.32:8000/media/mediums/xxx.jpg" } ] } ``` ### 6.3 视频流 WebSocket - **地址**:`ws://{host}:{dynamicPort}/` - **说明**:由 `startCameraStream` 返回动态端口,JSMpeg 直接连接播放 --- ## 7. 通用响应格式 ### 7.1 成功响应 ```json { "err": { "ec": 0, "dm": "ok" }, "ret": { /* 响应数据 */ } } ``` | 字段 | 类型 | 说明 | |------|------|------| | `err.ec` | `number` | 错误码,`0` 表示成功 | | `err.dm` | `string` | 状态描述,成功时为 `"ok"` | | `ret` | `object` / `array` | 返回的数据主体 | ### 7.2 错误响应 ```json { "err": { "ec": 1001, "dm": "错误描述信息" } } ``` ### 7.3 常见错误码 | 错误码 | 说明 | |--------|------| | `0` | 成功 | | `1001` | 参数错误 | | `1002` | 认证失败 | | `1003` | 权限不足 | | `1004` | 资源不存在 | | `1005` | 操作失败 | ### 7.4 HTTP 状态码 | 状态码 | 说明 | 前端处理 | |--------|------|----------| | `200 OK` | 请求成功 | 正常处理 | | `201 Created` | POST 创建成功 | 正常处理 | | `204 No Content` | DELETE / 无业务数据 PATCH | 视作成功 | | `400 Bad Request` | 参数错误 | 提示错误信息 | | `401 Unauthorized` | 未授权 / Token 过期 | 清除 Token,跳转登录页 | | `403 Forbidden` | 权限不足 | 提示无权限 | | `404 Not Found` | 资源不存在 | 提示未找到 | | `500 Internal Server Error` | 服务器内部错误 | 提示服务器错误 | --- ## 8. 认证与 Token 管理 ### 8.1 Token 有效期 - Token 有效期:**24 小时** - 前端每 **30 分钟** 检查一次 Token 是否过期 - 过期后自动清除 Token 并跳转到登录页 ### 8.2 请求头格式 ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` ### 8.3 拦截器行为 - **请求拦截**:每次请求前检查 Token 是否过期(`checkTokenExpiry`) - **响应拦截**:收到 `401` 状态码时自动清除 Token 并跳转登录 --- ## 9. 前端数据转换说明 ### 9.1 URL 规范化 后端返回的 JSON 中包含内部地址(如 `http://127.0.0.1:8000/media/...`),前端自动转换为: - `http://127.0.0.1:8000/xxx` → `http://<实际服务器IP>:8000/xxx` - `http://localhost:8000/xxx` → `http://<实际服务器IP>:8000/xxx` 适用字段: - `mediums[].file`(事件图片) - `camera.snapshot`(摄像头快照) - 顶层 `snapshot` / `file` - `next` / `previous` 分页链接 ### 9.2 分页结构 所有列表接口统一分页格式: ```typescript { count: number, // 总条数 next: string|null, // 下一页 URL previous: string|null, // 上一页 URL results: T[] // 当前页数据 } ``` --- ## 10. 完整调用示例 ### 10.1 登录并获取事件列表 ```typescript import { BoxApi } from '@/utils/boxApi'; const api = new BoxApi(); // 登录 const token = await api.login('admin', 'password'); // 获取事件(第1页,每页20条) const { tableData, totalItems } = await api.getEvents(token, 20, 1); // 按条件筛选 const { results, count } = await api.getEventsByParams( token, 20, 1, '2026-04-01T00:00:00Z', '2026-04-02T00:00:00Z', 'wander', null, 'pending' ); // 获取所有摄像头 const cameras = await api.getAllCameras(token); // 更新事件状态 await api.setEventStatus(90908, 'closed', '已处理', token); // 删除事件 await api.delEvents(token, [90908, 90909]); ``` ### 10.2 摄像头管理 ```typescript // 获取单个摄像头详情(含规则) const camera = await api.getCameraById(token, 1); // 更新摄像头基本设置 await api.updateCamera(token, 1, { name: '421枪机', mode: 'on' }); // 批量更新规则 await api.updateRule(token, [ { id: 1, camera: 1, name: '徘徊', mode: 'on' }, { id: 32, camera: 1, name: '入侵', mode: 'schedule', schedule: { type: 'daily', time_slots: [[480, 720]] } } ]); // 启动视频流 const { port } = await api.startCameraStream(token, 1); // 停止视频流 await api.stopCameraStream(token, 1); ``` --- ## 11. 附录:前端 API 方法速查表 | 方法 | HTTP 方法 | 路径 | 请求体/参数 | 响应体 | |------|-----------|------|------------|--------| | `login()` | POST | `/auth/login` | `{username, password, cookieless}` | `{token}` | | `logout()` | POST | `/auth/logout` | 无 | `{}` | | `addUser()` | POST | `/auth/adduser` | `{username, password, email?}` | `{}` | | `rmUser()` | POST | `/auth/rmuser` | `{username}` | `{}` | | `getAllUsers()` | GET | `/auth/allusers` | — | `{users: [...]}` | | `resetUser()` | POST | `/auth/resetuser` | `{username, password, email}` | `{}` | | `getEvents()` | GET | `/events?limit=&offset=` | — | `{count, next, prev, results}` | | `getEventsByParams()` | GET | `/events?limit=&offset=&...` | — | `{count, next, prev, results}` | | `getEventsByUrl()` | GET | 自定义 URL | — | `{count, next, prev, results}` | | `getEventById()` | GET | `/event/events/retrieves?id=` | — | `{objects: [EventItem]}` | | `getOneEvent()` | GET | `/events?limit=1&offset=0` | — | `{count, next, prev, results}` | | `setEventStatus()` | PATCH | `/events/{id}` | `{status, remark?}` | `{}` | | `delEvents()` | DELETE | `/event/events/{id}` | 无 | `[{id, success, message?}]` | | `getCameras()` | GET | `/cameras?limit=&offset=` | — | `{count, results: [...]}` | | `getCamerasByUrl()` | GET | 自定义 URL | — | `{count, results: [...]}` | | `getAllCameras()` | GET | `/camera/cameras/get_all` | — | `CameraItem[]` | | `getCameraById()` | GET | `/camera/cameras/{id}` | — | `CameraItem` | | `updateCamera()` | PATCH | `/camera/cameras/{id}` | `{name, mode}` | `CameraItem` | | `startCameraStream()` | POST | `/camera/cameras/{id}/start_stream` | 无 | `{port}` | | `stopCameraStream()` | POST | `/camera/cameras/{id}/stop_stream` | 无 | `{}` | | `updateRule()` | PATCH | `/rules/{id}` | `{id, camera, name?, mode?, schedule?}` | `RuleItem` | | `getAlgorithms()` | GET | `/algorithms` | — | `AlgorithmItem[]` | | `getAlgorithmName()` | — | 本地映射 | `code_name: string` | `string`(中文名) |