Procházet zdrojové kódy

refactor(lss): enhance input fields and table components for improved readability

- Streamlined input fields and table components in the LSS management view for better visual clarity.
- Consolidated multiple lines of code into single lines to enhance user experience.
- Updated button attributes for consistency and improved accessibility.
yb před 20 hodinami
rodič
revize
62d964bb14
2 změnil soubory, kde provedl 1057 přidání a 4 odebrání
  1. 1027 0
      docs/api_torna/camera-scan.md
  2. 30 4
      src/views/lss/index.vue

+ 1027 - 0
docs/api_torna/camera-scan.md

@@ -0,0 +1,1027 @@
+# 文档
+
+## 管理后台
+
+## 摄像头扫描管理
+
+### 触发 ONVIF 设备扫描
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/lss/{lssId}/scan
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss/{lssId}/scan
+
+描述:触发 ONVIF 设备扫描
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称  | 必填 | 描述        | 示例值 |
+| ----- | ---- | ----------- | ------ |
+| lssId | 是   | LSS 节点 ID |        |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: ScanResultDTO) |  |
+| └ taskId | String | 否 | - | 扫描任务 ID | scan_abc12345 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ status | String | 否 | - | 扫描状态: SCANNING / COMPLETED / FAILED | SCANNING |
+| └ discoveredCount | Integer | 否 | - | 发现的设备数量 | 5 |
+| └ newCount | Integer | 否 | - | 新发现的设备数量 | 3 |
+| └ devices | List<DiscoveredCameraDTO> | 否 |  | 发现的设备列表 (ActualType: DiscoveredCameraDTO) |  |
+| └ id | Long | 否 | - | ID | 1 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ uuid | String | 否 | - | 设备 UUID | uuid-1234-5678 |
+| └ deviceName | String | 否 | - | 设备名称 | IP Camera |
+| └ vendor | String | 否 | - | 厂商 | HIKVISION |
+| └ model | String | 否 | - | 型号 | DS-2CD2T45FWD |
+| └ serialNumber | String | 否 | - | 序列号 | SN123456789 |
+| └ rtspUrl | String | 否 | - | RTSP URL | rtsp://admin:12345@192.168.1.100:554/stream1 |
+| └ matchStatus | String | 否 | - | 匹配状态: PENDING / MATCHING / MATCHED / UNMATCHED | PENDING |
+| └ matchedCredentialId | Long | 否 | - | 匹配成功的凭证 ID | 1 |
+| └ matchAttempts | Integer | 否 | - | 匹配尝试次数 | 0 |
+| └ lastMatchAttempt | LocalDateTime | 否 | - | 最后匹配时间 | 2026-01-27T10:00:00 |
+| └ matchError | String | 否 | - | 匹配错误信息 | Authentication failed |
+| └ deviceInfo | String | 否 | - | 设备详细信息 JSON | {manufacturer:HIKVISION,model:DS-2CD2T45FWD,firmwareVersion:V5.6.5} |
+| └ bound | Boolean | 否 | - | 是否已绑定到 camera_info | false |
+| └ boundCameraId | Long | 否 | - | 绑定的 camera_info.id | 1 |
+| └ canMatch | Boolean | 否 | - | 是否可以匹配(未超过 3 次或已过 24 小时冷却期) | true |
+| └ discoveredAt | LocalDateTime | 否 | - | 发现时间 | 2026-01-27T10:00:00 |
+| └ error | String | 否 | - | 错误信息 |  |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "taskId": "scan_abc12345",
+        "lssId": "lss_001",
+        "status": "SCANNING",
+        "discoveredCount": 5,
+        "newCount": 3,
+        "devices": [
+            {
+                "id": 1,
+                "lssId": "lss_001",
+                "ip": "192.168.1.100",
+                "port": 80,
+                "uuid": "uuid-1234-5678",
+                "deviceName": "IP Camera",
+                "vendor": "HIKVISION",
+                "model": "DS-2CD2T45FWD",
+                "serialNumber": "SN123456789",
+                "rtspUrl": "rtsp://admin:12345@192.168.1.100:554/stream1",
+                "matchStatus": "PENDING",
+                "matchedCredentialId": 1,
+                "matchAttempts": 0,
+                "lastMatchAttempt": "2026-01-27T10:00:00",
+                "matchError": "Authentication failed",
+                "deviceInfo": "{manufacturer:HIKVISION,model:DS-2CD2T45FWD,firmwareVersion:V5.6.5}",
+                "bound": false,
+                "boundCameraId": 1,
+                "canMatch": true,
+                "discoveredAt": "2026-01-27T10:00:00"
+            }
+        ],
+        "error": "string"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 获取发现的设备列表
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/lss/{lssId}/discovered
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/lss/{lssId}/discovered
+
+描述:获取发现的设备列表
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称  | 必填 | 描述        | 示例值 |
+| ----- | ---- | ----------- | ------ |
+| lssId | 是   | LSS 节点 ID |        |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | array | 否 |  | 响应数据 (ActualType: List) |  |
+| └ id | Long | 否 | - | ID | 1 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ uuid | String | 否 | - | 设备 UUID | uuid-1234-5678 |
+| └ deviceName | String | 否 | - | 设备名称 | IP Camera |
+| └ vendor | String | 否 | - | 厂商 | HIKVISION |
+| └ model | String | 否 | - | 型号 | DS-2CD2T45FWD |
+| └ serialNumber | String | 否 | - | 序列号 | SN123456789 |
+| └ rtspUrl | String | 否 | - | RTSP URL | rtsp://admin:12345@192.168.1.100:554/stream1 |
+| └ matchStatus | String | 否 | - | 匹配状态: PENDING / MATCHING / MATCHED / UNMATCHED | PENDING |
+| └ matchedCredentialId | Long | 否 | - | 匹配成功的凭证 ID | 1 |
+| └ matchAttempts | Integer | 否 | - | 匹配尝试次数 | 0 |
+| └ lastMatchAttempt | LocalDateTime | 否 | - | 最后匹配时间 | 2026-01-27T10:00:00 |
+| └ matchError | String | 否 | - | 匹配错误信息 | Authentication failed |
+| └ deviceInfo | String | 否 | - | 设备详细信息 JSON | {manufacturer:HIKVISION,model:DS-2CD2T45FWD,firmwareVersion:V5.6.5} |
+| └ bound | Boolean | 否 | - | 是否已绑定到 camera_info | false |
+| └ boundCameraId | Long | 否 | - | 绑定的 camera_info.id | 1 |
+| └ canMatch | Boolean | 否 | - | 是否可以匹配(未超过 3 次或已过 24 小时冷却期) | true |
+| └ discoveredAt | LocalDateTime | 否 | - | 发现时间 | 2026-01-27T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 1,
+            "lssId": "lss_001",
+            "ip": "192.168.1.100",
+            "port": 80,
+            "uuid": "uuid-1234-5678",
+            "deviceName": "IP Camera",
+            "vendor": "HIKVISION",
+            "model": "DS-2CD2T45FWD",
+            "serialNumber": "SN123456789",
+            "rtspUrl": "rtsp://admin:12345@192.168.1.100:554/stream1",
+            "matchStatus": "PENDING",
+            "matchedCredentialId": 1,
+            "matchAttempts": 0,
+            "lastMatchAttempt": "2026-01-27T10:00:00",
+            "matchError": "Authentication failed",
+            "deviceInfo": "{manufacturer:HIKVISION,model:DS-2CD2T45FWD,firmwareVersion:V5.6.5}",
+            "bound": false,
+            "boundCameraId": 1,
+            "canMatch": true,
+            "discoveredAt": "2026-01-27T10:00:00"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 获取发现设备详情
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/discovered/{id}
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/discovered/{id}
+
+描述:获取发现设备详情
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称 | 必填 | 描述        | 示例值 |
+| ---- | ---- | ----------- | ------ |
+| id   | 是   | 发现设备 ID | 0      |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: DiscoveredCameraDTO) |  |
+| └ id | Long | 否 | - | ID | 1 |
+| └ lssId | String | 否 | - | LSS 节点 ID | lss_001 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ uuid | String | 否 | - | 设备 UUID | uuid-1234-5678 |
+| └ deviceName | String | 否 | - | 设备名称 | IP Camera |
+| └ vendor | String | 否 | - | 厂商 | HIKVISION |
+| └ model | String | 否 | - | 型号 | DS-2CD2T45FWD |
+| └ serialNumber | String | 否 | - | 序列号 | SN123456789 |
+| └ rtspUrl | String | 否 | - | RTSP URL | rtsp://admin:12345@192.168.1.100:554/stream1 |
+| └ matchStatus | String | 否 | - | 匹配状态: PENDING / MATCHING / MATCHED / UNMATCHED | PENDING |
+| └ matchedCredentialId | Long | 否 | - | 匹配成功的凭证 ID | 1 |
+| └ matchAttempts | Integer | 否 | - | 匹配尝试次数 | 0 |
+| └ lastMatchAttempt | LocalDateTime | 否 | - | 最后匹配时间 | 2026-01-27T10:00:00 |
+| └ matchError | String | 否 | - | 匹配错误信息 | Authentication failed |
+| └ deviceInfo | String | 否 | - | 设备详细信息 JSON | {manufacturer:HIKVISION,model:DS-2CD2T45FWD,firmwareVersion:V5.6.5} |
+| └ bound | Boolean | 否 | - | 是否已绑定到 camera_info | false |
+| └ boundCameraId | Long | 否 | - | 绑定的 camera_info.id | 1 |
+| └ canMatch | Boolean | 否 | - | 是否可以匹配(未超过 3 次或已过 24 小时冷却期) | true |
+| └ discoveredAt | LocalDateTime | 否 | - | 发现时间 | 2026-01-27T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "lssId": "lss_001",
+        "ip": "192.168.1.100",
+        "port": 80,
+        "uuid": "uuid-1234-5678",
+        "deviceName": "IP Camera",
+        "vendor": "HIKVISION",
+        "model": "DS-2CD2T45FWD",
+        "serialNumber": "SN123456789",
+        "rtspUrl": "rtsp://admin:12345@192.168.1.100:554/stream1",
+        "matchStatus": "PENDING",
+        "matchedCredentialId": 1,
+        "matchAttempts": 0,
+        "lastMatchAttempt": "2026-01-27T10:00:00",
+        "matchError": "Authentication failed",
+        "deviceInfo": "{manufacturer:HIKVISION,model:DS-2CD2T45FWD,firmwareVersion:V5.6.5}",
+        "bound": false,
+        "boundCameraId": 1,
+        "canMatch": true,
+        "discoveredAt": "2026-01-27T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 删除发现设备
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/discovered/{id}/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/discovered/{id}/delete
+
+描述:删除发现设备
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称 | 必填 | 描述        | 示例值 |
+| ---- | ---- | ----------- | ------ |
+| id   | 是   | 发现设备 ID | 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/lss/{lssId}/match
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/lss/{lssId}/match
+
+描述:触发凭证匹配
+
+ContentType:`application/json`
+
+#### Path 参数
+
+| 名称  | 必填 | 描述        | 示例值 |
+| ----- | ---- | ----------- | ------ |
+| lssId | 是   | LSS 节点 ID |        |
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| deviceIds | List<Long> | 否 | - | 要匹配的设备 ID 列表(可选,空表示全部 PENDING 设备) (ActualType: Long) | [1, 2, 3] |
+| credentialIds | List<Long> | 否 | - | 要使用的凭证 ID 列表(可选,空表示使用所有启用的凭证) (ActualType: Long) | [1, 2] |
+| maxRetry | Integer | 否 | - | 最大重试次数 | 3 |
+
+#### 请求示例
+
+```
+{
+    "deviceIds": [
+        1,
+        2,
+        3
+    ],
+    "credentialIds": [
+        1,
+        2
+    ],
+    "maxRetry": 3
+}
+```
+
+#### 响应参数
+
+| 名称           | 类型    | 必填 | 最大长度 | 描述                                    | 示例值         |
+| -------------- | ------- | ---- | -------- | --------------------------------------- | -------------- |
+| success        | Boolean | 否   | -        | 请求是否成功                            | true           |
+| errCode        | String  | 否   | -        | 错误码(失败时返回)                    |                |
+| errMessage     | String  | 否   | -        | 错误信息(失败时返回)                  |                |
+| data           | object  | 否   |          | 响应数据 (ActualType: MatchResultDTO)   |                |
+| └ taskId       | String  | 否   | -        | 匹配任务 ID                             | match_abc12345 |
+| └ lssId        | String  | 否   | -        | LSS 节点 ID                             | lss_001        |
+| └ status       | String  | 否   | -        | 匹配状态: MATCHING / COMPLETED / FAILED | MATCHING       |
+| └ totalCount   | Integer | 否   | -        | 匹配的设备数量                          | 5              |
+| └ successCount | Integer | 否   | -        | 成功匹配数量                            | 3              |
+| └ failCount    | Integer | 否   | -        | 失败数量                                | 2              |
+| └ error        | String  | 否   | -        | 错误信息                                |                |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "taskId": "match_abc12345",
+        "lssId": "lss_001",
+        "status": "MATCHING",
+        "totalCount": 5,
+        "successCount": 3,
+        "failCount": 2,
+        "error": "string"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 重新匹配单个设备
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/discovered/{id}/retry
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/discovered/{id}/retry
+
+描述:重新匹配单个设备
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称 | 必填 | 描述        | 示例值 |
+| ---- | ---- | ----------- | ------ |
+| id   | 是   | 发现设备 ID | 0      |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称           | 类型    | 必填 | 最大长度 | 描述                                    | 示例值         |
+| -------------- | ------- | ---- | -------- | --------------------------------------- | -------------- |
+| success        | Boolean | 否   | -        | 请求是否成功                            | true           |
+| errCode        | String  | 否   | -        | 错误码(失败时返回)                    |                |
+| errMessage     | String  | 否   | -        | 错误信息(失败时返回)                  |                |
+| data           | object  | 否   |          | 响应数据 (ActualType: MatchResultDTO)   |                |
+| └ taskId       | String  | 否   | -        | 匹配任务 ID                             | match_abc12345 |
+| └ lssId        | String  | 否   | -        | LSS 节点 ID                             | lss_001        |
+| └ status       | String  | 否   | -        | 匹配状态: MATCHING / COMPLETED / FAILED | MATCHING       |
+| └ totalCount   | Integer | 否   | -        | 匹配的设备数量                          | 5              |
+| └ successCount | Integer | 否   | -        | 成功匹配数量                            | 3              |
+| └ failCount    | Integer | 否   | -        | 失败数量                                | 2              |
+| └ error        | String  | 否   | -        | 错误信息                                |                |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "taskId": "match_abc12345",
+        "lssId": "lss_001",
+        "status": "MATCHING",
+        "totalCount": 5,
+        "successCount": 3,
+        "failCount": 2,
+        "error": "string"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 绑定发现设备到已有摄像头
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/scan/bind
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/scan/bind
+
+描述:绑定发现设备到已有摄像头
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称         | 类型 | 必填 | 最大长度 | 描述                                | 示例值 |
+| ------------ | ---- | ---- | -------- | ----------------------------------- | ------ |
+| discoveredId | Long | 是   | -        | 发现设备 ID                         | 1      |
+| cameraId     | Long | 是   | -        | 要绑定的摄像头 ID(camera_info.id) | 1      |
+
+#### 请求示例
+
+```
+{
+    "discoveredId": 1,
+    "cameraId": 1
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: CameraInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ cameraName | String | 否 | - | 设备名称 | 主摄像头 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ vendorName | String | 否 | - | 厂商名称 | 海康威视 |
+| └ brand | String | 否 | - | 品牌(兼容旧数据) | hikvision |
+| └ capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| └ status | String | 否 | - | 心跳状态: active, hold, dead | active |
+| └ 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 | 否 | - | 备注 |  |
+| └ paramConfig | String | 否 | - | 参数配置 (JSON 格式,包含 ip, port, username, password 等) | {ip:192.168.1.100,port:80,username:admin,password:123456} |
+| └ runtimeParams | String | 否 | - | 设备运行参数 (JSON 格式,通过 ONVIF 获取的摄像头参数)<br><br>现阶段:手动输入<br>TODO: 后续改为通过 ONVIF 协议扫描自动获取 | {resolution:1920x1080,fps:25,codec:H.264} |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2026-01-07T10:00:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2026-01-07T10:00:00 |
+| └ streamSn | String | 否 | - | 关联的推流任务流水号 | stream_e1d710b7b8a8 |
+| └ streamStatus | String | 否 | - | 推流状态: idle, streaming, stopped, error | streaming |
+| └ playbackUrl | String | 否 | - | 播放地址(WHEP) | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "cameraId": "cam_001",
+        "cameraName": "主摄像头",
+        "ip": "192.168.1.100",
+        "port": 80,
+        "username": "admin",
+        "vendorName": "海康威视",
+        "brand": "hikvision",
+        "capability": "ptz_enabled",
+        "status": "active",
+        "lssId": "lss_001",
+        "model": "DS-2CD2T47G2-LSU/SL",
+        "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+        "channelNo": "1",
+        "remark": "string",
+        "paramConfig": "{ip:192.168.1.100,port:80,username:admin,password:123456}",
+        "runtimeParams": "{resolution:1920x1080,fps:25,codec:H.264}",
+        "enabled": true,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00",
+        "streamSn": "stream_e1d710b7b8a8",
+        "streamStatus": "streaming",
+        "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 从发现设备创建摄像头(已废弃)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/discovered/create-camera
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/discovered/create-camera
+
+描述:从发现设备创建摄像头(已废弃)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称         | 类型   | 必填 | 最大长度 | 描述                                 | 示例值       |
+| ------------ | ------ | ---- | -------- | ------------------------------------ | ------------ |
+| discoveredId | Long   | 是   | -        | 发现设备 ID                          | 1            |
+| name         | String | 否   | -        | 摄像头名称(可选,默认使用设备名称) | 前门摄像头   |
+| remark       | String | 否   | -        | 备注                                 | 大门入口监控 |
+
+#### 请求示例
+
+```
+{
+    "discoveredId": 1,
+    "name": "前门摄像头",
+    "remark": "大门入口监控"
+}
+```
+
+#### 响应参数
+
+| 名称 | 类型 | 必填 | 最大长度 | 描述 | 示例值 |
+| --- | --- | --- | --- | --- | --- |
+| success | Boolean | 否 | - | 请求是否成功 | true |
+| errCode | String | 否 | - | 错误码(失败时返回) |  |
+| errMessage | String | 否 | - | 错误信息(失败时返回) |  |
+| data | object | 否 |  | 响应数据 (ActualType: CameraInfoDTO) |  |
+| └ id | Long | 否 | - | 主键 ID | 1 |
+| └ cameraId | String | 否 | - | 摄像头 ID | cam_001 |
+| └ cameraName | String | 否 | - | 设备名称 | 主摄像头 |
+| └ ip | String | 否 | - | IP 地址 | 192.168.1.100 |
+| └ port | Integer | 否 | - | 端口 | 80 |
+| └ username | String | 否 | - | 用户名 | admin |
+| └ vendorName | String | 否 | - | 厂商名称 | 海康威视 |
+| └ brand | String | 否 | - | 品牌(兼容旧数据) | hikvision |
+| └ capability | String | 否 | - | 能力: switch_only, ptz_enabled | ptz_enabled |
+| └ status | String | 否 | - | 心跳状态: active, hold, dead | active |
+| └ 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 | 否 | - | 备注 |  |
+| └ paramConfig | String | 否 | - | 参数配置 (JSON 格式,包含 ip, port, username, password 等) | {ip:192.168.1.100,port:80,username:admin,password:123456} |
+| └ runtimeParams | String | 否 | - | 设备运行参数 (JSON 格式,通过 ONVIF 获取的摄像头参数)<br><br>现阶段:手动输入<br>TODO: 后续改为通过 ONVIF 协议扫描自动获取 | {resolution:1920x1080,fps:25,codec:H.264} |
+| └ enabled | Boolean | 否 | - | 是否启用 | true |
+| └ createdAt | LocalDateTime | 否 | - | 创建时间 | 2026-01-07T10:00:00 |
+| └ updatedAt | LocalDateTime | 否 | - | 更新时间 | 2026-01-07T10:00:00 |
+| └ streamSn | String | 否 | - | 关联的推流任务流水号 | stream_e1d710b7b8a8 |
+| └ streamStatus | String | 否 | - | 推流状态: idle, streaming, stopped, error | streaming |
+| └ playbackUrl | String | 否 | - | 播放地址(WHEP) | https://customer-xxx.cloudflarestream.com/xxx/webRTC/play |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "cameraId": "cam_001",
+        "cameraName": "主摄像头",
+        "ip": "192.168.1.100",
+        "port": 80,
+        "username": "admin",
+        "vendorName": "海康威视",
+        "brand": "hikvision",
+        "capability": "ptz_enabled",
+        "status": "active",
+        "lssId": "lss_001",
+        "model": "DS-2CD2T47G2-LSU/SL",
+        "rtspUrl": "rtsp://admin:password@192.168.1.100:554/stream1",
+        "channelNo": "1",
+        "remark": "string",
+        "paramConfig": "{ip:192.168.1.100,port:80,username:admin,password:123456}",
+        "runtimeParams": "{resolution:1920x1080,fps:25,codec:H.264}",
+        "enabled": true,
+        "createdAt": "2026-01-07T10:00:00",
+        "updatedAt": "2026-01-07T10:00:00",
+        "streamSn": "stream_e1d710b7b8a8",
+        "streamStatus": "streaming",
+        "playbackUrl": "https://customer-xxx.cloudflarestream.com/xxx/webRTC/play"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 批量创建摄像头(已废弃)
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/discovered/batch-create
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/discovered/batch-create
+
+描述:批量创建摄像头(已废弃)
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称          | 类型  | 必填 | 最大长度 | 描述                              | 示例值 |
+| ------------- | ----- | ---- | -------- | --------------------------------- | ------ |
+| discoveredIds | array | 否   | -        | 发现设备 ID 列表,[array of int64] | 0,0    |
+
+#### 请求示例
+
+```
+{
+    "discoveredIds": [
+        0,
+        0
+    ]
+}
+```
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                           | 示例值 |
+| ---------- | ------- | ---- | -------- | ------------------------------ | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                   | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)           |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)         |        |
+| data       | int32   | 否   | -        | 响应数据 (ActualType: Integer) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": 0
+}
+```
+
+#### 错误码
+
+无
+
+### 获取凭证列表
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `GET` http://localhost:10050/api/admin/credentials
+- 开发环境: `GET` https://tg-live-game.pwtk.cc/api/admin/credentials
+
+描述:获取凭证列表
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称           | 类型          | 必填 | 最大长度 | 描述                        | 示例值              |
+| -------------- | ------------- | ---- | -------- | --------------------------- | ------------------- |
+| success        | Boolean       | 否   | -        | 请求是否成功                | true                |
+| errCode        | String        | 否   | -        | 错误码(失败时返回)        |                     |
+| errMessage     | String        | 否   | -        | 错误信息(失败时返回)      |                     |
+| data           | array         | 否   |          | 响应数据 (ActualType: List) |                     |
+| └ id           | Long          | 否   | -        | ID                          | 1                   |
+| └ name         | String        | 否   | -        | 凭证名称                    | 默认凭证            |
+| └ username     | String        | 否   | -        | 用户名                      | admin               |
+| └ password     | String        | 否   | -        | 密码(列表时可能隐藏)      | 12345               |
+| └ vendor       | String        | 否   | -        | 适用厂商(空表示通用)      | HIKVISION           |
+| └ priority     | Integer       | 否   | -        | 优先级                      | 100                 |
+| └ enabled      | Boolean       | 否   | -        | 是否启用                    | true                |
+| └ remark       | String        | 否   | -        | 备注                        | 海康威视默认凭证    |
+| └ successCount | Integer       | 否   | -        | 成功匹配次数                | 10                  |
+| └ failCount    | Integer       | 否   | -        | 失败匹配次数                | 5                   |
+| └ createdAt    | LocalDateTime | 否   | -        | 创建时间                    | 2026-01-27T10:00:00 |
+| └ updatedAt    | LocalDateTime | 否   | -        | 更新时间                    | 2026-01-27T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": [
+        {
+            "id": 1,
+            "name": "默认凭证",
+            "username": "admin",
+            "password": "12345",
+            "vendor": "HIKVISION",
+            "priority": 100,
+            "enabled": true,
+            "remark": "海康威视默认凭证",
+            "successCount": 10,
+            "failCount": 5,
+            "createdAt": "2026-01-27T10:00:00",
+            "updatedAt": "2026-01-27T10:00:00"
+        }
+    ]
+}
+```
+
+#### 错误码
+
+无
+
+### 添加凭证
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/credentials
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/credentials
+
+描述:添加凭证
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称     | 类型    | 必填 | 最大长度 | 描述                         | 示例值           |
+| -------- | ------- | ---- | -------- | ---------------------------- | ---------------- |
+| name     | String  | 是   | -        | 凭证名称                     | 默认凭证         |
+| username | String  | 是   | -        | 用户名                       | admin            |
+| password | String  | 是   | -        | 密码                         | 12345            |
+| vendor   | String  | 否   | -        | 适用厂商(空表示通用)       | HIKVISION        |
+| priority | Integer | 否   | -        | 优先级(数字越小优先级越高) | 100              |
+| enabled  | Boolean | 否   | -        | 是否启用                     | true             |
+| remark   | String  | 否   | -        | 备注                         | 海康威视默认凭证 |
+
+#### 请求示例
+
+```
+{
+    "name": "默认凭证",
+    "username": "admin",
+    "password": "12345",
+    "vendor": "HIKVISION",
+    "priority": 100,
+    "enabled": true,
+    "remark": "海康威视默认凭证"
+}
+```
+
+#### 响应参数
+
+| 名称           | 类型          | 必填 | 最大长度 | 描述                                       | 示例值              |
+| -------------- | ------------- | ---- | -------- | ------------------------------------------ | ------------------- |
+| success        | Boolean       | 否   | -        | 请求是否成功                               | true                |
+| errCode        | String        | 否   | -        | 错误码(失败时返回)                       |                     |
+| errMessage     | String        | 否   | -        | 错误信息(失败时返回)                     |                     |
+| data           | object        | 否   |          | 响应数据 (ActualType: CameraCredentialDTO) |                     |
+| └ id           | Long          | 否   | -        | ID                                         | 1                   |
+| └ name         | String        | 否   | -        | 凭证名称                                   | 默认凭证            |
+| └ username     | String        | 否   | -        | 用户名                                     | admin               |
+| └ password     | String        | 否   | -        | 密码(列表时可能隐藏)                     | 12345               |
+| └ vendor       | String        | 否   | -        | 适用厂商(空表示通用)                     | HIKVISION           |
+| └ priority     | Integer       | 否   | -        | 优先级                                     | 100                 |
+| └ enabled      | Boolean       | 否   | -        | 是否启用                                   | true                |
+| └ remark       | String        | 否   | -        | 备注                                       | 海康威视默认凭证    |
+| └ successCount | Integer       | 否   | -        | 成功匹配次数                               | 10                  |
+| └ failCount    | Integer       | 否   | -        | 失败匹配次数                               | 5                   |
+| └ createdAt    | LocalDateTime | 否   | -        | 创建时间                                   | 2026-01-27T10:00:00 |
+| └ updatedAt    | LocalDateTime | 否   | -        | 更新时间                                   | 2026-01-27T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "name": "默认凭证",
+        "username": "admin",
+        "password": "12345",
+        "vendor": "HIKVISION",
+        "priority": 100,
+        "enabled": true,
+        "remark": "海康威视默认凭证",
+        "successCount": 10,
+        "failCount": 5,
+        "createdAt": "2026-01-27T10:00:00",
+        "updatedAt": "2026-01-27T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 更新凭证
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/credentials/update
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/credentials/update
+
+描述:更新凭证
+
+ContentType:`application/json`
+
+#### 请求参数
+
+##### Body Parameter
+
+| 名称     | 类型    | 必填 | 最大长度 | 描述     | 示例值           |
+| -------- | ------- | ---- | -------- | -------- | ---------------- |
+| id       | Long    | 是   | -        | 凭证 ID  | 1                |
+| name     | String  | 否   | -        | 凭证名称 | 默认凭证         |
+| username | String  | 否   | -        | 用户名   | admin            |
+| password | String  | 否   | -        | 密码     | 12345            |
+| vendor   | String  | 否   | -        | 适用厂商 | HIKVISION        |
+| priority | Integer | 否   | -        | 优先级   | 100              |
+| enabled  | Boolean | 否   | -        | 是否启用 | true             |
+| remark   | String  | 否   | -        | 备注     | 海康威视默认凭证 |
+
+#### 请求示例
+
+```
+{
+    "id": 1,
+    "name": "默认凭证",
+    "username": "admin",
+    "password": "12345",
+    "vendor": "HIKVISION",
+    "priority": 100,
+    "enabled": true,
+    "remark": "海康威视默认凭证"
+}
+```
+
+#### 响应参数
+
+| 名称           | 类型          | 必填 | 最大长度 | 描述                                       | 示例值              |
+| -------------- | ------------- | ---- | -------- | ------------------------------------------ | ------------------- |
+| success        | Boolean       | 否   | -        | 请求是否成功                               | true                |
+| errCode        | String        | 否   | -        | 错误码(失败时返回)                       |                     |
+| errMessage     | String        | 否   | -        | 错误信息(失败时返回)                     |                     |
+| data           | object        | 否   |          | 响应数据 (ActualType: CameraCredentialDTO) |                     |
+| └ id           | Long          | 否   | -        | ID                                         | 1                   |
+| └ name         | String        | 否   | -        | 凭证名称                                   | 默认凭证            |
+| └ username     | String        | 否   | -        | 用户名                                     | admin               |
+| └ password     | String        | 否   | -        | 密码(列表时可能隐藏)                     | 12345               |
+| └ vendor       | String        | 否   | -        | 适用厂商(空表示通用)                     | HIKVISION           |
+| └ priority     | Integer       | 否   | -        | 优先级                                     | 100                 |
+| └ enabled      | Boolean       | 否   | -        | 是否启用                                   | true                |
+| └ remark       | String        | 否   | -        | 备注                                       | 海康威视默认凭证    |
+| └ successCount | Integer       | 否   | -        | 成功匹配次数                               | 10                  |
+| └ failCount    | Integer       | 否   | -        | 失败匹配次数                               | 5                   |
+| └ createdAt    | LocalDateTime | 否   | -        | 创建时间                                   | 2026-01-27T10:00:00 |
+| └ updatedAt    | LocalDateTime | 否   | -        | 更新时间                                   | 2026-01-27T10:00:00 |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {
+        "id": 1,
+        "name": "默认凭证",
+        "username": "admin",
+        "password": "12345",
+        "vendor": "HIKVISION",
+        "priority": 100,
+        "enabled": true,
+        "remark": "海康威视默认凭证",
+        "successCount": 10,
+        "failCount": 5,
+        "createdAt": "2026-01-27T10:00:00",
+        "updatedAt": "2026-01-27T10:00:00"
+    }
+}
+```
+
+#### 错误码
+
+无
+
+### 删除凭证
+
+维护人:TG Live
+
+#### URL
+
+- 本地开发环境: `POST` http://localhost:10050/api/admin/credentials/{id}/delete
+- 开发环境: `POST` https://tg-live-game.pwtk.cc/api/admin/credentials/{id}/delete
+
+描述:删除凭证
+
+ContentType:`application/x-www-form-urlencoded;charset=UTF-8`
+
+#### Path 参数
+
+| 名称 | 必填 | 描述    | 示例值 |
+| ---- | ---- | ------- | ------ |
+| id   | 是   | 凭证 ID | 0      |
+
+#### 请求参数
+
+#### 响应参数
+
+| 名称       | 类型    | 必填 | 最大长度 | 描述                        | 示例值 |
+| ---------- | ------- | ---- | -------- | --------------------------- | ------ |
+| success    | Boolean | 否   | -        | 请求是否成功                | true   |
+| errCode    | String  | 否   | -        | 错误码(失败时返回)        |        |
+| errMessage | String  | 否   | -        | 错误信息(失败时返回)      |        |
+| data       | object  | 否   | -        | 响应数据 (ActualType: Void) |        |
+
+#### 响应示例
+
+```
+{
+    "success": true,
+    "errCode": "string",
+    "errMessage": "string",
+    "data": {}
+}
+```
+
+#### 错误码
+
+无

