Pārlūkot izejas kodu

feat(lss): enhance LSS node management with new API integration and UI improvements

- Introduced new API endpoints for managing LSS nodes, including listing, enabling/disabling, and deleting nodes.
- Updated the LSS management UI to support pagination, filtering, and detailed views of LSS nodes.
- Refactored types to include LSS node-specific data structures and statuses.
- Improved the overall user experience with enhanced status displays and action buttons for LSS node management.
yb 1 nedēļu atpakaļ
vecāks
revīzija
cd875c5411

+ 764 - 0
docs/api_torna/camera_vendor.md

@@ -0,0 +1,764 @@
+# 文档
+
+## 摄像头厂家管理 Controller
+
+### 获取厂家列表(分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/camera-vendors/list
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/list
+
+描述:获取厂家列表(分页)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述                                            | 示例值    |
+| ------- | ------- | ---- | -------- | ----------------------------------------------- | --------- |
+| page    | Integer | 否   | -        | 页码 (从 1 开始)                                | 1         |
+| size    | Integer | 否   | -        | 每页条数                                        | 10        |
+| keyword | String  | 否   | -        | 搜索关键词 (模糊匹配名称、ID 等)                | 摄像头    |
+| enabled | Boolean | 否   | -        | 启用状态过滤 (null=全部, true=启用, false=禁用) | true      |
+| sortBy  | String  | 否   | -        | 排序字段                                        | createdAt |
+| sortDir | String  | 否   | -        | 排序方向 (ASC/DESC)                             | DESC      |
+
+#### 请求示例
+
+```
+{
+    "page": 1,
+    "size": 10,
+    "keyword": "摄像头",
+    "enabled": true,
+    "sortBy": "createdAt",
+    "sortDir": "DESC"
+}
+```
+
+#### 响应参数
+
+| 名称              | 类型          | 必填 | 最大长度 | 描述                                | 示例值              |
+| ----------------- | ------------- | ---- | -------- | ----------------------------------- | ------------------- |
+| success           | Boolean       | 否   | -        | 请求是否成功                        | true                |
+| errCode           | String        | 否   | -        | 错误码(失败时返回)                |                     |
+| errMessage        | String        | 否   | -        | 错误信息(失败时返回)              |                     |
+| data              | object        | 否   |          | 响应数据 (ActualType: PageResponse) |                     |
+| └ list            | List<T>       | 否   |          | 数据列表 (ActualType: T)            |                     |
+| └ id              | Long          | 否   | -        | 厂家 ID                             | 0                   |
+| └ code            | String        | 否   | -        | 厂家代码                            |                     |
+| └ name            | String        | 否   | -        | 厂家名称                            |                     |
+| └ description     | String        | 否   | -        | 厂家描述                            |                     |
+| └ logoUrl         | String        | 否   | -        | 厂家 Logo URL                       |                     |
+| └ supportOnvif    | Boolean       | 否   | -        | 是否支持 ONVIF 协议                 | true                |
+| └ supportPtz      | Boolean       | 否   | -        | 是否支持 PTZ 控制                   | true                |
+| └ supportIsapi    | Boolean       | 否   | -        | 是否支持 ISAPI 协议                 | true                |
+| └ supportGb28181  | Boolean       | 否   | -        | 是否支持 GB28181 协议               | true                |
+| └ supportAudio    | Boolean       | 否   | -        | 是否支持音频                        | true                |
+| └ resolution      | String        | 否   | -        | 默认分辨率                          |                     |
+| └ defaultPort     | Integer       | 否   | -        | 默认端口号                          | 0                   |
+| └ defaultRtspPort | Integer       | 否   | -        | 默认 RTSP 端口号                    | 0                   |
+| └ rtspUrlTemplate | String        | 否   | -        | RTSP URL 模板                       |                     |
+| └ enabled         | Boolean       | 否   | -        | 是否启用                            | true                |
+| └ sortOrder       | Integer       | 否   | -        | 排序号                              | 0                   |
+| └ createdAt       | LocalDateTime | 否   | -        | 创建时间                            | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt       | LocalDateTime | 否   | -        | 更新时间                            | yyyy-MM-dd HH:mm:ss |
+| └ page            | Integer       | 否   | -        | 当前页码 (从 1 开始)                | 1                   |
+| └ size            | Integer       | 否   | -        | 每页条数                            | 10                  |
+| └ total           | Long          | 否   | -        | 总记录数                            | 100                 |
+| └ totalPages      | Integer       | 否   | -        | 总页数                              | 10                  |
+| └ hasNext         | Boolean       | 否   | -        | 是否有下一页                        | true                |
+| └ hasPrevious     | Boolean       | 否   | -        | 是否有上一页                        | false               |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "list": [
+            {
+                "id": 0,
+                "code": "string",
+                "name": "string",
+                "description": "string",
+                "logoUrl": "string",
+                "supportOnvif": true,
+                "supportPtz": true,
+                "supportIsapi": true,
+                "supportGb28181": true,
+                "supportAudio": true,
+                "resolution": "string",
+                "defaultPort": 0,
+                "defaultRtspPort": 0,
+                "rtspUrlTemplate": "string",
+                "enabled": true,
+                "sortOrder": 0,
+                "createdAt": "yyyy-MM-dd HH:mm:ss",
+                "updatedAt": "yyyy-MM-dd HH:mm:ss"
+            }
+        ],
+        "page": 1,
+        "size": 10,
+        "total": 100,
+        "totalPages": 10,
+        "hasNext": true,
+        "hasPrevious": false
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取所有启用的厂家(用于下拉选择)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/camera-vendors/enabled
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/enabled
+
+描述:获取所有启用的厂家(用于下拉选择)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称              | 类型          | 必填 | 最大长度 | 描述                        | 示例值              |
+| ----------------- | ------------- | ---- | -------- | --------------------------- | ------------------- |
+| success           | Boolean       | 否   | -        | 请求是否成功                | true                |
+| errCode           | String        | 否   | -        | 错误码(失败时返回)        |                     |
+| errMessage        | String        | 否   | -        | 错误信息(失败时返回)      |                     |
+| data              | array         | 否   |          | 响应数据 (ActualType: List) |                     |
+| └ id              | Long          | 否   | -        | 厂家 ID                     | 0                   |
+| └ code            | String        | 否   | -        | 厂家代码                    |                     |
+| └ name            | String        | 否   | -        | 厂家名称                    |                     |
+| └ description     | String        | 否   | -        | 厂家描述                    |                     |
+| └ logoUrl         | String        | 否   | -        | 厂家 Logo URL               |                     |
+| └ supportOnvif    | Boolean       | 否   | -        | 是否支持 ONVIF 协议         | true                |
+| └ supportPtz      | Boolean       | 否   | -        | 是否支持 PTZ 控制           | true                |
+| └ supportIsapi    | Boolean       | 否   | -        | 是否支持 ISAPI 协议         | true                |
+| └ supportGb28181  | Boolean       | 否   | -        | 是否支持 GB28181 协议       | true                |
+| └ supportAudio    | Boolean       | 否   | -        | 是否支持音频                | true                |
+| └ resolution      | String        | 否   | -        | 默认分辨率                  |                     |
+| └ defaultPort     | Integer       | 否   | -        | 默认端口号                  | 0                   |
+| └ defaultRtspPort | Integer       | 否   | -        | 默认 RTSP 端口号            | 0                   |
+| └ rtspUrlTemplate | String        | 否   | -        | RTSP URL 模板               |                     |
+| └ enabled         | Boolean       | 否   | -        | 是否启用                    | true                |
+| └ sortOrder       | Integer       | 否   | -        | 排序号                      | 0                   |
+| └ createdAt       | LocalDateTime | 否   | -        | 创建时间                    | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt       | LocalDateTime | 否   | -        | 更新时间                    | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 0,
+            "code": "string",
+            "name": "string",
+            "description": "string",
+            "logoUrl": "string",
+            "supportOnvif": true,
+            "supportPtz": true,
+            "supportIsapi": true,
+            "supportGb28181": true,
+            "supportAudio": true,
+            "resolution": "string",
+            "defaultPort": 0,
+            "defaultRtspPort": 0,
+            "rtspUrlTemplate": "string",
+            "enabled": true,
+            "sortOrder": 0,
+            "createdAt": "yyyy-MM-dd HH:mm:ss",
+            "updatedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取所有厂家
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/camera-vendors/all
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/all
+
+描述:获取所有厂家
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称              | 类型          | 必填 | 最大长度 | 描述                        | 示例值              |
+| ----------------- | ------------- | ---- | -------- | --------------------------- | ------------------- |
+| success           | Boolean       | 否   | -        | 请求是否成功                | true                |
+| errCode           | String        | 否   | -        | 错误码(失败时返回)        |                     |
+| errMessage        | String        | 否   | -        | 错误信息(失败时返回)      |                     |
+| data              | array         | 否   |          | 响应数据 (ActualType: List) |                     |
+| └ id              | Long          | 否   | -        | 厂家 ID                     | 0                   |
+| └ code            | String        | 否   | -        | 厂家代码                    |                     |
+| └ name            | String        | 否   | -        | 厂家名称                    |                     |
+| └ description     | String        | 否   | -        | 厂家描述                    |                     |
+| └ logoUrl         | String        | 否   | -        | 厂家 Logo URL               |                     |
+| └ supportOnvif    | Boolean       | 否   | -        | 是否支持 ONVIF 协议         | true                |
+| └ supportPtz      | Boolean       | 否   | -        | 是否支持 PTZ 控制           | true                |
+| └ supportIsapi    | Boolean       | 否   | -        | 是否支持 ISAPI 协议         | true                |
+| └ supportGb28181  | Boolean       | 否   | -        | 是否支持 GB28181 协议       | true                |
+| └ supportAudio    | Boolean       | 否   | -        | 是否支持音频                | true                |
+| └ resolution      | String        | 否   | -        | 默认分辨率                  |                     |
+| └ defaultPort     | Integer       | 否   | -        | 默认端口号                  | 0                   |
+| └ defaultRtspPort | Integer       | 否   | -        | 默认 RTSP 端口号            | 0                   |
+| └ rtspUrlTemplate | String        | 否   | -        | RTSP URL 模板               |                     |
+| └ enabled         | Boolean       | 否   | -        | 是否启用                    | true                |
+| └ sortOrder       | Integer       | 否   | -        | 排序号                      | 0                   |
+| └ createdAt       | LocalDateTime | 否   | -        | 创建时间                    | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt       | LocalDateTime | 否   | -        | 更新时间                    | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 0,
+            "code": "string",
+            "name": "string",
+            "description": "string",
+            "logoUrl": "string",
+            "supportOnvif": true,
+            "supportPtz": true,
+            "supportIsapi": true,
+            "supportGb28181": true,
+            "supportAudio": true,
+            "resolution": "string",
+            "defaultPort": 0,
+            "defaultRtspPort": 0,
+            "rtspUrlTemplate": "string",
+            "enabled": true,
+            "sortOrder": 0,
+            "createdAt": "yyyy-MM-dd HH:mm:ss",
+            "updatedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取厂家详情
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/camera-vendors/detail
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/detail
+
+描述:获取厂家详情
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述               | 示例值 |
+| ---- | ----- | ---- | -------- | ------------------ | ------ |
+| id   | int64 | 是   | -        | No comments found. | 0      |
+
+#### 响应参数
+
+| 名称              | 类型          | 必填 | 最大长度 | 描述                                   | 示例值              |
+| ----------------- | ------------- | ---- | -------- | -------------------------------------- | ------------------- |
+| success           | Boolean       | 否   | -        | 请求是否成功                           | true                |
+| errCode           | String        | 否   | -        | 错误码(失败时返回)                   |                     |
+| errMessage        | String        | 否   | -        | 错误信息(失败时返回)                 |                     |
+| data              | object        | 否   |          | 响应数据 (ActualType: CameraVendorDTO) |                     |
+| └ id              | Long          | 否   | -        | 厂家 ID                                | 0                   |
+| └ code            | String        | 否   | -        | 厂家代码                               |                     |
+| └ name            | String        | 否   | -        | 厂家名称                               |                     |
+| └ description     | String        | 否   | -        | 厂家描述                               |                     |
+| └ logoUrl         | String        | 否   | -        | 厂家 Logo URL                          |                     |
+| └ supportOnvif    | Boolean       | 否   | -        | 是否支持 ONVIF 协议                    | true                |
+| └ supportPtz      | Boolean       | 否   | -        | 是否支持 PTZ 控制                      | true                |
+| └ supportIsapi    | Boolean       | 否   | -        | 是否支持 ISAPI 协议                    | true                |
+| └ supportGb28181  | Boolean       | 否   | -        | 是否支持 GB28181 协议                  | true                |
+| └ supportAudio    | Boolean       | 否   | -        | 是否支持音频                           | true                |
+| └ resolution      | String        | 否   | -        | 默认分辨率                             |                     |
+| └ defaultPort     | Integer       | 否   | -        | 默认端口号                             | 0                   |
+| └ defaultRtspPort | Integer       | 否   | -        | 默认 RTSP 端口号                       | 0                   |
+| └ rtspUrlTemplate | String        | 否   | -        | RTSP URL 模板                          |                     |
+| └ enabled         | Boolean       | 否   | -        | 是否启用                               | true                |
+| └ sortOrder       | Integer       | 否   | -        | 排序号                                 | 0                   |
+| └ createdAt       | LocalDateTime | 否   | -        | 创建时间                               | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt       | LocalDateTime | 否   | -        | 更新时间                               | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 0,
+        "code": "string",
+        "name": "string",
+        "description": "string",
+        "logoUrl": "string",
+        "supportOnvif": true,
+        "supportPtz": true,
+        "supportIsapi": true,
+        "supportGb28181": true,
+        "supportAudio": true,
+        "resolution": "string",
+        "defaultPort": 0,
+        "defaultRtspPort": 0,
+        "rtspUrlTemplate": "string",
+        "enabled": true,
+        "sortOrder": 0,
+        "createdAt": "yyyy-MM-dd HH:mm:ss",
+        "updatedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 根据代码获取厂家
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/camera-vendors/byCode
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/byCode
+
+描述:根据代码获取厂家
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型   | 必填 | 最大长度 | 描述               | 示例值 |
+| ---- | ------ | ---- | -------- | ------------------ | ------ |
+| code | string | 是   | -        | No comments found. |        |
+
+#### 响应参数
+
+| 名称              | 类型          | 必填 | 最大长度 | 描述                                   | 示例值              |
+| ----------------- | ------------- | ---- | -------- | -------------------------------------- | ------------------- |
+| success           | Boolean       | 否   | -        | 请求是否成功                           | true                |
+| errCode           | String        | 否   | -        | 错误码(失败时返回)                   |                     |
+| errMessage        | String        | 否   | -        | 错误信息(失败时返回)                 |                     |
+| data              | object        | 否   |          | 响应数据 (ActualType: CameraVendorDTO) |                     |
+| └ id              | Long          | 否   | -        | 厂家 ID                                | 0                   |
+| └ code            | String        | 否   | -        | 厂家代码                               |                     |
+| └ name            | String        | 否   | -        | 厂家名称                               |                     |
+| └ description     | String        | 否   | -        | 厂家描述                               |                     |
+| └ logoUrl         | String        | 否   | -        | 厂家 Logo URL                          |                     |
+| └ supportOnvif    | Boolean       | 否   | -        | 是否支持 ONVIF 协议                    | true                |
+| └ supportPtz      | Boolean       | 否   | -        | 是否支持 PTZ 控制                      | true                |
+| └ supportIsapi    | Boolean       | 否   | -        | 是否支持 ISAPI 协议                    | true                |
+| └ supportGb28181  | Boolean       | 否   | -        | 是否支持 GB28181 协议                  | true                |
+| └ supportAudio    | Boolean       | 否   | -        | 是否支持音频                           | true                |
+| └ resolution      | String        | 否   | -        | 默认分辨率                             |                     |
+| └ defaultPort     | Integer       | 否   | -        | 默认端口号                             | 0                   |
+| └ defaultRtspPort | Integer       | 否   | -        | 默认 RTSP 端口号                       | 0                   |
+| └ rtspUrlTemplate | String        | 否   | -        | RTSP URL 模板                          |                     |
+| └ enabled         | Boolean       | 否   | -        | 是否启用                               | true                |
+| └ sortOrder       | Integer       | 否   | -        | 排序号                                 | 0                   |
+| └ createdAt       | LocalDateTime | 否   | -        | 创建时间                               | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt       | LocalDateTime | 否   | -        | 更新时间                               | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 0,
+        "code": "string",
+        "name": "string",
+        "description": "string",
+        "logoUrl": "string",
+        "supportOnvif": true,
+        "supportPtz": true,
+        "supportIsapi": true,
+        "supportGb28181": true,
+        "supportAudio": true,
+        "resolution": "string",
+        "defaultPort": 0,
+        "defaultRtspPort": 0,
+        "rtspUrlTemplate": "string",
+        "enabled": true,
+        "sortOrder": 0,
+        "createdAt": "yyyy-MM-dd HH:mm:ss",
+        "updatedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 创建厂家
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/camera-vendors/create
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/create
+
+描述:创建厂家
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称            | 类型    | 必填 | 最大长度 | 描述                                  | 示例值 |
+| --------------- | ------- | ---- | -------- | ------------------------------------- | ------ |
+| id              | Long    | 否   | -        | 厂家 ID (更新时必填)                  | 0      |
+| code            | String  | 是   | 50       | 厂家代码<br>Validate[max: 50; ]       |        |
+| name            | String  | 是   | 100      | 厂家名称<br>Validate[max: 100; ]      |        |
+| description     | String  | 否   | 500      | 厂家描述<br>Validate[max: 500; ]      |        |
+| logoUrl         | String  | 否   | 500      | 厂家 Logo URL<br>Validate[max: 500; ] |        |
+| supportOnvif    | Boolean | 否   | -        | 是否支持 ONVIF 协议                   | true   |
+| supportPtz      | Boolean | 否   | -        | 是否支持 PTZ 控制                     | true   |
+| supportIsapi    | Boolean | 否   | -        | 是否支持 ISAPI 协议                   | true   |
+| supportGb28181  | Boolean | 否   | -        | 是否支持 GB28181 协议                 | true   |
+| supportAudio    | Boolean | 否   | -        | 是否支持音频                          | true   |
+| resolution      | String  | 否   | 20       | 默认分辨率<br>Validate[max: 20; ]     |        |
+| defaultPort     | Integer | 否   | -        | 默认端口号                            | 0      |
+| defaultRtspPort | Integer | 否   | -        | 默认 RTSP 端口号                      | 0      |
+| rtspUrlTemplate | String  | 否   | 500      | RTSP URL 模板<br>Validate[max: 500; ] |        |
+| enabled         | Boolean | 否   | -        | 是否启用                              | true   |
+| sortOrder       | Integer | 否   | -        | 排序号                                | 0      |
+
+#### 请求示例
+
+```
+{
+    "id": 0,
+    "code": "string",
+    "name": "string",
+    "description": "string",
+    "logoUrl": "string",
+    "supportOnvif": true,
+    "supportPtz": true,
+    "supportIsapi": true,
+    "supportGb28181": true,
+    "supportAudio": true,
+    "resolution": "string",
+    "defaultPort": 0,
+    "defaultRtspPort": 0,
+    "rtspUrlTemplate": "string",
+    "enabled": true,
+    "sortOrder": 0
+}
+```
+
+#### 响应参数
+
+| 名称              | 类型          | 必填 | 最大长度 | 描述                                   | 示例值              |
+| ----------------- | ------------- | ---- | -------- | -------------------------------------- | ------------------- |
+| success           | Boolean       | 否   | -        | 请求是否成功                           | true                |
+| errCode           | String        | 否   | -        | 错误码(失败时返回)                   |                     |
+| errMessage        | String        | 否   | -        | 错误信息(失败时返回)                 |                     |
+| data              | object        | 否   |          | 响应数据 (ActualType: CameraVendorDTO) |                     |
+| └ id              | Long          | 否   | -        | 厂家 ID                                | 0                   |
+| └ code            | String        | 否   | -        | 厂家代码                               |                     |
+| └ name            | String        | 否   | -        | 厂家名称                               |                     |
+| └ description     | String        | 否   | -        | 厂家描述                               |                     |
+| └ logoUrl         | String        | 否   | -        | 厂家 Logo URL                          |                     |
+| └ supportOnvif    | Boolean       | 否   | -        | 是否支持 ONVIF 协议                    | true                |
+| └ supportPtz      | Boolean       | 否   | -        | 是否支持 PTZ 控制                      | true                |
+| └ supportIsapi    | Boolean       | 否   | -        | 是否支持 ISAPI 协议                    | true                |
+| └ supportGb28181  | Boolean       | 否   | -        | 是否支持 GB28181 协议                  | true                |
+| └ supportAudio    | Boolean       | 否   | -        | 是否支持音频                           | true                |
+| └ resolution      | String        | 否   | -        | 默认分辨率                             |                     |
+| └ defaultPort     | Integer       | 否   | -        | 默认端口号                             | 0                   |
+| └ defaultRtspPort | Integer       | 否   | -        | 默认 RTSP 端口号                       | 0                   |
+| └ rtspUrlTemplate | String        | 否   | -        | RTSP URL 模板                          |                     |
+| └ enabled         | Boolean       | 否   | -        | 是否启用                               | true                |
+| └ sortOrder       | Integer       | 否   | -        | 排序号                                 | 0                   |
+| └ createdAt       | LocalDateTime | 否   | -        | 创建时间                               | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt       | LocalDateTime | 否   | -        | 更新时间                               | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 0,
+        "code": "string",
+        "name": "string",
+        "description": "string",
+        "logoUrl": "string",
+        "supportOnvif": true,
+        "supportPtz": true,
+        "supportIsapi": true,
+        "supportGb28181": true,
+        "supportAudio": true,
+        "resolution": "string",
+        "defaultPort": 0,
+        "defaultRtspPort": 0,
+        "rtspUrlTemplate": "string",
+        "enabled": true,
+        "sortOrder": 0,
+        "createdAt": "yyyy-MM-dd HH:mm:ss",
+        "updatedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 更新厂家
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/camera-vendors/update
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/update
+
+描述:更新厂家
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称            | 类型    | 必填 | 最大长度 | 描述                                  | 示例值 |
+| --------------- | ------- | ---- | -------- | ------------------------------------- | ------ |
+| id              | Long    | 否   | -        | 厂家 ID (更新时必填)                  | 0      |
+| code            | String  | 是   | 50       | 厂家代码<br>Validate[max: 50; ]       |        |
+| name            | String  | 是   | 100      | 厂家名称<br>Validate[max: 100; ]      |        |
+| description     | String  | 否   | 500      | 厂家描述<br>Validate[max: 500; ]      |        |
+| logoUrl         | String  | 否   | 500      | 厂家 Logo URL<br>Validate[max: 500; ] |        |
+| supportOnvif    | Boolean | 否   | -        | 是否支持 ONVIF 协议                   | true   |
+| supportPtz      | Boolean | 否   | -        | 是否支持 PTZ 控制                     | true   |
+| supportIsapi    | Boolean | 否   | -        | 是否支持 ISAPI 协议                   | true   |
+| supportGb28181  | Boolean | 否   | -        | 是否支持 GB28181 协议                 | true   |
+| supportAudio    | Boolean | 否   | -        | 是否支持音频                          | true   |
+| resolution      | String  | 否   | 20       | 默认分辨率<br>Validate[max: 20; ]     |        |
+| defaultPort     | Integer | 否   | -        | 默认端口号                            | 0      |
+| defaultRtspPort | Integer | 否   | -        | 默认 RTSP 端口号                      | 0      |
+| rtspUrlTemplate | String  | 否   | 500      | RTSP URL 模板<br>Validate[max: 500; ] |        |
+| enabled         | Boolean | 否   | -        | 是否启用                              | true   |
+| sortOrder       | Integer | 否   | -        | 排序号                                | 0      |
+
+#### 请求示例
+
+```
+{
+    "id": 0,
+    "code": "string",
+    "name": "string",
+    "description": "string",
+    "logoUrl": "string",
+    "supportOnvif": true,
+    "supportPtz": true,
+    "supportIsapi": true,
+    "supportGb28181": true,
+    "supportAudio": true,
+    "resolution": "string",
+    "defaultPort": 0,
+    "defaultRtspPort": 0,
+    "rtspUrlTemplate": "string",
+    "enabled": true,
+    "sortOrder": 0
+}
+```
+
+#### 响应参数
+
+| 名称              | 类型          | 必填 | 最大长度 | 描述                                   | 示例值              |
+| ----------------- | ------------- | ---- | -------- | -------------------------------------- | ------------------- |
+| success           | Boolean       | 否   | -        | 请求是否成功                           | true                |
+| errCode           | String        | 否   | -        | 错误码(失败时返回)                   |                     |
+| errMessage        | String        | 否   | -        | 错误信息(失败时返回)                 |                     |
+| data              | object        | 否   |          | 响应数据 (ActualType: CameraVendorDTO) |                     |
+| └ id              | Long          | 否   | -        | 厂家 ID                                | 0                   |
+| └ code            | String        | 否   | -        | 厂家代码                               |                     |
+| └ name            | String        | 否   | -        | 厂家名称                               |                     |
+| └ description     | String        | 否   | -        | 厂家描述                               |                     |
+| └ logoUrl         | String        | 否   | -        | 厂家 Logo URL                          |                     |
+| └ supportOnvif    | Boolean       | 否   | -        | 是否支持 ONVIF 协议                    | true                |
+| └ supportPtz      | Boolean       | 否   | -        | 是否支持 PTZ 控制                      | true                |
+| └ supportIsapi    | Boolean       | 否   | -        | 是否支持 ISAPI 协议                    | true                |
+| └ supportGb28181  | Boolean       | 否   | -        | 是否支持 GB28181 协议                  | true                |
+| └ supportAudio    | Boolean       | 否   | -        | 是否支持音频                           | true                |
+| └ resolution      | String        | 否   | -        | 默认分辨率                             |                     |
+| └ defaultPort     | Integer       | 否   | -        | 默认端口号                             | 0                   |
+| └ defaultRtspPort | Integer       | 否   | -        | 默认 RTSP 端口号                       | 0                   |
+| └ rtspUrlTemplate | String        | 否   | -        | RTSP URL 模板                          |                     |
+| └ enabled         | Boolean       | 否   | -        | 是否启用                               | true                |
+| └ sortOrder       | Integer       | 否   | -        | 排序号                                 | 0                   |
+| └ createdAt       | LocalDateTime | 否   | -        | 创建时间                               | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt       | LocalDateTime | 否   | -        | 更新时间                               | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 0,
+        "code": "string",
+        "name": "string",
+        "description": "string",
+        "logoUrl": "string",
+        "supportOnvif": true,
+        "supportPtz": true,
+        "supportIsapi": true,
+        "supportGb28181": true,
+        "supportAudio": true,
+        "resolution": "string",
+        "defaultPort": 0,
+        "defaultRtspPort": 0,
+        "rtspUrlTemplate": "string",
+        "enabled": true,
+        "sortOrder": 0,
+        "createdAt": "yyyy-MM-dd HH:mm:ss",
+        "updatedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 删除厂家
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/camera-vendors/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/delete
+
+描述:删除厂家
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述               | 示例值 |
+| ---- | ----- | ---- | -------- | ------------------ | ------ |
+| id   | int64 | 是   | -        | No comments found. | 0      |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 初始化默认厂家数据
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/camera-vendors/init
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/camera-vendors/init
+
+描述:初始化默认厂家数据
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无

