package service import ( "encoding/json" "fmt" "sort" "be.ems/src/framework/utils/parse" "be.ems/src/modules/ne_data/model" "be.ems/src/modules/ne_data/repository" ) // 实例化数据层 KpiCReport 结构体 var NewKpiCReport = &KpiCReport{ kpiCReportRepository: repository.NewKpiCReport, } // KpiCReport 自定义性能统计 服务层处理 type KpiCReport struct { kpiCReportRepository *repository.KpiCReport // 自定义KPI数据信息 } // FindKPI 通过网元指标数据信息 func (s KpiCReport) FindData(query model.KPICQuery) []map[string]any { // 标题单位映射 kpicTitles := s.kpiCReportRepository.SelectKPITitle(query.NeType) kpicTitleUnitMap := map[string]string{} for _, v := range kpicTitles { kpicTitleUnitMap[v.KpiId] = v.Unit } // 原始数据 rows := s.kpiCReportRepository.SelectKPI(query) if len(rows) <= 0 { return []map[string]any{} } kpiIdsHas := false kpiIds := []string{} // 处理数据 arr := []map[string]any{} for _, row := range rows { // 解析 JSON 字符串为 map var kpiValues []map[string]any err := json.Unmarshal([]byte(row.KpiValues), &kpiValues) if err != nil { continue } item := map[string]any{ "neType": row.NeType, "neName": row.NeName, "rmUID": row.RmUid, "startIndex": row.Index, "timeGroup": row.CreatedAt, } // 遍历 kpiValues 数组 for _, v := range kpiValues { kpiId := "-" if k, ok := v["kpiId"]; ok { kpiId = fmt.Sprint(k) } item[kpiId] = v["value"] } arr = append(arr, item) // 添加指标ID if !kpiIdsHas { for _, v := range kpiValues { kpiId := "-" if k, ok := v["kpiId"]; ok { kpiId = fmt.Sprint(k) } kpiIds = append(kpiIds, kpiId) } kpiIdsHas = true } } // 时间密度分钟 数值单位秒 5分钟的传入300秒 timeInterval := query.Interval // 创建一个map来存储按时间段合并后的数据 timeGroup := make(map[int64][]map[string]any) // 遍历每个数据项 for _, v := range arr { itemTime := parse.Number(v["timeGroup"]) // 计算时间戳的x分钟时间段(使用秒并除以x分钟) timeMinute := itemTime / 1000 / timeInterval * timeInterval // 合并到对应的时间段 timeGroup[timeMinute] = append(timeGroup[timeMinute], v) } // 时间组合输出 data := []map[string]any{} for _, records := range timeGroup { if len(records) <= 0 { continue } // 转换为具体时间显示(根据需要可以格式化显示) // timeStr := time.Unix(k, 0).Format("2006-01-02 15:04:05") // fmt.Printf("Time Group: %s records: %d\n", timeStr, len(records)) startItem := records[len(records)-1] // 取最后一条数据也是最开始startIndex if len(records) >= 2 { // 最后一条数据不参与计算 for _, record := range records[:len(records)-1] { // fmt.Printf(" - startIndex: %v, Value: %v\n", record["startIndex"], record["timeGroup"]) // 遍历kpiIds数组对lastRecord赋值 for _, kpiId := range kpiIds { if v, ok := record[kpiId]; ok { value := v.(float64) + startItem[kpiId].(float64) startItem[kpiId] = value // value := parse.Number(startItem[kpiId]) // startItem[kpiId] = value + parse.Number(v) } } } // 处理单位 for _, kpiId := range kpiIds { unit, ok := kpicTitleUnitMap[kpiId] if !ok { continue } // "Mbps" "%" if unit == "%" { startItem[kpiId] = startItem[kpiId].(float64) / float64(len(records)) } } } data = append(data, startItem) } // 按时间排序 sort.SliceStable(data, func(i, j int) bool { vi := parse.Number(data[i]["timeGroup"]) vj := parse.Number(data[j]["timeGroup"]) if query.SortOrder == "asc" { return vi < vj // asc } return vi > vj // desc }) return data } // Insert 新增信息 func (s KpiCReport) Insert(param model.KpiCReport) int64 { return s.kpiCReportRepository.Insert(param) } // FindKPITitle 网元对应的指标名称 func (r KpiCReport) FindTitle(neType string) []model.KpiCTitle { return r.kpiCReportRepository.SelectKPITitle(neType) } // TitleLastKPIId 指标标题最后kpiid func (r KpiCReport) TitleLastKPIId(neType string) string { return r.kpiCReportRepository.TitleLastKPIId(neType) } // FindByPage 根据条件分页查询 func (r KpiCReport) TitleFindByPage(query map[string]string) ([]model.KpiCTitle, int64) { return r.kpiCReportRepository.TitleSelectByPage(query) } // TitleFind 查询信息 func (r KpiCReport) TitleFind(param model.KpiCTitle) []model.KpiCTitle { return r.kpiCReportRepository.TitleSelect(param) } // TitleUpdate 更新信息 func (r KpiCReport) TitleUpdate(param model.KpiCTitle) int64 { return r.kpiCReportRepository.TitleUpdate(param) } // TitleDeleteByIds 批量删除信息 func (r KpiCReport) TitleDeleteByIds(ids []int64) (int64, error) { rows := r.kpiCReportRepository.TitleDeleteByIds(ids) if rows > 0 { return rows, nil } // 删除信息失败! return 0, fmt.Errorf("delete fail") } // TitleInsert 新增信息 func (r KpiCReport) TitleInsert(param model.KpiCTitle) int64 { return r.kpiCReportRepository.TitleInsert(param) }