package jobs import ( "encoding/json" "fmt" "fwh-toolbox-server/domain" "fwh-toolbox-server/repositories" "sort" "strconv" "time" "go.mongodb.org/mongo-driver/bson/primitive" "go.uber.org/zap" ) type SiteDataSet struct { Log_0 []domain.MqttLogItem Log_101 []domain.MqttLogItem Log_201 []domain.MqttLogItem Log_357 []domain.MqttLogItem EventLog []domain.EventAlarmItem AlarmLog []domain.EventAlarmItem } // 分析站点时间线数据 func AnalysisSiteTimeline(id primitive.ObjectID, data SiteDataSet) error { var timelineItemList []domain.TimelineItem // 分析offline for _, log := range data.Log_0 { _, err := time.Parse(time.DateTime, log.LogTime) if err != nil { zap.L().Error("0日志时间格式错误", zap.String("time", log.LogTime)) return err } timelineItem := domain.TimelineItem{ Time: log.LogTime, Type: domain.TimelineOffline, } timelineItemList = append(timelineItemList, timelineItem) } // 分析online for _, log := range data.Log_101 { _, err := time.Parse(time.DateTime, log.LogTime) if err != nil { zap.L().Error("101日志时间格式错误", zap.String("time", log.LogTime)) return err } timelineItem := domain.TimelineItem{ Time: log.LogTime, Type: domain.TimelineOnline, } timelineItemList = append(timelineItemList, timelineItem) } // 分析套餐&模式日志 scheduleDataList := make(map[uint]domain.ScheduleData) for _, log := range data.Log_357 { _, err := time.Parse(time.DateTime, log.LogTime) if err != nil { zap.L().Error("357日志时间格式错误", zap.String("time", log.LogTime)) return err } var log_357 domain.MqttLogType_357 err = json.Unmarshal([]byte(log.LogData), &log_357) if err != nil { zap.L().Error("357日志JSON数据格式错误", zap.String("data", log.LogData)) return err } // 判断操作类型 1-增加/编辑 2-删除 3-修改当前工作序列 opt := log_357.Opt var modeInfo *string var modeData *string switch opt { case 1: // 记录策略ID对应的策略信息,用于关联切换的模式 if log_357.Data != nil { scheduleDataList[log_357.Data.ID] = *log_357.Data } case 2: // 删除不做处理 case 3: if log_357.CurrentId != nil && *log_357.CurrentId >= 0 { val, ok := scheduleDataList[uint(*log_357.CurrentId)] if ok { modeInfo = &val.Name // 转成 JSON 字符串 jsonModeData, err := json.Marshal(val) if err != nil { fmt.Println("序列化失败:", err) zap.L().Error("357日志策略信息JSON数据序列化失败", zap.String("err", err.Error()), zap.Any("data", val)) } else { dataStr := string(jsonModeData) modeData = &dataStr } } else { infoStr := fmt.Sprintf("未知模式(%d)", log_357.CurrentId) modeInfo = &infoStr } } default: zap.L().Error("357日志不支持的操作类型", zap.String("opt", strconv.Itoa(log_357.Opt))) return err } timelineItem := domain.TimelineItem{ Time: log.LogTime, Type: domain.TimelineModeChange, Info: modeInfo, Data: modeData, } timelineItemList = append(timelineItemList, timelineItem) } // 分析Event for _, log := range data.EventLog { _, err := time.Parse(time.DateTime, log.LogTime) if err != nil { zap.L().Error("Event日志时间格式错误", zap.String("time", log.LogTime)) return err } timelineItem := domain.TimelineItem{ Time: log.LogTime, Type: domain.TimelineEvent, Info: &log.LogName, } timelineItemList = append(timelineItemList, timelineItem) } // 分析Alarm for _, log := range data.AlarmLog { _, err := time.Parse(time.DateTime, log.LogTime) if err != nil { zap.L().Error("Alarm日志时间格式错误", zap.String("time", log.LogTime)) return err } alarmCode := []byte(log.AlarmCode) var alarmName string if len(alarmCode) < 4 { alarmName = fmt.Sprintf("#? %s", log.LogName) } else { if alarmCode[1] == '0' { alarmName = log.LogName } else { alarmName = fmt.Sprintf("#%s %s", string(alarmCode[1]), log.LogName) } } timelineItem := domain.TimelineItem{ Time: log.LogTime, Type: domain.TimelineAlarm, Info: &alarmName, } timelineItemList = append(timelineItemList, timelineItem) } // 数据时间排序 timelineSlice(&timelineItemList) // 最后将时间线数据存入数据库 if err := repositories.InsertSiteAnalysisTimeline(id, timelineItemList); err != nil { zap.L().Error("插入站点分析timeline数据失败", zap.String("id", id.String())) return err } return nil } func timelineSlice(list *[]domain.TimelineItem) { if list == nil { return } // 排序 sort.Slice(*list, func(i, j int) bool { ti, _ := time.Parse(time.DateTime, (*list)[i].Time) tj, _ := time.Parse(time.DateTime, (*list)[j].Time) return ti.Before(tj) }) } // 分析站点运行实时数据 func AnalysisSiteRuntime(id primitive.ObjectID, data SiteDataSet) error { var runtimeItemList []domain.RuntimeItem // 分析offline for _, log := range data.Log_201 { _, err := time.Parse(time.DateTime, log.LogTime) if err != nil { zap.L().Error("201日志时间格式错误", zap.String("time", log.LogTime)) return err } runtimeItem := domain.RuntimeItem{ Time: log.LogTime, Data_201: log.LogData, } runtimeItemList = append(runtimeItemList, runtimeItem) } // 将运行时数据存入数据库 if err := repositories.InsertSiteAnalysisRuntime(id, runtimeItemList); err != nil { zap.L().Error("插入站点分析runtime数据失败", zap.String("id", id.String())) return err } return nil }