From a57799c470e54d1c4f5cd1cdac903885a1f03e38 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 7 Jun 2024 19:44:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20AMF=E4=BA=8B=E4=BB=B6UE=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/network_data/controller/amf.go | 142 +++++++++++++++++- .../network_data/repository/ue_event.impl.go | 13 +- src/modules/ws/processor/ue_connect.go | 4 +- 3 files changed, 146 insertions(+), 13 deletions(-) diff --git a/src/modules/network_data/controller/amf.go b/src/modules/network_data/controller/amf.go index 4611797b..d1cbf007 100644 --- a/src/modules/network_data/controller/amf.go +++ b/src/modules/network_data/controller/amf.go @@ -1,16 +1,24 @@ 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/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" ) // 实例化控制层 AMFController 结构体 @@ -41,12 +49,12 @@ func (s *AMFController) UEList(c *gin.Context) { } // 查询网元获取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.ueEventService.SelectPage(querys) @@ -78,3 +86,125 @@ func (s *AMFController) UERemove(c *gin.Context) { msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } + +// UE会话列表导出 +// +// POST /ue/export +func (s *AMFController) UEExport(c *gin.Context) { + language := ctx.AcceptLanguage(c) + // 查询结果,根据查询条件结果,单页最大值限制 + var querys model.UEEventQuery + 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.ueEventService.SelectPage(querys) + if parse.Number(data["total"]) == 0 { + // 导出数据记录为空 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) + return + } + rows := data["rows"].([]model.UEEvent) + + // 导出文件名称 + fileName := fmt.Sprintf("amf_ue_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "IMSI", + "C1": "Event Type", + "D1": "Result", + "E1": "Time", + } + // 读取字典数据 UE 事件类型 + dictUEEventType := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_type") + // 读取字典数据 UE 事件认证代码类型 + dictUEAauthCode := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_auth_code") + // 读取字典数据 UE 事件CM状态 + dictUEEventCmState := sysService.NewSysDictDataImpl.SelectDictDataByType("ue_event_cm_state") + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 解析 JSON 字符串为 map + var eventJSON map[string]interface{} + err := json.Unmarshal([]byte(row.EventJSONStr), &eventJSON) + if err != nil { + logger.Warnf("UEExport Error parsing JSON: %s", err.Error()) + continue + } + + // 取IMSI + imsi := "" + if v, ok := eventJSON["imsi"]; ok && v != nil { + imsi = v.(string) + } + // 取类型 + eventType := "" + for _, v := range dictUEEventType { + if row.EventType == v.DictValue { + eventType = i18n.TKey(language, v.DictLabel) + break + } + } + // 取结果 + eventResult := "" + // 取时间 + timeStr := "" + if row.EventType == "auth-result" { + if v, ok := eventJSON["authTime"]; ok && v != nil { + timeStr = v.(string) + } + if v, ok := eventJSON["authCode"]; ok && v != nil { + eventResult = v.(string) + for _, v := range dictUEAauthCode { + if eventResult == v.DictValue { + eventResult = i18n.TKey(language, v.DictLabel) + break + } + } + } + } + if row.EventType == "detach" { + if v, ok := eventJSON["detachTime"]; ok && v != nil { + timeStr = v.(string) + } + eventResult = "Success" + } + if row.EventType == "cm-state" { + if v, ok := eventJSON["changeTime"]; ok && v != nil { + timeStr = v.(string) + } + if v, ok := eventJSON["status"]; ok && v != nil { + eventResult = v.(string) + for _, v := range dictUEEventCmState { + if eventResult == v.DictValue { + eventResult = i18n.TKey(language, v.DictLabel) + break + } + } + } + } + + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.ID, + "B" + idx: imsi, + "C" + idx: eventType, + "D" + idx: eventResult, + "E" + 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/repository/ue_event.impl.go b/src/modules/network_data/repository/ue_event.impl.go index fa8c38f6..4ecf23c3 100644 --- a/src/modules/network_data/repository/ue_event.impl.go +++ b/src/modules/network_data/repository/ue_event.impl.go @@ -6,7 +6,6 @@ import ( "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" @@ -66,13 +65,17 @@ func (r *UEEventImpl) SelectPage(querys model.UEEventQuery) map[string]any { } 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 len(querys.StartTime) == 13 { + querys.StartTime = querys.StartTime[:10] + } + params = append(params, querys.StartTime) } 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 len(querys.EndTime) == 13 { + querys.EndTime = querys.EndTime[:10] + } + params = append(params, querys.EndTime) } if querys.IMSI != "" { conditions = append(conditions, "JSON_EXTRACT(event_json, '$.imsi') = ?") diff --git a/src/modules/ws/processor/ue_connect.go b/src/modules/ws/processor/ue_connect.go index 29caace6..32a4d7c8 100644 --- a/src/modules/ws/processor/ue_connect.go +++ b/src/modules/ws/processor/ue_connect.go @@ -10,8 +10,8 @@ import ( neDataService "be.ems/src/modules/network_data/service" ) -// GetUEConnect 获取UE会话事件-AMF -func GetUEConnect(requestID string, data any) ([]byte, error) { +// GetUEConnectByAMF 获取UE会话事件-AMF +func GetUEConnectByAMF(requestID string, data any) ([]byte, error) { msgByte, _ := json.Marshal(data) var query neDataModel.UEEventQuery err := json.Unmarshal(msgByte, &query)