diff --git a/src/modules/network_data/controller/ims.go b/src/modules/network_data/controller/ims.go index 4ddf7ba4..4116c137 100644 --- a/src/modules/network_data/controller/ims.go +++ b/src/modules/network_data/controller/ims.go @@ -1,22 +1,31 @@ package controller import ( + "encoding/json" + "fmt" + "strconv" "strings" + "time" "be.ems/src/framework/i18n" + "be.ems/src/framework/logger" "be.ems/src/framework/utils/ctx" + "be.ems/src/framework/utils/date" + "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" "be.ems/src/framework/vo/result" "be.ems/src/modules/network_data/model" neDataService "be.ems/src/modules/network_data/service" neService "be.ems/src/modules/network_element/service" + sysService "be.ems/src/modules/system/service" "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" ) // 实例化控制层 IMSController 结构体 var NewIMSController = &IMSController{ neInfoService: neService.NewNeInfoImpl, - cdrEventService: neDataService.NewCDREventImpl, + cdrEventService: neDataService.NewCDREventIMSImpl, } // 网元IMS @@ -26,7 +35,7 @@ type IMSController struct { // 网元信息服务 neInfoService neService.INeInfo // CDR会话事件服务 - cdrEventService neDataService.ICDREvent + cdrEventService neDataService.ICDREventIMS } // CDR会话列表 @@ -34,19 +43,19 @@ type IMSController struct { // GET /cdr/list func (s *IMSController) CDRList(c *gin.Context) { language := ctx.AcceptLanguage(c) - var querys model.CDREventQuery + var querys model.CDREventIMSQuery if err := c.ShouldBindQuery(&querys); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 查询网元获取IP - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) - if neInfo.NeId != querys.NeID || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) - return - } - querys.RmUID = neInfo.RmUID + // neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) + // if neInfo.NeId != querys.NeID || neInfo.IP == "" { + // c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + // return + // } + // querys.RmUID = neInfo.RmUID // 查询数据 data := s.cdrEventService.SelectPage(querys) @@ -78,3 +87,126 @@ func (s *IMSController) CDRRemove(c *gin.Context) { msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } + +// CDR会话列表导出 +// +// POST /cdr/export +func (s *IMSController) CDRExport(c *gin.Context) { + language := ctx.AcceptLanguage(c) + // 查询结果,根据查询条件结果,单页最大值限制 + var querys model.CDREventIMSQuery + if err := c.ShouldBindBodyWith(&querys, binding.JSON); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 限制导出数据集 + if querys.PageSize > 10000 { + querys.PageSize = 10000 + } + data := s.cdrEventService.SelectPage(querys) + if parse.Number(data["total"]) == 0 { + // 导出数据记录为空 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) + return + } + rows := data["rows"].([]model.CDREventIMS) + + // 导出文件名称 + fileName := fmt.Sprintf("ims_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "Record Behavior", + "C1": "Type", + "D1": "Called", + "E1": "Caller", + "F1": "Duration", + "G1": "Result", + "H1": "Time", + } + // 读取字典数据 CDR SIP响应代码类别类型 + dictCDRSipCode := sysService.NewSysDictDataImpl.SelectDictDataByType("cdr_sip_code") + // 读取字典数据 CDR 呼叫类型 + dictCDRCallType := sysService.NewSysDictDataImpl.SelectDictDataByType("cdr_call_type") + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 解析 JSON 字符串为 map + var cdrJSON map[string]interface{} + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("UEExport Error parsing JSON: %s", err.Error()) + continue + } + // 记录类型 + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = v.(string) + } + // 被叫 + called := "" + if v, ok := cdrJSON["calledParty"]; ok && v != nil { + called = v.(string) + } + // 主叫 + caller := "" + if v, ok := cdrJSON["callerParty"]; ok && v != nil { + caller = v.(string) + } + // 呼叫类型 + callType := "sms" + callTypeLable := "SMS" + if v, ok := cdrJSON["callType"]; ok && v != nil { + callType = v.(string) + for _, v := range dictCDRCallType { + if callType == v.DictValue { + callTypeLable = i18n.TKey(language, v.DictLabel) + break + } + } + } + // 时长 + duration := "-" + if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" { + duration = fmt.Sprint(parse.Number(v)) + } + // 呼叫结果 非短信都有code作为结果 sms短信都ok + callResult := "Success" + if v, ok := cdrJSON["cause"]; ok && v != nil && callType != "sms" { + cause := fmt.Sprint(v) + for _, v := range dictCDRSipCode { + if cause == v.DictValue { + callResult = i18n.TKey(language, v.DictLabel) + break + } + } + } + // 取时间 + timeStr := "" + if v, ok := cdrJSON["releaseTime"]; ok && v != nil { + releaseTime := parse.Number(v) + timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ) + } + + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.ID, + "B" + idx: recordType, + "C" + idx: callTypeLable, + "D" + idx: called, + "E" + idx: caller, + "F" + idx: duration, + "G" + idx: callResult, + "H" + idx: timeStr, + }) + } + + // 导出数据表格 + saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "") + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + + c.FileAttachment(saveFilePath, fileName) +} diff --git a/src/modules/network_data/model/cdr_event.go b/src/modules/network_data/model/cdr_event_ims.go similarity index 83% rename from src/modules/network_data/model/cdr_event.go rename to src/modules/network_data/model/cdr_event_ims.go index ae49041f..ffe280c5 100644 --- a/src/modules/network_data/model/cdr_event.go +++ b/src/modules/network_data/model/cdr_event_ims.go @@ -2,20 +2,20 @@ package model import "time" -// CDREvent CDR会话对象 cdr_event_ims/cdr_event_smf -type CDREvent struct { +// CDREventIMS CDR会话对象IMS cdr_event_ims +type CDREventIMS struct { ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` NeType string `json:"neType" gorm:"column:ne_type"` NeName string `json:"neName" gorm:"column:ne_name"` - RmUID string `json:"rmUID" gorm:"column:rm_uid"` + RmUID string `json:"rmUID" gorm:"column:rm_uid"` // 可能没有 Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` CDRJSONStr string `json:"cdrJSON" gorm:"column:cdr_json"` CreatedAt time.Time `json:"createdAt" gorm:"column:created_at;default:CURRENT_TIMESTAMP"` } -// CDREventQuery CDR会话对象查询参数结构体 -type CDREventQuery struct { - NeType string `json:"neType" form:"neType" binding:"required"` // 网元类型 +// CDREventIMSQuery CDR会话对象IMS查询参数结构体 +type CDREventIMSQuery struct { + NeType string `json:"neType" form:"neType" binding:"required"` // 网元类型IMS NeID string `json:"neId" form:"neId" binding:"required"` RmUID string `json:"rmUID" form:"rmUID"` RecordType string `json:"recordType" form:"recordType"` // 记录行为 MOC MTC MOSM MTSM diff --git a/src/modules/network_data/repository/cdr_event.go b/src/modules/network_data/repository/cdr_event.go deleted file mode 100644 index bd5c562e..00000000 --- a/src/modules/network_data/repository/cdr_event.go +++ /dev/null @@ -1,27 +0,0 @@ -package repository - -import "be.ems/src/modules/network_data/model" - -// CDR会话事件 数据层接口 -type ICDREvent interface { - // SelectPage 根据条件分页查询 - SelectPage(querys model.CDREventQuery) map[string]any - - // SelectByIds 通过ID查询 - SelectByIds(cdrIds []string) []model.CDREvent - - // DeleteByIds 批量删除信息 - DeleteByIds(cdrIds []string) int64 -} - -// SMF CDR Event -type SMFCDREvent interface { - // SelectPage 根据条件分页查询 - SelectPage(querys model.SMFCDREventQuery) map[string]any - - // SelectByIds 通过ID查询 - SelectByIds(cdrIds []string) []model.CDREventSMF - - // DeleteByIds 批量删除信息 - DeleteByIds(cdrIds []string) int64 -} diff --git a/src/modules/network_data/repository/cdr_event.impl.go b/src/modules/network_data/repository/cdr_event.impl.go deleted file mode 100644 index c9903b8e..00000000 --- a/src/modules/network_data/repository/cdr_event.impl.go +++ /dev/null @@ -1,344 +0,0 @@ -package repository - -import ( - "fmt" - "strings" - - "be.ems/src/framework/datasource" - "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" - "be.ems/src/framework/utils/parse" - "be.ems/src/framework/utils/repo" - "be.ems/src/modules/network_data/model" -) - -// 实例化数据层 CDREventImpl 结构体 -var NewCDREventImpl = &CDREventImpl{ - selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, cdr_json, created_at from cdr_event_ims`, - - resultMap: map[string]string{ - "id": "ID", - "ne_type": "NeType", - "ne_name": "NeName", - "rm_uid": "RmUID", - "timestamp": "Timestamp", - "cdr_json": "CDRJSONStr", - "created_at": "CreatedAt", - }, -} - -// CDREventImpl CDR会话事件 数据层处理 -type CDREventImpl struct { - // 查询视图对象SQL - selectSql string - // 结果字段与实体映射 - resultMap map[string]string -} - -// Instance of SMF CDREventImpl -var NewSMFCDREventImpl = &SMFCDREventImpl{ - selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, JSON_EXTRACT(cdr_json, '$.recordType') AS record_type, JSON_EXTRACT(cdr_json, '$.chargingID') AS charging_id, JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') AS subscriber_id, JSON_EXTRACT(cdr_json, '$.duration') AS duration, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink') AS data_volume_uplink, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink') AS data_volume_downlink, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume') AS data_total_volume, JSON_EXTRACT(cdr_json, '$.pDUSessionChargingInformation.pDUAddress') AS pdu_address, created_at from cdr_event_smf`, - - resultMap: map[string]string{ - "id": "ID", - "ne_type": "NeType", - "ne_name": "NeName", - "rm_uid": "RmUID", - "timestamp": "Timestamp", - "record_type": "RecordType", - "charging_id": "ChargingID", - "subscriber_id": "SubscriberID", - "duration": "Duration", - "data_volume_uplink": "DataVolumeUplink", - "data_volume_downlink": "DataVolumeDownlink", - "data_total_volume": "DataTotalVolume", - "pdu_address": "PDUAddress", - "created_at": "CreatedAt", - }, -} - -// CDREventImpl CDR会话事件 数据层处理 -type SMFCDREventImpl struct { - // 查询视图对象SQL - selectSql string - // 结果字段与实体映射 - resultMap map[string]string -} - -// convertResultRows 将结果记录转实体结果组 -func (r *CDREventImpl) convertResultRows(rows []map[string]any) []model.CDREvent { - arr := make([]model.CDREvent, 0) - for _, row := range rows { - item := model.CDREvent{} - for key, value := range row { - if keyMapper, ok := r.resultMap[key]; ok { - repo.SetFieldValue(&item, keyMapper, value) - } - } - arr = append(arr, item) - } - return arr -} - -// SelectPage 根据条件分页查询 -func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any { - // 查询条件拼接 - var conditions []string - var params []any - if querys.NeType != "" { - conditions = append(conditions, "ne_type = ?") - params = append(params, querys.NeType) - } - if querys.RmUID != "" { - conditions = append(conditions, "rm_uid = ?") - params = append(params, querys.RmUID) - } - if querys.StartTime != "" { - conditions = append(conditions, "timestamp >= ?") - beginDate := date.ParseStrToDate(querys.StartTime, date.YYYY_MM_DD_HH_MM_SS) - params = append(params, beginDate.Unix()) - } - if querys.EndTime != "" { - conditions = append(conditions, "timestamp <= ?") - endDate := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS) - params = append(params, endDate.Unix()) - } - if querys.CallerParty != "" { - conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.callerParty') = ?") - params = append(params, querys.CallerParty) - } - if querys.CalledParty != "" { - conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.calledParty') = ?") - params = append(params, querys.CalledParty) - } - if querys.RecordType != "" { - recordTypes := strings.Split(querys.RecordType, ",") - placeholder := repo.KeyPlaceholderByQuery(len(recordTypes)) - conditions = append(conditions, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') in (%s)", placeholder)) - for _, recordType := range recordTypes { - params = append(params, recordType) - } - } - - // 构建查询条件语句 - whereSql := "" - if len(conditions) > 0 { - whereSql += " where " + strings.Join(conditions, " and ") - } - - result := map[string]any{ - "total": 0, - "rows": []model.CDREvent{}, - } - - // 查询数量 长度为0直接返回 - totalSql := "select count(1) as 'total' from cdr_event_ims" - totalRows, err := datasource.RawDB("", totalSql+whereSql, params) - if err != nil { - logger.Errorf("total err => %v", err) - return result - } - total := parse.Number(totalRows[0]["total"]) - if total == 0 { - return result - } else { - result["total"] = total - } - - // 分页 - pageNum, pageSize := repo.PageNumSize(querys.PageNum, querys.PageSize) - pageSql := " limit ?,? " - params = append(params, pageNum*pageSize) - params = append(params, pageSize) - - // 排序 - orderSql := "" - if querys.SortField != "" { - sortSql := querys.SortField - if querys.SortOrder != "" { - if querys.SortOrder == "desc" { - sortSql += " desc " - } else { - sortSql += " asc " - } - } - orderSql = fmt.Sprintf(" order by id desc, %s ", sortSql) - } - - // 查询数据 - querySql := r.selectSql + whereSql + orderSql + pageSql - results, err := datasource.RawDB("", querySql, params) - if err != nil { - logger.Errorf("query err => %v", err) - } - - // 转换实体 - result["rows"] = r.convertResultRows(results) - return result -} - -// SelectByIds 通过ID查询 -func (r *CDREventImpl) SelectByIds(cdrIds []string) []model.CDREvent { - placeholder := repo.KeyPlaceholderByQuery(len(cdrIds)) - querySql := r.selectSql + " where id in (" + placeholder + ")" - parameters := repo.ConvertIdsSlice(cdrIds) - results, err := datasource.RawDB("", querySql, parameters) - if err != nil { - logger.Errorf("query err => %v", err) - return []model.CDREvent{} - } - // 转换实体 - return r.convertResultRows(results) -} - -// DeleteByIds 批量删除信息 -func (r *CDREventImpl) DeleteByIds(cdrIds []string) int64 { - placeholder := repo.KeyPlaceholderByQuery(len(cdrIds)) - sql := "delete from cdr_event_ims where id in (" + placeholder + ")" - parameters := repo.ConvertIdsSlice(cdrIds) - results, err := datasource.ExecDB("", sql, parameters) - if err != nil { - logger.Errorf("delete err => %v", err) - return 0 - } - return results -} - -// convertResultRows 将结果记录转实体结果组 -func (r *SMFCDREventImpl) convertResultRows(rows []map[string]any) []model.CDREventSMF { - arr := make([]model.CDREventSMF, 0) - for _, row := range rows { - item := model.CDREventSMF{} - for key, value := range row { - if keyMapper, ok := r.resultMap[key]; ok { - repo.SetFieldValue(&item, keyMapper, value) - } - } - arr = append(arr, item) - } - return arr -} - -// SelectPage 根据条件分页查询 -func (r *SMFCDREventImpl) SelectPage(querys model.SMFCDREventQuery) map[string]any { - // 查询条件拼接 - var conditions []string - var params []any - if querys.NeType != "" { - conditions = append(conditions, "ne_type = ?") - params = append(params, querys.NeType) - } - if querys.RmUID != "" { - conditions = append(conditions, "rm_uid = ?") - params = append(params, querys.RmUID) - } - if querys.StartTime != "" { - conditions = append(conditions, "timestamp >= ?") - beginDate := date.ParseStrToDate(querys.StartTime, date.YYYY_MM_DD_HH_MM_SS) - params = append(params, beginDate.Unix()) - } - if querys.EndTime != "" { - conditions = append(conditions, "timestamp <= ?") - endDate := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS) - params = append(params, endDate.Unix()) - } - if querys.RecordType != "" { - conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.recordType') = ?") - params = append(params, querys.RecordType) - } - if querys.SubscriberID != "" { - conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') = ?") - params = append(params, querys.SubscriberID) - } - // if querys.RecordType != "" { - // recordTypes := strings.Split(querys.RecordType, ",") - // placeholder := repo.KeyPlaceholderByQuery(len(recordTypes)) - // conditions = append(conditions, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') in (%s)", placeholder)) - // for _, recordType := range recordTypes { - // params = append(params, recordType) - // } - // } - - // 构建查询条件语句 - whereSql := "" - if len(conditions) > 0 { - whereSql += " where " + strings.Join(conditions, " and ") - } - - result := map[string]any{ - "total": 0, - "rows": []model.CDREventSMF{}, - } - - // 查询数量 长度为0直接返回 - totalSql := "select count(1) as 'total' from cdr_event_smf" - totalRows, err := datasource.RawDB("", totalSql+whereSql, params) - if err != nil { - logger.Errorf("total err => %v", err) - return result - } - total := parse.Number(totalRows[0]["total"]) - if total == 0 { - return result - } else { - result["total"] = total - } - - // 分页 - pageNum, pageSize := repo.PageNumSize(querys.PageNum, querys.PageSize) - pageSql := " limit ?,? " - params = append(params, pageNum*pageSize) - params = append(params, pageSize) - - // 排序 - orderSql := "" - if querys.SortField != "" { - sortSql := querys.SortField - if querys.SortOrder != "" { - if querys.SortOrder == "desc" { - sortSql += " desc " - } else { - sortSql += " asc " - } - } - orderSql = fmt.Sprintf(" order by id desc, %s ", sortSql) - } - - // 查询数据 - querySql := r.selectSql + whereSql + orderSql + pageSql - results, err := datasource.RawDB("", querySql, params) - if err != nil { - logger.Errorf("query err => %v", err) - } - - // 转换实体 - result["rows"] = r.convertResultRows(results) - return result -} - -// SelectByIds 通过ID查询 -func (r *SMFCDREventImpl) SelectByIds(cdrIds []string) []model.CDREventSMF { - placeholder := repo.KeyPlaceholderByQuery(len(cdrIds)) - querySql := r.selectSql + " where id in (" + placeholder + ")" - parameters := repo.ConvertIdsSlice(cdrIds) - results, err := datasource.RawDB("", querySql, parameters) - if err != nil { - logger.Errorf("query err => %v", err) - return []model.CDREventSMF{} - } - // 转换实体 - return r.convertResultRows(results) -} - -// DeleteByIds 批量删除信息 -func (r *SMFCDREventImpl) DeleteByIds(cdrIds []string) int64 { - placeholder := repo.KeyPlaceholderByQuery(len(cdrIds)) - sql := "delete from cdr_event_smf where id in (" + placeholder + ")" - parameters := repo.ConvertIdsSlice(cdrIds) - results, err := datasource.ExecDB("", sql, parameters) - if err != nil { - logger.Errorf("delete err => %v", err) - return 0 - } - return results -} diff --git a/src/modules/network_data/repository/cdr_event_ims.go b/src/modules/network_data/repository/cdr_event_ims.go new file mode 100644 index 00000000..fcc9a7bb --- /dev/null +++ b/src/modules/network_data/repository/cdr_event_ims.go @@ -0,0 +1,15 @@ +package repository + +import "be.ems/src/modules/network_data/model" + +// CDR会话事件IMS 数据层接口 +type ICDREventIMS interface { + // SelectPage 根据条件分页查询 + SelectPage(querys model.CDREventIMSQuery) map[string]any + + // SelectByIds 通过ID查询 + SelectByIds(cdrIds []string) []model.CDREventIMS + + // DeleteByIds 批量删除信息 + DeleteByIds(cdrIds []string) int64 +} diff --git a/src/modules/network_data/repository/cdr_event_ims.impl.go b/src/modules/network_data/repository/cdr_event_ims.impl.go new file mode 100644 index 00000000..8ab83dda --- /dev/null +++ b/src/modules/network_data/repository/cdr_event_ims.impl.go @@ -0,0 +1,178 @@ +package repository + +import ( + "fmt" + "strings" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" + "be.ems/src/modules/network_data/model" +) + +// 实例化数据层 CDREventImpl 结构体 +var NewCDREventIMSImpl = &CDREventIMSImpl{ + selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, cdr_json, created_at from cdr_event_ims`, + + resultMap: map[string]string{ + "id": "ID", + "ne_type": "NeType", + "ne_name": "NeName", + "rm_uid": "RmUID", + "timestamp": "Timestamp", + "cdr_json": "CDRJSONStr", + "created_at": "CreatedAt", + }, +} + +// CDREventIMSImpl CDR会话事件IMS 数据层处理 +type CDREventIMSImpl struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *CDREventIMSImpl) convertResultRows(rows []map[string]any) []model.CDREventIMS { + arr := make([]model.CDREventIMS, 0) + for _, row := range rows { + item := model.CDREventIMS{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} + +// SelectPage 根据条件分页查询 +func (r *CDREventIMSImpl) SelectPage(querys model.CDREventIMSQuery) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if querys.NeType != "" { + conditions = append(conditions, "ne_type = ?") + params = append(params, querys.NeType) + } + if querys.RmUID != "" { + conditions = append(conditions, "rm_uid = ?") + params = append(params, querys.RmUID) + } + if querys.StartTime != "" { + conditions = append(conditions, "timestamp >= ?") + if len(querys.StartTime) == 13 { + querys.StartTime = querys.StartTime[:10] + } + params = append(params, querys.StartTime) + } + if querys.EndTime != "" { + conditions = append(conditions, "timestamp <= ?") + if len(querys.EndTime) == 13 { + querys.EndTime = querys.EndTime[:10] + } + params = append(params, querys.EndTime) + } + if querys.CallerParty != "" { + conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.callerParty') = ?") + params = append(params, querys.CallerParty) + } + if querys.CalledParty != "" { + conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.calledParty') = ?") + params = append(params, querys.CalledParty) + } + if querys.RecordType != "" { + recordTypes := strings.Split(querys.RecordType, ",") + placeholder := repo.KeyPlaceholderByQuery(len(recordTypes)) + conditions = append(conditions, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') in (%s)", placeholder)) + for _, recordType := range recordTypes { + params = append(params, recordType) + } + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.CDREventIMS{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from cdr_event_ims" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + return result + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return result + } else { + result["total"] = total + } + + // 分页 + pageNum, pageSize := repo.PageNumSize(querys.PageNum, querys.PageSize) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 排序 + orderSql := "" + if querys.SortField != "" { + sortSql := querys.SortField + if querys.SortOrder != "" { + if querys.SortOrder == "desc" { + sortSql += " desc " + } else { + sortSql += " asc " + } + } + orderSql = fmt.Sprintf(" order by id desc, %s ", sortSql) + } + + // 查询数据 + querySql := r.selectSql + whereSql + orderSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectByIds 通过ID查询 +func (r *CDREventIMSImpl) SelectByIds(cdrIds []string) []model.CDREventIMS { + placeholder := repo.KeyPlaceholderByQuery(len(cdrIds)) + querySql := r.selectSql + " where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(cdrIds) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.CDREventIMS{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// DeleteByIds 批量删除信息 +func (r *CDREventIMSImpl) DeleteByIds(cdrIds []string) int64 { + placeholder := repo.KeyPlaceholderByQuery(len(cdrIds)) + sql := "delete from cdr_event_ims where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(cdrIds) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} diff --git a/src/modules/network_data/service/cdr_event.go b/src/modules/network_data/service/cdr_event.go deleted file mode 100644 index b05234cd..00000000 --- a/src/modules/network_data/service/cdr_event.go +++ /dev/null @@ -1,21 +0,0 @@ -package service - -import "be.ems/src/modules/network_data/model" - -// CDR会话事件 服务层接口 -type ICDREvent interface { - // SelectPage 根据条件分页查询 - SelectPage(querys model.CDREventQuery) map[string]any - - // DeleteByIds 批量删除信息 - DeleteByIds(cdrIds []string) (int64, error) -} - -// CDR会话事件 服务层接口 -type SMFCDREvent interface { - // SelectPage 根据条件分页查询 - SelectPage(querys model.SMFCDREventQuery) map[string]any - - // DeleteByIds 批量删除信息 - DeleteByIds(cdrIds []string) (int64, error) -} diff --git a/src/modules/network_data/service/cdr_event.impl.go b/src/modules/network_data/service/cdr_event.impl.go deleted file mode 100644 index fef4a13c..00000000 --- a/src/modules/network_data/service/cdr_event.impl.go +++ /dev/null @@ -1,69 +0,0 @@ -package service - -import ( - "fmt" - - "be.ems/src/modules/network_data/model" - "be.ems/src/modules/network_data/repository" -) - -// 实例化数据层 CDREventImpl 结构体 -var NewCDREventImpl = &CDREventImpl{ - cdrEventRepository: repository.NewCDREventImpl, -} - -var NewSMFCDREventImpl = &SMFCDREventImpl{ - cdrEventRepository: repository.NewSMFCDREventImpl, -} - -// CDREventImpl CDR会话事件 服务层处理 -type CDREventImpl struct { - // CDR会话事件数据信息 - cdrEventRepository repository.ICDREvent -} - -type SMFCDREventImpl struct { - // CDR会话事件数据信息 - cdrEventRepository repository.SMFCDREvent -} - -// SelectPage 根据条件分页查询 -func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any { - return r.cdrEventRepository.SelectPage(querys) -} - -// DeleteByIds 批量删除信息 -func (r *CDREventImpl) DeleteByIds(cdrIds []string) (int64, error) { - // 检查是否存在 - ids := r.cdrEventRepository.SelectByIds(cdrIds) - if len(ids) <= 0 { - return 0, fmt.Errorf("not data") - } - - if len(ids) == len(cdrIds) { - rows := r.cdrEventRepository.DeleteByIds(cdrIds) - return rows, nil - } - // 删除信息失败! - return 0, fmt.Errorf("delete fail") -} - -func (r *SMFCDREventImpl) SelectPage(querys model.SMFCDREventQuery) map[string]any { - return r.cdrEventRepository.SelectPage(querys) -} - -// DeleteByIds 批量删除信息 -func (r *SMFCDREventImpl) DeleteByIds(cdrIds []string) (int64, error) { - // 检查是否存在 - ids := r.cdrEventRepository.SelectByIds(cdrIds) - if len(ids) <= 0 { - return 0, fmt.Errorf("not data") - } - - if len(ids) == len(cdrIds) { - rows := r.cdrEventRepository.DeleteByIds(cdrIds) - return rows, nil - } - // 删除信息失败! - return 0, fmt.Errorf("delete fail") -} diff --git a/src/modules/network_data/service/cdr_event_ims.go b/src/modules/network_data/service/cdr_event_ims.go new file mode 100644 index 00000000..2f5be53e --- /dev/null +++ b/src/modules/network_data/service/cdr_event_ims.go @@ -0,0 +1,12 @@ +package service + +import "be.ems/src/modules/network_data/model" + +// CDR会话事件IMS 服务层接口 +type ICDREventIMS interface { + // SelectPage 根据条件分页查询 + SelectPage(querys model.CDREventIMSQuery) map[string]any + + // DeleteByIds 批量删除信息 + DeleteByIds(cdrIds []string) (int64, error) +} diff --git a/src/modules/network_data/service/cdr_event_ims.impl.go b/src/modules/network_data/service/cdr_event_ims.impl.go new file mode 100644 index 00000000..15dfbd81 --- /dev/null +++ b/src/modules/network_data/service/cdr_event_ims.impl.go @@ -0,0 +1,40 @@ +package service + +import ( + "fmt" + + "be.ems/src/modules/network_data/model" + "be.ems/src/modules/network_data/repository" +) + +// 实例化数据层 NewCDREventIMSImpl 结构体 +var NewCDREventIMSImpl = &CDREventIMSImpl{ + cdrEventIMSRepository: repository.NewCDREventIMSImpl, +} + +// CDREventImpl CDR会话事件IMS 服务层处理 +type CDREventIMSImpl struct { + // CDR会话事件数据信息 + cdrEventIMSRepository repository.ICDREventIMS +} + +// SelectPage 根据条件分页查询 +func (r *CDREventIMSImpl) SelectPage(querys model.CDREventIMSQuery) map[string]any { + return r.cdrEventIMSRepository.SelectPage(querys) +} + +// DeleteByIds 批量删除信息 +func (r *CDREventIMSImpl) DeleteByIds(cdrIds []string) (int64, error) { + // 检查是否存在 + ids := r.cdrEventIMSRepository.SelectByIds(cdrIds) + if len(ids) <= 0 { + return 0, fmt.Errorf("not data") + } + + if len(ids) == len(cdrIds) { + rows := r.cdrEventIMSRepository.DeleteByIds(cdrIds) + return rows, nil + } + // 删除信息失败! + return 0, fmt.Errorf("delete fail") +} diff --git a/src/modules/ws/processor/cdr_connect.go b/src/modules/ws/processor/cdr_connect.go index bd05465c..fc8dc1e8 100644 --- a/src/modules/ws/processor/cdr_connect.go +++ b/src/modules/ws/processor/cdr_connect.go @@ -10,17 +10,17 @@ import ( neDataService "be.ems/src/modules/network_data/service" ) -// GetCDRConnect 获取CDR会话事件-IMS -func GetCDRConnect(requestID string, data any) ([]byte, error) { +// GetCDRConnectByIMS 获取CDR会话事件-IMS +func GetCDRConnectByIMS(requestID string, data any) ([]byte, error) { msgByte, _ := json.Marshal(data) - var query neDataModel.CDREventQuery + var query neDataModel.CDREventIMSQuery err := json.Unmarshal(msgByte, &query) if err != nil { logger.Warnf("ws processor GetCDRConnect err: %s", err.Error()) return nil, fmt.Errorf("query data structure error") } - dataMap := neDataService.NewCDREventImpl.SelectPage(query) + dataMap := neDataService.NewCDREventIMSImpl.SelectPage(query) resultByte, err := json.Marshal(result.Ok(map[string]any{ "requestId": requestID, "data": dataMap, @@ -28,17 +28,17 @@ func GetCDRConnect(requestID string, data any) ([]byte, error) { return resultByte, err } -// GetCDRConnect 获取CDR会话事件-SMF -func GetSMFCDRConnect(requestID string, data any) ([]byte, error) { +// GetCDRConnectBySMF 获取CDR会话事件-SMF +func GetCDRConnectBySMF(requestID string, data any) ([]byte, error) { msgByte, _ := json.Marshal(data) - var query neDataModel.SMFCDREventQuery + var query neDataModel.CDREventSMFQuery err := json.Unmarshal(msgByte, &query) if err != nil { logger.Warnf("ws processor GetCDRConnect err: %s", err.Error()) return nil, fmt.Errorf("query data structure error") } - dataMap := neDataService.NewSMFCDREventImpl.SelectPage(query) + dataMap := neDataService.NewCDREventSMFImpl.SelectPage(query) resultByte, err := json.Marshal(result.Ok(map[string]any{ "requestId": requestID, "data": dataMap,