+ 4075 - 0
docs/api_torna/export-1768870608391.md

@@ -0,0 +1,4075 @@
+# 文档
+
+## 摄像头控制 Controller
+
+MVP API 接口:
+
+- GET /camera/list 获取摄像头列表
+- GET /camera/{id} 获取摄像头信息
+- POST /camera/switch 切换摄像头通道
+- GET /camera/current 获取当前通道
+
+后台 PTZ 接口(可选):
+
+- POST /camera/{id}/ptz/start 开始 PTZ 控制
+- POST /camera/{id}/ptz/stop 停止 PTZ 控制
+
+### 获取摄像头列表
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/camera/list
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/camera/list
+
+描述:获取摄像头列表
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称      | 类型   | 必填 | 最大长度 | 描述            | 示例值      |
+| --------- | ------ | ---- | -------- | --------------- | ----------- |
+| machineId | String | 否   | -        | 机器 ID(可选) | machine_001 |
+
+#### 请求示例
+
+```
+{
+    "machineId": "machine_001"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ name | String | 否 | - | 摄像头名称 | 主摄像头 |
+| └ lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| └ model | String | 否 | - | 摄像头型号 | DS-2CD2143G2-IS |
+| └ rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101 |
+| └ channelNo | String | 否 | - | 通道号 | 1 |
+| └ status | String | 否 | - | 摄像头状态: ONLINE, OFFLINE | ONLINE |
+| └ capability | String | 否 | - | 摄像头能力: switch_only, ptz_enabled | ptz_enabled |
+| └ ptzSupported | Boolean | 否 | - | 是否支持 PTZ | true |
+| └ remark | String | 否 | - | 备注 |  |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "cameraId": "cam_001",
+            "name": "主摄像头",
+            "lssId": "lss_001",
+            "model": "DS-2CD2143G2-IS",
+            "rtspUrl": "rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101",
+            "channelNo": "1",
+            "status": "ONLINE",
+            "capability": "ptz_enabled",
+            "ptzSupported": true,
+            "remark": "string",
+            "enabled": true
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取摄像头信息
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/camera/{cameraId}
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/camera/{cameraId}
+
+描述:获取摄像头信息
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称     | 必填 | 描述      | 示例值     |
+| -------- | ---- | --------- | ---------- |
+| cameraId | 是   | 摄像头 ID | camera_001 |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: CameraDTO) |  |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ name | String | 否 | - | 摄像头名称 | 主摄像头 |
+| └ lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| └ model | String | 否 | - | 摄像头型号 | DS-2CD2143G2-IS |
+| └ rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101 |
+| └ channelNo | String | 否 | - | 通道号 | 1 |
+| └ status | String | 否 | - | 摄像头状态: ONLINE, OFFLINE | ONLINE |
+| └ capability | String | 否 | - | 摄像头能力: switch_only, ptz_enabled | ptz_enabled |
+| └ ptzSupported | Boolean | 否 | - | 是否支持 PTZ | true |
+| └ remark | String | 否 | - | 备注 |  |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "cameraId": "cam_001",
+        "name": "主摄像头",
+        "lssId": "lss_001",
+        "model": "DS-2CD2143G2-IS",
+        "rtspUrl": "rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101",
+        "channelNo": "1",
+        "status": "ONLINE",
+        "capability": "ptz_enabled",
+        "ptzSupported": true,
+        "remark": "string",
+        "enabled": true
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 切换摄像头通道(MVP 核心)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/camera/switch
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/camera/switch
+
+描述:切换摄像头通道(MVP 核心)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称      | 类型   | 必填 | 最大长度 | 描述        | 示例值      |
+| --------- | ------ | ---- | -------- | ----------- | ----------- |
+| machineId | String | 是   | -        | 机器 ID     | machine_001 |
+| channelId | String | 是   | -        | 目标通道 ID | ch_001      |
+
+#### 请求示例
+
+```
+{
+    "machineId": "machine_001",
+    "channelId": "ch_001"
+}
+```
+
+#### 响应参数
+
+| 名称          | 类型    | 必填 | 最大长度 | 描述                              | 示例值                           |
+| ------------- | ------- | ---- | -------- | --------------------------------- | -------------------------------- |
+| success       | Boolean | 否   | -        | 请求是否成功                      | true                             |
+| errCode       | String  | 否   | -        | 错误码(失败时返回)              |                                  |
+| errMessage    | String  | 否   | -        | 错误信息(失败时返回)            |                                  |
+| data          | object  | 否   |          | 响应数据 (ActualType: ChannelDTO) |                                  |
+| └ channelId   | String  | 否   | -        | 通道 ID                           | ch_001                           |
+| └ name        | String  | 否   | -        | 通道名称                          | 主通道                           |
+| └ rtspUrl     | String  | 否   | -        | RTSP 地址                         | rtsp://192.168.1.100:554/stream1 |
+| └ defaultView | Boolean | 否   | -        | 是否默认视角                      | true                             |
+| └ status      | String  | 否   | -        | 通道状态: ONLINE, OFFLINE         | ONLINE                           |
+| └ cameraId    | String  | 否   | -        | 所属摄像头 ID                     | cam_001                          |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "channelId": "ch_001",
+        "name": "主通道",
+        "rtspUrl": "rtsp://192.168.1.100:554/stream1",
+        "defaultView": true,
+        "status": "ONLINE",
+        "cameraId": "cam_001"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取当前活动通道
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/camera/current
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/camera/current
+
+描述:获取当前活动通道
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称      | 类型   | 必填 | 最大长度 | 描述    | 示例值      |
+| --------- | ------ | ---- | -------- | ------- | ----------- |
+| machineId | string | 是   | -        | 机器 ID | machine_001 |
+
+#### 响应参数
+
+| 名称          | 类型    | 必填 | 最大长度 | 描述                              | 示例值                           |
+| ------------- | ------- | ---- | -------- | --------------------------------- | -------------------------------- |
+| success       | Boolean | 否   | -        | 请求是否成功                      | true                             |
+| errCode       | String  | 否   | -        | 错误码(失败时返回)              |                                  |
+| errMessage    | String  | 否   | -        | 错误信息(失败时返回)            |                                  |
+| data          | object  | 否   |          | 响应数据 (ActualType: ChannelDTO) |                                  |
+| └ channelId   | String  | 否   | -        | 通道 ID                           | ch_001                           |
+| └ name        | String  | 否   | -        | 通道名称                          | 主通道                           |
+| └ rtspUrl     | String  | 否   | -        | RTSP 地址                         | rtsp://192.168.1.100:554/stream1 |
+| └ defaultView | Boolean | 否   | -        | 是否默认视角                      | true                             |
+| └ status      | String  | 否   | -        | 通道状态: ONLINE, OFFLINE         | ONLINE                           |
+| └ cameraId    | String  | 否   | -        | 所属摄像头 ID                     | cam_001                          |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "channelId": "ch_001",
+        "name": "主通道",
+        "rtspUrl": "rtsp://192.168.1.100:554/stream1",
+        "defaultView": true,
+        "status": "ONLINE",
+        "cameraId": "cam_001"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 开始 PTZ 控制(后台专用)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/camera/{cameraId}/ptz/start
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/camera/{cameraId}/ptz/start
+
+描述:开始 PTZ 控制(后台专用)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称     | 必填 | 描述      | 示例值        |
+| -------- | ---- | --------- | ------------- |
+| cameraId | 是   | 摄像头 ID | hikvision_ptz |
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称   | 类型   | 必填 | 最大长度 | 描述        | 示例值 |
+| ------ | ------ | ---- | -------- | ----------- | ------ |
+| action | string | 是   | -        | PTZ 动作    | up     |
+| speed  | int32  | 是   | -        | 速度(1-100) | 50     |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 停止 PTZ 控制(后台专用)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/camera/{cameraId}/ptz/stop
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/camera/{cameraId}/ptz/stop
+
+描述:停止 PTZ 控制(后台专用)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称     | 必填 | 描述      | 示例值        |
+| -------- | ---- | --------- | ------------- |
+| cameraId | 是   | 摄像头 ID | hikvision_ptz |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### PTZ 直接控制(兼容前端 pan/tilt/zoom 方式)
+
+与前端海康调试接口一致:直接传 pan/tilt/zoom 值
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/camera/{cameraId}/ptz/control
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/camera/{cameraId}/ptz/control
+
+描述:PTZ 直接控制(兼容前端 pan/tilt/zoom 方式)
+
+与前端海康调试接口一致:直接传 pan/tilt/zoom 值
+
+ContentType:`application/json`
+
+#### Path 参数
+
+| 名称     | 必填 | 描述      | 示例值        |
+| -------- | ---- | --------- | ------------- |
+| cameraId | 是   | 摄像头 ID | hikvision_ptz |
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述                                                   | 示例值 |
+| ------- | ------- | ---- | -------- | ------------------------------------------------------ | ------ |
+| pan     | Integer | 否   | 100      | 水平移动速度<br>负值向左,正值向右<br>范围: -100 ~ 100 | 0      |
+| tilt    | Integer | 否   | 100      | 垂直移动速度<br>负值向下,正值向上<br>范围: -100 ~ 100 | 0      |
+| zoom    | Integer | 否   | 100      | 缩放速度<br>负值缩小,正值放大<br>范围: -100 ~ 100     | 0      |
+| channel | Integer | 否   | -        | 通道号(可选,默认 1)                                 | 0      |
+
+#### 请求示例
+
+```
+{
+    "pan": 0,
+    "tilt": 0,
+    "zoom": 0,
+    "channel": 0
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+## 摄像头管理
+
+### 获取摄像头列表(分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/cameras/list
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/cameras/list
+
+描述:获取摄像头列表(分页)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述                                            | 示例值    |
+| ------- | ------- | ---- | -------- | ----------------------------------------------- | --------- |
+| page    | Integer | 否   | -        | 页码 (从 1 开始)                                | 1         |
+| size    | Integer | 否   | -        | 每页条数                                        | 10        |
+| keyword | String  | 否   | -        | 搜索关键词 (模糊匹配名称、ID 等)                | 摄像头    |
+| enabled | Boolean | 否   | -        | 启用状态过滤 (null=全部, true=启用, false=禁用) | true      |
+| sortBy  | String  | 否   | -        | 排序字段                                        | createdAt |
+| sortDir | String  | 否   | -        | 排序方向 (ASC/DESC)                             | DESC      |
+| lssId   | String  | 否   | -        | LSS 节点 ID 过滤                                | lss_001   |
+| status  | String  | 否   | -        | 在线状态过滤 (ONLINE/OFFLINE)                   | ONLINE    |
+
+#### 请求示例
+
+```
+{
+    "page": 1,
+    "size": 10,
+    "keyword": "摄像头",
+    "enabled": true,
+    "sortBy": "createdAt",
+    "sortDir": "DESC",
+    "lssId": "lss_001",
+    "status": "ONLINE"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: PageResponse) |  |
+| └ list | List<T> | 否 |  | 数据列表 (ActualType: T) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ name | String | 否 | - | 名称 | 主摄像头 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ brand | String | 否 | - | 品牌 | hikvision |
+| └ capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| └ status | String | 否 | - | 状态: ONLINE, OFFLINE | ONLINE |
+| └ lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| └ model | String | 否 | - | 摄像头型号 | DS-2CD2T47G2-LSU/SL |
+| └ rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/stream1 |
+| └ channelNo | String | 否 | - | 通道号 | 1 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2026-01-07T10:00:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2026-01-07T10:00:00 |
+| └ page | Integer | 否 | - | 当前页码 (从 1 开始) | 1 |
+| └ size | Integer | 否 | - | 每页条数 | 10 |
+| └ total | Long | 否 | - | 总记录数 | 100 |
+| └ totalPages | Integer | 否 | - | 总页数 | 10 |
+| └ hasNext | Boolean | 否 | - | 是否有下一页 | true |
+| └ hasPrevious | Boolean | 否 | - | 是否有上一页 | false |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "list": [
+            {
+                "id": 1,
+                "cameraId": "cam_001",
+                "name": "主摄像头",
+                "ip": "192.168.1.100",
+                "port": 80,
+                "username": "admin",
+                "brand": "hikvision",
+                "capability": "ptz_enabled",
+                "status": "ONLINE",
+                "lssId": "lss_001",
+                "model": "DS-2CD2T47G2-LSU/SL",
+                "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+                "channelNo": "1",
+                "remark": "string",
+                "enabled": true,
+                "createdAt": "2026-01-07T10:00:00",
+                "updatedAt": "2026-01-07T10:00:00"
+            }
+        ],
+        "page": 1,
+        "size": 10,
+        "total": 100,
+        "totalPages": 10,
+        "hasNext": true,
+        "hasPrevious": false
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取摄像头列表(全部,不分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/cameras/listAll
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/cameras/listAll
+
+描述:获取摄像头列表(全部,不分页)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称      | 类型   | 必填 | 最大长度 | 描述            | 示例值      |
+| --------- | ------ | ---- | -------- | --------------- | ----------- |
+| machineId | string | 否   | -        | 机器 ID(可选) | machine_001 |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ name | String | 否 | - | 名称 | 主摄像头 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ brand | String | 否 | - | 品牌 | hikvision |
+| └ capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| └ status | String | 否 | - | 状态: ONLINE, OFFLINE | ONLINE |
+| └ lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| └ model | String | 否 | - | 摄像头型号 | DS-2CD2T47G2-LSU/SL |
+| └ rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/stream1 |
+| └ channelNo | String | 否 | - | 通道号 | 1 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2026-01-07T10:00:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 1,
+            "cameraId": "cam_001",
+            "name": "主摄像头",
+            "ip": "192.168.1.100",
+            "port": 80,
+            "username": "admin",
+            "brand": "hikvision",
+            "capability": "ptz_enabled",
+            "status": "ONLINE",
+            "lssId": "lss_001",
+            "model": "DS-2CD2T47G2-LSU/SL",
+            "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+            "channelNo": "1",
+            "remark": "string",
+            "enabled": true,
+            "createdAt": "2026-01-07T10:00:00",
+            "updatedAt": "2026-01-07T10:00:00"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取摄像头详情
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/cameras/detail
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/cameras/detail
+
+描述:获取摄像头详情
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述          | 示例值 |
+| ---- | ----- | ---- | -------- | ------------- | ------ |
+| id   | int64 | 是   | -        | 摄像头主键 ID | 1      |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: CameraInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ name | String | 否 | - | 名称 | 主摄像头 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ brand | String | 否 | - | 品牌 | hikvision |
+| └ capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| └ status | String | 否 | - | 状态: ONLINE, OFFLINE | ONLINE |
+| └ lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| └ model | String | 否 | - | 摄像头型号 | DS-2CD2T47G2-LSU/SL |
+| └ rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/stream1 |
+| └ channelNo | String | 否 | - | 通道号 | 1 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2026-01-07T10:00:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "cameraId": "cam_001",
+        "name": "主摄像头",
+        "ip": "192.168.1.100",
+        "port": 80,
+        "username": "admin",
+        "brand": "hikvision",
+        "capability": "ptz_enabled",
+        "status": "ONLINE",
+        "lssId": "lss_001",
+        "model": "DS-2CD2T47G2-LSU/SL",
+        "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+        "channelNo": "1",
+        "remark": "string",
+        "enabled": true,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 添加摄像头
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/cameras/add
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/cameras/add
+
+描述:添加摄像头
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
+| cameraId | String | 是 | 50 | 摄像头 ID(唯一标识)<br>Validate[max: 50; ] | cam_001 |
+| name | String | 是 | 100 | 名称<br>Validate[max: 100; ] | 主摄像头 |
+| ip | String | 是 | - | IP 地址<br>Validate[regexp: ^((25[0-5] | 2[0-4]\\d | [01]?\\d\\d?)\\.){3}(25[0-5] | 2[0-4]\\d | [01]?\\d\\d?)$; ] | 192.168.1.100 |
+| port | Integer | 否 | - | 端口 | 80 |
+| username | String | 否 | 50 | 用户名<br>Validate[max: 50; ] | admin |
+| password | String | 否 | 100 | 密码<br>Validate[max: 100; ] | password123 |
+| brand | String | 否 | 30 | 品牌<br>Validate[max: 30; ] | hikvision |
+| capability | String | 否 | - | 能力: switch_only, ptz_enabled<br>Validate[regexp: ^(switch_only | ptz_enabled)$; ] | ptz_enabled |
+| lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| model | String | 否 | 100 | 摄像头型号<br>Validate[max: 100; ] | DS-2CD2T47G2-LSU/SL |
+| rtspUrl | String | 否 | 500 | RTSP 推流地址<br>Validate[max: 500; ] | rtsp://admin:password@192.168.1.100:554/stream1 |
+| channelNo | String | 否 | 20 | 通道号 (用于多通道摄像头)<br>Validate[max: 20; ] | 1 |
+| remark | String | 否 | 500 | 备注<br>Validate[max: 500; ] |  |
+
+#### 请求示例
+
+```
+{
+    "cameraId": "cam_001",
+    "name": "主摄像头",
+    "ip": "192.168.1.100",
+    "port": 80,
+    "username": "admin",
+    "password": "password123",
+    "brand": "hikvision",
+    "capability": "ptz_enabled",
+    "lssId": "lss_001",
+    "model": "DS-2CD2T47G2-LSU/SL",
+    "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+    "channelNo": "1",
+    "remark": "string"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: CameraInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ name | String | 否 | - | 名称 | 主摄像头 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ brand | String | 否 | - | 品牌 | hikvision |
+| └ capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| └ status | String | 否 | - | 状态: ONLINE, OFFLINE | ONLINE |
+| └ lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| └ model | String | 否 | - | 摄像头型号 | DS-2CD2T47G2-LSU/SL |
+| └ rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/stream1 |
+| └ channelNo | String | 否 | - | 通道号 | 1 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2026-01-07T10:00:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "cameraId": "cam_001",
+        "name": "主摄像头",
+        "ip": "192.168.1.100",
+        "port": 80,
+        "username": "admin",
+        "brand": "hikvision",
+        "capability": "ptz_enabled",
+        "status": "ONLINE",
+        "lssId": "lss_001",
+        "model": "DS-2CD2T47G2-LSU/SL",
+        "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+        "channelNo": "1",
+        "remark": "string",
+        "enabled": true,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 更新摄像头
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/cameras/update
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/cameras/update
+
+描述:更新摄像头
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| id | Long | 否 | - | 摄像头数据库 ID | 1 |
+| name | String | 否 | - | 名称 | 主摄像头 |
+| ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| port | Integer | 否 | - | 端口 | 80 |
+| username | String | 否 | - | 用户名 | admin |
+| password | String | 否 | - | 密码(不传或为空则不修改) | password123 |
+| brand | String | 否 | - | 品牌 | hikvision |
+| capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| model | String | 否 | - | 摄像头型号 | DS-2CD2T47G2-LSU/SL |
+| rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/stream1 |
+| channelNo | String | 否 | - | 通道号 | 1 |
+| remark | String | 否 | - | 备注 |  |
+| enabled | Boolean | 否 | - | 启用状态 | true |
+
+#### 请求示例
+
+```
+{
+    "id": 1,
+    "name": "主摄像头",
+    "ip": "192.168.1.100",
+    "port": 80,
+    "username": "admin",
+    "password": "password123",
+    "brand": "hikvision",
+    "capability": "ptz_enabled",
+    "lssId": "lss_001",
+    "model": "DS-2CD2T47G2-LSU/SL",
+    "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+    "channelNo": "1",
+    "remark": "string",
+    "enabled": true
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: CameraInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ name | String | 否 | - | 名称 | 主摄像头 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ brand | String | 否 | - | 品牌 | hikvision |
+| └ capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| └ status | String | 否 | - | 状态: ONLINE, OFFLINE | ONLINE |
+| └ lssId | String | 否 | - | 绑定的 LSS 节点 ID | lss_001 |
+| └ model | String | 否 | - | 摄像头型号 | DS-2CD2T47G2-LSU/SL |
+| └ rtspUrl | String | 否 | - | RTSP 推流地址 | rtsp://admin:password@192.168.1.100:554/stream1 |
+| └ channelNo | String | 否 | - | 通道号 | 1 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2026-01-07T10:00:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "cameraId": "cam_001",
+        "name": "主摄像头",
+        "ip": "192.168.1.100",
+        "port": 80,
+        "username": "admin",
+        "brand": "hikvision",
+        "capability": "ptz_enabled",
+        "status": "ONLINE",
+        "lssId": "lss_001",
+        "model": "DS-2CD2T47G2-LSU/SL",
+        "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+        "channelNo": "1",
+        "remark": "string",
+        "enabled": true,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 删除摄像头
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/cameras/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/cameras/delete
+
+描述:删除摄像头
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述          | 示例值 |
+| ---- | ----- | ---- | -------- | ------------- | ------ |
+| id   | int64 | 是   | -        | 摄像头主键 ID | 1      |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 检测摄像头连通性
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/cameras/check
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/cameras/check
+
+描述:检测摄像头连通性
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述          | 示例值 |
+| ---- | ----- | ---- | -------- | ------------- | ------ |
+| id   | int64 | 是   | -        | 摄像头主键 ID | 1      |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                           | 示例值 |
+| ---------- | ------- | ---- | -------- | ------------------------------ | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                   | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)           |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)         |        |
+| data       | boolean | 否   | -        | 响应数据 (ActualType: Boolean) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": false
+}
+```
+
+#### 错误码
+
+无
+
+### 获取摄像头快照
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/cameras/snapshot
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/cameras/snapshot
+
+描述:获取摄像头快照
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述          | 示例值 |
+| ---- | ----- | ---- | -------- | ------------- | ------ |
+| id   | int64 | 是   | -        | 摄像头主键 ID | 1      |
+
+#### 响应参数
+
+| 名称       | 类型          | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean       | 否   | -        | 请求是否成功                | true   |
+| errCode    | String        | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String        | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | array         | 否   |          | 响应数据 (ActualType: byte) |        |
+| └ -        | array[byte[]] | 否   | -        | array of byte[]             |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            " -": ""
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### PTZ 控制
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/cameras/ptz
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/cameras/ptz
+
+描述:PTZ 控制
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称   | 类型   | 必填 | 最大长度 | 描述             | 示例值 |
+| ------ | ------ | ---- | -------- | ---------------- | ------ |
+| id     | Long   | 否   | -        | 摄像头 ID        | 1      |
+| action | String | 否   | -        | PTZ 动作         | UP     |
+| speed  | Float  | 否   | -        | 速度 (0.0 - 1.0) | 0.5    |
+
+#### 请求示例
+
+```
+{
+    "id": 1,
+    "action": "UP",
+    "speed": 0.5
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                           | 示例值 |
+| ---------- | ------- | ---- | -------- | ------------------------------ | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                   | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)           |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)         |        |
+| data       | boolean | 否   | -        | 响应数据 (ActualType: Boolean) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": false
+}
+```
+
+#### 错误码
+
+无
+
+## 机器管理
+
+### 获取机器列表(分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/machines/list
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/machines/list
+
+描述:获取机器列表(分页)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述                                            | 示例值    |
+| ------- | ------- | ---- | -------- | ----------------------------------------------- | --------- |
+| page    | Integer | 否   | -        | 页码 (从 1 开始)                                | 1         |
+| size    | Integer | 否   | -        | 每页条数                                        | 10        |
+| keyword | String  | 否   | -        | 搜索关键词 (模糊匹配名称、ID 等)                | 摄像头    |
+| enabled | Boolean | 否   | -        | 启用状态过滤 (null=全部, true=启用, false=禁用) | true      |
+| sortBy  | String  | 否   | -        | 排序字段                                        | createdAt |
+| sortDir | String  | 否   | -        | 排序方向 (ASC/DESC)                             | DESC      |
+
+#### 请求示例
+
+```
+{
+    "page": 1,
+    "size": 10,
+    "keyword": "摄像头",
+    "enabled": true,
+    "sortBy": "createdAt",
+    "sortDir": "DESC"
+}
+```
+
+#### 响应参数
+
+| 名称          | 类型          | 必填 | 最大长度 | 描述                                | 示例值              |
+| ------------- | ------------- | ---- | -------- | ----------------------------------- | ------------------- |
+| success       | Boolean       | 否   | -        | 请求是否成功                        | true                |
+| errCode       | String        | 否   | -        | 错误码(失败时返回)                |                     |
+| errMessage    | String        | 否   | -        | 错误信息(失败时返回)              |                     |
+| data          | object        | 否   |          | 响应数据 (ActualType: PageResponse) |                     |
+| └ list        | List<T>       | 否   |          | 数据列表 (ActualType: T)            |                     |
+| └ id          | Long          | 否   | -        | 主键 ID                             | 1                   |
+| └ machineId   | String        | 否   | -        | 机器 ID                             | machine_001         |
+| └ name        | String        | 否   | -        | 名称                                | 1 号机              |
+| └ location    | String        | 否   | -        | 位置                                | A 区 1 楼           |
+| └ description | String        | 否   | -        | 描述                                | 主力机器            |
+| └ enabled     | Boolean       | 否   | -        | 是否启用                            | true                |
+| └ cameraCount | Integer       | 否   | -        | 摄像头数量                          | 3                   |
+| └ createdAt   | LocalDateTime | 否   | -        | 创建时间                            | 2026-01-07T10:00:00 |
+| └ updatedAt   | LocalDateTime | 否   | -        | 更新时间                            | 2026-01-07T10:00:00 |
+| └ page        | Integer       | 否   | -        | 当前页码 (从 1 开始)                | 1                   |
+| └ size        | Integer       | 否   | -        | 每页条数                            | 10                  |
+| └ total       | Long          | 否   | -        | 总记录数                            | 100                 |
+| └ totalPages  | Integer       | 否   | -        | 总页数                              | 10                  |
+| └ hasNext     | Boolean       | 否   | -        | 是否有下一页                        | true                |
+| └ hasPrevious | Boolean       | 否   | -        | 是否有上一页                        | false               |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "list": [
+            {
+                "id": 1,
+                "machineId": "machine_001",
+                "name": "1号机",
+                "location": "A区1楼",
+                "description": "主力机器",
+                "enabled": true,
+                "cameraCount": 3,
+                "createdAt": "2026-01-07T10:00:00",
+                "updatedAt": "2026-01-07T10:00:00"
+            }
+        ],
+        "page": 1,
+        "size": 10,
+        "total": 100,
+        "totalPages": 10,
+        "hasNext": true,
+        "hasPrevious": false
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取机器列表(全部,不分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/machines/listAll
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/machines/listAll
+
+描述:获取机器列表(全部,不分页)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称          | 类型          | 必填 | 最大长度 | 描述                        | 示例值              |
+| ------------- | ------------- | ---- | -------- | --------------------------- | ------------------- |
+| success       | Boolean       | 否   | -        | 请求是否成功                | true                |
+| errCode       | String        | 否   | -        | 错误码(失败时返回)        |                     |
+| errMessage    | String        | 否   | -        | 错误信息(失败时返回)      |                     |
+| data          | array         | 否   |          | 响应数据 (ActualType: List) |                     |
+| └ id          | Long          | 否   | -        | 主键 ID                     | 1                   |
+| └ machineId   | String        | 否   | -        | 机器 ID                     | machine_001         |
+| └ name        | String        | 否   | -        | 名称                        | 1 号机              |
+| └ location    | String        | 否   | -        | 位置                        | A 区 1 楼           |
+| └ description | String        | 否   | -        | 描述                        | 主力机器            |
+| └ enabled     | Boolean       | 否   | -        | 是否启用                    | true                |
+| └ cameraCount | Integer       | 否   | -        | 摄像头数量                  | 3                   |
+| └ createdAt   | LocalDateTime | 否   | -        | 创建时间                    | 2026-01-07T10:00:00 |
+| └ updatedAt   | LocalDateTime | 否   | -        | 更新时间                    | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 1,
+            "machineId": "machine_001",
+            "name": "1号机",
+            "location": "A区1楼",
+            "description": "主力机器",
+            "enabled": true,
+            "cameraCount": 3,
+            "createdAt": "2026-01-07T10:00:00",
+            "updatedAt": "2026-01-07T10:00:00"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取机器详情
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/machines/detail
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/machines/detail
+
+描述:获取机器详情
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述        | 示例值 |
+| ---- | ----- | ---- | -------- | ----------- | ------ |
+| id   | int64 | 是   | -        | 机器主键 ID | 1      |
+
+#### 响应参数
+
+| 名称          | 类型          | 必填 | 最大长度 | 描述                              | 示例值              |
+| ------------- | ------------- | ---- | -------- | --------------------------------- | ------------------- |
+| success       | Boolean       | 否   | -        | 请求是否成功                      | true                |
+| errCode       | String        | 否   | -        | 错误码(失败时返回)              |                     |
+| errMessage    | String        | 否   | -        | 错误信息(失败时返回)            |                     |
+| data          | object        | 否   |          | 响应数据 (ActualType: MachineDTO) |                     |
+| └ id          | Long          | 否   | -        | 主键 ID                           | 1                   |
+| └ machineId   | String        | 否   | -        | 机器 ID                           | machine_001         |
+| └ name        | String        | 否   | -        | 名称                              | 1 号机              |
+| └ location    | String        | 否   | -        | 位置                              | A 区 1 楼           |
+| └ description | String        | 否   | -        | 描述                              | 主力机器            |
+| └ enabled     | Boolean       | 否   | -        | 是否启用                          | true                |
+| └ cameraCount | Integer       | 否   | -        | 摄像头数量                        | 3                   |
+| └ createdAt   | LocalDateTime | 否   | -        | 创建时间                          | 2026-01-07T10:00:00 |
+| └ updatedAt   | LocalDateTime | 否   | -        | 更新时间                          | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "machineId": "machine_001",
+        "name": "1号机",
+        "location": "A区1楼",
+        "description": "主力机器",
+        "enabled": true,
+        "cameraCount": 3,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 添加机器
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/machines/add
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/machines/add
+
+描述:添加机器
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称        | 类型   | 必填 | 最大长度 | 描述                                       | 示例值      |
+| ----------- | ------ | ---- | -------- | ------------------------------------------ | ----------- |
+| machineId   | String | 是   | 50       | 机器 ID(唯一标识)<br>Validate[max: 50; ] | machine_001 |
+| name        | String | 是   | 100      | 名称<br>Validate[max: 100; ]               | 1 号机      |
+| location    | String | 否   | 200      | 位置<br>Validate[max: 200; ]               | A 区 1 楼   |
+| description | String | 否   | 500      | 描述<br>Validate[max: 500; ]               | 主力机器    |
+
+#### 请求示例
+
+```
+{
+    "machineId": "machine_001",
+    "name": "1号机",
+    "location": "A区1楼",
+    "description": "主力机器"
+}
+```
+
+#### 响应参数
+
+| 名称          | 类型          | 必填 | 最大长度 | 描述                              | 示例值              |
+| ------------- | ------------- | ---- | -------- | --------------------------------- | ------------------- |
+| success       | Boolean       | 否   | -        | 请求是否成功                      | true                |
+| errCode       | String        | 否   | -        | 错误码(失败时返回)              |                     |
+| errMessage    | String        | 否   | -        | 错误信息(失败时返回)            |                     |
+| data          | object        | 否   |          | 响应数据 (ActualType: MachineDTO) |                     |
+| └ id          | Long          | 否   | -        | 主键 ID                           | 1                   |
+| └ machineId   | String        | 否   | -        | 机器 ID                           | machine_001         |
+| └ name        | String        | 否   | -        | 名称                              | 1 号机              |
+| └ location    | String        | 否   | -        | 位置                              | A 区 1 楼           |
+| └ description | String        | 否   | -        | 描述                              | 主力机器            |
+| └ enabled     | Boolean       | 否   | -        | 是否启用                          | true                |
+| └ cameraCount | Integer       | 否   | -        | 摄像头数量                        | 3                   |
+| └ createdAt   | LocalDateTime | 否   | -        | 创建时间                          | 2026-01-07T10:00:00 |
+| └ updatedAt   | LocalDateTime | 否   | -        | 更新时间                          | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "machineId": "machine_001",
+        "name": "1号机",
+        "location": "A区1楼",
+        "description": "主力机器",
+        "enabled": true,
+        "cameraCount": 3,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 更新机器
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/machines/update
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/machines/update
+
+描述:更新机器
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称        | 类型    | 必填 | 最大长度 | 描述          | 示例值    |
+| ----------- | ------- | ---- | -------- | ------------- | --------- |
+| id          | Long    | 否   | -        | 机器数据库 ID | 1         |
+| name        | String  | 否   | -        | 名称          | 1 号机    |
+| location    | String  | 否   | -        | 位置          | A 区 1 楼 |
+| description | String  | 否   | -        | 描述          | 主力机器  |
+| enabled     | Boolean | 否   | -        | 启用状态      | true      |
+
+#### 请求示例
+
+```
+{
+    "id": 1,
+    "name": "1号机",
+    "location": "A区1楼",
+    "description": "主力机器",
+    "enabled": true
+}
+```
+
+#### 响应参数
+
+| 名称          | 类型          | 必填 | 最大长度 | 描述                              | 示例值              |
+| ------------- | ------------- | ---- | -------- | --------------------------------- | ------------------- |
+| success       | Boolean       | 否   | -        | 请求是否成功                      | true                |
+| errCode       | String        | 否   | -        | 错误码(失败时返回)              |                     |
+| errMessage    | String        | 否   | -        | 错误信息(失败时返回)            |                     |
+| data          | object        | 否   |          | 响应数据 (ActualType: MachineDTO) |                     |
+| └ id          | Long          | 否   | -        | 主键 ID                           | 1                   |
+| └ machineId   | String        | 否   | -        | 机器 ID                           | machine_001         |
+| └ name        | String        | 否   | -        | 名称                              | 1 号机              |
+| └ location    | String        | 否   | -        | 位置                              | A 区 1 楼           |
+| └ description | String        | 否   | -        | 描述                              | 主力机器            |
+| └ enabled     | Boolean       | 否   | -        | 是否启用                          | true                |
+| └ cameraCount | Integer       | 否   | -        | 摄像头数量                        | 3                   |
+| └ createdAt   | LocalDateTime | 否   | -        | 创建时间                          | 2026-01-07T10:00:00 |
+| └ updatedAt   | LocalDateTime | 否   | -        | 更新时间                          | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "machineId": "machine_001",
+        "name": "1号机",
+        "location": "A区1楼",
+        "description": "主力机器",
+        "enabled": true,
+        "cameraCount": 3,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 删除机器
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/machines/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/machines/delete
+
+描述:删除机器
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述        | 示例值 |
+| ---- | ----- | ---- | -------- | ----------- | ------ |
+| id   | int64 | 是   | -        | 机器主键 ID | 1      |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+## 推流通道管理
+
+### 获取推流通道列表(分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/stream-channels/list
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/stream-channels/list
+
+描述:获取推流通道列表(分页)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述                                            | 示例值    |
+| ------- | ------- | ---- | -------- | ----------------------------------------------- | --------- |
+| page    | Integer | 否   | -        | 页码 (从 1 开始)                                | 1         |
+| size    | Integer | 否   | -        | 每页条数                                        | 10        |
+| keyword | String  | 否   | -        | 搜索关键词 (模糊匹配名称、ID 等)                | 摄像头    |
+| enabled | Boolean | 否   | -        | 启用状态过滤 (null=全部, true=启用, false=禁用) | true      |
+| sortBy  | String  | 否   | -        | 排序字段                                        | createdAt |
+| sortDir | String  | 否   | -        | 排序方向 (ASC/DESC)                             | DESC      |
+
+#### 请求示例
+
+```
+{
+    "page": 1,
+    "size": 10,
+    "keyword": "摄像头",
+    "enabled": true,
+    "sortBy": "createdAt",
+    "sortDir": "DESC"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: PageResponse) |  |
+| └ list | List<T> | 否 |  | 数据列表 (ActualType: T) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ channelId | String | 否 | - | 通道 ID | cf_channel_001 |
+| └ name | String | 否 | - | 通道名称 | 主推流通道 |
+| └ accountId | String | 否 | - | Cloudflare 账户 ID | 5544eac7cfb260d4fec9467d49513cea |
+| └ liveInputId | String | 否 | - | Cloudflare Live Input ID | b51e49994b6fd9e56b6f1fdfcd339fe6 |
+| └ customerSubdomain | String | 否 | - | 客户子域名 | customer-pj89kn2ke2tcuh19 |
+| └ mode | String | 否 | - | 推流模式: WHIP / RTMPS / SRT | WHIP |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish |
+| └ rtmpsUrl | String | 否 | - | RTMPS 推流地址 | rtmps://live.cloudflare.com:443/live/xxx |
+| └ hlsPlaybackUrl | String | 否 | - | HLS 播放地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8 |
+| └ whepPlaybackUrl | String | 否 | - | WHEP 播放地址 (WebRTC) | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play |
+| └ recordingEnabled | Boolean | 否 | - | 是否启用录制 | false |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2024-01-15T10:30:00 |
+| └ page | Integer | 否 | - | 当前页码 (从 1 开始) | 1 |
+| └ size | Integer | 否 | - | 每页条数 | 10 |
+| └ total | Long | 否 | - | 总记录数 | 100 |
+| └ totalPages | Integer | 否 | - | 总页数 | 10 |
+| └ hasNext | Boolean | 否 | - | 是否有下一页 | true |
+| └ hasPrevious | Boolean | 否 | - | 是否有上一页 | false |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "list": [
+            {
+                "id": 1,
+                "channelId": "cf_channel_001",
+                "name": "主推流通道",
+                "accountId": "5544eac7cfb260d4fec9467d49513cea",
+                "liveInputId": "b51e49994b6fd9e56b6f1fdfcd339fe6",
+                "customerSubdomain": "customer-pj89kn2ke2tcuh19",
+                "mode": "WHIP",
+                "whipUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish",
+                "rtmpsUrl": "rtmps://live.cloudflare.com:443/live/xxx",
+                "hlsPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8",
+                "whepPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play",
+                "recordingEnabled": false,
+                "enabled": true,
+                "createdAt": "2024-01-15T10:30:00",
+                "updatedAt": "2024-01-15T10:30:00"
+            }
+        ],
+        "page": 1,
+        "size": 10,
+        "total": 100,
+        "totalPages": 10,
+        "hasNext": true,
+        "hasPrevious": false
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取推流通道列表(全部,不分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/stream-channels/listAll
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/stream-channels/listAll
+
+描述:获取推流通道列表(全部,不分页)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ channelId | String | 否 | - | 通道 ID | cf_channel_001 |
+| └ name | String | 否 | - | 通道名称 | 主推流通道 |
+| └ accountId | String | 否 | - | Cloudflare 账户 ID | 5544eac7cfb260d4fec9467d49513cea |
+| └ liveInputId | String | 否 | - | Cloudflare Live Input ID | b51e49994b6fd9e56b6f1fdfcd339fe6 |
+| └ customerSubdomain | String | 否 | - | 客户子域名 | customer-pj89kn2ke2tcuh19 |
+| └ mode | String | 否 | - | 推流模式: WHIP / RTMPS / SRT | WHIP |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish |
+| └ rtmpsUrl | String | 否 | - | RTMPS 推流地址 | rtmps://live.cloudflare.com:443/live/xxx |
+| └ hlsPlaybackUrl | String | 否 | - | HLS 播放地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8 |
+| └ whepPlaybackUrl | String | 否 | - | WHEP 播放地址 (WebRTC) | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play |
+| └ recordingEnabled | Boolean | 否 | - | 是否启用录制 | false |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2024-01-15T10:30:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 1,
+            "channelId": "cf_channel_001",
+            "name": "主推流通道",
+            "accountId": "5544eac7cfb260d4fec9467d49513cea",
+            "liveInputId": "b51e49994b6fd9e56b6f1fdfcd339fe6",
+            "customerSubdomain": "customer-pj89kn2ke2tcuh19",
+            "mode": "WHIP",
+            "whipUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish",
+            "rtmpsUrl": "rtmps://live.cloudflare.com:443/live/xxx",
+            "hlsPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8",
+            "whepPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play",
+            "recordingEnabled": false,
+            "enabled": true,
+            "createdAt": "2024-01-15T10:30:00",
+            "updatedAt": "2024-01-15T10:30:00"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取推流通道详情
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/stream-channels/detail
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/stream-channels/detail
+
+描述:获取推流通道详情
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述            | 示例值 |
+| ---- | ----- | ---- | -------- | --------------- | ------ |
+| id   | int64 | 是   | -        | 推流通道主键 ID | 1      |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: StreamChannelInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ channelId | String | 否 | - | 通道 ID | cf_channel_001 |
+| └ name | String | 否 | - | 通道名称 | 主推流通道 |
+| └ accountId | String | 否 | - | Cloudflare 账户 ID | 5544eac7cfb260d4fec9467d49513cea |
+| └ liveInputId | String | 否 | - | Cloudflare Live Input ID | b51e49994b6fd9e56b6f1fdfcd339fe6 |
+| └ customerSubdomain | String | 否 | - | 客户子域名 | customer-pj89kn2ke2tcuh19 |
+| └ mode | String | 否 | - | 推流模式: WHIP / RTMPS / SRT | WHIP |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish |
+| └ rtmpsUrl | String | 否 | - | RTMPS 推流地址 | rtmps://live.cloudflare.com:443/live/xxx |
+| └ hlsPlaybackUrl | String | 否 | - | HLS 播放地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8 |
+| └ whepPlaybackUrl | String | 否 | - | WHEP 播放地址 (WebRTC) | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play |
+| └ recordingEnabled | Boolean | 否 | - | 是否启用录制 | false |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2024-01-15T10:30:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "channelId": "cf_channel_001",
+        "name": "主推流通道",
+        "accountId": "5544eac7cfb260d4fec9467d49513cea",
+        "liveInputId": "b51e49994b6fd9e56b6f1fdfcd339fe6",
+        "customerSubdomain": "customer-pj89kn2ke2tcuh19",
+        "mode": "WHIP",
+        "whipUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish",
+        "rtmpsUrl": "rtmps://live.cloudflare.com:443/live/xxx",
+        "hlsPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8",
+        "whepPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play",
+        "recordingEnabled": false,
+        "enabled": true,
+        "createdAt": "2024-01-15T10:30:00",
+        "updatedAt": "2024-01-15T10:30:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 添加推流通道
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/stream-channels/add
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/stream-channels/add
+
+描述:添加推流通道
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| channelId | String | 是 | - | 通道 ID | cf_channel_001 |
+| name | String | 是 | - | 通道名称 | 主推流通道 |
+| accountId | String | 否 | - | Cloudflare 账户 ID | 5544eac7cfb260d4fec9467d49513cea |
+| apiToken | String | 否 | - | Cloudflare API Token | d_f4nGUKFlB66MMMIS3NfVlUbn0A0p4jlrW5BbZW |
+| liveInputId | String | 是 | - | Cloudflare Live Input ID | b51e49994b6fd9e56b6f1fdfcd339fe6 |
+| streamKey | String | 否 | - | 流密钥 (用于 RTMPS) | 8c108b4025d3278b188b443e8a6c5503kb51e49994b6fd9e56b6f1fdfcd339fe6 |
+| customerSubdomain | String | 是 | - | 客户子域名 | customer-pj89kn2ke2tcuh19 |
+| mode | String | 否 | - | 推流模式: WHIP / RTMPS / SRT | WHIP |
+| recordingEnabled | Boolean | 否 | - | 是否启用录制 | false |
+
+#### 请求示例
+
+```
+{
+    "channelId": "cf_channel_001",
+    "name": "主推流通道",
+    "accountId": "5544eac7cfb260d4fec9467d49513cea",
+    "apiToken": "d_f4nGUKFlB66MMMIS3NfVlUbn0A0p4jlrW5BbZW",
+    "liveInputId": "b51e49994b6fd9e56b6f1fdfcd339fe6",
+    "streamKey": "8c108b4025d3278b188b443e8a6c5503kb51e49994b6fd9e56b6f1fdfcd339fe6",
+    "customerSubdomain": "customer-pj89kn2ke2tcuh19",
+    "mode": "WHIP",
+    "recordingEnabled": false
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: StreamChannelInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ channelId | String | 否 | - | 通道 ID | cf_channel_001 |
+| └ name | String | 否 | - | 通道名称 | 主推流通道 |
+| └ accountId | String | 否 | - | Cloudflare 账户 ID | 5544eac7cfb260d4fec9467d49513cea |
+| └ liveInputId | String | 否 | - | Cloudflare Live Input ID | b51e49994b6fd9e56b6f1fdfcd339fe6 |
+| └ customerSubdomain | String | 否 | - | 客户子域名 | customer-pj89kn2ke2tcuh19 |
+| └ mode | String | 否 | - | 推流模式: WHIP / RTMPS / SRT | WHIP |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish |
+| └ rtmpsUrl | String | 否 | - | RTMPS 推流地址 | rtmps://live.cloudflare.com:443/live/xxx |
+| └ hlsPlaybackUrl | String | 否 | - | HLS 播放地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8 |
+| └ whepPlaybackUrl | String | 否 | - | WHEP 播放地址 (WebRTC) | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play |
+| └ recordingEnabled | Boolean | 否 | - | 是否启用录制 | false |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2024-01-15T10:30:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "channelId": "cf_channel_001",
+        "name": "主推流通道",
+        "accountId": "5544eac7cfb260d4fec9467d49513cea",
+        "liveInputId": "b51e49994b6fd9e56b6f1fdfcd339fe6",
+        "customerSubdomain": "customer-pj89kn2ke2tcuh19",
+        "mode": "WHIP",
+        "whipUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish",
+        "rtmpsUrl": "rtmps://live.cloudflare.com:443/live/xxx",
+        "hlsPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8",
+        "whepPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play",
+        "recordingEnabled": false,
+        "enabled": true,
+        "createdAt": "2024-01-15T10:30:00",
+        "updatedAt": "2024-01-15T10:30:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 更新推流通道
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/stream-channels/update
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/stream-channels/update
+
+描述:更新推流通道
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| id | Long | 是 | - | 主键 ID | 1 |
+| name | String | 否 | - | 通道名称 | 主推流通道 |
+| accountId | String | 否 | - | Cloudflare 账户 ID | 5544eac7cfb260d4fec9467d49513cea |
+| apiToken | String | 否 | - | Cloudflare API Token | d_f4nGUKFlB66MMMIS3NfVlUbn0A0p4jlrW5BbZW |
+| liveInputId | String | 否 | - | Cloudflare Live Input ID | b51e49994b6fd9e56b6f1fdfcd339fe6 |
+| streamKey | String | 否 | - | 流密钥 (用于 RTMPS) | 8c108b4025d3278b188b443e8a6c5503kb51e49994b6fd9e56b6f1fdfcd339fe6 |
+| customerSubdomain | String | 否 | - | 客户子域名 | customer-pj89kn2ke2tcuh19 |
+| mode | String | 否 | - | 推流模式: WHIP / RTMPS / SRT | WHIP |
+| recordingEnabled | Boolean | 否 | - | 是否启用录制 | false |
+| enabled | Boolean | 否 | - | 是否启用 | true |
+
+#### 请求示例
+
+```
+{
+    "id": 1,
+    "name": "主推流通道",
+    "accountId": "5544eac7cfb260d4fec9467d49513cea",
+    "apiToken": "d_f4nGUKFlB66MMMIS3NfVlUbn0A0p4jlrW5BbZW",
+    "liveInputId": "b51e49994b6fd9e56b6f1fdfcd339fe6",
+    "streamKey": "8c108b4025d3278b188b443e8a6c5503kb51e49994b6fd9e56b6f1fdfcd339fe6",
+    "customerSubdomain": "customer-pj89kn2ke2tcuh19",
+    "mode": "WHIP",
+    "recordingEnabled": false,
+    "enabled": true
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: StreamChannelInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ channelId | String | 否 | - | 通道 ID | cf_channel_001 |
+| └ name | String | 否 | - | 通道名称 | 主推流通道 |
+| └ accountId | String | 否 | - | Cloudflare 账户 ID | 5544eac7cfb260d4fec9467d49513cea |
+| └ liveInputId | String | 否 | - | Cloudflare Live Input ID | b51e49994b6fd9e56b6f1fdfcd339fe6 |
+| └ customerSubdomain | String | 否 | - | 客户子域名 | customer-pj89kn2ke2tcuh19 |
+| └ mode | String | 否 | - | 推流模式: WHIP / RTMPS / SRT | WHIP |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish |
+| └ rtmpsUrl | String | 否 | - | RTMPS 推流地址 | rtmps://live.cloudflare.com:443/live/xxx |
+| └ hlsPlaybackUrl | String | 否 | - | HLS 播放地址 | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8 |
+| └ whepPlaybackUrl | String | 否 | - | WHEP 播放地址 (WebRTC) | https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play |
+| └ recordingEnabled | Boolean | 否 | - | 是否启用录制 | false |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2024-01-15T10:30:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "channelId": "cf_channel_001",
+        "name": "主推流通道",
+        "accountId": "5544eac7cfb260d4fec9467d49513cea",
+        "liveInputId": "b51e49994b6fd9e56b6f1fdfcd339fe6",
+        "customerSubdomain": "customer-pj89kn2ke2tcuh19",
+        "mode": "WHIP",
+        "whipUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/publish",
+        "rtmpsUrl": "rtmps://live.cloudflare.com:443/live/xxx",
+        "hlsPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/manifest/video.m3u8",
+        "whepPlaybackUrl": "https://customer-pj89kn2ke2tcuh19.cloudflarestream.com/b51e49994b6fd9e56b6f1fdfcd339fe6/webRTC/play",
+        "recordingEnabled": false,
+        "enabled": true,
+        "createdAt": "2024-01-15T10:30:00",
+        "updatedAt": "2024-01-15T10:30:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 删除推流通道
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/stream-channels/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/stream-channels/delete
+
+描述:删除推流通道
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称 | 类型  | 必填 | 最大长度 | 描述            | 示例值 |
+| ---- | ----- | ---- | -------- | --------------- | ------ |
+| id   | int64 | 是   | -        | 推流通道主键 ID | 1      |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+## 管理员认证
+
+### 登录
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/auth/login
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/auth/login
+
+描述:登录
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称     | 类型   | 必填 | 最大长度 | 描述                          | 示例值 |
+| -------- | ------ | ---- | -------- | ----------------------------- | ------ |
+| username | String | 是   | 50       | 用户名<br>Validate[max: 50; ] | admin  |
+| password | String | 是   | 100      | 密码<br>Validate[max: 100; ]  | 123456 |
+
+#### 请求示例
+
+```
+{
+    "username": "admin",
+    "password": "123456"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: LoginResponse) |  |
+| └ token | String | 否 | - | JWT Token | eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiJ9.xxx |
+| └ tokenType | String | 否 | - | Token 类型 | Bearer |
+| └ expiresIn | Long | 否 | - | 过期时间(秒) | 86400 |
+| └ admin | AdminInfoDTO | 否 |  | 用户信息 |  |
+| └ id | Long | 否 | - | 用户 ID | 1 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ nickname | String | 否 | - | 昵称 | 管理员 |
+| └ role | String | 否 | - | 角色 | ADMIN |
+| └ lastLoginAt | LocalDateTime | 否 | - | 最后登录时间 | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiJ9.xxx",
+        "tokenType": "Bearer",
+        "expiresIn": 86400,
+        "admin": {
+            "id": 1,
+            "username": "admin",
+            "nickname": "管理员",
+            "role": "ADMIN",
+            "lastLoginAt": "2026-01-07T10:00:00"
+        }
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 登出
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/auth/logout
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/auth/logout
+
+描述:登出
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 获取当前用户信息(直接从 Token 解析,不查询数据库)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/auth/info
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/auth/info
+
+描述:获取当前用户信息(直接从 Token 解析,不查询数据库)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称          | 类型          | 必填 | 最大长度 | 描述                                | 示例值              |
+| ------------- | ------------- | ---- | -------- | ----------------------------------- | ------------------- |
+| success       | Boolean       | 否   | -        | 请求是否成功                        | true                |
+| errCode       | String        | 否   | -        | 错误码(失败时返回)                |                     |
+| errMessage    | String        | 否   | -        | 错误信息(失败时返回)              |                     |
+| data          | object        | 否   |          | 响应数据 (ActualType: AdminInfoDTO) |                     |
+| └ id          | Long          | 否   | -        | 用户 ID                             | 1                   |
+| └ username    | String        | 否   | -        | 用户名                              | admin               |
+| └ nickname    | String        | 否   | -        | 昵称                                | 管理员              |
+| └ role        | String        | 否   | -        | 角色                                | ADMIN               |
+| └ lastLoginAt | LocalDateTime | 否   | -        | 最后登录时间                        | 2026-01-07T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "username": "admin",
+        "nickname": "管理员",
+        "role": "ADMIN",
+        "lastLoginAt": "2026-01-07T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 修改密码
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/auth/password
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/auth/password
+
+描述:修改密码
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称        | 类型   | 必填 | 最大长度 | 描述                                         | 示例值      |
+| ----------- | ------ | ---- | -------- | -------------------------------------------- | ----------- |
+| oldPassword | String | 是   | -        | 旧密码                                       | oldpassword |
+| newPassword | String | 是   | 100      | 新密码(6-100 字符)<br>Validate[max: 100; ] | newpassword |
+
+#### 请求示例
+
+```
+{
+    "oldPassword": "oldpassword",
+    "newPassword": "newpassword"
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+## 统计
+
+### 获取仪表盘统计数据
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/stats/dashboard
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/stats/dashboard
+
+描述:获取仪表盘统计数据
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称             | 类型    | 必填 | 最大长度 | 描述                                     | 示例值 |
+| ---------------- | ------- | ---- | -------- | ---------------------------------------- | ------ |
+| success          | Boolean | 否   | -        | 请求是否成功                             | true   |
+| errCode          | String  | 否   | -        | 错误码(失败时返回)                     |        |
+| errMessage       | String  | 否   | -        | 错误信息(失败时返回)                   |        |
+| data             | object  | 否   |          | 响应数据 (ActualType: DashboardStatsDTO) |        |
+| └ machineTotal   | Long    | 否   | -        | 机器总数                                 | 10     |
+| └ machineEnabled | Long    | 否   | -        | 启用的机器数                             | 8      |
+| └ cameraTotal    | Long    | 否   | -        | 摄像头总数                               | 20     |
+| └ cameraOnline   | Long    | 否   | -        | 在线摄像头数                             | 15     |
+| └ cameraOffline  | Long    | 否   | -        | 离线摄像头数                             | 5      |
+| └ channelTotal   | Long    | 否   | -        | 通道总数                                 | 40     |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "machineTotal": 10,
+        "machineEnabled": 8,
+        "cameraTotal": 20,
+        "cameraOnline": 15,
+        "cameraOffline": 5,
+        "channelTotal": 40
+    }
+}
+```
+
+#### 错误码
+
+无
+
+## LSS 节点管理
+
+### 获取 LSS 节点列表(分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/lss-nodes/list
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/list
+
+描述:获取 LSS 节点列表(分页)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述                                            | 示例值    |
+| ------- | ------- | ---- | -------- | ----------------------------------------------- | --------- |
+| page    | Integer | 否   | -        | 页码 (从 1 开始)                                | 1         |
+| size    | Integer | 否   | -        | 每页条数                                        | 10        |
+| keyword | String  | 否   | -        | 搜索关键词 (模糊匹配名称、ID 等)                | 摄像头    |
+| enabled | Boolean | 否   | -        | 启用状态过滤 (null=全部, true=启用, false=禁用) | true      |
+| sortBy  | String  | 否   | -        | 排序字段                                        | createdAt |
+| sortDir | String  | 否   | -        | 排序方向 (ASC/DESC)                             | DESC      |
+
+#### 请求示例
+
+```
+{
+    "page": 1,
+    "size": 10,
+    "keyword": "摄像头",
+    "enabled": true,
+    "sortBy": "createdAt",
+    "sortDir": "DESC"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: PageResponse) |  |
+| └ list | List<T> | 否 |  | 数据列表 (ActualType: T) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+| └ page | Integer | 否 | - | 当前页码 (从 1 开始) | 1 |
+| └ size | Integer | 否 | - | 每页条数 | 10 |
+| └ total | Long | 否 | - | 总记录数 | 100 |
+| └ totalPages | Integer | 否 | - | 总页数 | 10 |
+| └ hasNext | Boolean | 否 | - | 是否有下一页 | true |
+| └ hasPrevious | Boolean | 否 | - | 是否有上一页 | false |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "list": [
+            {
+                "id": 0,
+                "lssId": "string",
+                "lssName": "string",
+                "machineId": "string",
+                "address": "string",
+                "maxTasks": 0,
+                "currentTasks": 0,
+                "status": "string",
+                "ffmpegVersion": "string",
+                "systemInfo": "string",
+                "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+                "enabled": true,
+                "loadRate": 0,
+                "createdAt": "yyyy-MM-dd HH:mm:ss",
+                "updatedAt": "yyyy-MM-dd HH:mm:ss"
+            }
+        ],
+        "page": 1,
+        "size": 10,
+        "total": 100,
+        "totalPages": 10,
+        "hasNext": true,
+        "hasPrevious": false
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取全部 LSS 节点列表
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/listAll
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/listAll
+
+描述:获取全部 LSS 节点列表
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 0,
+            "lssId": "string",
+            "lssName": "string",
+            "machineId": "string",
+            "address": "string",
+            "maxTasks": 0,
+            "currentTasks": 0,
+            "status": "string",
+            "ffmpegVersion": "string",
+            "systemInfo": "string",
+            "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+            "enabled": true,
+            "loadRate": 0,
+            "createdAt": "yyyy-MM-dd HH:mm:ss",
+            "updatedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取 LSS 节点详情
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/detail
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/detail
+
+描述:获取 LSS 节点详情
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称  | 类型   | 必填 | 最大长度 | 描述        | 示例值 |
+| ----- | ------ | ---- | -------- | ----------- | ------ |
+| lssId | string | 是   | -        | LSS 节点 ID |        |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: LssNodeDTO) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 0,
+        "lssId": "string",
+        "lssName": "string",
+        "machineId": "string",
+        "address": "string",
+        "maxTasks": 0,
+        "currentTasks": 0,
+        "status": "string",
+        "ffmpegVersion": "string",
+        "systemInfo": "string",
+        "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+        "enabled": true,
+        "loadRate": 0,
+        "createdAt": "yyyy-MM-dd HH:mm:ss",
+        "updatedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 根据机器 ID 获取关联的 LSS 节点
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/byMachine
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/byMachine
+
+描述:根据机器 ID 获取关联的 LSS 节点
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称      | 类型   | 必填 | 最大长度 | 描述    | 示例值 |
+| --------- | ------ | ---- | -------- | ------- | ------ |
+| machineId | string | 是   | -        | 机器 ID |        |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 0,
+            "lssId": "string",
+            "lssName": "string",
+            "machineId": "string",
+            "address": "string",
+            "maxTasks": 0,
+            "currentTasks": 0,
+            "status": "string",
+            "ffmpegVersion": "string",
+            "systemInfo": "string",
+            "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+            "enabled": true,
+            "loadRate": 0,
+            "createdAt": "yyyy-MM-dd HH:mm:ss",
+            "updatedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 启用/禁用 LSS 节点
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/lss-nodes/setEnabled
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/setEnabled
+
+描述:启用/禁用 LSS 节点
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述        | 示例值 |
+| ------- | ------- | ---- | -------- | ----------- | ------ |
+| lssId   | string  | 是   | -        | LSS 节点 ID |        |
+| enabled | boolean | 是   | -        | 是否启用    | true   |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 删除 LSS 节点
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/lss-nodes/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/delete
+
+描述:删除 LSS 节点
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称  | 类型   | 必填 | 最大长度 | 描述        | 示例值 |
+| ----- | ------ | ---- | -------- | ----------- | ------ |
+| lssId | string | 是   | -        | LSS 节点 ID |        |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 获取 LSS 节点统计信息
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/stats
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/stats
+
+描述:获取 LSS 节点统计信息
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称          | 类型    | 必填 | 最大长度 | 描述                                | 示例值 |
+| ------------- | ------- | ---- | -------- | ----------------------------------- | ------ |
+| success       | Boolean | 否   | -        | 请求是否成功                        | true   |
+| errCode       | String  | 否   | -        | 错误码(失败时返回)                |        |
+| errMessage    | String  | 否   | -        | 错误信息(失败时返回)              |        |
+| data          | object  | 否   |          | 响应数据 (ActualType: LssNodeStats) |        |
+| └ total       | long    | 否   | -        | No comments found.                  | 0      |
+| └ online      | long    | 否   | -        | No comments found.                  | 0      |
+| └ offline     | long    | 否   | -        | No comments found.                  | 0      |
+| └ busy        | long    | 否   | -        | No comments found.                  | 0      |
+| └ maintenance | long    | 否   | -        | No comments found.                  | 0      |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "total": 0,
+        "online": 0,
+        "offline": 0,
+        "busy": 0,
+        "maintenance": 0
+    }
+}
+```
+
+#### 错误码
+
+无
+
+## 本地视频推流 Controller
+
+本地视频直接推送到 Cloudflare WHIP:
+
+- POST /stream/local/start 启动本地视频推流
+- POST /stream/local/stop 停止本地视频推流
+- GET /stream/local/{name} 获取推流状态
+- GET /stream/local/list 获取所有本地视频推流
+
+### 启动本地视频推流
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/stream/local/start
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/stream/local/start
+
+描述:启动本地视频推流
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称            | 类型    | 必填 | 最大长度 | 描述                                        | 示例值 |
+| --------------- | ------- | ---- | -------- | ------------------------------------------- | ------ |
+| streamName      | String  | 否   | -        | 流名称(唯一标识)                          |        |
+| videoPath       | String  | 否   | -        | 视频文件路径                                |        |
+| loop            | Boolean | 否   | -        | 是否循环播放                                | true   |
+| targetChannelId | String  | 否   | -        | 目标推流通道 ID(可选,不传则使用默认通道) |        |
+
+#### 请求示例
+
+```
+{
+    "streamName": "string",
+    "videoPath": "string",
+    "loop": true,
+    "targetChannelId": "string"
+}
+```
+
+#### 响应参数
+
+| 名称           | 类型    | 必填 | 最大长度 | 描述                                       | 示例值 |
+| -------------- | ------- | ---- | -------- | ------------------------------------------ | ------ |
+| success        | Boolean | 否   | -        | 请求是否成功                               | true   |
+| errCode        | String  | 否   | -        | 错误码(失败时返回)                       |        |
+| errMessage     | String  | 否   | -        | 错误信息(失败时返回)                     |        |
+| data           | object  | 否   |          | 响应数据 (ActualType: LocalVideoStreamDTO) |        |
+| └ streamName   | String  | 否   | -        | 流名称                                     |        |
+| └ sourceType   | String  | 否   | -        | 源类型:local_video 或 rtsp_camera         |        |
+| └ sourcePath   | String  | 否   | -        | 源路径(视频文件路径或 RTSP URL)          |        |
+| └ rtspUrl      | String  | 否   | -        | MediaMTX 提供的 RTSP URL                   |        |
+| └ loop         | Boolean | 否   | -        | 是否循环播放                               | true   |
+| └ streamTaskId | String  | 否   | -        | 推流任务 ID(如果已推送到 Cloudflare)     |        |
+| └ playbackUrl  | String  | 否   | -        | 播放地址(Cloudflare HLS/WHEP)            |        |
+| └ status       | String  | 否   | -        | 状态                                       |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "streamName": "string",
+        "sourceType": "string",
+        "sourcePath": "string",
+        "rtspUrl": "string",
+        "loop": true,
+        "streamTaskId": "string",
+        "playbackUrl": "string",
+        "status": "string"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 停止本地视频推流
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/stream/local/stop
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/stream/local/stop
+
+描述:停止本地视频推流
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称       | 类型   | 必填 | 最大长度 | 描述               | 示例值 |
+| ---------- | ------ | ---- | -------- | ------------------ | ------ |
+| streamName | string | 是   | -        | No comments found. |        |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 获取本地视频推流状态
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/stream/local/{streamName}
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/stream/local/{streamName}
+
+描述:获取本地视频推流状态
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称       | 必填 | 描述               | 示例值 |
+| ---------- | ---- | ------------------ | ------ |
+| streamName | 是   | No comments found. |        |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称           | 类型    | 必填 | 最大长度 | 描述                                       | 示例值 |
+| -------------- | ------- | ---- | -------- | ------------------------------------------ | ------ |
+| success        | Boolean | 否   | -        | 请求是否成功                               | true   |
+| errCode        | String  | 否   | -        | 错误码(失败时返回)                       |        |
+| errMessage     | String  | 否   | -        | 错误信息(失败时返回)                     |        |
+| data           | object  | 否   |          | 响应数据 (ActualType: LocalVideoStreamDTO) |        |
+| └ streamName   | String  | 否   | -        | 流名称                                     |        |
+| └ sourceType   | String  | 否   | -        | 源类型:local_video 或 rtsp_camera         |        |
+| └ sourcePath   | String  | 否   | -        | 源路径(视频文件路径或 RTSP URL)          |        |
+| └ rtspUrl      | String  | 否   | -        | MediaMTX 提供的 RTSP URL                   |        |
+| └ loop         | Boolean | 否   | -        | 是否循环播放                               | true   |
+| └ streamTaskId | String  | 否   | -        | 推流任务 ID(如果已推送到 Cloudflare)     |        |
+| └ playbackUrl  | String  | 否   | -        | 播放地址(Cloudflare HLS/WHEP)            |        |
+| └ status       | String  | 否   | -        | 状态                                       |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "streamName": "string",
+        "sourceType": "string",
+        "sourcePath": "string",
+        "rtspUrl": "string",
+        "loop": true,
+        "streamTaskId": "string",
+        "playbackUrl": "string",
+        "status": "string"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取所有本地视频推流
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/stream/local/list
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/stream/local/list
+
+描述:获取所有本地视频推流
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称           | 类型    | 必填 | 最大长度 | 描述                                   | 示例值 |
+| -------------- | ------- | ---- | -------- | -------------------------------------- | ------ |
+| success        | Boolean | 否   | -        | 请求是否成功                           | true   |
+| errCode        | String  | 否   | -        | 错误码(失败时返回)                   |        |
+| errMessage     | String  | 否   | -        | 错误信息(失败时返回)                 |        |
+| data           | array   | 否   |          | 响应数据 (ActualType: List)            |        |
+| └ streamName   | String  | 否   | -        | 流名称                                 |        |
+| └ sourceType   | String  | 否   | -        | 源类型:local_video 或 rtsp_camera     |        |
+| └ sourcePath   | String  | 否   | -        | 源路径(视频文件路径或 RTSP URL)      |        |
+| └ rtspUrl      | String  | 否   | -        | MediaMTX 提供的 RTSP URL               |        |
+| └ loop         | Boolean | 否   | -        | 是否循环播放                           | true   |
+| └ streamTaskId | String  | 否   | -        | 推流任务 ID(如果已推送到 Cloudflare) |        |
+| └ playbackUrl  | String  | 否   | -        | 播放地址(Cloudflare HLS/WHEP)        |        |
+| └ status       | String  | 否   | -        | 状态                                   |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "streamName": "string",
+            "sourceType": "string",
+            "sourcePath": "string",
+            "rtspUrl": "string",
+            "loop": true,
+            "streamTaskId": "string",
+            "playbackUrl": "string",
+            "status": "string"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+## 推流服务 Controller
+
+推流管理 API 接口:
+
+- POST /stream/start 启动推流任务
+- POST /stream/stop 停止推流任务
+- GET /stream/task/{streamSn} 获取任务状态
+- GET /stream/tasks 获取 LSS 推流任务列表
+- GET /stream/tasks/active 获取所有活动任务
+- GET /stream/channels 获取推流通道列表
+- POST /stream/switch 切换推流源
+
+### 启动推流任务
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/stream/start
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/stream/start
+
+描述:启动推流任务
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| name | String | 否 | - | 任务名称 | 投币机 1 号直播 |
+| lssId | String | 否 | - | LSS 节点 ID(可选,不传则自动选择) | lss_001 |
+| cameraId | String | 否 | - | 摄像头 ID(必填) | cam_001 |
+| sourceRtspUrl | String | 否 | - | 源 RTSP 地址(可选,如不传则从摄像头服务获取) | rtsp://admin:password@192.168.1.101:554/stream1 |
+| profile | String | 否 | - | 推流配置档位: low_latency / standard / file_loop | low_latency |
+| whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish |
+| playbackUrl | String | 否 | - | WebRTC 播放地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+| remark | String | 否 | - | 备注 |  |
+
+#### 请求示例
+
+```
+{
+    "name": "投币机1号直播",
+    "lssId": "lss_001",
+    "cameraId": "cam_001",
+    "sourceRtspUrl": "rtsp://admin:password@192.168.1.101:554/stream1",
+    "profile": "low_latency",
+    "whipUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish",
+    "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play",
+    "remark": "string"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: StreamTaskDTO) |  |
+| └ streamSn | String | 否 | - | 推流任务流水号 | stream_abc123def456 |
+| └ name | String | 否 | - | 任务名称 | 投币机 1 号直播 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ sourceRtspUrl | String | 否 | - | 源 RTSP 地址 | rtsp://admin:password@192.168.1.101:554/stream1 |
+| └ profile | String | 否 | - | 推流配置档位: low_latency / standard / file_loop | low_latency |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish |
+| └ playbackUrl | String | 否 | - | WebRTC 播放地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+| └ status | String | 否 | - | 推流状态: IDLE, STARTING, STREAMING, STOPPED, ERROR | STREAMING |
+| └ statusDescription | String | 否 | - | 状态描述 | 推流中 |
+| └ errorMessage | String | 否 | - | 错误信息 |  |
+| └ retryCount | int | 否 | - | 重试次数 | 0 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ startedAt | LocalDateTime | 否 | - | 开始推流时间 | 2024-01-15T10:30:05 |
+| └ stoppedAt | LocalDateTime | 否 | - | 停止推流时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "streamSn": "stream_abc123def456",
+        "name": "投币机1号直播",
+        "lssId": "lss_001",
+        "cameraId": "cam_001",
+        "sourceRtspUrl": "rtsp://admin:password@192.168.1.101:554/stream1",
+        "profile": "low_latency",
+        "whipUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish",
+        "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play",
+        "status": "STREAMING",
+        "statusDescription": "推流中",
+        "errorMessage": "string",
+        "retryCount": 0,
+        "remark": "string",
+        "createdAt": "2024-01-15T10:30:00",
+        "startedAt": "2024-01-15T10:30:05",
+        "stoppedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 停止推流任务
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/stream/stop
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/stream/stop
+
+描述:停止推流任务
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称   | 类型   | 必填 | 最大长度 | 描述                                                 | 示例值              |
+| ------ | ------ | ---- | -------- | ---------------------------------------------------- | ------------------- |
+| taskId | String | 否   | -        | 推流任务流水号(与 lssId 二选一)                    | stream_abc123def456 |
+| lssId  | String | 否   | -        | LSS 节点 ID(与 taskId 二选一,停止该 LSS 所有推流) | lss_001             |
+
+#### 请求示例
+
+```
+{
+    "taskId": "stream_abc123def456",
+    "lssId": "lss_001"
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 获取任务状态
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/stream/task/{streamSn}
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/stream/task/{streamSn}
+
+描述:获取任务状态
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称     | 必填 | 描述           | 示例值              |
+| -------- | ---- | -------------- | ------------------- |
+| streamSn | 是   | 推流任务流水号 | stream_abc123def456 |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: StreamTaskDTO) |  |
+| └ streamSn | String | 否 | - | 推流任务流水号 | stream_abc123def456 |
+| └ name | String | 否 | - | 任务名称 | 投币机 1 号直播 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ sourceRtspUrl | String | 否 | - | 源 RTSP 地址 | rtsp://admin:password@192.168.1.101:554/stream1 |
+| └ profile | String | 否 | - | 推流配置档位: low_latency / standard / file_loop | low_latency |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish |
+| └ playbackUrl | String | 否 | - | WebRTC 播放地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+| └ status | String | 否 | - | 推流状态: IDLE, STARTING, STREAMING, STOPPED, ERROR | STREAMING |
+| └ statusDescription | String | 否 | - | 状态描述 | 推流中 |
+| └ errorMessage | String | 否 | - | 错误信息 |  |
+| └ retryCount | int | 否 | - | 重试次数 | 0 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ startedAt | LocalDateTime | 否 | - | 开始推流时间 | 2024-01-15T10:30:05 |
+| └ stoppedAt | LocalDateTime | 否 | - | 停止推流时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "streamSn": "stream_abc123def456",
+        "name": "投币机1号直播",
+        "lssId": "lss_001",
+        "cameraId": "cam_001",
+        "sourceRtspUrl": "rtsp://admin:password@192.168.1.101:554/stream1",
+        "profile": "low_latency",
+        "whipUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish",
+        "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play",
+        "status": "STREAMING",
+        "statusDescription": "推流中",
+        "errorMessage": "string",
+        "retryCount": 0,
+        "remark": "string",
+        "createdAt": "2024-01-15T10:30:00",
+        "startedAt": "2024-01-15T10:30:05",
+        "stoppedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取 LSS 推流任务列表
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/stream/tasks
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/stream/tasks
+
+描述:获取 LSS 推流任务列表
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称  | 类型   | 必填 | 最大长度 | 描述        | 示例值  |
+| ----- | ------ | ---- | -------- | ----------- | ------- |
+| lssId | string | 是   | -        | LSS 节点 ID | lss_001 |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ streamSn | String | 否 | - | 推流任务流水号 | stream_abc123def456 |
+| └ name | String | 否 | - | 任务名称 | 投币机 1 号直播 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ sourceRtspUrl | String | 否 | - | 源 RTSP 地址 | rtsp://admin:password@192.168.1.101:554/stream1 |
+| └ profile | String | 否 | - | 推流配置档位: low_latency / standard / file_loop | low_latency |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish |
+| └ playbackUrl | String | 否 | - | WebRTC 播放地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+| └ status | String | 否 | - | 推流状态: IDLE, STARTING, STREAMING, STOPPED, ERROR | STREAMING |
+| └ statusDescription | String | 否 | - | 状态描述 | 推流中 |
+| └ errorMessage | String | 否 | - | 错误信息 |  |
+| └ retryCount | int | 否 | - | 重试次数 | 0 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ startedAt | LocalDateTime | 否 | - | 开始推流时间 | 2024-01-15T10:30:05 |
+| └ stoppedAt | LocalDateTime | 否 | - | 停止推流时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "streamSn": "stream_abc123def456",
+            "name": "投币机1号直播",
+            "lssId": "lss_001",
+            "cameraId": "cam_001",
+            "sourceRtspUrl": "rtsp://admin:password@192.168.1.101:554/stream1",
+            "profile": "low_latency",
+            "whipUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish",
+            "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play",
+            "status": "STREAMING",
+            "statusDescription": "推流中",
+            "errorMessage": "string",
+            "retryCount": 0,
+            "remark": "string",
+            "createdAt": "2024-01-15T10:30:00",
+            "startedAt": "2024-01-15T10:30:05",
+            "stoppedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取所有活动任务
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/stream/tasks/active
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/stream/tasks/active
+
+描述:获取所有活动任务
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ streamSn | String | 否 | - | 推流任务流水号 | stream_abc123def456 |
+| └ name | String | 否 | - | 任务名称 | 投币机 1 号直播 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ sourceRtspUrl | String | 否 | - | 源 RTSP 地址 | rtsp://admin:password@192.168.1.101:554/stream1 |
+| └ profile | String | 否 | - | 推流配置档位: low_latency / standard / file_loop | low_latency |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish |
+| └ playbackUrl | String | 否 | - | WebRTC 播放地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+| └ status | String | 否 | - | 推流状态: IDLE, STARTING, STREAMING, STOPPED, ERROR | STREAMING |
+| └ statusDescription | String | 否 | - | 状态描述 | 推流中 |
+| └ errorMessage | String | 否 | - | 错误信息 |  |
+| └ retryCount | int | 否 | - | 重试次数 | 0 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ startedAt | LocalDateTime | 否 | - | 开始推流时间 | 2024-01-15T10:30:05 |
+| └ stoppedAt | LocalDateTime | 否 | - | 停止推流时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "streamSn": "stream_abc123def456",
+            "name": "投币机1号直播",
+            "lssId": "lss_001",
+            "cameraId": "cam_001",
+            "sourceRtspUrl": "rtsp://admin:password@192.168.1.101:554/stream1",
+            "profile": "low_latency",
+            "whipUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish",
+            "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play",
+            "status": "STREAMING",
+            "statusDescription": "推流中",
+            "errorMessage": "string",
+            "retryCount": 0,
+            "remark": "string",
+            "createdAt": "2024-01-15T10:30:00",
+            "startedAt": "2024-01-15T10:30:05",
+            "stoppedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取推流通道列表
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/stream/channels
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/stream/channels
+
+描述:获取推流通道列表
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ channelId | String | 否 | - | 通道 ID | cf_channel_001 |
+| └ name | String | 否 | - | 通道名称 | 主推流通道 |
+| └ mode | String | 否 | - | 推流模式: WHIP, RTMPS | WHIP |
+| └ hlsPlaybackUrl | String | 否 | - | HLS 播放地址 | https://customer-xxx.cloudflarestream.com/xxx/manifest/video.m3u8 |
+| └ recordingEnabled | boolean | 否 | - | 是否启用录制 | false |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "channelId": "cf_channel_001",
+            "name": "主推流通道",
+            "mode": "WHIP",
+            "hlsPlaybackUrl": "https://customer-xxx.cloudflarestream.com/xxx/manifest/video.m3u8",
+            "recordingEnabled": false
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 切换推流源
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/stream/switch
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/stream/switch
+
+描述:切换推流源
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称        | 类型   | 必填 | 最大长度 | 描述           | 示例值                                          |
+| ----------- | ------ | ---- | -------- | -------------- | ----------------------------------------------- |
+| streamSn    | String | 是   | -        | 推流任务流水号 | stream_abc123def456                             |
+| newCameraId | String | 是   | -        | 新的摄像头 ID  | cam_001                                         |
+| newRtspUrl  | String | 是   | -        | 新的 RTSP 地址 | rtsp://admin:password@192.168.1.101:554/stream1 |
+
+#### 请求示例
+
+```
+{
+    "streamSn": "stream_abc123def456",
+    "newCameraId": "cam_001",
+    "newRtspUrl": "rtsp://admin:password@192.168.1.101:554/stream1"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: StreamTaskDTO) |  |
+| └ streamSn | String | 否 | - | 推流任务流水号 | stream_abc123def456 |
+| └ name | String | 否 | - | 任务名称 | 投币机 1 号直播 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ sourceRtspUrl | String | 否 | - | 源 RTSP 地址 | rtsp://admin:password@192.168.1.101:554/stream1 |
+| └ profile | String | 否 | - | 推流配置档位: low_latency / standard / file_loop | low_latency |
+| └ whipUrl | String | 否 | - | WHIP 推流地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish |
+| └ playbackUrl | String | 否 | - | WebRTC 播放地址 | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+| └ status | String | 否 | - | 推流状态: IDLE, STARTING, STREAMING, STOPPED, ERROR | STREAMING |
+| └ statusDescription | String | 否 | - | 状态描述 | 推流中 |
+| └ errorMessage | String | 否 | - | 错误信息 |  |
+| └ retryCount | int | 否 | - | 重试次数 | 0 |
+| └ remark | String | 否 | - | 备注 |  |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2024-01-15T10:30:00 |
+| └ startedAt | LocalDateTime | 否 | - | 开始推流时间 | 2024-01-15T10:30:05 |
+| └ stoppedAt | LocalDateTime | 否 | - | 停止推流时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "streamSn": "stream_abc123def456",
+        "name": "投币机1号直播",
+        "lssId": "lss_001",
+        "cameraId": "cam_001",
+        "sourceRtspUrl": "rtsp://admin:password@192.168.1.101:554/stream1",
+        "profile": "low_latency",
+        "whipUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/publish",
+        "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play",
+        "status": "STREAMING",
+        "statusDescription": "推流中",
+        "errorMessage": "string",
+        "retryCount": 0,
+        "remark": "string",
+        "createdAt": "2024-01-15T10:30:00",
+        "startedAt": "2024-01-15T10:30:05",
+        "stoppedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+## 房间控制 Controller
+
+房间播放 API 接口:
+
+- GET /room/{roomId}/play 获取播放信息(按需启动推流)
+- POST /room/{roomId}/stop 停止房间推流
+
+### 获取房间播放信息
+
+按需启动推流:
+
+- 检查 FFmpeg 是否在跑
+- 没跑则自动启动
+- 返回 WHEP URL (WebRTC 播放)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/room/{roomId}/play
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/room/{roomId}/play
+
+描述:获取房间播放信息
+
+按需启动推流:
+
+- 检查 FFmpeg 是否在跑
+- 没跑则自动启动
+- 返回 WHEP URL (WebRTC 播放)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称   | 必填 | 描述    | 示例值 |
+| ------ | ---- | ------- | ------ |
+| roomId | 是   | 房间 ID |        |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称           | 类型    | 必填 | 最大长度 | 描述                                    | 示例值 |
+| -------------- | ------- | ---- | -------- | --------------------------------------- | ------ |
+| success        | Boolean | 否   | -        | 请求是否成功                            | true   |
+| errCode        | String  | 否   | -        | 错误码(失败时返回)                    |        |
+| errMessage     | String  | 否   | -        | 错误信息(失败时返回)                  |        |
+| data           | object  | 否   |          | 响应数据 (ActualType: RoomPlayResponse) |        |
+| └ roomId       | String  | 否   | -        | 房间 ID                                 |        |
+| └ taskId       | String  | 否   | -        | 推流任务 ID                             |        |
+| └ whepUrl      | String  | 否   | -        | WHEP 播放地址 (WebRTC)                  |        |
+| └ status       | String  | 否   | -        | 推流状态                                |        |
+| └ newlyStarted | boolean | 否   | -        | 是否为新启动的推流                      | true   |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "roomId": "string",
+        "taskId": "string",
+        "whepUrl": "string",
+        "status": "string",
+        "newlyStarted": true
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 停止房间推流
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/room/{roomId}/stop
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/room/{roomId}/stop
+
+描述:停止房间推流
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称   | 必填 | 描述    | 示例值 |
+| ------ | ---- | ------- | ------ |
+| roomId | 是   | 房间 ID |        |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+## Ably Token 接口
+
+前端通过此接口获取 Ably Token,用于连接 Ably 实时通信
+
+### 获取 Ably Token
+
+前端使用此 Token 连接 Ably,只授予订阅权限(不能发布)
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/ably/token
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/ably/token
+
+描述:获取 Ably Token
+
+前端使用此 Token 连接 Ably,只授予订阅权限(不能发布)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称     | 类型   | 必填 | 最大长度 | 描述                              | 示例值     |
+| -------- | ------ | ---- | -------- | --------------------------------- | ---------- |
+| clientId | string | 否   | -        | 客户端标识(如用户 ID 或会话 ID) | web-client |
+
+#### 响应参数
+
+| 名称         | 类型    | 必填 | 最大长度 | 描述                       | 示例值 |
+| ------------ | ------- | ---- | -------- | -------------------------- | ------ |
+| success      | Boolean | 否   | -        | 请求是否成功               | true   |
+| errCode      | String  | 否   | -        | 错误码(失败时返回)       |        |
+| errMessage   | String  | 否   | -        | 错误信息(失败时返回)     |        |
+| data         | object  | 否   |          | 响应数据 (ActualType: Map) |        |
+| └ mapKey     | Object  | 否   |          | A map key.                 |        |
+| └ any object | object  | 否   | -        | any object.                |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "mapKey": {
+            "any object": {}
+        }
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取 Ably 连接信息
+
+返回前端连接 Ably 所需的配置信息(不包含 API Key)
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/ably/config
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/ably/config
+
+描述:获取 Ably 连接信息
+
+返回前端连接 Ably 所需的配置信息(不包含 API Key)
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称         | 类型    | 必填 | 最大长度 | 描述                       | 示例值 |
+| ------------ | ------- | ---- | -------- | -------------------------- | ------ |
+| success      | Boolean | 否   | -        | 请求是否成功               | true   |
+| errCode      | String  | 否   | -        | 错误码(失败时返回)       |        |
+| errMessage   | String  | 否   | -        | 错误信息(失败时返回)     |        |
+| data         | object  | 否   |          | 响应数据 (ActualType: Map) |        |
+| └ mapKey     | Object  | 否   |          | A map key.                 |        |
+| └ any object | object  | 否   | -        | any object.                |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "mapKey": {
+            "any object": {}
+        }
+    }
+}
+```
+
+#### 错误码
+
+无
+
+## LSS 回调接口
+
+接收来自 LSS (Local Sender Service) 的回调请求:
+
+- 节点注册
+- 心跳上报
+- 任务状态回调
+
+### LSS 节点注册
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/lss/register
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/lss/register
+
+描述:LSS 节点注册
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称              | 类型       | 必填 | 最大长度 | 描述               | 示例值 |
+| ----------------- | ---------- | ---- | -------- | ------------------ | ------ |
+| nodeId            | String     | 否   | -        | No comments found. |        |
+| nodeName          | String     | 否   | -        | No comments found. |        |
+| nodeIp            | String     | 否   | -        | No comments found. |        |
+| nodePort          | Integer    | 否   | -        | No comments found. | 0      |
+| machineId         | String     | 否   | -        | No comments found. |        |
+| maxTasks          | int        | 否   | -        | No comments found. | 0      |
+| ffmpegPath        | String     | 否   | -        | No comments found. |        |
+| systemInfo        | SystemInfo | 否   |          | No comments found. |        |
+| └ os              | String     | 否   | -        | No comments found. |        |
+| └ cpuCores        | int        | 否   | -        | No comments found. | 0      |
+| └ totalMemory     | long       | 否   | -        | No comments found. | 0      |
+| └ availableMemory | long       | 否   | -        | No comments found. | 0      |
+| └ ffmpegVersion   | String     | 否   | -        | No comments found. |        |
+
+#### 请求示例
+
+```
+{
+    "nodeId": "string",
+    "nodeName": "string",
+    "nodeIp": "string",
+    "nodePort": 0,
+    "machineId": "string",
+    "maxTasks": 0,
+    "ffmpegPath": "string",
+    "systemInfo": {
+        "os": "string",
+        "cpuCores": 0,
+        "totalMemory": 0,
+        "availableMemory": 0,
+        "ffmpegVersion": "string"
+    }
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### LSS 心跳上报
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/lss/heartbeat
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/lss/heartbeat
+
+描述:LSS 心跳上报
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称            | 类型   | 必填 | 最大长度 | 描述               | 示例值 |
+| --------------- | ------ | ---- | -------- | ------------------ | ------ |
+| nodeId          | String | 否   | -        | No comments found. |        |
+| activeTaskCount | int    | 否   | -        | No comments found. | 0      |
+| cpuUsage        | Double | 否   | -        | No comments found. | 0.0    |
+| memoryUsage     | Double | 否   | -        | No comments found. | 0.0    |
+
+#### 请求示例
+
+```
+{
+    "nodeId": "string",
+    "activeTaskCount": 0,
+    "cpuUsage": 0,
+    "memoryUsage": 0
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### LSS 任务状态回调
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/lss/task/callback
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/lss/task/callback
+
+描述:LSS 任务状态回调
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| taskId | String | 否 | - | No comments found. |  |
+| nodeId | String | 否 | - | No comments found. |  |
+| callbackType | enum | 否 | - | No comments found.<br/>[Enum values:<br/>STARTED()<br/>STOPPED()<br/>ERROR()<br/>STATUS_UPDATE()<br/>] | STARTED |
+| status | String | 否 | - | No comments found. |  |
+| processId | Long | 否 | - | No comments found. | 0 |
+| hlsPlaybackUrl | String | 否 | - | No comments found. |  |
+| errorMessage | String | 否 | - | No comments found. |  |
+
+#### 请求示例
+
+```
+{
+    "taskId": "string",
+    "nodeId": "string",
+    "callbackType": "STARTED",
+    "status": "string",
+    "processId": 0,
+    "hlsPlaybackUrl": "string",
+    "errorMessage": "string"
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无

+ 481 - 0
docs/api_torna/lss_management.md

@@ -0,0 +1,481 @@
+# 文档
+
+## LSS 节点管理
+
+### 获取 LSS 节点列表(分页)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/lss-nodes/list
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/list
+
+描述:获取 LSS 节点列表(分页)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述                                            | 示例值    |
+| ------- | ------- | ---- | -------- | ----------------------------------------------- | --------- |
+| page    | Integer | 否   | -        | 页码 (从 1 开始)                                | 1         |
+| size    | Integer | 否   | -        | 每页条数                                        | 10        |
+| keyword | String  | 否   | -        | 搜索关键词 (模糊匹配名称、ID 等)                | 摄像头    |
+| enabled | Boolean | 否   | -        | 启用状态过滤 (null=全部, true=启用, false=禁用) | true      |
+| sortBy  | String  | 否   | -        | 排序字段                                        | createdAt |
+| sortDir | String  | 否   | -        | 排序方向 (ASC/DESC)                             | DESC      |
+
+#### 请求示例
+
+```
+{
+    "page": 1,
+    "size": 10,
+    "keyword": "摄像头",
+    "enabled": true,
+    "sortBy": "createdAt",
+    "sortDir": "DESC"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: PageResponse) |  |
+| └ list | List<T> | 否 |  | 数据列表 (ActualType: T) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+| └ page | Integer | 否 | - | 当前页码 (从 1 开始) | 1 |
+| └ size | Integer | 否 | - | 每页条数 | 10 |
+| └ total | Long | 否 | - | 总记录数 | 100 |
+| └ totalPages | Integer | 否 | - | 总页数 | 10 |
+| └ hasNext | Boolean | 否 | - | 是否有下一页 | true |
+| └ hasPrevious | Boolean | 否 | - | 是否有上一页 | false |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "list": [
+            {
+                "id": 0,
+                "lssId": "string",
+                "lssName": "string",
+                "machineId": "string",
+                "address": "string",
+                "maxTasks": 0,
+                "currentTasks": 0,
+                "status": "string",
+                "ffmpegVersion": "string",
+                "systemInfo": "string",
+                "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+                "enabled": true,
+                "loadRate": 0,
+                "createdAt": "yyyy-MM-dd HH:mm:ss",
+                "updatedAt": "yyyy-MM-dd HH:mm:ss"
+            }
+        ],
+        "page": 1,
+        "size": 10,
+        "total": 100,
+        "totalPages": 10,
+        "hasNext": true,
+        "hasPrevious": false
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取全部 LSS 节点列表
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/listAll
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/listAll
+
+描述:获取全部 LSS 节点列表
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 0,
+            "lssId": "string",
+            "lssName": "string",
+            "machineId": "string",
+            "address": "string",
+            "maxTasks": 0,
+            "currentTasks": 0,
+            "status": "string",
+            "ffmpegVersion": "string",
+            "systemInfo": "string",
+            "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+            "enabled": true,
+            "loadRate": 0,
+            "createdAt": "yyyy-MM-dd HH:mm:ss",
+            "updatedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取 LSS 节点详情
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/detail
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/detail
+
+描述:获取 LSS 节点详情
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称  | 类型   | 必填 | 最大长度 | 描述        | 示例值 |
+| ----- | ------ | ---- | -------- | ----------- | ------ |
+| lssId | string | 是   | -        | LSS 节点 ID |        |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: LssNodeDTO) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 0,
+        "lssId": "string",
+        "lssName": "string",
+        "machineId": "string",
+        "address": "string",
+        "maxTasks": 0,
+        "currentTasks": 0,
+        "status": "string",
+        "ffmpegVersion": "string",
+        "systemInfo": "string",
+        "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+        "enabled": true,
+        "loadRate": 0,
+        "createdAt": "yyyy-MM-dd HH:mm:ss",
+        "updatedAt": "yyyy-MM-dd HH:mm:ss"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 根据机器 ID 获取关联的 LSS 节点
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/byMachine
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/byMachine
+
+描述:根据机器 ID 获取关联的 LSS 节点
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称      | 类型   | 必填 | 最大长度 | 描述    | 示例值 |
+| --------- | ------ | ---- | -------- | ------- | ------ |
+| machineId | string | 是   | -        | 机器 ID |        |
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ id | Long | 否 | - | 数据库主键 | 0 |
+| └ lssId | String | 否 | - | LSS 节点 ID |  |
+| └ lssName | String | 否 | - | LSS 节点名称 |  |
+| └ machineId | String | 否 | - | 关联的机器 ID |  |
+| └ address | String | 否 | - | LSS 地址 (IP:Port) |  |
+| └ maxTasks | Integer | 否 | - | 最大并发任务数 | 0 |
+| └ currentTasks | Integer | 否 | - | 当前任务数 | 0 |
+| └ status | String | 否 | - | 节点状态: ONLINE, OFFLINE, BUSY, MAINTENANCE |  |
+| └ ffmpegVersion | String | 否 | - | FFmpeg 版本 |  |
+| └ systemInfo | String | 否 | - | 系统信息 (JSON) |  |
+| └ lastHeartbeatAt | LocalDateTime | 否 | - | 最后心跳时间 | yyyy-MM-dd HH:mm:ss |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ loadRate | Double | 否 | - | 负载率 (0.0 - 1.0) | 0.0 |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | yyyy-MM-dd HH:mm:ss |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | yyyy-MM-dd HH:mm:ss |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 0,
+            "lssId": "string",
+            "lssName": "string",
+            "machineId": "string",
+            "address": "string",
+            "maxTasks": 0,
+            "currentTasks": 0,
+            "status": "string",
+            "ffmpegVersion": "string",
+            "systemInfo": "string",
+            "lastHeartbeatAt": "yyyy-MM-dd HH:mm:ss",
+            "enabled": true,
+            "loadRate": 0,
+            "createdAt": "yyyy-MM-dd HH:mm:ss",
+            "updatedAt": "yyyy-MM-dd HH:mm:ss"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 启用/禁用 LSS 节点
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/lss-nodes/setEnabled
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/setEnabled
+
+描述:启用/禁用 LSS 节点
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称    | 类型    | 必填 | 最大长度 | 描述        | 示例值 |
+| ------- | ------- | ---- | -------- | ----------- | ------ |
+| lssId   | string  | 是   | -        | LSS 节点 ID |        |
+| enabled | boolean | 是   | -        | 是否启用    | true   |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 删除 LSS 节点
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/lss-nodes/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/delete
+
+描述:删除 LSS 节点
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+##### Query Parameter
+
+| 名称  | 类型   | 必填 | 最大长度 | 描述        | 示例值 |
+| ----- | ------ | ---- | -------- | ----------- | ------ |
+| lssId | string | 是   | -        | LSS 节点 ID |        |
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无
+
+### 获取 LSS 节点统计信息
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss-nodes/stats
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss-nodes/stats
+
+描述:获取 LSS 节点统计信息
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称          | 类型    | 必填 | 最大长度 | 描述                                | 示例值 |
+| ------------- | ------- | ---- | -------- | ----------------------------------- | ------ |
+| success       | Boolean | 否   | -        | 请求是否成功                        | true   |
+| errCode       | String  | 否   | -        | 错误码(失败时返回)                |        |
+| errMessage    | String  | 否   | -        | 错误信息(失败时返回)              |        |
+| data          | object  | 否   |          | 响应数据 (ActualType: LssNodeStats) |        |
+| └ total       | long    | 否   | -        | No comments found.                  | 0      |
+| └ online      | long    | 否   | -        | No comments found.                  | 0      |
+| └ offline     | long    | 否   | -        | No comments found.                  | 0      |
+| └ busy        | long    | 否   | -        | No comments found.                  | 0      |
+| └ maintenance | long    | 否   | -        | No comments found.                  | 0      |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "total": 0,
+        "online": 0,
+        "offline": 0,
+        "busy": 0,
+        "maintenance": 0
+    }
+}
+```
+
+#### 错误码
+
+无

+ 48 - 0
go_stream/go2rtc_all.yaml

@@ -0,0 +1,48 @@
+# go2rtc 配置文件 - 4 个摄像头统一配置
+# 启动命令: ./go2rtc -config go2rtc_all.yaml
+# Web界面: http://localhost:1984
+
+streams:
+  # ========== HIKVISION PTZ 球机 ==========
+  # IP: 192.168.0.64 | 型号: DS-2DE2A404IW-DE3
+  hikvision:
+    - rtsp://admin:Wxc767718929@192.168.0.64:554/Streaming/Channels/101
+  hikvision_sub:
+    - rtsp://admin:Wxc767718929@192.168.0.64:554/Streaming/Channels/102
+
+  # ========== ANPVIZ 枪机 ==========
+  # IP: 192.168.0.96 | 型号: L12D2_19_IR_AF | H.265 需要转码
+  anpviz:
+    - ffmpeg:rtsp://admin:123456@192.168.0.96:554/Streaming/Channels/101#video=h264
+  anpviz_raw:
+    - rtsp://admin:123456@192.168.0.96:554/Streaming/Channels/101
+  anpviz_sub:
+    - rtsp://admin:123456@192.168.0.96:554/Streaming/Channels/102
+
+  # ========== CT-IP500 枪机 ==========
+  # IP: 192.168.0.100:8999 | 型号: IPC-D53000
+  ct-ip500:
+    - rtsp://admin:admin@192.168.0.100:554/cam/realmonitor?channel=1&subtype=0
+  ct-ip500_sub:
+    - rtsp://admin:admin@192.168.0.100:554/cam/realmonitor?channel=1&subtype=1
+
+  # ========== SVBC 枪机 ==========
+  # IP: 192.168.0.246:8080 | 型号: C6F0SoZ3N0PoL2 | H.265 需要转码
+  svbc:
+    - ffmpeg:rtsp://admin:admin@192.168.0.246:554/1#video=h264
+  svbc_raw:
+    - rtsp://admin:admin@192.168.0.246:554/1
+  svbc_sub:
+    - rtsp://admin:admin@192.168.0.246:554/2
+
+webrtc:
+  candidates:
+    - stun:stun.l.google.com:19302
+
+api:
+  listen: ":1984"
+  origin: "*"
+
+log:
+  level: info
+  format: text

+ 51 - 4
src/api/lss.ts

@@ -1,9 +1,56 @@
-import { post } from '@/utils/request'
-import type { IPageResponse, LssDTO, LssListRequest } from '@/types'
+import { get, post } from '@/utils/request'
+import type {
+  IPageResponse,
+  IBaseResponse,
+  IListResponse,
+  BaseResponse,
+  LssDTO,
+  LssListRequest,
+  LssNodeDTO,
+  LssNodeListRequest,
+  LssNodeStatsDTO
+} from '@/types'
 
-// ==================== LSS Admin APIs ====================
+// ==================== LSS 节点管理 APIs (新) ====================
 
-// 获取 LSS 列表 (分页)
+// 1. 获取 LSS 节点列表(分页)
+export function listLssNodes(params?: LssNodeListRequest): Promise<IPageResponse<LssNodeDTO>> {
+  return post('/admin/lss-nodes/list', params || {})
+}
+
+// 2. 获取全部 LSS 节点列表
+export function listAllLssNodes(): Promise<IListResponse<LssNodeDTO>> {
+  return get('/admin/lss-nodes/listAll')
+}
+
+// 3. 获取 LSS 节点详情
+export function getLssNodeDetail(lssId: string): Promise<IBaseResponse<LssNodeDTO>> {
+  return get('/admin/lss-nodes/detail', { lssId })
+}
+
+// 4. 根据机器 ID 获取关联的 LSS 节点
+export function getLssNodesByMachine(machineId: string): Promise<IListResponse<LssNodeDTO>> {
+  return get('/admin/lss-nodes/byMachine', { machineId })
+}
+
+// 5. 启用/禁用 LSS 节点
+export function setLssNodeEnabled(lssId: string, enabled: boolean): Promise<BaseResponse> {
+  return post('/admin/lss-nodes/setEnabled', { lssId, enabled })
+}
+
+// 6. 删除 LSS 节点
+export function deleteLssNode(lssId: string): Promise<BaseResponse> {
+  return post('/admin/lss-nodes/delete', { lssId })
+}
+
+// 7. 获取 LSS 节点统计信息
+export function getLssNodeStats(): Promise<IBaseResponse<LssNodeStatsDTO>> {
+  return get('/admin/lss-nodes/stats')
+}
+
+// ==================== LSS Admin APIs (旧,兼容) ====================
+
+// 获取 LSS 列表 (分页) - 旧接口
 export function listLss(params?: LssListRequest): Promise<IPageResponse<LssDTO>> {
   return post('/admin/lss/list', params || {})
 }

+ 41 - 6
src/types/index.ts

@@ -327,24 +327,59 @@ export interface RecordItem {
   type?: string
 }
 
-// ==================== LSS 相关类型 ====================
+// ==================== LSS 节点相关类型 ====================
 
-// LSS 心跳状态
+// LSS 节点状态
+export type LssNodeStatus = 'ONLINE' | 'OFFLINE' | 'BUSY' | 'MAINTENANCE'
+
+// LSS 节点信息 (新 API)
+export interface LssNodeDTO {
+  id: number
+  lssId: string
+  lssName: string
+  machineId?: string
+  address: string
+  maxTasks: number
+  currentTasks: number
+  status: LssNodeStatus
+  ffmpegVersion?: string
+  systemInfo?: string
+  enabled: boolean
+  createdAt: string
+  updatedAt: string
+}
+
+// LSS 节点列表请求参数
+export interface LssNodeListRequest extends PageRequest {
+  status?: LssNodeStatus
+  machineId?: string
+}
+
+// LSS 节点统计信息
+export interface LssNodeStatsDTO {
+  total: number
+  online: number
+  offline: number
+  busy: number
+  maintenance: number
+}
+
+// 兼容旧代码 - LSS 心跳状态
 export type LssHeartbeatStatus = 'active' | 'hold' | 'dead'
 
-// LSS 信息
+// 兼容旧代码 - LSS 信息 (旧 API)
 export interface LssDTO {
   id: number
   lssId: string
   name: string
   address: string
-  publicIp: string
-  heartbeat: LssHeartbeatStatus
+  publicIp?: string
+  heartbeat?: LssHeartbeatStatus
   heartbeatTime?: string
   ablyInfo?: string
 }
 
-// LSS 列表请求参数
+// 兼容旧代码 - LSS 列表请求参数
 export interface LssListRequest extends PageRequest {
   heartbeat?: LssHeartbeatStatus
 }

+ 150 - 415
src/views/lss/index.vue

@@ -13,11 +13,19 @@
           />
         </el-form-item>
         <el-form-item>
-          <el-select v-model="searchForm.heartbeat" placeholder="心跳状态" clearable data-id="search-heartbeat">
+          <el-select v-model="searchForm.status" placeholder="状态" clearable data-id="search-status">
             <el-option label="全部" value="" />
-            <el-option label="active" value="active" />
-            <el-option label="hold" value="hold" />
-            <el-option label="dead" value="dead" />
+            <el-option label="在线" value="ONLINE" />
+            <el-option label="离线" value="OFFLINE" />
+            <el-option label="繁忙" value="BUSY" />
+            <el-option label="维护" value="MAINTENANCE" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-select v-model="searchForm.enabled" placeholder="启用状态" clearable data-id="search-enabled">
+            <el-option label="全部" :value="null" />
+            <el-option label="已启用" :value="true" />
+            <el-option label="已禁用" :value="false" />
           </el-select>
         </el-form-item>
         <el-form-item>
@@ -34,7 +42,7 @@
       <el-table
         ref="tableRef"
         v-loading="loading"
-        :data="sortedList"
+        :data="lssList"
         stripe
         size="default"
         data-id="lss-table"
@@ -42,30 +50,35 @@
         @sort-change="handleSortChange"
       >
         <el-table-column prop="lssId" label="LSS ID" min-width="120" sortable="custom" show-overflow-tooltip />
-        <el-table-column prop="name" :label="t('名称')" min-width="140" sortable="custom" show-overflow-tooltip />
+        <el-table-column prop="lssName" :label="t('名称')" min-width="140" sortable="custom" show-overflow-tooltip />
         <el-table-column prop="address" :label="t('地址')" min-width="180" sortable="custom" show-overflow-tooltip />
-        <el-table-column prop="publicIp" :label="t('公网IP')" min-width="130" sortable="custom" show-overflow-tooltip />
-        <el-table-column prop="heartbeat" :label="t('心跳')" min-width="200" sortable="custom">
+        <el-table-column prop="status" :label="t('状态')" min-width="100" sortable="custom">
           <template #default="{ row }">
-            <span :class="getHeartbeatClass(row.heartbeat)">
-              {{ formatHeartbeat(row) }}
-            </span>
+            <el-tag :type="getStatusTagType(row.status)" size="small">
+              {{ formatStatus(row.status) }}
+            </el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="詳情" width="70" align="center">
+        <el-table-column prop="currentTasks" :label="t('当前任务')" min-width="100" sortable="custom" align="center">
+          <template #default="{ row }">{{ row.currentTasks }} / {{ row.maxTasks }}</template>
+        </el-table-column>
+        <el-table-column prop="enabled" :label="t('启用')" min-width="80" align="center">
           <template #default="{ row }">
-            <el-button type="primary" link :icon="View" @click="handleViewDetail(row)" />
+            <el-switch
+              v-model="row.enabled"
+              :loading="row._switching"
+              @change="(val: boolean) => handleToggleEnabled(row, val)"
+            />
           </template>
         </el-table-column>
-        <el-table-column label="設備列表" width="90" align="center">
+        <el-table-column prop="ffmpegVersion" label="FFmpeg" min-width="120" show-overflow-tooltip />
+        <el-table-column label="詳情" width="70" align="center">
           <template #default="{ row }">
-            <el-button type="primary" link :icon="List" @click="handleViewDevices(row)" />
+            <el-button type="primary" link :icon="View" @click="handleViewDetail(row)" />
           </template>
         </el-table-column>
-        <el-table-column prop="ablyInfo" label="ably信息" min-width="120" show-overflow-tooltip />
-        <el-table-column :label="t('操作')" width="90" align="center" fixed="right">
+        <el-table-column :label="t('操作')" width="70" align="center" fixed="right">
           <template #default="{ row }">
-            <el-button type="primary" link :icon="Edit" @click="handleEdit(row)" />
             <el-button type="danger" link :icon="Delete" @click="handleDelete(row)" />
           </template>
         </el-table-column>
@@ -73,62 +86,32 @@
     </div>
 
     <!-- LSS 详情抽屉 -->
-    <el-drawer v-model="detailDrawerVisible" title="LSS 详情" direction="rtl" size="500px" destroy-on-close>
+    <el-drawer v-model="detailDrawerVisible" title="LSS 节点详情" direction="rtl" size="500px" destroy-on-close>
       <el-descriptions :column="1" border>
         <el-descriptions-item label="LSS ID">{{ currentLss?.lssId }}</el-descriptions-item>
-        <el-descriptions-item label="名称">{{ currentLss?.name }}</el-descriptions-item>
+        <el-descriptions-item label="名称">{{ currentLss?.lssName }}</el-descriptions-item>
         <el-descriptions-item label="地址">{{ currentLss?.address }}</el-descriptions-item>
-        <el-descriptions-item label="公网IP">{{ currentLss?.publicIp }}</el-descriptions-item>
-        <el-descriptions-item label="心跳状态">
-          <span :class="getHeartbeatClass(currentLss?.heartbeat || 'dead')">
-            {{ formatHeartbeat(currentLss) }}
-          </span>
+        <el-descriptions-item label="机器 ID">{{ currentLss?.machineId || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="状态">
+          <el-tag :type="getStatusTagType(currentLss?.status)" size="small">
+            {{ formatStatus(currentLss?.status) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="任务数">
+          {{ currentLss?.currentTasks }} / {{ currentLss?.maxTasks }}
+        </el-descriptions-item>
+        <el-descriptions-item label="FFmpeg 版本">{{ currentLss?.ffmpegVersion || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="系统信息">{{ currentLss?.systemInfo || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="启用状态">
+          <el-tag :type="currentLss?.enabled ? 'success' : 'info'" size="small">
+            {{ currentLss?.enabled ? '已启用' : '已禁用' }}
+          </el-tag>
         </el-descriptions-item>
-        <el-descriptions-item label="ably信息">{{ currentLss?.ablyInfo || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="创建时间">{{ formatTime(currentLss?.createdAt) }}</el-descriptions-item>
+        <el-descriptions-item label="更新时间">{{ formatTime(currentLss?.updatedAt) }}</el-descriptions-item>
       </el-descriptions>
     </el-drawer>
 
-    <!-- 设备列表抽屉 -->
-    <el-drawer v-model="deviceDrawerVisible" title="设备列表" direction="rtl" size="80%" destroy-on-close>
-      <template #header>
-        <div class="drawer-header">
-          <span>设备列表</span>
-          <el-button type="primary" :icon="Plus" @click="handleAddDevice">新增</el-button>
-        </div>
-      </template>
-      <el-table :data="deviceList" stripe size="default" height="100%">
-        <el-table-column prop="localIp" label="本地IP" min-width="100" />
-        <el-table-column prop="deviceId" label="設備ID" min-width="100" />
-        <el-table-column prop="name" label="名稱" min-width="100" />
-        <el-table-column prop="heartbeat" label="狀態(心跳)" min-width="180">
-          <template #default="{ row }">
-            <span :class="getHeartbeatClass(row.heartbeat)">
-              {{ formatDeviceHeartbeat(row) }}
-            </span>
-          </template>
-        </el-table-column>
-        <el-table-column label="參數配置" width="80" align="center">
-          <template #default="{ row }">
-            <el-link type="primary" @click="handleViewConfig(row)">查看</el-link>
-          </template>
-        </el-table-column>
-        <el-table-column label="運行參數" width="80" align="center">
-          <template #default="{ row }">
-            <el-link type="primary" @click="handleViewRunParams(row)">查看</el-link>
-          </template>
-        </el-table-column>
-        <el-table-column prop="manufacturer" label="廠商" min-width="100" />
-        <el-table-column prop="model" label="型號" min-width="140" />
-        <el-table-column prop="addTime" label="添加時間" min-width="150" />
-        <el-table-column label="設備控制" width="100" align="center">
-          <template #default="{ row }">
-            <el-button type="primary" link :icon="Edit" @click="handleEditDevice(row)" />
-            <el-button type="danger" link :icon="Delete" @click="handleDeleteDevice(row)" />
-          </template>
-        </el-table-column>
-      </el-table>
-    </el-drawer>
-
     <!-- 分页 -->
     <div class="pagination-container">
       <el-pagination
@@ -146,83 +129,80 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, onMounted, computed } from 'vue'
-import { Search, RefreshRight, Edit, Delete, View, List, Plus } from '@element-plus/icons-vue'
+import { ref, reactive, onMounted } from 'vue'
+import { Search, RefreshRight, Delete, View } from '@element-plus/icons-vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { listLss } from '@/api/lss'
-import type { LssDTO, LssHeartbeatStatus } from '@/types'
+import { listLssNodes, deleteLssNode, setLssNodeEnabled } from '@/api/lss'
+import type { LssNodeDTO, LssNodeStatus, LssNodeListRequest } from '@/types'
 import dayjs from 'dayjs'
 import { useI18n } from 'vue-i18n'
 
 const { t } = useI18n({ useScope: 'global' })
 
-// 格式化心跳显示
-function formatHeartbeat(row: LssDTO | null | undefined): string {
-  if (!row) return '-'
-  if (row.heartbeat === 'active') {
-    const time = row.heartbeatTime ? dayjs(row.heartbeatTime).format('YY-MM-DD HH:mm:ss') : ''
-    return `active [${time}]`
-  } else if (row.heartbeat === 'hold') {
-    return 'hold(5分鐘內)'
-  } else if (row.heartbeat === 'dead') {
-    return 'dead (超過5分)'
+// 格式化状态显示
+function formatStatus(status: LssNodeStatus | undefined): string {
+  switch (status) {
+    case 'ONLINE':
+      return '在线'
+    case 'OFFLINE':
+      return '离线'
+    case 'BUSY':
+      return '繁忙'
+    case 'MAINTENANCE':
+      return '维护中'
+    default:
+      return '-'
   }
-  return row.heartbeat || '-'
 }
 
-// 获取心跳状态样式类
-function getHeartbeatClass(status: LssHeartbeatStatus): string {
+// 获取状态标签类型
+function getStatusTagType(status: LssNodeStatus | undefined): 'success' | 'danger' | 'warning' | 'info' {
   switch (status) {
-    case 'active':
-      return 'heartbeat-active'
-    case 'hold':
-      return 'heartbeat-hold'
-    case 'dead':
-      return 'heartbeat-dead'
+    case 'ONLINE':
+      return 'success'
+    case 'OFFLINE':
+      return 'danger'
+    case 'BUSY':
+      return 'warning'
+    case 'MAINTENANCE':
+      return 'info'
     default:
-      return ''
+      return 'info'
   }
 }
 
+// 格式化时间
+function formatTime(time: string | undefined): string {
+  if (!time) return '-'
+  return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
+}
+
 const loading = ref(false)
-const lssList = ref<LssDTO[]>([])
+const lssList = ref<(LssNodeDTO & { _switching?: boolean })[]>([])
 const tableRef = ref()
 
 // 抽屉状态
 const detailDrawerVisible = ref(false)
-const deviceDrawerVisible = ref(false)
-const currentLss = ref<LssDTO | null>(null)
-
-interface DeviceItem {
-  id: number
-  localIp: string
-  deviceId: string
-  name: string
-  heartbeat: LssHeartbeatStatus
-  heartbeatTime?: string
-  manufacturer: string
-  model: string
-  addTime: string
-}
-
-const deviceList = ref<DeviceItem[]>([])
+const currentLss = ref<LssNodeDTO | null>(null)
 
 // 排序状态
 const sortState = reactive<{
-  prop: string
-  order: 'ascending' | 'descending' | null
+  sortBy: string
+  sortDir: 'ASC' | 'DESC' | undefined
 }>({
-  prop: '',
-  order: null
+  sortBy: '',
+  sortDir: undefined
 })
 
 // 搜索表单
 const searchForm = reactive<{
   keyword: string
-  heartbeat: LssHeartbeatStatus | ''
+  status: LssNodeStatus | ''
+  enabled: boolean | null
 }>({
   keyword: '',
-  heartbeat: ''
+  status: '',
+  enabled: null
 })
 
 // 分页相关
@@ -230,154 +210,37 @@ const currentPage = ref(1)
 const pageSize = ref(20)
 const total = ref(0)
 
-// 排序后的数据
-const sortedList = computed(() => {
-  const list = [...lssList.value]
-  if (sortState.prop && sortState.order) {
-    list.sort((a, b) => {
-      const aVal = a[sortState.prop as keyof LssDTO]
-      const bVal = b[sortState.prop as keyof LssDTO]
-
-      if (aVal == null && bVal == null) return 0
-      if (aVal == null) return sortState.order === 'ascending' ? -1 : 1
-      if (bVal == null) return sortState.order === 'ascending' ? 1 : -1
-
-      let result = 0
-      if (typeof aVal === 'number' && typeof bVal === 'number') {
-        result = aVal - bVal
-      } else {
-        result = String(aVal).localeCompare(String(bVal))
-      }
-
-      return sortState.order === 'ascending' ? result : -result
-    })
-  }
-  return list
-})
-
-// 模拟测试数据
-const mockData: LssDTO[] = [
-  {
-    id: 1,
-    lssId: 'L001',
-    name: '现场-初台1',
-    address: '西新宿初台3-3-2',
-    publicIp: '10.72.44.56',
-    heartbeat: 'active',
-    heartbeatTime: '2026-01-18T12:33:31',
-    ablyInfo: 'ably-channel-001'
-  },
-  {
-    id: 2,
-    lssId: 'L002',
-    name: '现场-渋谷2',
-    address: '涩谷区道玄坂1-2-3',
-    publicIp: '10.72.44.57',
-    heartbeat: 'active',
-    heartbeatTime: '2026-01-18T12:35:22',
-    ablyInfo: 'ably-channel-002'
-  },
-  {
-    id: 3,
-    lssId: 'L003',
-    name: '现场-新宿3',
-    address: '新宿区歌舞伎町1-1-1',
-    publicIp: '10.72.44.58',
-    heartbeat: 'hold',
-    heartbeatTime: '2026-01-18T12:30:00',
-    ablyInfo: 'ably-channel-003'
-  },
-  {
-    id: 4,
-    lssId: 'L004',
-    name: '现场-池袋4',
-    address: '島区南池袋2-5-6',
-    publicIp: '10.72.44.59',
-    heartbeat: 'dead',
-    heartbeatTime: '2026-01-18T12:00:00',
-    ablyInfo: ''
-  },
-  {
-    id: 5,
-    lssId: 'L005',
-    name: '现场-秋叶原5',
-    address: '千代田区外神田4-4-4',
-    publicIp: '10.72.44.60',
-    heartbeat: 'active',
-    heartbeatTime: '2026-01-18T12:36:10',
-    ablyInfo: 'ably-channel-005'
-  },
-  {
-    id: 6,
-    lssId: 'L006',
-    name: '现场-银座6',
-    address: '中央区银座5-5-5',
-    publicIp: '10.72.44.61',
-    heartbeat: 'hold',
-    heartbeatTime: '2026-01-18T12:32:00'
-  },
-  {
-    id: 7,
-    lssId: 'L007',
-    name: '现场-上野7',
-    address: '台东区上野公园7-7',
-    publicIp: '10.72.44.62',
-    heartbeat: 'dead',
-    heartbeatTime: '2026-01-18T11:50:00',
-    ablyInfo: 'ably-channel-007'
-  },
-  {
-    id: 8,
-    lssId: 'L008',
-    name: '现场-品川8',
-    address: '港区高轮3-3-3',
-    publicIp: '10.72.44.63',
-    heartbeat: 'active',
-    heartbeatTime: '2026-01-18T12:36:55',
-    ablyInfo: 'ably-channel-008'
-  }
-]
-
 async function getList() {
   loading.value = true
   try {
-    // TODO: 替换为真实 API 调用
-    // const params: Record<string, any> = {
-    //   page: currentPage.value,
-    //   size: pageSize.value
-    // }
-    // if (searchForm.keyword) {
-    //   params.keyword = searchForm.keyword
-    // }
-    // if (searchForm.heartbeat) {
-    //   params.heartbeat = searchForm.heartbeat
-    // }
-    // const res = await listLss(params)
-    // if (res.success) {
-    //   lssList.value = res.data.list
-    //   total.value = res.data.total || 0
-    // }
-
-    // 使用模拟数据
-    await new Promise((resolve) => setTimeout(resolve, 300))
-    let filtered = [...mockData]
-
-    // 关键词过滤
+    const params: LssNodeListRequest = {
+      page: currentPage.value,
+      size: pageSize.value
+    }
     if (searchForm.keyword) {
-      const kw = searchForm.keyword.toLowerCase()
-      filtered = filtered.filter(
-        (item) => item.lssId.toLowerCase().includes(kw) || item.name.toLowerCase().includes(kw)
-      )
+      params.keyword = searchForm.keyword
     }
-
-    // 心跳状态过滤
-    if (searchForm.heartbeat) {
-      filtered = filtered.filter((item) => item.heartbeat === searchForm.heartbeat)
+    if (searchForm.status) {
+      params.status = searchForm.status
+    }
+    if (searchForm.enabled !== null) {
+      params.enabled = searchForm.enabled
+    }
+    if (sortState.sortBy) {
+      params.sortBy = sortState.sortBy
+      params.sortDir = sortState.sortDir
     }
 
-    total.value = filtered.length
-    const start = (currentPage.value - 1) * pageSize.value
-    lssList.value = filtered.slice(start, start + pageSize.value)
+    const res = await listLssNodes(params)
+    if (res.success && res.data) {
+      lssList.value = res.data.list
+      total.value = res.data.total || 0
+    } else {
+      ElMessage.error(res.errMessage || '获取列表失败')
+    }
+  } catch (error) {
+    console.error('获取 LSS 列表失败', error)
+    ElMessage.error('获取列表失败')
   } finally {
     loading.value = false
   }
@@ -390,16 +253,17 @@ function handleSearch() {
 
 function handleReset() {
   searchForm.keyword = ''
-  searchForm.heartbeat = ''
+  searchForm.status = ''
+  searchForm.enabled = null
   currentPage.value = 1
-  sortState.prop = ''
-  sortState.order = null
+  sortState.sortBy = ''
+  sortState.sortDir = undefined
   getList()
 }
 
 function handleSortChange({ prop, order }: { prop: string; order: 'ascending' | 'descending' | null }) {
-  sortState.prop = prop || ''
-  sortState.order = order
+  sortState.sortBy = prop || ''
+  sortState.sortDir = order === 'ascending' ? 'ASC' : order === 'descending' ? 'DESC' : undefined
   getList()
 }
 
@@ -414,132 +278,47 @@ function handleCurrentChange(val: number) {
   getList()
 }
 
-function handleViewDetail(row: LssDTO) {
+function handleViewDetail(row: LssNodeDTO) {
   currentLss.value = row
   detailDrawerVisible.value = true
 }
 
-function handleViewDevices(row: LssDTO) {
-  currentLss.value = row
-  // 模拟设备列表数据
-  deviceList.value = [
-    {
-      id: 1,
-      localIp: '192.168.0.64',
-      deviceId: 'CAM-069',
-      name: '攝像頭名稱1',
-      heartbeat: 'active',
-      heartbeatTime: '2026-01-16T14:33:33',
-      manufacturer: 'HIKVISION',
-      model: 'DS-2DE2A404IW-DE3',
-      addTime: '26-01-16 14:33:33'
-    },
-    {
-      id: 2,
-      localIp: '10.0.2.102',
-      deviceId: 'CAM-069',
-      name: '攝像頭名稱1',
-      heartbeat: 'hold',
-      heartbeatTime: '2026-01-16T14:30:00',
-      manufacturer: 'HIKVISION',
-      model: 'DS-2DE2A404IW-DE3',
-      addTime: '26-01-16 14:33:33'
-    },
-    {
-      id: 3,
-      localIp: '10.0.2.102',
-      deviceId: 'CAM-069',
-      name: '攝像頭名稱1',
-      heartbeat: 'dead',
-      heartbeatTime: '2026-01-16T14:00:00',
-      manufacturer: 'HIKVISION',
-      model: 'DS-2DE2A404IW-DE3',
-      addTime: '26-01-16 14:33:33'
-    },
-    {
-      id: 4,
-      localIp: '10.0.2.102',
-      deviceId: 'CAM-069',
-      name: '攝像頭名稱1',
-      heartbeat: 'active',
-      heartbeatTime: '2026-01-16T14:33:33',
-      manufacturer: 'HIKVISION',
-      model: 'DS-2DE2A404IW-DE3',
-      addTime: '26-01-16 14:33:33'
-    },
-    {
-      id: 5,
-      localIp: '10.0.2.102',
-      deviceId: 'CAM-069',
-      name: '攝像頭名稱1',
-      heartbeat: 'hold',
-      heartbeatTime: '2026-01-16T14:30:00',
-      manufacturer: 'HIKVISION',
-      model: 'DS-2DE2A404IW-DE3',
-      addTime: '26-01-16 14:33:33'
-    }
-  ]
-  deviceDrawerVisible.value = true
-}
-
-// 格式化设备心跳显示
-function formatDeviceHeartbeat(row: DeviceItem): string {
-  if (row.heartbeat === 'active') {
-    const time = row.heartbeatTime ? dayjs(row.heartbeatTime).format('YY-MM-DD HH:mm:ss') : ''
-    return `active [${time}]`
-  } else if (row.heartbeat === 'hold') {
-    return 'hold(5分鐘內)'
-  } else if (row.heartbeat === 'dead') {
-    return 'dead (超過5分)'
-  }
-  return row.heartbeat || '-'
-}
-
-function handleAddDevice() {
-  ElMessage.info('新增设备')
-}
-
-function handleViewConfig(row: DeviceItem) {
-  ElMessage.info(`查看参数配置: ${row.deviceId}`)
-}
-
-function handleViewRunParams(row: DeviceItem) {
-  ElMessage.info(`查看运行参数: ${row.deviceId}`)
-}
-
-function handleEditDevice(row: DeviceItem) {
-  ElMessage.info(`编辑设备: ${row.deviceId}`)
-}
-
-async function handleDeleteDevice(row: DeviceItem) {
+async function handleToggleEnabled(row: LssNodeDTO & { _switching?: boolean }, enabled: boolean) {
+  row._switching = true
   try {
-    await ElMessageBox.confirm(`确定要删除设备 "${row.name}" 吗?`, '提示', {
-      type: 'warning'
-    })
-    ElMessage.success('删除成功')
-  } catch (error) {
-    if (error !== 'cancel') {
-      console.error('删除失败', error)
+    const res = await setLssNodeEnabled(row.lssId, enabled)
+    if (res.success) {
+      ElMessage.success(enabled ? '已启用' : '已禁用')
+    } else {
+      // 恢复原状态
+      row.enabled = !enabled
+      ElMessage.error(res.errMessage || '操作失败')
     }
+  } catch (error) {
+    row.enabled = !enabled
+    console.error('切换启用状态失败', error)
+    ElMessage.error('操作失败')
+  } finally {
+    row._switching = false
   }
 }
 
-function handleEdit(row: LssDTO) {
-  // TODO: 实现编辑功能
-  ElMessage.info(`编辑 ${row.name}`)
-}
-
-async function handleDelete(row: LssDTO) {
+async function handleDelete(row: LssNodeDTO) {
   try {
-    await ElMessageBox.confirm(`确定要删除 LSS "${row.name}" 吗?`, '提示', {
+    await ElMessageBox.confirm(`确定要删除 LSS 节点 "${row.lssName}" 吗?`, '提示', {
       type: 'warning'
     })
-    // TODO: 调用删除 API
-    ElMessage.success('删除成功')
-    getList()
+    const res = await deleteLssNode(row.lssId)
+    if (res.success) {
+      ElMessage.success('删除成功')
+      getList()
+    } else {
+      ElMessage.error(res.errMessage || '删除失败')
+    }
   } catch (error) {
     if (error !== 'cancel') {
       console.error('删除失败', error)
+      ElMessage.error('删除失败')
     }
   }
 }
@@ -616,43 +395,7 @@ onMounted(() => {
   }
 }
 
-// 心跳状态样式
-.heartbeat-active {
-  color: #67c23a;
-}
-
-.heartbeat-hold {
-  color: #e6a23c;
-}
-
-.heartbeat-dead {
-  color: #f56c6c;
-}
-
 // 抽屉样式
-.drawer-header {
-  display: flex;
-  align-items: center;
-  width: 100%;
-
-  span {
-    font-size: 16px;
-    font-weight: 600;
-    margin-right: 10px;
-  }
-
-  :deep(.el-button--primary) {
-    background-color: #4f46e5;
-    border-color: #4f46e5;
-
-    &:hover,
-    &:focus {
-      background-color: #6366f1;
-      border-color: #6366f1;
-    }
-  }
-}
-
 :deep(.el-drawer) {
   .el-drawer__header {
     margin-bottom: 0;
@@ -670,14 +413,6 @@ onMounted(() => {
       font-weight: 600;
     }
   }
-
-  .el-link--primary {
-    color: #4f46e5;
-
-    &:hover {
-      color: #6366f1;
-    }
-  }
 }
 
 // 表格样式