This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
stderrors "errors"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/gateway"
|
||||
@@ -442,36 +443,36 @@ func (s *Service) fetchDeviceGatewayInfo(ctx context.Context, deviceID uint) *dt
|
||||
func mapSyncRespToDeviceGatewayInfo(r *gateway.SyncDeviceInfoResp) *dto.DeviceGatewayInfo {
|
||||
info := &dto.DeviceGatewayInfo{
|
||||
OnlineStatus: flexIntPtr(r.OnlineStatus),
|
||||
RunTime: strPtr(r.RunTime),
|
||||
ConnectTime: strPtr(r.ConnectTime),
|
||||
LastOnlineTime: strPtr(r.LastOnlineTime),
|
||||
LastUpdateTime: strPtr(r.LastUpdateTime),
|
||||
RunTime: flexStrPtr(r.RunTime),
|
||||
ConnectTime: flexStrPtr(r.ConnectTime),
|
||||
LastOnlineTime: flexStrPtr(r.LastOnlineTime),
|
||||
LastUpdateTime: flexStrPtr(r.LastUpdateTime),
|
||||
Rsrp: flexIntPtr(r.Rsrp),
|
||||
Rsrq: flexIntPtr(r.Rsrq),
|
||||
Rssi: strPtr(r.RSSI),
|
||||
Rssi: flexStrPtr(r.RSSI),
|
||||
Sinr: flexIntPtr(r.Sinr),
|
||||
SSID: strPtr(r.SSID),
|
||||
SSID: flexStrPtr(r.SSID),
|
||||
WifiEnabled: flexBoolPtr(r.WifiEnabled),
|
||||
WifiPassword: strPtr(r.WifiPassword),
|
||||
IPAddress: strPtr(r.IPAddress),
|
||||
WANIP: strPtr(r.WANIP),
|
||||
LANIP: strPtr(r.LANIP),
|
||||
MACAddress: strPtr(r.MacAddress),
|
||||
DailyUsage: strPtr(r.DailyUsage),
|
||||
DLStats: strPtr(r.DLStats),
|
||||
ULStats: strPtr(r.ULStats),
|
||||
WifiPassword: flexStrPtr(r.WifiPassword),
|
||||
IPAddress: flexStrPtr(r.IPAddress),
|
||||
WANIP: flexStrPtr(r.WANIP),
|
||||
LANIP: flexStrPtr(r.LANIP),
|
||||
MACAddress: flexStrPtr(r.MacAddress),
|
||||
DailyUsage: flexStrPtr(r.DailyUsage),
|
||||
DLStats: flexStrPtr(r.DLStats),
|
||||
ULStats: flexStrPtr(r.ULStats),
|
||||
LimitSpeed: flexIntPtr(r.LimitSpeed),
|
||||
CurrentIccid: strPtr(r.CurrentIccid),
|
||||
CurrentIccid: flexStrPtr(r.CurrentIccid),
|
||||
MaxClients: flexIntPtr(r.MaxClients),
|
||||
ClientNumber: flexIntPtr(r.ClientNumber),
|
||||
SoftwareVersion: strPtr(r.SoftwareVersion),
|
||||
SwitchMode: strPtr(r.SwitchMode),
|
||||
SoftwareVersion: flexStrPtr(r.SoftwareVersion),
|
||||
SwitchMode: flexStrPtr(r.SwitchMode),
|
||||
SyncInterval: flexIntPtr(r.SyncInterval),
|
||||
DeviceID: strPtr(r.DeviceID),
|
||||
DeviceName: strPtr(r.DeviceName),
|
||||
DeviceType: strPtr(r.DeviceType),
|
||||
IMEI: strPtr(r.IMEI),
|
||||
IMSI: strPtr(r.IMSI),
|
||||
DeviceID: flexStrPtr(r.DeviceID),
|
||||
DeviceName: flexStrPtr(r.DeviceName),
|
||||
DeviceType: flexStrPtr(r.DeviceType),
|
||||
IMEI: flexStrPtr(r.IMEI),
|
||||
IMSI: flexStrPtr(r.IMSI),
|
||||
Status: flexIntPtr(r.Status),
|
||||
}
|
||||
if r.BatteryLevel != nil {
|
||||
@@ -490,6 +491,11 @@ func strPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
// flexStrPtr 将 FlexString 转为字符串指针
|
||||
func flexStrPtr(s gateway.FlexString) *string {
|
||||
return strPtr(string(s))
|
||||
}
|
||||
|
||||
func flexBoolPtr(fb gateway.FlexBool) *bool {
|
||||
b := bool(fb)
|
||||
return &b
|
||||
@@ -580,19 +586,14 @@ func (s *Service) Refresh(ctx context.Context, assetType string, id uint) (*dto.
|
||||
func (s *Service) updateDeviceFromSyncInfo(ctx context.Context, deviceID uint, resp *gateway.SyncDeviceInfoResp) {
|
||||
now := time.Now()
|
||||
|
||||
// 解析 LastOnlineTime(ISO 8601 字符串 → *time.Time)
|
||||
var lastOnlineTime *time.Time
|
||||
if resp.LastOnlineTime != "" {
|
||||
if t, err := time.Parse(time.RFC3339, resp.LastOnlineTime); err == nil {
|
||||
lastOnlineTime = &t
|
||||
}
|
||||
}
|
||||
// Gateway 时间字段可能返回 RFC3339 或 Unix 时间戳,统一解析后再回写数据库
|
||||
lastOnlineTime := parseGatewayTime(resp.LastOnlineTime)
|
||||
|
||||
// 更新设备 5 个存储字段
|
||||
updates := map[string]any{
|
||||
"online_status": int(resp.OnlineStatus),
|
||||
"software_version": resp.SoftwareVersion,
|
||||
"switch_mode": resp.SwitchMode,
|
||||
"software_version": string(resp.SoftwareVersion),
|
||||
"switch_mode": string(resp.SwitchMode),
|
||||
"last_gateway_sync_at": now,
|
||||
}
|
||||
if lastOnlineTime != nil {
|
||||
@@ -609,9 +610,9 @@ func (s *Service) updateDeviceFromSyncInfo(ctx context.Context, deviceID uint, r
|
||||
return
|
||||
}
|
||||
|
||||
if resp.CurrentIccid != "" {
|
||||
if string(resp.CurrentIccid) != "" {
|
||||
// 更新 is_current 标识(事务原子操作,per D-14 决策)
|
||||
if err := s.deviceSimBindingStore.UpdateIsCurrentByDeviceID(ctx, deviceID, resp.CurrentIccid); err != nil {
|
||||
if err := s.deviceSimBindingStore.UpdateIsCurrentByDeviceID(ctx, deviceID, string(resp.CurrentIccid)); err != nil {
|
||||
logger.GetAppLogger().Warn("sync-info 更新 is_current 失败",
|
||||
zap.Uint("device_id", deviceID),
|
||||
zap.Error(err))
|
||||
@@ -619,6 +620,33 @@ func (s *Service) updateDeviceFromSyncInfo(ctx context.Context, deviceID uint, r
|
||||
}
|
||||
}
|
||||
|
||||
// parseGatewayTime 兼容解析 Gateway 时间字段
|
||||
// 支持 RFC3339 字符串、Unix 秒时间戳、Unix 毫秒时间戳。
|
||||
func parseGatewayTime(raw gateway.FlexString) *time.Time {
|
||||
value := string(raw)
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if t, err := time.Parse(time.RFC3339, value); err == nil {
|
||||
return &t
|
||||
}
|
||||
|
||||
// 兼容网关返回的纯数字时间戳(秒或毫秒)
|
||||
ts, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var t time.Time
|
||||
if len(value) >= 13 {
|
||||
t = time.UnixMilli(ts)
|
||||
} else {
|
||||
t = time.Unix(ts, 0)
|
||||
}
|
||||
return &t
|
||||
}
|
||||
|
||||
// GetPackages 获取资产的所有套餐列表(支持分页)
|
||||
// page 默认 1,pageSize 默认 50,pageSize 最大 100
|
||||
func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, page, pageSize int) (*dto.AssetPackagesResult, error) {
|
||||
|
||||
Reference in New Issue
Block a user