Files
front/3D机房前后端接口文档.md
2026-08-24 22:02:55 +08:00

1124 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 3D 机房前后端接口对接文档
本文档依据 2026-07-31 工作区内 `assets``dc-control``alert` 的实际代码整理,供前端开发和联调使用。
## 1. 对接范围
3D 机房由 `Assets` 服务提供统一场景接口,支持:
- 加载单个机房或全部有权限的 3D 场景。
- 保存机房长、宽、高。
- 拖拽机柜并保存三维坐标。
- 将设备放入机柜并调整 U 位。
- 将智能空调、监控摄像头、智能插座等设备直接放置在机房内。
- 解除设备在机柜或机房内的位置。
- 查看设备运行状态、最新指标和活动告警。
- 将资产与 `dc-control` 监控资源绑定。
前端渲染和写入场景时主要访问 `Assets``Assets` 会在后台聚合 `dc-control``alert`,前端不直接调用运行状态及活动告警的内部批量接口。
## 2. 通用约定
### 2.1 基础地址和请求头
本文使用 `{API_BASE}` 表示网关地址,例如:
```text
{API_BASE}/Assets/v1/three-d/rooms/1/scene
```
所有本文列出的接口均需要 JWT
```http
Authorization: Bearer <token>
Content-Type: application/json
```
GET 请求不需要设置 `Content-Type`。DELETE 设备位置接口需要携带 JSON 请求体。
### 2.2 统一响应结构
成功响应:
```json
{
"code": 0,
"message": "",
"details": {},
"timeseq": 1785465600000
}
```
失败响应示例:
```json
{
"code": 500,
"message": "布局版本已变化,当前版本为 5",
"details": "",
"timeseq": 1785465600000
}
```
注意:
- 业务成功以 `code === 0` 为准。
- 当前统一响应即使业务失败HTTP 状态通常仍为 `200`,不能只判断 HTTP 状态。
- 失败时直接展示或记录 `message``details` 不承载错误详情。
- `timeseq` 是毫秒时间戳。
### 2.3 数据权限
3D 接口从 JWT 扩展声明中读取数据范围:
| JWT 扩展字段 | 示例 | 含义 |
| --- | --- | --- |
| `data_scope_all` | `"true"` | 可访问全部机房 |
| `data_scope_datacenter_ids` | `"1,2"` | 可访问指定数据中心 |
| `data_scope_room_ids` | `"10,11"` | 可访问指定机房 |
规则:
- 仅配置数据中心范围时,该数据中心下的机房可访问。
- 仅配置机房范围时,指定机房可访问。
- 两种范围同时存在时,数据中心和机房必须同时匹配。
- 三个字段均未提供时3D 接口返回“登录凭证缺少机房数据权限”。
- 前端不能通过自定义请求头或查询参数扩大数据范围。
### 2.4 坐标和尺寸
坐标系约定:
- `X`:机房长度方向。
- `Y`:高度方向。
- `Z`:机房宽度方向。
- 场景坐标、机房尺寸和独立设备尺寸单位均为米。
- `position_x/y/z` 表示物体底面中心点,不是包围盒中心点。
- 设备旋转角度单位为度,合法范围为 `[0, 360)`,旋转顺序为 X、Y、Z。
- 机柜只允许绕 Y 轴旋转。
- 传入的小数会四舍五入到两位后再校验和保存。
机柜尺寸:
- `width_mm``depth_mm` 的单位是毫米。
- `height` 的单位是 U。
- 后端进行空间碰撞校验时,机柜高度按 `height × 0.04445` 米计算。
边界范围:
```text
X: 0 ~ scene_length
Y: 0 ~ scene_height
Z: 0 ~ scene_width
```
后端会对机柜和机房内独立设备做完整三维有向包围盒校验,包括越界、机柜与机柜、机柜与独立设备、独立设备与独立设备的重叠。物体边界接触允许,空间重叠不允许。
机柜内设备不参与场景包围盒碰撞,其位置由机柜和 U 位约束。
### 2.5 布局版本和并发控制
每个机房包含 `layout_version`。以下写接口都必须提交当前版本:
- 保存机房 3D 配置。
- 保存机柜布局。
- 保存设备位置。
- 解除设备位置。
每次成功写入后版本加一,响应会返回新的 `layout_version`
前端处理规则:
1. 加载场景后保存 `room.layout_version`
2. 同一个机房的写请求串行发送。
3. 写入成功后,用响应中的 `layout_version` 更新本地版本。
4. 收到“布局版本已变化”时,重新调用场景接口获取最新数据,不覆盖服务端的新布局。
## 3. 接口总览
### 3.1 3D 核心接口
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/Assets/v1/three-d/export` | 获取权限范围内全部 3D 场景 |
| GET | `/Assets/v1/three-d/rooms/:room_id/scene` | 获取单个机房场景 |
| PUT | `/Assets/v1/three-d/rooms/:room_id/config` | 保存机房尺寸及初始机柜位置 |
| PUT | `/Assets/v1/three-d/rooms/:room_id/layout` | 批量保存机柜位置 |
| PUT | `/Assets/v1/three-d/rooms/:room_id/devices/:asset_id/placement` | 保存设备的机柜或机房位置 |
| DELETE | `/Assets/v1/three-d/rooms/:room_id/devices/:asset_id/placement` | 解除设备位置 |
| GET | `/Assets/v1/three-d/rooms/:room_id/signals` | 获取机房设备状态和告警摘要 |
| GET | `/Assets/v1/three-d/devices/:asset_id/observability` | 获取设备状态、指标和告警详情 |
### 3.2 资源绑定接口
| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/DC-Control/v1/resources/options` | 查询可绑定监控资源选项 |
| POST | `/Assets/v1/asset/resource/link` | 绑定资产与监控资源 |
| GET | `/Assets/v1/asset/resource/:asset_id` | 查询资产资源绑定 |
| DELETE | `/Assets/v1/asset/resource/:asset_id` | 解除资产资源绑定 |
## 4. 场景数据结构
### 4.1 `RoomScene`
```json
{
"room": {
"id": 1,
"datacenter_id": 1,
"floor_id": 2,
"name": "一号机房",
"code": "ROOM-001",
"scene_length": 20,
"scene_width": 12,
"scene_height": 4,
"layout_version": 4
},
"racks": [],
"room_devices": [],
"summary": {
"rack_count": 0,
"unit_count": 0,
"rack_device_count": 0,
"room_device_count": 0,
"device_count": 0
}
}
```
### 4.2 `SceneRack`
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | number | 机柜 ID |
| `name` | string | 机柜名称 |
| `code` | string | 机柜编码 |
| `row` | number | 业务行号,不直接参与空间校验 |
| `column` | number | 业务列号,不直接参与空间校验 |
| `height` | number | 机柜高度,单位 U |
| `width_mm` | number | 机柜宽度,毫米 |
| `depth_mm` | number | 机柜深度,毫米 |
| `status` | string | 机柜状态 |
| `transform` | object | 三维位置和旋转 |
| `utilization_rate` | number | U 位使用率百分比,占用和预留 U 位均计入 |
| `units` | array | 全部 U 位,按 `unit_number` 升序 |
| `devices` | array | 机柜中已上架设备,每台设备只出现一次 |
机柜 `transform` 固定包含全部轴,当前仅 `rotation_y` 可写:
```json
{
"position_x": 2,
"position_y": 0,
"position_z": 3,
"rotation_x": 0,
"rotation_y": 90,
"rotation_z": 0
}
```
U 位结构:
```json
{
"id": 1001,
"unit_number": 10,
"status": "occupied",
"asset_id": 201
}
```
`status` 可见值包括:
- `available`:可用。
- `occupied`:已占用。
- `reserved`:已预留。
- `disabled`:已禁用。
U 位编号从 1 开始,自下向上递增。多 U 设备会在连续多个 `units` 项中使用相同 `asset_id`,但只在 `rack.devices` 中出现一次。
### 4.3 `SceneDevice`
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `asset_id` | number | 资产 ID |
| `asset_code` | string | 资产编码 |
| `asset_name` | string | 资产名称 |
| `category_id` | number/null | 资产分类 ID |
| `category_code` | string | 资产分类编码 |
| `category_name` | string | 资产分类名称 |
| `placement_type` | string | `rack``room` |
| `rack_id` | number/null | 所属机柜,独立设备为 `null` |
| `unit_start` | number/null | 起始 U 位 |
| `unit_end` | number/null | 结束 U 位 |
| `occupied_units` | number | 占用 U 位数;独立设备为 0 |
| `power_consumption` | number | 机柜设备功耗,单位 W |
| `transform` | object/省略 | 独立设备的三维位置,机柜设备不返回 |
| `size` | object/省略 | 独立设备的尺寸,机柜设备不返回 |
| `bindings` | array | 绑定的监控资源 |
独立设备尺寸结构:
```json
{
"width": 1.2,
"height": 2,
"depth": 0.8
}
```
监控资源绑定结构:
```json
{
"resource_uid": "room_device:ac-01",
"resource_category": "room_device",
"service_identity": "ac-01",
"display_name": "一号智能空调",
"business_system_id": null
}
```
## 5. 获取单个机房场景
```http
GET /Assets/v1/three-d/rooms/{room_id}/scene
```
路径参数:
| 参数 | 类型 | 说明 |
| --- | --- | --- |
| `room_id` | 正整数 | 机房 ID |
成功响应的 `details`
```json
{
"room": {
"id": 1,
"datacenter_id": 1,
"floor_id": 2,
"name": "一号机房",
"code": "ROOM-001",
"scene_length": 20,
"scene_width": 12,
"scene_height": 4,
"layout_version": 4
},
"racks": [
{
"id": 101,
"name": "A01机柜",
"code": "RACK-A01",
"row": 1,
"column": 1,
"height": 42,
"width_mm": 600,
"depth_mm": 1000,
"status": "in_use",
"transform": {
"position_x": 2,
"position_y": 0,
"position_z": 2,
"rotation_x": 0,
"rotation_y": 0,
"rotation_z": 0
},
"utilization_rate": 4.761904761904762,
"units": [
{
"id": 1001,
"unit_number": 1,
"status": "available",
"asset_id": null
},
{
"id": 1010,
"unit_number": 10,
"status": "occupied",
"asset_id": 201
}
],
"devices": [
{
"asset_id": 201,
"asset_code": "SRV-001",
"asset_name": "应用服务器01",
"category_id": 5,
"category_code": "server",
"category_name": "服务器",
"placement_type": "rack",
"rack_id": 101,
"unit_start": 10,
"unit_end": 11,
"occupied_units": 2,
"power_consumption": 850,
"bindings": [
{
"resource_uid": "server:srv-001",
"resource_category": "server",
"service_identity": "srv-001",
"display_name": "应用服务器01",
"business_system_id": null
}
]
}
]
}
],
"room_devices": [
{
"asset_id": 301,
"asset_code": "AC-001",
"asset_name": "一号智能空调",
"category_id": 12,
"category_code": "air_conditioner",
"category_name": "智能空调",
"placement_type": "room",
"rack_id": null,
"unit_start": null,
"unit_end": null,
"occupied_units": 0,
"power_consumption": 0,
"transform": {
"position_x": 8,
"position_y": 0,
"position_z": 2,
"rotation_x": 0,
"rotation_y": 90,
"rotation_z": 0
},
"size": {
"width": 1.2,
"height": 2,
"depth": 0.8
},
"bindings": [
{
"resource_uid": "room_device:ac-01",
"resource_category": "room_device",
"service_identity": "ac-01",
"display_name": "一号智能空调",
"business_system_id": null
}
]
}
],
"summary": {
"rack_count": 1,
"unit_count": 42,
"rack_device_count": 1,
"room_device_count": 1,
"device_count": 2
}
}
```
说明:
- 示例为便于阅读只展示了部分 U 位,实际响应返回机柜全部 U 位。
- 如果机房尚未完成 3D 配置,三个场景尺寸可能为 0。前端应进入初始化配置流程。
- 场景接口不包含实时运行状态和告警,加载完成后再调用机房信号接口叠加状态。
## 6. 保存机房 3D 配置
```http
PUT /Assets/v1/three-d/rooms/{room_id}/config
```
请求体:
```json
{
"expected_version": 1,
"scene_length": 20,
"scene_width": 12,
"scene_height": 4,
"racks": [
{
"rack_id": 101,
"row": 1,
"column": 1,
"position_x": 2,
"position_y": 0,
"position_z": 2,
"rotation_y": 0
}
]
}
```
字段说明:
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `expected_version` | 是 | 当前布局版本,必须大于 0 |
| `scene_length` | 是 | 机房长度,米,必须大于 0 |
| `scene_width` | 是 | 机房宽度,米,必须大于 0 |
| `scene_height` | 是 | 机房高度,米,必须大于 0 |
| `racks` | 条件必填 | 机柜位置列表 |
首次配置规则:
- 如果机房已有机柜,必须一次提交该机房全部机柜的位置。
- 同一个 `rack_id` 不能重复。
- 所有机柜必须属于当前机房。
- 保存前会统一验证全部机柜是否越界或重叠。
已配置机房再次修改尺寸时,`racks` 可以为空或只包含需要同步调整的机柜,但后端仍会使用新尺寸验证全部已有机柜和独立设备。
成功响应的 `details`
```json
{
"room_id": 1,
"layout_version": 2
}
```
## 7. 批量保存机柜布局
用于机柜拖拽结束后保存一个或多个机柜的位置。
```http
PUT /Assets/v1/three-d/rooms/{room_id}/layout
```
请求体:
```json
{
"expected_version": 2,
"racks": [
{
"rack_id": 101,
"row": 1,
"column": 1,
"position_x": 3.25,
"position_y": 0,
"position_z": 2.5,
"rotation_y": 90
},
{
"rack_id": 102,
"row": 1,
"column": 2,
"position_x": 5,
"position_y": 0,
"position_z": 2.5,
"rotation_y": 90
}
]
}
```
规则:
- `racks` 不能为空,可以只提交本次变化的机柜。
- `position_x/y/z` 不能小于 0。
- `rotation_y` 范围为 `[0, 360)`
- 后端将未提交机柜的原位置和本次候选位置一起进行全场景校验。
- 任一机柜失败时整批请求回滚,不会保存部分结果。
成功响应的 `details`
```json
{
"room_id": 1,
"layout_version": 3
}
```
## 8. 保存设备位置
```http
PUT /Assets/v1/three-d/rooms/{room_id}/devices/{asset_id}/placement
```
同一接口通过 `placement_type` 区分机柜设备和机房内独立设备。
### 8.1 放入机柜或调整上架位置
请求体:
```json
{
"expected_version": 3,
"placement_type": "rack",
"rack_id": 101,
"start_unit": 10,
"occupied_units": 2,
"power_consumption": 850
}
```
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `expected_version` | 是 | 当前布局版本 |
| `placement_type` | 是 | 固定为 `rack` |
| `rack_id` | 是 | 目标机柜 ID |
| `start_unit` | 是 | 起始 U 位,从 1 开始 |
| `occupied_units` | 是 | 连续占用 U 位数,必须大于 0 |
| `power_consumption` | 是 | 设备功耗,单位 W可为 0不能为负数 |
校验规则:
- 目标机柜必须属于路径中的机房。
- U 位范围必须完整、连续且可用。
- 调整同一设备的位置时,设备当前占用的 U 位可以作为本次目标位置的一部分。
- 机柜配置了 `power_capacity` 时,会校验调整后的剩余电力容量。机柜容量及已用电力单位为 kW请求功耗单位为 W。
- 从一个机柜移动到另一个机柜时,原 U 位和原机柜功耗会在同一事务中释放。
### 8.2 放置在机房内
智能空调、摄像头、智能插座等不在机柜中的设备使用 `room`
```json
{
"expected_version": 3,
"placement_type": "room",
"position_x": 8,
"position_y": 0,
"position_z": 2,
"rotation_x": 0,
"rotation_y": 90,
"rotation_z": 0,
"scene_width": 1.2,
"scene_height": 2,
"scene_depth": 0.8
}
```
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `expected_version` | 是 | 当前布局版本 |
| `placement_type` | 是 | 固定为 `room` |
| `position_x/y/z` | 是 | 设备底面中心坐标,米,不能为负数 |
| `rotation_x/y/z` | 是 | 三轴旋转角度,范围 `[0, 360)` |
| `scene_width` | 是 | 设备本地 X 轴尺寸,米,必须大于 0 |
| `scene_height` | 是 | 设备本地 Y 轴尺寸,米,必须大于 0 |
| `scene_depth` | 是 | 设备本地 Z 轴尺寸,米,必须大于 0 |
保存时会校验设备是否越界,以及是否与机柜或其他独立设备重叠。从机柜移到机房内时,原 U 位和功耗会在同一事务中释放。
### 8.3 跨机房限制
已经放置在其他机房的设备不能直接移动到当前机房。必须先调用原机房的解除位置接口,再使用当前机房的 `layout_version` 放置。
### 8.4 成功响应
两种放置方式的成功响应结构相同:
```json
{
"room_id": 1,
"asset_id": 201,
"placement_type": "rack",
"layout_version": 4
}
```
## 9. 解除设备位置
```http
DELETE /Assets/v1/three-d/rooms/{room_id}/devices/{asset_id}/placement
```
请求体:
```json
{
"expected_version": 4
}
```
规则:
- 设备必须已放置在路径指定的机房。
- 机柜设备会释放原 U 位和机柜功耗。
- 解除后资产的机房、机柜、U 位、三维坐标、旋转和尺寸均清空。
- 解除后的 `placement_type``unplaced`
成功响应的 `details`
```json
{
"room_id": 1,
"asset_id": 201,
"placement_type": "unplaced",
"layout_version": 5
}
```
## 10. 获取机房设备信号
该接口用于给整个 3D 场景批量叠加设备颜色、状态标识和告警角标。
```http
GET /Assets/v1/three-d/rooms/{room_id}/signals
```
成功响应的 `details`
```json
{
"room_id": 1,
"signals": [
{
"asset_id": 201,
"status": "warning",
"active_alert_count": 2,
"highest_alert_severity": {
"name": "严重",
"code": "critical",
"color": "#F5222D",
"priority": 1
},
"resources": [
{
"resource_uid": "server:srv-001",
"resource_category": "server",
"service_identity": "srv-001",
"display_name": "应用服务器01",
"status": "warning",
"metrics": []
}
],
"alerts": [
{
"resource_uid": "server:srv-001",
"active_count": 2,
"highest_severity": {
"name": "严重",
"code": "critical",
"color": "#F5222D",
"priority": 1
},
"alerts": [
{
"id": 9001,
"alert_name": "CPU使用率过高",
"summary": "CPU使用率持续超过阈值",
"severity": {
"name": "严重",
"code": "critical",
"color": "#F5222D",
"priority": 1
},
"status": "firing",
"starts_at": "2026-07-31T09:00:00+08:00",
"last_seen_at": "2026-07-31T09:05:00+08:00",
"updated_at": "2026-07-31T09:05:00+08:00"
}
]
}
]
}
]
}
```
信号状态取值:
| 状态 | 含义 |
| --- | --- |
| `unbound` | 资产没有绑定任何监控资源 |
| `unknown` | 已绑定资源,但没有可用运行数据,或出现未识别状态 |
| `healthy` | 所有可用资源状态正常 |
| `warning` | 至少一个资源为警告或降级,且没有异常资源 |
| `abnormal` | 至少一个资源为离线、错误或严重异常 |
后端状态映射:
- 异常:`offline``down``error``critical``unhealthy``failed`
- 警告:`warning``degraded`
- 健康:`online``up``healthy``normal``running``success`
告警规则:
- `active_alert_count` 是该资产全部绑定资源的活动告警数量之和。
- `highest_alert_severity``priority` 数字最小的最高级别。
- 机房信号接口每个资源最多返回最近 3 条活动告警。
- 活动告警包括 `pending``firing``acked``silenced``suppressed`,已恢复告警不返回。
- 该接口不查询指标,因此资源的 `metrics``[]`
当前 3D 接口没有 WebSocket 推送。前端需要刷新状态时,应轮询机房信号接口,不要为场景内每台设备并发调用设备详情接口。
## 11. 获取设备可观测详情
用户在 3D 场景选中设备后调用:
```http
GET /Assets/v1/three-d/devices/{asset_id}/observability
```
成功响应的 `details`
```json
{
"device": {
"asset_id": 201,
"asset_code": "SRV-001",
"asset_name": "应用服务器01",
"category_id": 5,
"category_code": "server",
"category_name": "服务器",
"placement_type": "rack",
"rack_id": 101,
"unit_start": 10,
"unit_end": 11,
"occupied_units": 2,
"power_consumption": 850,
"bindings": [
{
"resource_uid": "server:srv-001",
"resource_category": "server",
"service_identity": "srv-001",
"display_name": "应用服务器01",
"business_system_id": null
}
]
},
"resources": [
{
"resource_uid": "server:srv-001",
"resource_category": "server",
"service_identity": "srv-001",
"display_name": "应用服务器01",
"status": "online",
"metrics_at": "2026-07-31T09:05:00+08:00",
"metrics": [
{
"name": "cpu_usage",
"value": 63.5,
"unit": "%",
"type": "gauge",
"timestamp": "2026-07-31T09:05:00+08:00"
}
]
}
],
"alerts": [
{
"resource_uid": "server:srv-001",
"active_count": 1,
"highest_severity": {
"name": "警告",
"code": "warning",
"color": "#FAAD14",
"priority": 2
},
"alerts": []
}
]
}
```
说明:
- `device` 使用与场景接口相同的 `SceneDevice` 结构。
- `resources` 返回每个绑定资源的当前状态和最近一批指标。
- 没有指标的资源返回 `metrics: []`,并省略 `metrics_at`
- 每个资源最多返回最近 20 条活动告警。
- 资产未绑定监控资源时,`resources``alerts` 均为 `[]`
## 12. 导出全部 3D 场景
```http
GET /Assets/v1/three-d/export
```
用于一次获取当前 JWT 数据范围内已启用的数据中心和机房场景。它不包含实时状态、指标和告警。
成功响应的 `details`
```json
{
"datacenters": [
{
"id": 1,
"name": "北京数据中心",
"code": "DC-BJ-01",
"status": "running",
"latitude": "39.9042",
"longitude": "116.4074",
"rooms": []
}
],
"summary": {
"datacenter_count": 1,
"room_count": 2,
"rack_count": 30,
"unit_count": 1260,
"device_count": 150
}
}
```
`rooms` 中每一项都是完整的 `RoomScene`
## 13. 资产与监控资源绑定
设备只有绑定 `dc-control` 统一监控资源后3D 页面才能展示该设备的实时状态、指标和活动告警。一个资产可以绑定多个资源,一个 `resource_uid` 在全局只能绑定一个资产。
### 13.1 查询可绑定资源
```http
GET /DC-Control/v1/resources/options?resource_category=room_device
```
查询参数:
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `resource_category` | 否 | 按资源分类过滤;不传时返回全部分类,最多 500 条 |
成功响应的 `details`
```json
{
"list": [
{
"id": 501,
"label": "一号智能空调",
"value": "room_device:ac-01"
}
],
"count": 1
}
```
其中 `value` 就是绑定接口需要的 `resource_uid`
当前可查询运行状态的资源分类包括:
- `host`
- `server`
- `pc`
- `database`
- `middleware`
- `url`
- `network`
- `security`
- `storage`
- `room_device`
智能空调、监控摄像头、智能插座等机房设备统一使用 `room_device` 资源分类,具体设备类型由 `dc-control` 中的机房设备分类区分。
### 13.2 绑定资源
```http
POST /Assets/v1/asset/resource/link
```
请求体:
```json
{
"asset_id": 301,
"resource_uid": "room_device:ac-01",
"display_name": "一号智能空调",
"business_system_id": null
}
```
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `asset_id` | 是 | 资产 ID |
| `resource_uid` | 是 | 格式为 `category:identity` |
| `display_name` | 否 | 为空时使用 `dc-control` 中的资源名称 |
| `business_system_id` | 否 | 关联业务系统 ID |
后端会实时调用 `dc-control` 验证资源存在。重复提交同一资产和资源会更新绑定;资源已绑定其他资产时返回错误。
成功响应的 `details` 包含绑定记录,例如:
```json
{
"id": 100,
"created_at": "2026-07-31T09:00:00+08:00",
"updated_at": "2026-07-31T09:00:00+08:00",
"asset_id": 301,
"resource_uid": "room_device:ac-01",
"resource_category": "room_device",
"service_identity": "ac-01",
"display_name": "一号智能空调",
"business_system_id": null,
"health_status": "online",
"alert_status": "none",
"created_by": "admin",
"updated_by": "admin"
}
```
实时页面不要使用绑定记录中的 `health_status``alert_status` 作为实时值,应使用机房信号或设备可观测接口。
### 13.3 查询绑定
```http
GET /Assets/v1/asset/resource/{asset_id}
```
成功响应的 `details` 是绑定记录数组:
```json
[
{
"id": 100,
"asset_id": 301,
"resource_uid": "room_device:ac-01",
"resource_category": "room_device",
"service_identity": "ac-01",
"display_name": "一号智能空调",
"business_system_id": null,
"health_status": "online",
"alert_status": "none",
"created_by": "admin",
"updated_by": "admin",
"created_at": "2026-07-31T09:00:00+08:00",
"updated_at": "2026-07-31T09:00:00+08:00"
}
]
```
### 13.4 解除绑定
```http
DELETE /Assets/v1/asset/resource/{asset_id}?resource_uid=room_device%3Aac-01
```
`resource_uid` 必须放在查询参数中,并进行 URL 编码。
成功响应的 `details`
```json
"解除绑定成功"
```
## 14. 待放置资产
当前没有单独的 3D 待放置资产接口。可使用现有资产下拉接口:
```http
GET /Assets/v1/asset/all?keyword=
```
响应 `details` 是资产数组,前端可按以下条件筛选:
```text
placement_type === "unplaced"
```
`placement_type` 取值:
- `unplaced`:未放置。
- `rack`:已放入机柜。
- `room`:已放置在机房内。
前端筛选只用于交互最终能否放置仍由设备位置接口的数据权限、版本、机房归属、U 位、边界和碰撞校验决定。
## 15. 前端推荐调用流程
### 15.1 打开机房
1. 调用 `GET /three-d/rooms/{room_id}/scene` 加载几何场景。
2. 保存 `room.layout_version`
3. 如果机房尺寸为 0进入初始化配置否则渲染机房、机柜、机柜设备和独立设备。
4. 调用 `GET /three-d/rooms/{room_id}/signals` 叠加状态颜色和告警角标。
### 15.2 拖拽机柜
1. 前端本地计算候选坐标并更新预览。
2. 拖拽结束后调用机柜布局接口,可批量提交本次变更。
3. 成功后更新本地 `layout_version`;失败则恢复或重新加载场景。
### 15.3 设备上架或移动
1. 从待放置资产中选择设备,或选择场景内已有设备。
2. 放入机柜时提交 `rack` 请求和连续 U 位区间。
3. 放在机房内时提交 `room` 请求、完整坐标、旋转角度和物体尺寸。
4. 成功后更新 `layout_version`,再按需刷新场景和信号。
### 15.4 查看设备状态
1. 场景批量状态使用机房信号接口。
2. 用户点击设备时调用设备可观测接口。
3. 设备没有绑定资源时显示“未绑定监控资源”,不要显示为离线。
### 15.5 版本冲突
遇到以下任一消息时重新加载场景:
```text
布局版本已变化,当前版本为 N
布局版本已变化,请重新加载
```
不要用旧坐标自动覆盖新场景。需要保留用户拖拽意图时,应先获取新场景,再由用户确认重新应用。
## 16. 常见失败场景
| `message` 特征 | 前端处理建议 |
| --- | --- |
| `登录凭证缺少机房数据权限` | 提示权限配置问题,不重试写请求 |
| `无权访问该机房``无权移动该资产` | 提示无权限并退出编辑状态 |
| `布局版本已变化` | 重新加载场景和版本 |
| `机房三维长度、宽度和高度必须大于0` | 校验尺寸输入 |
| `首次配置...必须同时提交...全部机柜的位置` | 补齐当前机房全部机柜 |
| `超出机房三维边界` | 恢复物体到合法位置 |
| `发生空间重叠` | 调整位置后重试 |
| `目标U位...不可用` | 刷新场景或重新选择连续 U 位 |
| `目标机柜剩余电力容量不足` | 调整机柜或功耗值 |
| `资产属于其他机房` | 先在原机房解除位置 |
| `环境变量 DC_CONTROL_BASE_URL 未配置` | 后端部署配置问题 |
| `环境变量 ALERT_BASE_URL 未配置` | 后端部署配置问题 |
| `查询 dc-control 设备状态失败` | 状态聚合依赖异常,保留场景并提示状态暂不可用 |
| `查询 alert 活动告警失败` | 告警聚合依赖异常,保留场景并提示告警暂不可用 |
写请求是事务性的。任一校验或数据库操作失败时不会只保存部分机柜、U 位或设备位置。
## 17. 后端聚合依赖
以下接口由 `Assets` 后台调用,前端不直接调用:
| 服务 | 内部接口 | 用途 |
| --- | --- | --- |
| `dc-control` | `POST /DC-Control/v1/resources/runtime` | 按资源 UID 批量读取状态和最新指标 |
| `alert` | `POST /Alert/v1/record/active/by-resources` | 按资源 UID 批量读取活动告警 |
`Assets` 会转发前端请求中的 `Authorization`。聚合请求按每批 500 个资源处理,单个下游请求超时为 8 秒。
部署 `Assets` 时需要配置:
```text
DC_CONTROL_BASE_URL=<dc-control服务根地址>
ALERT_BASE_URL=<alert服务根地址>
```
## 18. 代码依据
本文档未读取项目既有文档,接口事实来自以下实际代码:
- `assets/internal/routers/register.go`
- `assets/internal/logic/three_d/types.go`
- `assets/internal/logic/three_d/scene.go`
- `assets/internal/logic/three_d/layout.go`
- `assets/internal/logic/three_d/placement.go`
- `assets/internal/logic/three_d/geometry.go`
- `assets/internal/logic/three_d/integration.go`
- `assets/internal/logic/three_d/scope.go`
- `assets/internal/logic/asset/resource_binding.go`
- `assets/internal/models/assets_asset.go`
- `assets/internal/models/assets_asset_resource_binding.go`
- `assets/internal/models/assets_rack.go`
- `assets/internal/models/assets_room.go`
- `dc-control/internal/routers/register.go`
- `dc-control/internal/logic/controllers/resource_controller.go`
- `dc-control/internal/logic/controllers/resource_runtime_controller.go`
- `dc-control/internal/logic/resource_runtime/runtime.go`
- `alert/internal/routers/register.go`
- `alert/internal/logic/record/resource.go`
- `bsm-sdk/core@v0.1.7/infra/response.go`