Files
be.ems/src/modules/ne_data/repository/kpi_report.go

326 lines
8.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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(&param).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(&param)
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
}