From 1cfbfa2d1b9e3ed7f1e54738ce7579defd58327d Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 27 Dec 2024 18:25:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20UE=E4=BA=8B=E4=BB=B6AMF/MME=E5=8C=BA?= =?UTF-8?q?=E5=88=86=E7=BD=91=E5=85=83=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/network_data/controller/amf.go | 151 ++++++------------ src/modules/network_data/controller/mme.go | 107 ++----------- .../network_data/service/ue_event_amf.go | 102 +++++++++++- .../network_data/service/ue_event_mme.go | 91 +++++++++++ src/modules/ws/processor/ue_connect.go | 15 ++ src/modules/ws/service/ws_send.go | 4 +- 6 files changed, 272 insertions(+), 198 deletions(-) diff --git a/src/modules/network_data/controller/amf.go b/src/modules/network_data/controller/amf.go index 98ea42c9..cdbe1434 100644 --- a/src/modules/network_data/controller/amf.go +++ b/src/modules/network_data/controller/amf.go @@ -1,25 +1,20 @@ 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" neFetchlink "be.ems/src/modules/network_element/fetch_link" 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 结构体 @@ -48,12 +43,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("AMF", 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 // 查询数据 rows, total := s.ueEventService.SelectPage(querys) @@ -93,7 +88,7 @@ func (s *AMFController) UEExport(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 var querys model.UEEventAMFQuery - if err := c.ShouldBindBodyWith(&querys, binding.JSON); err != nil { + if err := c.ShouldBindBodyWithJSON(&querys); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -101,6 +96,13 @@ func (s *AMFController) UEExport(c *gin.Context) { if querys.PageSize > 10000 { querys.PageSize = 10000 } + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("AMF", 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 rows, total := s.ueEventService.SelectPage(querys) if total == 0 { // 导出数据记录为空 @@ -110,95 +112,8 @@ func (s *AMFController) UEExport(c *gin.Context) { // 导出文件名称 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.NewSysDictData.SelectDictDataByType("ue_event_type") - // 读取字典数据 UE 事件认证代码类型 - dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code") - // 读取字典数据 UE 事件CM状态 - dictUEEventCmState := sysService.NewSysDictData.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 = fmt.Sprint(v) - 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, "") + saveFilePath, err := s.ueEventService.ExportXlsx(rows, fileName, language) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return @@ -214,7 +129,7 @@ func (s *AMFController) NbInfoList(c *gin.Context) { language := ctx.AcceptLanguage(c) var query struct { NeId string `form:"neId" binding:"required"` - NbId string `form:"nbId"` + NbId string `form:"id"` } if err := c.ShouldBindQuery(&query); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -230,7 +145,7 @@ func (s *AMFController) NbInfoList(c *gin.Context) { // 网元直连 data, err := neFetchlink.AMFNbInfoList(neInfo, map[string]string{ - "nbId": query.NbId, + "id": query.NbId, }) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) @@ -239,3 +154,33 @@ func (s *AMFController) NbInfoList(c *gin.Context) { c.JSON(200, result.OkData(data)) } + +// 接入基站状态信息列表 +// +// GET /nb/list-cfg +func (s *AMFController) NbStateList(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var query struct { + NeId string `form:"neId" binding:"required"` + } + if err := c.ShouldBindQuery(&query); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元信息 + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("AMF", query.NeId) + if neInfo.NeId != query.NeId || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + // 网元直连 + data, err := neFetchlink.AMFGnbStateList(neInfo) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + + c.JSON(200, result.OkData(data)) +} diff --git a/src/modules/network_data/controller/mme.go b/src/modules/network_data/controller/mme.go index 6143dd6e..a6f49339 100644 --- a/src/modules/network_data/controller/mme.go +++ b/src/modules/network_data/controller/mme.go @@ -1,24 +1,18 @@ 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" neFetchlink "be.ems/src/modules/network_element/fetch_link" 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" ) @@ -49,12 +43,12 @@ func (s *MMEController) 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("MME", 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 // 查询数据 rows, total := s.ueEventService.SelectPage(querys) @@ -102,6 +96,13 @@ func (s *MMEController) UEExport(c *gin.Context) { if querys.PageSize > 10000 { querys.PageSize = 10000 } + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("MME", 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 rows, total := s.ueEventService.SelectPage(querys) if total == 0 { // 导出数据记录为空 @@ -111,84 +112,8 @@ func (s *MMEController) UEExport(c *gin.Context) { // 导出文件名称 fileName := fmt.Sprintf("mme_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.NewSysDictData.SelectDictDataByType("ue_event_type") - // 读取字典数据 UE 事件认证代码类型 - dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code") - // 读取字典数据 UE 事件CM状态 - dictUEEventCmState := sysService.NewSysDictData.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 := row.EventType - for _, v := range dictUEEventType { - if row.EventType == v.DictValue { - eventType = i18n.TKey(language, v.DictLabel) - break - } - } - // 取结果 - eventResult := "" - if v, ok := eventJSON["result"]; ok && v != nil { - eventResult = v.(string) - if row.EventType == "auth-result" { - for _, v := range dictUEAauthCode { - if eventResult == v.DictValue { - eventResult = i18n.TKey(language, v.DictLabel) - break - } - } - } - if row.EventType == "cm-state" { - for _, v := range dictUEEventCmState { - if eventResult == v.DictValue { - eventResult = i18n.TKey(language, v.DictLabel) - break - } - } - } - } - // 取时间 - timeStr := "" - if v, ok := eventJSON["timestamp"]; ok && v != nil { - rowTime := parse.Number(v) - timeStr = date.ParseDateToStr(rowTime, date.YYYY_MM_DDTHH_MM_SSZ) - } - - 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, "") + saveFilePath, err := s.ueEventService.ExportXlsx(rows, fileName, language) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return @@ -204,7 +129,7 @@ func (s *MMEController) NbInfoList(c *gin.Context) { language := ctx.AcceptLanguage(c) var query struct { NeId string `form:"neId" binding:"required"` - NbId string `form:"nbId"` + NbId string `form:"id"` } if err := c.ShouldBindQuery(&query); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -220,7 +145,7 @@ func (s *MMEController) NbInfoList(c *gin.Context) { // 网元直连 data, err := neFetchlink.MMENbInfoList(neInfo, map[string]string{ - "nbId": query.NbId, + "id": query.NbId, }) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) diff --git a/src/modules/network_data/service/ue_event_amf.go b/src/modules/network_data/service/ue_event_amf.go index 8ba7cc3d..63234e6c 100644 --- a/src/modules/network_data/service/ue_event_amf.go +++ b/src/modules/network_data/service/ue_event_amf.go @@ -1,10 +1,16 @@ package service import ( + "encoding/json" "fmt" + "strconv" + "be.ems/src/framework/i18n" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/file" "be.ems/src/modules/network_data/model" "be.ems/src/modules/network_data/repository" + sysService "be.ems/src/modules/system/service" ) // 实例化数据层 UEEventAMF 结构体 @@ -14,8 +20,7 @@ var NewUEEventAMF = &UEEventAMF{ // UEEventAMF UE会话事件AMF 服务层处理 type UEEventAMF struct { - // UE会话事件数据信息 - ueEventRepository *repository.UEEventAMF + ueEventRepository *repository.UEEventAMF // UE会话事件数据信息 } // SelectPage 根据条件分页查询 @@ -38,3 +43,96 @@ func (r *UEEventAMF) DeleteByIds(ueIds []string) (int64, error) { // 删除信息失败! return 0, fmt.Errorf("delete fail") } + +// ExportXlsx 导出数据到 xlsx 文件 +func (r UEEventAMF) ExportXlsx(rows []model.UEEventAMF, fileName, language string) (string, error) { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "IMSI", + "C1": "Event Type", + "D1": "Result", + "E1": "Time", + } + // 读取字典数据 UE 事件类型 + dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type") + // 读取字典数据 UE 事件认证代码类型 + dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code") + // 读取字典数据 UE 事件CM状态 + dictUEEventCmState := sysService.NewSysDictData.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 = fmt.Sprint(v) + 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, + }) + } + + // 导出数据表格 + return file.WriteSheet(headerCells, dataCells, fileName, "") +} diff --git a/src/modules/network_data/service/ue_event_mme.go b/src/modules/network_data/service/ue_event_mme.go index 2768686f..7f35a19b 100644 --- a/src/modules/network_data/service/ue_event_mme.go +++ b/src/modules/network_data/service/ue_event_mme.go @@ -1,10 +1,18 @@ package service import ( + "encoding/json" "fmt" + "strconv" + "be.ems/src/framework/i18n" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/date" + "be.ems/src/framework/utils/file" + "be.ems/src/framework/utils/parse" "be.ems/src/modules/network_data/model" "be.ems/src/modules/network_data/repository" + sysService "be.ems/src/modules/system/service" ) // 实例化数据层 UEEventMME 结构体 @@ -37,3 +45,86 @@ func (r *UEEventMME) DeleteByIds(ueIds []string) (int64, error) { // 删除信息失败! return 0, fmt.Errorf("delete fail") } + +// ExportXlsx 导出数据到 xlsx 文件 +func (r UEEventMME) ExportXlsx(rows []model.UEEventMME, fileName, language string) (string, error) { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "IMSI", + "C1": "Event Type", + "D1": "Result", + "E1": "Time", + } + // 读取字典数据 UE 事件类型 + dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type") + // 读取字典数据 UE 事件认证代码类型 + dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code") + // 读取字典数据 UE 事件CM状态 + dictUEEventCmState := sysService.NewSysDictData.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 := row.EventType + for _, v := range dictUEEventType { + if row.EventType == v.DictValue { + eventType = i18n.TKey(language, v.DictLabel) + break + } + } + // 取结果 + eventResult := "" + if v, ok := eventJSON["result"]; ok && v != nil { + eventResult = v.(string) + if row.EventType == "auth-result" { + for _, v := range dictUEAauthCode { + if eventResult == v.DictValue { + eventResult = i18n.TKey(language, v.DictLabel) + break + } + } + } + if row.EventType == "cm-state" { + for _, v := range dictUEEventCmState { + if eventResult == v.DictValue { + eventResult = i18n.TKey(language, v.DictLabel) + break + } + } + } + } + // 取时间 + timeStr := "" + if v, ok := eventJSON["timestamp"]; ok && v != nil { + rowTime := parse.Number(v) + timeStr = date.ParseDateToStr(rowTime, date.YYYY_MM_DDTHH_MM_SSZ) + } + + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.ID, + "B" + idx: imsi, + "C" + idx: eventType, + "D" + idx: eventResult, + "E" + idx: timeStr, + }) + } + + // 导出数据表格 + return file.WriteSheet(headerCells, dataCells, fileName, "") + +} diff --git a/src/modules/ws/processor/ue_connect.go b/src/modules/ws/processor/ue_connect.go index 7734e41f..b875e8e8 100644 --- a/src/modules/ws/processor/ue_connect.go +++ b/src/modules/ws/processor/ue_connect.go @@ -8,6 +8,7 @@ import ( "be.ems/src/framework/vo/result" neDataModel "be.ems/src/modules/network_data/model" neDataService "be.ems/src/modules/network_data/service" + neService "be.ems/src/modules/network_element/service" ) // GetUEConnectByAMF 获取UE会话事件-AMF @@ -20,6 +21,13 @@ func GetUEConnectByAMF(requestID string, data any) ([]byte, error) { return nil, fmt.Errorf("query data structure error") } + // 查询网元获取IP + neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID("AMF", query.NeID) + if neInfo.NeId != query.NeID || neInfo.IP == "" { + return nil, fmt.Errorf("not fount neId info") + } + query.RmUID = neInfo.RmUID + rows, total := neDataService.NewUEEventAMF.SelectPage(query) resultByte, err := json.Marshal(result.Ok(map[string]any{ "requestId": requestID, @@ -38,6 +46,13 @@ func GetUEConnectByMME(requestID string, data any) ([]byte, error) { return nil, fmt.Errorf("query data structure error") } + // 查询网元获取IP + neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID("MME", query.NeID) + if neInfo.NeId != query.NeID || neInfo.IP == "" { + return nil, fmt.Errorf("not fount neId info") + } + query.RmUID = neInfo.RmUID + rows, total := neDataService.NewUEEventMME.SelectPage(query) resultByte, err := json.Marshal(result.Ok(map[string]any{ "requestId": requestID, diff --git a/src/modules/ws/service/ws_send.go b/src/modules/ws/service/ws_send.go index 70d81682..eba535b4 100644 --- a/src/modules/ws/service/ws_send.go +++ b/src/modules/ws/service/ws_send.go @@ -30,10 +30,10 @@ const ( GROUP_SMSC_CDR = "1007_" // 组号-SGWC_CDR会话事件 1008_neId GROUP_SGWC_CDR = "1008_" - // 组号-AMF_UE会话事件 + // 组号-AMF_UE会话事件 1010_neId GROUP_AMF_UE = "1010" // 组号-MME_UE会话事件 1011_neId - GROUP_MME_UE = "1011_" + GROUP_MME_UE = "1011" ) // 实例化服务层 WSSend 结构体