package repository import ( "fmt" "sort" "strings" "time" "be.ems/src/framework/database/db" "be.ems/src/framework/logger" "be.ems/src/modules/ne_data/model" ) // 实例化数据层 KpiReport 结构体 var NewKpiReport = &KpiReport{} // KpiReport 性能统计 数据层处理 type KpiReport struct{} // SelectGoldKPI 通过网元指标数据信息 func (r KpiReport) SelectKPI(neType string, neId int64, query model.KPIQuery) []model.KpiReport { rows := []model.KpiReport{} if neType == "" { return rows } tx := db.DB("").Model(&model.KpiReport{}) // 表名 tableName := fmt.Sprintf("kpi_report_%s", strings.ToLower(neType)) tx = tx.Table(tableName) // 构建查询条件 if neId != 0 { tx = tx.Where("ne_id = ?", neId) } if query.BeginTime != 0 { tx = tx.Where("created_time >= ?", query.BeginTime) } if query.EndTime != 0 { tx = tx.Where("created_time <= ?", query.EndTime) } // 查询数据 if err := tx.Find(&rows).Error; err != nil { logger.Errorf("query find err => %v", err.Error()) return rows } // 排序 r.sortRows(query.SortField, query.SortOrder, rows) return rows } // sortRows 排序数据集合 // sortField 排序字段 支持id timeGroup createdAt // sortOrder 排序顺序 升序asc 降序desc func (r KpiReport) sortRows(sortField, sortOrder string, rows []model.KpiReport) { if sortField == "" { return } sort.SliceStable(rows, func(i, j int) bool { // 支持的排序字段映射 fieldGetters := map[string]func(*model.KpiReport) any{ "id": func(row *model.KpiReport) any { return row.ID }, "timeGroup": func(row *model.KpiReport) any { return row.CreatedTime }, "createdTime": func(row *model.KpiReport) any { return row.CreatedTime }, // 可添加更多支持的字段 } // 获取字段 getter 函数 getter, ok := fieldGetters[sortField] if !ok { // 非法字段,使用默认排序(id升序) return rows[i].ID < rows[j].ID } // 获取比较值 valI, valJ := getter(&rows[i]), getter(&rows[j]) // 根据字段类型进行比较 switch v := valI.(type) { case int64: if sortOrder == "desc" { return v > valJ.(int64) } return v < valJ.(int64) case string: if sortOrder == "desc" { return v > valJ.(string) } return v < valJ.(string) default: // 不支持的字段类型,使用默认排序 return rows[i].ID < rows[j].ID } }) } // Insert 新增信息 返回新增数据ID func (r KpiReport) Insert(neType string, param model.KpiReport) int64 { if neType == "" { return 0 } if param.CreatedTime == 0 { param.CreatedTime = time.Now().UnixMilli() } // 表名 tableName := fmt.Sprintf("kpi_report_%s", strings.ToLower(neType)) // 执行插入 if err := db.DB("").Table(tableName).Create(¶m).Error; err != nil { errMsg := err.Error() // 动态创建表 if strings.HasPrefix(errMsg, "Error 1146 (42S02): Table") { if err := r.createTableByMySQL(neType); err != nil { logger.Errorf("create table err => %v", err.Error()) return 0 } } if strings.HasPrefix(errMsg, "SQL logic error: no such table") { if err := r.createTableBySQLite(neType); err != nil { logger.Errorf("create table err => %v", err.Error()) return 0 } } logger.Errorf("insert err => %v", errMsg) return 0 } return param.ID } // createTableByMySQL 创建表MySQL func (r KpiReport) createTableByMySQL(neType string) error { lowerNeType := strings.ToLower(neType) sql := fmt.Sprintf( ` CREATE TABLE IF NOT EXISTS kpi_report_%s ( id int NOT NULL AUTO_INCREMENT, ne_id bigint DEFAULT '0' COMMENT '网元ID', created_time bigint DEFAULT '0' COMMENT '创建时间', record_time bigint DEFAULT '0' COMMENT '记录时间', index int NOT NULL COMMENT 'Index of the report', granularity int DEFAULT '60' COMMENT 'Time granualarity: 5/10/.../60/300 (second)', kpi_values text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin COMMENT 'KPI values JSON String', PRIMARY KEY (id) USING BTREE, KEY idx_kpi_%s_ne_at (ne_id DESC, created_time DESC) USING BTREE COMMENT '索引-网元ID_记录时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='KPI_%s'; `, lowerNeType, lowerNeType, strings.ToUpper(neType), ) _, err := db.ExecDB("", sql, nil) return err } // createTableBySQLite 创建表SQLite func (r KpiReport) createTableBySQLite(neType string) error { lowerNeType := strings.ToLower(neType) sql := fmt.Sprintf( ` CREATE TABLE IF NOT EXISTS "kpi_report_%s" ( "id" integer NOT NULL, "ne_id" integer, "created_time" integer, "record_time" integer, "index" integer NOT NULL, "granularity" integer, "kpi_values" text, PRIMARY KEY ("id") ); CREATE INDEX IF NOT EXISTS "idx_kpi_%s_ne_at" ON "kpi_report_%s" ( "ne_id" DESC, "created_time" DESC ); `, lowerNeType, lowerNeType, lowerNeType, ) _, err := db.ExecDB("", sql, nil) return err } // Select 查询数据 func (r KpiReport) Select(neType string, neId int64, beginTime, endTime int64) []model.KpiReport { rows := []model.KpiReport{} if neType == "" { return rows } tx := db.DB("").Model(&model.KpiReport{}) // 表名 tx = tx.Table(fmt.Sprintf("kpi_report_%s", strings.ToLower(neType))) tx = tx.Where("ne_id = ?", neId) tx = tx.Where("created_time >= ? and created_time <= ?", beginTime, endTime) // 查询数据 if err := tx.Select("kpi_values", "created_time").Find(&rows).Error; err != nil { logger.Errorf("query find err => %v", err.Error()) return rows } return rows } // SelectKPITitle 网元对应的指标名称 func (r KpiReport) SelectKPITitle(neType string) []model.KpiTitle { rows := []model.KpiTitle{} if neType == "" { return rows } tx := db.DB("").Model(&model.KpiTitle{}) // 构建查询条件 tx = tx.Where("ne_type = ? and status_flag = ?", neType, "1") // 查询数据 if err := tx.Find(&rows).Error; err != nil { logger.Errorf("query find err => %v", err.Error()) return rows } return rows } // SelectByPageTitle 分页查询集合 func (r KpiReport) TitleSelectByPage(query map[string]string) ([]model.KpiTitle, int64) { tx := db.DB("").Model(&model.KpiTitle{}) // 查询条件拼接 if v, ok := query["neType"]; ok && v != "" { tx = tx.Where("ne_type = ?", v) } if v, ok := query["kpiId"]; ok && v != "" { tx = tx.Where("kpi_id like ?", fmt.Sprintf("%s%%", v)) } if v, ok := query["title"]; ok && v != "" { tx = tx.Where("cn_title like ? or en_title like ?", fmt.Sprintf("%%%s%%", v), fmt.Sprintf("%%%s%%", v)) } if v, ok := query["statusFlag"]; ok && v != "" { tx = tx.Where("status_flag = ?", v) } // 查询结果 var total int64 = 0 rows := []model.KpiTitle{} // 查询数量 长度为0直接返回 if err := tx.Count(&total).Error; err != nil || total <= 0 { return rows, total } // 分页 pageNum, pageSize := db.PageNumSize(query["pageNum"], query["pageSize"]) tx = tx.Offset(int(pageNum * pageSize)).Limit(int(pageSize)) // 排序 if v, ok := query["sortField"]; ok && v != "" { sortSql := v if o, ok := query["sortOrder"]; ok && o != "" { if o == "desc" { sortSql += " desc " } else { sortSql += " asc " } } tx = tx.Order(sortSql) } // 查询数据 if err := tx.Find(&rows).Error; err != nil { logger.Errorf("query err => %v", err) } return rows, total } // TitleSelect 网元对应的指标名称 func (r KpiReport) TitleSelect(param model.KpiTitle) []model.KpiTitle { tx := db.DB("").Model(&model.KpiTitle{}) // 构建查询条件 if param.NeType != "" { tx = tx.Where("ne_type =?", param.NeType) } if param.KpiId != "" { tx = tx.Where("kpi_id = ?", param.KpiId) } if param.StatusFlag != "" { tx = tx.Where("status_flag = ?", param.StatusFlag) } // 查询数据 rows := []model.KpiTitle{} if err := tx.Find(&rows).Error; err != nil { logger.Errorf("query find err => %v", err.Error()) return rows } return rows } // TitleInsert 新增信息 func (r KpiReport) TitleInsert(param model.KpiTitle) int64 { tx := db.DB("").Create(¶m) if err := tx.Error; err != nil { logger.Errorf("Create err => %v", err) } return param.ID } // TitleUpdate 修改信息 func (r KpiReport) TitleUpdate(param model.KpiTitle) int64 { if param.ID <= 0 { return 0 } tx := db.DB("").Model(&model.KpiTitle{}) // 构建查询条件 tx = tx.Where("id = ?", param.ID) tx = tx.Omit("id", "title_json") // 执行更新 if err := tx.Updates(param).Error; err != nil { logger.Errorf("update err => %v", err.Error()) return 0 } return tx.RowsAffected } // TitleDeleteByIds 批量删除信息 func (r KpiReport) TitleDeleteByIds(ids []int64) int64 { if len(ids) <= 0 { return 0 } tx := db.DB("").Where("id in ?", ids) if err := tx.Delete(&model.KpiTitle{}).Error; err != nil { logger.Errorf("delete err => %v", err.Error()) return 0 } return tx.RowsAffected }