Files
front/3D机房前后端接口文档.md

1124 lines
30 KiB
Markdown
Raw Normal View History

2026-08-24 22:02:55 +08:00
# 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`