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

7.3 KiB
Raw Blame History

phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
03.1-sync-info-phase-3-dto 01 asset/device
gateway
dto
device
realtime
requires provides affects
Phase 3 DEVICE-01~04DB 字段写入已完成)
设备管理列表/详情返回 5 个 DB 缓存字段
设备绑卡列表返回 is_current 字段
资产 Resolve/Refresh BoundCardInfo 含 is_current
admin 资产解析返回 5 个 DB 缓存字段
GetRealtimeStatus device 类型实时调用 Gateway
C 端 GetAssetInfo device_realtime 为真实 Gateway 数据
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 改为真实数据)
added patterns
isCurrentMap 与 slotMap 同构模式asset/service.go
strPtr() 辅助函数空字符串→nil防止 JSON 冗余字段)
mapSyncRespToDeviceGatewayInfo() Gateway DTO → B端 DTO 映射
mapDeviceGatewayInfoToClientInfo() B端 DTO → C端 DTO 映射
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
DeviceGatewayInfoB端与 DeviceRealtimeInfoC端独立结构通过映射函数转换per D-08
SwitchMode 在 B端为 *stringGateway 原始C端为 *int映射时使用 strconv.Atoi 转换
strPtr() 在 asset/service.go 包内独立定义order/service.go 已有同名函数但不同包)
duration completed_date tasks files_modified
5min 2026-03-28 3 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 个缺失字段:

  • 信号:RsrpRsrqSinr
  • WiFiWifiPassword
  • 网络:IPAddressWANIPLANIP
  • 连接:MaxClientsConnectTime
  • 设备:StatusIMSIULStatsDLStatsLimitSpeedSyncInterval

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
    • OnlineStatusLastOnlineTimeSoftwareVersionSwitchModeLastGatewaySyncAt

Task 2修复静态 DTO 映射缺口

internal/service/device/service.gotoDeviceResponse(),第 559-563 行):

补全 5 个 DB 缓存字段赋值:

OnlineStatus:      device.OnlineStatus,
LastOnlineTime:    device.LastOnlineTime,
SoftwareVersion:   device.SoftwareVersion,
SwitchMode:        device.SwitchMode,
LastGatewaySyncAt: device.LastGatewaySyncAt,

internal/service/device/binding.goListBindings(),第 60 行):

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 模式:

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() 调用,替换为:

    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: 计划中 mapDeviceGatewayInfoToClientInfoSwitchMode 转换代码为 v := int(*g.SwitchMode),但 g.SwitchMode*stringB端 Gateway DTO 定义),DeviceRealtimeInfo.SwitchMode*intC端 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 ./... 编译通过 通过