377 lines
7.3 KiB
Markdown
377 lines
7.3 KiB
Markdown
|
|
# 资产设备源地址前端对接文档
|
|||
|
|
|
|||
|
|
## 1. 变更说明
|
|||
|
|
|
|||
|
|
设备资产新增可选字段 `source_address`,界面名称为“源地址”。该字段适用于所有设备分类,可用于保存 RTSP、HTTP、HTTPS、HLS 等形式的播放源地址。
|
|||
|
|
|
|||
|
|
| 属性 | 内容 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| JSON 字段 | `source_address` |
|
|||
|
|
| TypeScript 类型 | `string` |
|
|||
|
|
| 是否必填 | 否 |
|
|||
|
|
| 最大长度 | 1000 个字符 |
|
|||
|
|
| 协议限制 | 无 |
|
|||
|
|
| 数据库字段 | `assets_assets.source_address` |
|
|||
|
|
| 数据库类型 | `varchar(1000)` |
|
|||
|
|
|
|||
|
|
前端不需要根据设备分类判断是否展示该字段。
|
|||
|
|
|
|||
|
|
## 2. 接口公共约定
|
|||
|
|
|
|||
|
|
资产接口基础路径:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
/Assets/v1/asset
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
请求头:
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
Authorization: Bearer <token>
|
|||
|
|
Content-Type: application/json
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
统一响应结构:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
interface ApiResponse<T> {
|
|||
|
|
code: number
|
|||
|
|
message: string
|
|||
|
|
details: T
|
|||
|
|
timeseq: number
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`code === 0` 表示请求成功,业务数据位于 `details`。
|
|||
|
|
|
|||
|
|
## 3. 前端类型
|
|||
|
|
|
|||
|
|
在资产表单类型中增加 `source_address`:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
export interface AssetForm {
|
|||
|
|
id?: number
|
|||
|
|
asset_name: string
|
|||
|
|
asset_code: string
|
|||
|
|
source_address?: string
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当前项目已经在 `src/api/ops/asset.ts` 的 `AssetForm` 中加入该字段。其他以资产对象为基础的详情、列表和批量导入数据可以直接复用该字段。
|
|||
|
|
|
|||
|
|
## 4. 创建设备资产
|
|||
|
|
|
|||
|
|
### 4.1 接口
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
POST /Assets/v1/asset/create
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 请求示例
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"asset_name": "东门监控摄像头",
|
|||
|
|
"asset_code": "CAMERA-001",
|
|||
|
|
"category_id": 12,
|
|||
|
|
"model": "DS-2CD3T",
|
|||
|
|
"manufacturer": "海康威视",
|
|||
|
|
"serial_number": "SN20260817001",
|
|||
|
|
"source_address": "rtsp://192.168.1.100:554/Streaming/Channels/101",
|
|||
|
|
"status": "in_use"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
未填写源地址时可以省略 `source_address`,也可以传空字符串:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"asset_name": "普通设备",
|
|||
|
|
"asset_code": "DEVICE-001",
|
|||
|
|
"source_address": ""
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.3 成功响应
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "",
|
|||
|
|
"details": {
|
|||
|
|
"id": 101,
|
|||
|
|
"asset_name": "东门监控摄像头",
|
|||
|
|
"asset_code": "CAMERA-001",
|
|||
|
|
"source_address": "rtsp://192.168.1.100:554/Streaming/Channels/101",
|
|||
|
|
"status": "in_use"
|
|||
|
|
},
|
|||
|
|
"timeseq": 1786932000000
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.4 调用方式
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
import { createAsset, type AssetForm } from '@/api/ops/asset'
|
|||
|
|
|
|||
|
|
const data: AssetForm = {
|
|||
|
|
asset_name: '东门监控摄像头',
|
|||
|
|
asset_code: 'CAMERA-001',
|
|||
|
|
source_address: 'rtsp://192.168.1.100:554/Streaming/Channels/101',
|
|||
|
|
status: 'in_use',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const response = await createAsset(data)
|
|||
|
|
if (response.code !== 0) {
|
|||
|
|
throw new Error(response.message || '创建设备失败')
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 5. 更新设备资产
|
|||
|
|
|
|||
|
|
### 5.1 接口
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
PUT /Assets/v1/asset/update
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 请求示例
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"id": 101,
|
|||
|
|
"asset_name": "东门监控摄像头",
|
|||
|
|
"asset_code": "CAMERA-001",
|
|||
|
|
"source_address": "https://video.example.com/live/camera-001.m3u8",
|
|||
|
|
"status": "in_use"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
更新接口需要同时传入:
|
|||
|
|
|
|||
|
|
- `id`
|
|||
|
|
- `asset_name`
|
|||
|
|
- `asset_code`
|
|||
|
|
|
|||
|
|
`source_address` 仍为选填字段。传入非空值时更新源地址;不传时保留原值。
|
|||
|
|
|
|||
|
|
当前后端使用 GORM 结构体更新,空字符串属于零值,因此传入 `source_address: ""` 不会清空已有源地址。前端暂时不要把“传空字符串”作为清空操作。
|
|||
|
|
|
|||
|
|
### 5.3 调用方式
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
import { updateAsset, type AssetForm } from '@/api/ops/asset'
|
|||
|
|
|
|||
|
|
const data: AssetForm = {
|
|||
|
|
id: 101,
|
|||
|
|
asset_name: '东门监控摄像头',
|
|||
|
|
asset_code: 'CAMERA-001',
|
|||
|
|
source_address: 'https://video.example.com/live/camera-001.m3u8',
|
|||
|
|
status: 'in_use',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const response = await updateAsset(data)
|
|||
|
|
if (response.code !== 0) {
|
|||
|
|
throw new Error(response.message || '更新设备失败')
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 6. 查询设备详情
|
|||
|
|
|
|||
|
|
### 6.1 接口
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
GET /Assets/v1/asset/detail/{id}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.2 成功响应
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "",
|
|||
|
|
"details": {
|
|||
|
|
"id": 101,
|
|||
|
|
"asset_name": "东门监控摄像头",
|
|||
|
|
"asset_code": "CAMERA-001",
|
|||
|
|
"source_address": "rtsp://192.168.1.100:554/Streaming/Channels/101",
|
|||
|
|
"status": "in_use"
|
|||
|
|
},
|
|||
|
|
"timeseq": 1786932000000
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
未填写源地址时,`source_address` 返回空字符串。
|
|||
|
|
|
|||
|
|
### 6.3 表单回填
|
|||
|
|
|
|||
|
|
当前编辑页面使用详情对象整体回填:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const response = await fetchAssetDetail(deviceId)
|
|||
|
|
if (response.code === 0) {
|
|||
|
|
form.value = { ...response.details } as AssetForm
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`source_address` 会随其他资产字段自动回填,不需要单独请求。
|
|||
|
|
|
|||
|
|
## 7. 分页查询设备资产
|
|||
|
|
|
|||
|
|
### 7.1 接口
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
POST /Assets/v1/asset/list
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.2 请求示例
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"page": 1,
|
|||
|
|
"page_size": 20,
|
|||
|
|
"keyword": "",
|
|||
|
|
"status": "in_use"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.3 响应示例
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 0,
|
|||
|
|
"message": "",
|
|||
|
|
"details": {
|
|||
|
|
"total": 1,
|
|||
|
|
"page": 1,
|
|||
|
|
"page_size": 20,
|
|||
|
|
"data": [
|
|||
|
|
{
|
|||
|
|
"id": 101,
|
|||
|
|
"asset_name": "东门监控摄像头",
|
|||
|
|
"asset_code": "CAMERA-001",
|
|||
|
|
"source_address": "rtsp://192.168.1.100:554/Streaming/Channels/101"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"timeseq": 1786932000000
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
以下接口返回的资产对象同样包含 `source_address`:
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
GET /Assets/v1/asset/page
|
|||
|
|
GET /Assets/v1/asset/all
|
|||
|
|
GET /Assets/v1/asset/export
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 8. 批量导入
|
|||
|
|
|
|||
|
|
### 8.1 接口
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
POST /Assets/v1/asset/bulk_import
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 8.2 请求示例
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"dry_run": false,
|
|||
|
|
"items": [
|
|||
|
|
{
|
|||
|
|
"asset_name": "西门监控摄像头",
|
|||
|
|
"asset_code": "CAMERA-002",
|
|||
|
|
"source_address": "rtsp://192.168.1.101:554/live",
|
|||
|
|
"status": "in_use"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
每个 `items` 元素都可以单独填写或省略 `source_address`。
|
|||
|
|
|
|||
|
|
## 9. 表单接入
|
|||
|
|
|
|||
|
|
### 9.1 默认值
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const form = ref<AssetForm>({
|
|||
|
|
asset_name: '',
|
|||
|
|
asset_code: '',
|
|||
|
|
source_address: '',
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 9.2 表单组件
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<a-form-item label="源地址" field="source_address">
|
|||
|
|
<a-input
|
|||
|
|
v-model="form.source_address"
|
|||
|
|
placeholder="请输入源地址"
|
|||
|
|
:max-length="1000"
|
|||
|
|
allow-clear
|
|||
|
|
/>
|
|||
|
|
</a-form-item>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
该字段不设置 `required` 规则,也不校验具体协议格式。
|
|||
|
|
|
|||
|
|
### 9.3 提交
|
|||
|
|
|
|||
|
|
新增和编辑直接复用现有资产提交逻辑:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const data = { ...form.value }
|
|||
|
|
|
|||
|
|
if (isEdit.value && deviceId.value) {
|
|||
|
|
await updateAsset({ ...data, id: deviceId.value })
|
|||
|
|
} else {
|
|||
|
|
await createAsset(data)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 10. 详情展示
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<a-descriptions-item label="源地址" :span="2">
|
|||
|
|
<span class="source-address">{{ device?.source_address || '-' }}</span>
|
|||
|
|
</a-descriptions-item>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
长地址需要允许换行:
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
.source-address {
|
|||
|
|
word-break: break-all;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 11. 播放功能使用建议
|
|||
|
|
|
|||
|
|
获取播放地址时直接读取资产对象的 `source_address`:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const sourceAddress = record.source_address?.trim()
|
|||
|
|
|
|||
|
|
if (!sourceAddress) {
|
|||
|
|
Message.warning('该设备未配置源地址')
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
前端不要自动补全协议、转换大小写或修改地址内容。具体播放器需要支持对应的流媒体协议,例如浏览器不能直接原生播放 RTSP 地址。
|
|||
|
|
|
|||
|
|
## 12. 对接检查项
|
|||
|
|
|
|||
|
|
- 新增设备时可以不填写源地址。
|
|||
|
|
- 新增设备时填写源地址后可以正常保存。
|
|||
|
|
- 编辑设备时能够正确回填源地址。
|
|||
|
|
- 编辑设备时修改源地址后可以正常保存。
|
|||
|
|
- 详情接口和详情弹窗能够显示源地址。
|
|||
|
|
- 列表接口返回的每条资产数据包含 `source_address`。
|
|||
|
|
- 超长地址能够在详情区域正常换行。
|
|||
|
|
- 接口失败时优先显示响应中的 `message`。
|