+ 30 - 4
src/views/lss/index.vue

@@ -80,13 +80,13 @@
         </el-table-column>
         <el-table-column :label="t('操作')" width="130" align="center" fixed="right">
           <template #default="{ row }">
-            <el-button type="primary" link @click="handleEdit(row, 'detail')">
+            <el-button data-id="btn-edit" type="primary" link @click="handleEdit(row, 'detail')">
               <Icon icon="mdi:note-edit-outline" width="20" height="20" />
             </el-button>
-            <el-button type="primary" link @click="handleScanDevices(row)">
+            <el-button data-id="btn-scan-devices" type="primary" link @click="handleScanDevices(row)">
               <Icon icon="mdi:radar" width="20" height="20" />
             </el-button>
-            <el-button type="danger" link @click="handleDelete(row)">
+            <el-button data-id="btn-delete" type="danger" link @click="handleDelete(row)">
               <Icon icon="mdi:delete" width="20" height="20" />
             </el-button>
           </template>
@@ -515,7 +515,13 @@
               :disabled="isEditCamera"
               :placeholder="t('请输入设备ID')"
               style="max-width: 300px"
-            />
+            >
+              <template v-if="!isEditCamera" #suffix>
+                <el-icon class="generate-id-btn" @click="generateCameraId">
+                  <Icon icon="mdi:refresh" />
+                </el-icon>
+              </template>
+            </el-input>
           </el-form-item>
           <el-form-item :label="t('设备名称') + ':'" prop="cameraName">
             <el-input v-model="cameraForm.cameraName" :placeholder="t('请输入设备名称')" style="max-width: 300px" />
@@ -1200,6 +1206,16 @@ function handleVendorSelect(vendorId: number) {
   }
 }
 
+function generateCameraId() {
+  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
+  const prefix = 'CAM-'
+  let id = ''
+  for (let i = 0; i < 6; i++) {
+    id += chars.charAt(Math.floor(Math.random() * chars.length))
+  }
+  cameraForm.cameraId = prefix + id
+}
+
 async function handleAddCamera() {
   isEditCamera.value = false
   currentCamera.value = null
@@ -1477,6 +1493,16 @@ onMounted(() => {
   justify-content: flex-end;
 }
 
+.generate-id-btn {
+  cursor: pointer;
+  color: #909399;
+  transition: color 0.2s;
+
+  &:hover {
+    color: var(--el-color-primary);
+  }
+}
+
 .status-text {
   font-size: 12px;
 }