Files
junhong_cmp_fiber/.planning/phases/03.1-sync-info-phase-3-dto/03.1-01-SUMMARY.md
huang f9da1a937f docs(03.1-01): 完成 Phase 03.1 Plan 01 执行总结
- 创建 03.1-01-SUMMARY.md:记录 3 个任务完成情况、6 个文件修改、SwitchMode 类型偏差修复
- 更新 STATE.md:追加执行日志、补充 B/C 端独立 DTO 结构决策
2026-03-28 13:23:43 +08:00

186 lines
7.3 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.
---
phase: 03.1-sync-info-phase-3-dto
plan: "01"
subsystem: asset/device
tags:
- gateway
- dto
- device
- realtime
dependency_graph:
requires:
- Phase 3 DEVICE-01~04DB 字段写入已完成)
provides:
- 设备管理列表/详情返回 5 个 DB 缓存字段
- 设备绑卡列表返回 is_current 字段
- 资产 Resolve/Refresh BoundCardInfo 含 is_current
- admin 资产解析返回 5 个 DB 缓存字段
- GetRealtimeStatus device 类型实时调用 Gateway
- C 端 GetAssetInfo device_realtime 为真实 Gateway 数据
affects:
- GET /api/admin/devices新增 5 字段)
- GET /api/admin/devices/:id/cards新增 is_current
- GET /api/admin/assets/resolve/:identifier新增 5 字段 + is_current
- GET /api/admin/assets/:type/:id/realtime新增 device_realtime
- GET /api/c/v1/asset/infodevice_realtime 从 mock 改为真实数据)
tech_stack:
added: []
patterns:
- isCurrentMap 与 slotMap 同构模式asset/service.go
- strPtr() 辅助函数空字符串→nil防止 JSON 冗余字段)
- mapSyncRespToDeviceGatewayInfo() Gateway DTO → B端 DTO 映射
- mapDeviceGatewayInfoToClientInfo() B端 DTO → C端 DTO 映射
key_files:
created: []
modified:
- internal/gateway/models.go+16 行SyncDeviceInfoResp 补全 15 个字段)
- internal/model/dto/asset_dto.go+77 行DeviceGatewayInfo 新增AssetRealtimeStatusResponse.DeviceRealtime 新增AssetResolveResponse 5 字段新增)
- internal/service/device/service.go+5 行toDeviceResponse 补全 5 字段)
- internal/service/device/binding.go+1 行ListBindings IsCurrent 补全)
- internal/service/asset/service.go+84 行isCurrentMap 两处补全Gateway 实时调用mapSyncRespToDeviceGatewayInfostrPtr
- internal/handler/app/client_asset.go+113/-41 行mock 替换为真实 Gateway 调用mapDeviceGatewayInfoToClientInfo
decisions:
- DeviceGatewayInfoB端与 DeviceRealtimeInfoC端独立结构通过映射函数转换per D-08
- SwitchMode 在 B端为 *stringGateway 原始C端为 *int映射时使用 strconv.Atoi 转换
- strPtr() 在 asset/service.go 包内独立定义order/service.go 已有同名函数但不同包)
metrics:
duration: 5min
completed_date: "2026-03-28"
tasks: 3
files_modified: 6
---
# Phase 03.1 Plan 01: 设备读取链路修复 + DTO 映射补全 Summary
**一句话总结:** 补全 Phase 3 设备数据写入链路的读取侧缺口——6 个字段映射缺口修复 + Gateway sync-info 实时调用链路建立 + C端 mock 数据替换。
---
## 完成的任务
### Task 1补全 Gateway 模型和 B 端 DTO 契约
**`internal/gateway/models.go`(第 162-183 行):**
`SyncDeviceInfoResp` 新增 15 个缺失字段:
- 信号:`Rsrp``Rsrq``Sinr`
- WiFi`WifiPassword`
- 网络:`IPAddress``WANIP``LANIP`
- 连接:`MaxClients``ConnectTime`
- 设备:`Status``IMSI``ULStats``DLStats``LimitSpeed``SyncInterval`
**`internal/model/dto/asset_dto.go`**
1. 新增 `DeviceGatewayInfo` 结构体(第 138-188 行49 字段,全部含 `description` tagper D-08/D-09
2. `AssetRealtimeStatusResponse` 新增 `DeviceRealtime *DeviceGatewayInfo` 字段(第 77 行per D-07/D-08
3. `AssetResolveResponse` 新增 5 个设备 DB 缓存字段(第 44-49 行per D-12
- `OnlineStatus``LastOnlineTime``SoftwareVersion``SwitchMode``LastGatewaySyncAt`
---
### Task 2修复静态 DTO 映射缺口
**`internal/service/device/service.go``toDeviceResponse()`,第 559-563 行):**
补全 5 个 DB 缓存字段赋值:
```go
OnlineStatus: device.OnlineStatus,
LastOnlineTime: device.LastOnlineTime,
SoftwareVersion: device.SoftwareVersion,
SwitchMode: device.SwitchMode,
LastGatewaySyncAt: device.LastGatewaySyncAt,
```
**`internal/service/device/binding.go``ListBindings()`,第 60 行):**
```go
IsCurrent: binding.IsCurrent,
```
**`internal/service/asset/service.go`(两处修复):**
1. `buildDeviceResolveResponse()`(第 124-128 行):新增 `isCurrentMap` + `IsCurrent` + 5 个 DB 缓存字段
2. `GetRealtimeStatus()` device case第 274-279 行):新增 `isCurrentMap` + `IsCurrent`
两处均采用与现有 `slotMap` 同构的 `isCurrentMap` 模式:
```go
isCurrentMap := make(map[uint]bool, len(bindings))
// ...
isCurrentMap[b.IotCardID] = b.IsCurrent
// ...
IsCurrent: isCurrentMap[c.ID],
```
---
### Task 3建立设备实时 Gateway 调用链路
**`internal/service/asset/service.go`**
1. `GetRealtimeStatus()` device case 末尾(第 291-312 行)新增 Gateway 实时调用:
- `gatewayClient != nil` 安全检查
- IMEI 优先,无则用 SN与 Refresh 逻辑一致)
- 调用 `s.gatewayClient.SyncDeviceInfo(ctx, &gateway.SyncDeviceInfoReq{CardNo: cardNo})`
- 成功时调用 `mapSyncRespToDeviceGatewayInfo(syncResp)` 填充 `resp.DeviceRealtime`
- 失败时仅记录 Warn 日志,`DeviceRealtime` 保持 nilper D-06
2. 新增 `mapSyncRespToDeviceGatewayInfo()`(第 330-369 行Gateway resp → B端 DTO 映射
3. 新增 `strPtr()`(第 371-378 行):辅助函数,将空字符串转为 nil 指针
**`internal/handler/app/client_asset.go`**
1. `GetAssetInfo()`(第 188-197 行):删除 `buildMockDeviceRealtime()` 调用,替换为:
```go
realtimeResp, realtimeErr := h.assetService.GetRealtimeStatus(
c.UserContext(), "device", resp.AssetID,
)
if realtimeErr == nil && realtimeResp.DeviceRealtime != nil {
resp.DeviceRealtime = mapDeviceGatewayInfoToClientInfo(realtimeResp.DeviceRealtime)
}
```
2. 删除 `buildMockDeviceRealtime()` 函数(原第 595-635 行)
3. 新增 `mapDeviceGatewayInfoToClientInfo()`(第 595-660 行B端 DeviceGatewayInfo → C端 DeviceRealtimeInfo 映射
---
## 编译验证
```
go build ./... → 全量编译通过
go vet ./internal/gateway/... ./internal/model/dto/... ./internal/service/asset/... ./internal/service/device/... ./internal/handler/app/... → 无新增错误
```
---
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] SwitchMode 类型不匹配**
- **Found during:** Task 3
- **Issue:** 计划中 `mapDeviceGatewayInfoToClientInfo` 的 `SwitchMode` 转换代码为 `v := int(*g.SwitchMode)`,但 `g.SwitchMode` 是 `*string`B端 Gateway DTO 定义),`DeviceRealtimeInfo.SwitchMode` 是 `*int`C端 DTO直接转换会编译报错
- **Fix:** 使用 `strconv.Atoi(*g.SwitchMode)` 进行字符串→整型安全转换,解析失败时忽略(`SwitchMode` 保持 nil
- **Files modified:** `internal/handler/app/client_asset.go`
- **Commit:** `a202b2d`
---
## Self-Check: PASSED
| 检查项 | 结果 |
|--------|------|
| `internal/gateway/models.go` 存在 | ✅ FOUND |
| `internal/model/dto/asset_dto.go` 存在 | ✅ FOUND |
| `internal/service/device/service.go` 存在 | ✅ FOUND |
| `internal/service/device/binding.go` 存在 | ✅ FOUND |
| `internal/service/asset/service.go` 存在 | ✅ FOUND |
| `internal/handler/app/client_asset.go` 存在 | ✅ FOUND |
| 提交 `00dba42` 存在 | ✅ FOUND |
| 提交 `3b54850` 存在 | ✅ FOUND |
| 提交 `a202b2d` 存在 | ✅ FOUND |
| `go build ./...` 编译通过 | ✅ 通过 |