## 1. DTO 扩展

- [x] 1.1 在 `internal/model/dto/asset_dto.go` 的 `AssetResolveResponse` 中新增 `RealNameAt *time.Time` 字段（json tag: `real_name_at`，description: 最近一次完成实名的时间，未实名时为 null）
- [x] 1.2 在 `internal/model/dto/asset_dto.go` 的 `BoundCardInfo` 中新增 `RealNameAt *time.Time` 字段（json tag: `real_name_at`，description: 该卡最近一次完成实名的时间，未实名时为 null）

## 2. Service 填充逻辑

- [x] 2.1 在 `internal/service/asset/service.go` 的 `buildCardResolveResponse` 中填充 `resp.RealNameAt = card.FirstRealnameAt`
- [x] 2.2 在 `internal/service/asset/service.go` 的 `buildDeviceResolveResponse` 构建绑定卡列表时，为每个 `BoundCardInfo` 填充 `RealNameAt: c.FirstRealnameAt`
- [x] 2.3 在 `internal/service/asset/service.go` 的 `buildDeviceResolveResponse` 中，遍历绑定卡列表聚合设备级 `RealNameAt`：取所有卡 `FirstRealnameAt` 中的最小值（跳过 nil），赋值给 `resp.RealNameAt`

## 3. Bug 修复：手动刷新路径补写实名时间

- [x] 3.1 在 `internal/service/iot_card/service.go` 的 `RefreshCardDataFromGateway` 中，在更新 `real_name_status` 后，检测 `0→1` 变化：若旧状态非已实名且新状态为已实名，则在 `updates` map 中同步写入 `first_realname_at = time.Now()`

## 4. 验证

- [x] 4.1 通过 PostgreSQL MCP 查询一张已知已实名的卡，确认 `first_realname_at` 不为 null，调用 `/api/admin/assets/resolve/:identifier` 确认响应中 `real_name_at` 有值
- [x] 4.2 通过 PostgreSQL MCP 查询一台绑定了已实名卡的设备，调用 `/api/admin/assets/resolve/:identifier` 确认设备响应中 `real_name_at` = 最早绑定卡的实名时间，且 `cards` 列表中各卡 `real_name_at` 正确
- [x] 4.3 查询一张未实名的卡和一台所有卡均未实名的设备，确认 `real_name_at` 均为 null
