ref: v3变更,,api路由调整,菜单角色分配
This commit is contained in:
@@ -53,7 +53,7 @@ type AlarmController struct {
|
||||
// @Security TokenAuth
|
||||
// @Summary Alarm List
|
||||
// @Description Alarm List
|
||||
// @Router /neData/alarm/list [get]
|
||||
// @Router /ne/data/alarm/list [get]
|
||||
func (s AlarmController) List(c *gin.Context) {
|
||||
var query model.AlarmQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
@@ -229,7 +229,7 @@ func (s AlarmController) CountTop(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary Alarm List Export
|
||||
// @Description Alarm List Export
|
||||
// @Router /neData/alarm/export [get]
|
||||
// @Router /ne/data/alarm/export [get]
|
||||
func (s AlarmController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
@@ -38,7 +38,7 @@ type AlarmForwardController struct {
|
||||
// @Security TokenAuth
|
||||
// @Summary Alarm Forward Log List
|
||||
// @Description Alarm Forward Log List
|
||||
// @Router /neData/alarm/forward/log/list [get]
|
||||
// @Router /ne/data/data/alarm/forward/log/list [get]
|
||||
func (s AlarmForwardController) List(c *gin.Context) {
|
||||
var query model.AlarmForwardLogQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
@@ -44,7 +44,7 @@ type AlarmLogController struct {
|
||||
// @Security TokenAuth
|
||||
// @Summary AlarmLog List
|
||||
// @Description AlarmLog List
|
||||
// @Router /neData/alarm/log/list [get]
|
||||
// @Router /ne/data/alarm/log/list [get]
|
||||
func (s AlarmLogController) List(c *gin.Context) {
|
||||
var query model.AlarmLogQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
@@ -77,7 +77,7 @@ func (s AlarmLogController) List(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary Alarm Event Log List
|
||||
// @Description Alarm Event Log List
|
||||
// @Router /neData/alarm/log/event [get]
|
||||
// @Router /ne/data/alarm/log/event [get]
|
||||
func (s AlarmLogController) Event(c *gin.Context) {
|
||||
var query model.AlarmEventQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
@@ -1,251 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 AMFController 结构体
|
||||
var NewAMF = &AMFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
ueEventService: neDataService.NewUEEvent,
|
||||
}
|
||||
|
||||
// 网元AMF
|
||||
//
|
||||
// PATH /amf
|
||||
type AMFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEvent // UE会话事件服务
|
||||
}
|
||||
|
||||
// UE会话列表
|
||||
//
|
||||
// GET /ue/list
|
||||
//
|
||||
// @Tags ne_data/amf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neType query string true "NE Type only AMF" Enums(AMF)
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "imsi"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session List
|
||||
// @Description UE Session List
|
||||
// @Router /neData/amf/ue/list [get]
|
||||
func (s *AMFController) UEList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UE会话删除
|
||||
//
|
||||
// DELETE /ue/:id
|
||||
//
|
||||
// @Tags ne_data/amf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "list data id, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session Deletion
|
||||
// @Description UE Session Deletion
|
||||
// @Router /neData/amf/ue/{id} [delete]
|
||||
func (s *AMFController) UERemove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
uniqueIDs := parse.RemoveDuplicatesToArray(id, ",")
|
||||
// 转换成int64数组类型
|
||||
ids := make([]int64, 0)
|
||||
for _, v := range uniqueIDs {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.ueEventService.DeleteByIds("AMF", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, resp.OkMsg(msg))
|
||||
}
|
||||
|
||||
// UE会话列表导出
|
||||
//
|
||||
// GET /ue/export
|
||||
//
|
||||
// @Tags ne_data/amf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session List Export
|
||||
// @Description UE Session List Export
|
||||
// @Router /neData/amf/ue/export [get]
|
||||
func (s *AMFController) UEExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("amf_ue_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.ueEventService.ExportAMF(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 接入基站信息列表
|
||||
//
|
||||
// GET /nb/list
|
||||
//
|
||||
// @Tags ne_data/amf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param id query string false "Base Station ID"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Access Base Station Information List
|
||||
// @Description Access Base Station Information List
|
||||
// @Router /neData/amf/nb/list [get]
|
||||
func (s *AMFController) NbInfoList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
NbId string `form:"id"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.AMFNbInfoList(neInfo, map[string]string{
|
||||
"id": query.NbId,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 接入基站状态信息列表
|
||||
//
|
||||
// GET /nb/addrs
|
||||
//
|
||||
// @Tags ne_data/amf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Access to the base station status information list
|
||||
// @Description Access to the base station status information list
|
||||
// @Router /neData/amf/nb/addrs [get]
|
||||
func (s *AMFController) NbStateList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.AMFGnbStateList(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -1,317 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
neType = "CBC" // 网元类型
|
||||
)
|
||||
|
||||
// 实例化控制层 CBCController 结构体
|
||||
var NewCBC = &CBCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neCBCMessageService: neDataService.NewCBCMessage,
|
||||
}
|
||||
|
||||
// 网元CBC
|
||||
type CBCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neCBCMessageService *neDataService.CBCMessage // CBC消息服务
|
||||
}
|
||||
|
||||
func (m *CBCController) List(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
neId := c.Query("neId")
|
||||
if neId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
var query model.CBCMessageQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
query.NeType = neType
|
||||
query.NeId = neId
|
||||
|
||||
data, total, err := neDataService.NewCBCMessage.SelectByPage(query)
|
||||
if err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 转换数据格式,确保 MessageJson 正确序列化
|
||||
processedData := make([]map[string]interface{}, len(data))
|
||||
for i, msg := range data {
|
||||
var messageJson interface{}
|
||||
if len(msg.MessageJson) > 0 {
|
||||
// 尝试解析为 JSON 对象
|
||||
if err := json.Unmarshal(msg.MessageJson, &messageJson); err != nil {
|
||||
// 如果解析失败,就作为字符串
|
||||
messageJson = string(msg.MessageJson)
|
||||
}
|
||||
}
|
||||
|
||||
processedData[i] = map[string]interface{}{
|
||||
"id": msg.Id,
|
||||
"neType": msg.NeType,
|
||||
"neId": msg.NeId,
|
||||
"messageJson": messageJson, // 这里是解析后的 JSON 对象
|
||||
"status": msg.Status.Enum(),
|
||||
"detail": msg.Detail,
|
||||
"createdAt": msg.CreatedAt,
|
||||
"updatedAt": msg.UpdatedAt,
|
||||
}
|
||||
}
|
||||
c.JSON(200, resp.Ok(gin.H{
|
||||
"total": total,
|
||||
"data": processedData,
|
||||
}))
|
||||
}
|
||||
|
||||
// Update 更新CB消息
|
||||
func (m *CBCController) Insert(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 绑定请求体
|
||||
var msg model.CBCMessage
|
||||
msg.NeType = neType
|
||||
msg.NeId = c.Query("neId")
|
||||
msg.Status = model.CBCEventStatusInactive // 默认状态为 INACTIVE
|
||||
if msg.NeId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
now := time.Now().UnixMilli()
|
||||
msg.CreatedAt = now
|
||||
msg.UpdatedAt = now
|
||||
|
||||
// 使用 ShouldBindBodyWithJSON 读取请求体
|
||||
var jsonData interface{}
|
||||
if err := c.ShouldBindBodyWithJSON(&jsonData); err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 将绑定的数据转换为 JSON
|
||||
jsonBytes, err := json.Marshal(jsonData)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
msg.MessageJson = json.RawMessage(jsonBytes)
|
||||
|
||||
if err := neDataService.NewCBCMessage.Insert(msg); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// Update 更新CB消息
|
||||
func (m *CBCController) Update(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
// 获取路径参数
|
||||
messageId := c.Param("id")
|
||||
if messageId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(messageId, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
// 直接读取body为json.RawMessage
|
||||
var jsonData interface{}
|
||||
if err := c.ShouldBindBodyWithJSON(&jsonData); err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 将绑定的数据转换为 JSON
|
||||
jsonBytes, err := json.Marshal(jsonData)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
messageJson := json.RawMessage(jsonBytes)
|
||||
|
||||
if err := neDataService.NewCBCMessage.Update(id, messageJson); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// UpdateStatus 更新CB消息状态
|
||||
// 这里的 neId 参数是为了兼容性,实际更新状态时不需要使用它
|
||||
// 但为了保持与原有接口一致,仍然保留该参数
|
||||
// 如果需要根据 neId 进行特定的逻辑处理,可以在服务层实现
|
||||
// 但在当前实现中,neId 仅用于验证请求的有效性
|
||||
// 实际的状态更新逻辑不依赖于 neId
|
||||
// 该接口用于更新 CB 消息的状态,状态值通过查询参数传递
|
||||
// 例如:PUT /:neId/message/status?status=ACTIVE
|
||||
func (m *CBCController) UpdateStatus(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
neId := c.Query("neId")
|
||||
status := c.Param("status")
|
||||
if neId == "" || status == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
messageId := c.Param("id")
|
||||
if messageId != "" {
|
||||
id, err := strconv.ParseInt(messageId, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
// 如果提供了 messageId,则更新特定消息的状态
|
||||
if err := neDataService.NewCBCMessage.UpdateStatus(id, status); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
return
|
||||
}
|
||||
// 如果没有提供 messageId,则更新所有消息的状态
|
||||
if err := neDataService.NewCBCMessage.UpdateStatusByNeId(neId, status); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// Delete 删除CB消息
|
||||
func (m *CBCController) Delete(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
// 获取路径参数
|
||||
messageId := c.Param("id")
|
||||
if messageId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(messageId, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
if err := neDataService.NewCBCMessage.Delete(id); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// ListById 根据ID获取CB消息
|
||||
func (m *CBCController) ListById(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
// 获取路径参数
|
||||
idStr := c.Param("id")
|
||||
if idStr == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(idStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
data, err := neDataService.NewCBCMessage.SelectById(id)
|
||||
if err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
c.JSON(404, resp.CodeMsg(404, i18n.TKey(language, "app.common.err404")))
|
||||
return
|
||||
}
|
||||
// 转换数据格式,确保 MessageJson 正确序列化
|
||||
var messageJson interface{}
|
||||
if len(data.MessageJson) > 0 {
|
||||
// 尝试解析为 JSON 对象
|
||||
if err := json.Unmarshal(data.MessageJson, &messageJson); err != nil {
|
||||
// 如果解析失败,就作为字符串
|
||||
messageJson = string(data.MessageJson)
|
||||
}
|
||||
}
|
||||
|
||||
processedData := map[string]interface{}{
|
||||
"id": data.Id,
|
||||
"neType": data.NeType,
|
||||
"neId": data.NeId,
|
||||
"messageJson": messageJson, // 这里是解析后的 JSON 对象
|
||||
"status": data.Status.Enum(),
|
||||
"detail": data.Detail,
|
||||
"createdAt": data.CreatedAt,
|
||||
"updatedAt": data.UpdatedAt,
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(gin.H{
|
||||
"data": processedData,
|
||||
}))
|
||||
}
|
||||
|
||||
func (m *CBCController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var query model.CBCMessageQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
// 限制导出数据集
|
||||
if query.PageSize > 10000 {
|
||||
query.PageSize = 10000
|
||||
}
|
||||
// 查询数据
|
||||
rows, total, err := m.neCBCMessageService.SelectByPage(query)
|
||||
if err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("cbc_message_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := m.neCBCMessageService.ExportXlsx(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 IMSController 结构体
|
||||
var NewIMS = &IMSController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
kpiReportService: neDataService.NewKpiReport,
|
||||
}
|
||||
|
||||
// 网元IMS
|
||||
//
|
||||
// PATH /ims
|
||||
type IMSController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
kpiReportService *neDataService.KpiReport // 统计信息服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags ne_data/ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neType query string true "NE Type only IMS" Enums(IMS)
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param callerParty query string false "callerParty"
|
||||
// @Param calledParty query string false "calledParty"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List
|
||||
// @Description CDR Session List
|
||||
// @Router /neData/ims/cdr/list [get]
|
||||
func (s *IMSController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags ne_data/ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "list data id, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session Delete
|
||||
// @Description CDR Session Delete
|
||||
// @Router /neData/ims/cdr/{id} [delete]
|
||||
func (s *IMSController) CDRRemove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(422, resp.CodeMsg(442002, "bind err: id is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
uniqueIDs := parse.RemoveDuplicatesToArray(id, ",")
|
||||
// 转换成int64数组类型
|
||||
ids := make([]int64, 0)
|
||||
for _, v := range uniqueIDs {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds("IMS", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, resp.OkMsg(msg))
|
||||
}
|
||||
|
||||
// CDR会话列表导出
|
||||
//
|
||||
// GET /cdr/export
|
||||
//
|
||||
// @Tags ne_data/ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List Export
|
||||
// @Description CDR Session List Export
|
||||
// @Router /neData/ims/cdr/export [get]
|
||||
func (s *IMSController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("ims_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportIMS(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 在线会话用户数量
|
||||
//
|
||||
// GET /session/num
|
||||
//
|
||||
// @Tags ne_data/ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Number of online session users
|
||||
// @Description Number of online session users
|
||||
// @Router /neData/ims/session/num [get]
|
||||
func (s *IMSController) UeSessionNum(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
num, err := neFetchlink.IMSUeSessionNum(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(num))
|
||||
}
|
||||
|
||||
// 在线会话用户列表信息
|
||||
//
|
||||
// GET /session/list
|
||||
//
|
||||
// @Tags ne_data/ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "imsi"
|
||||
// @Param msisdn query string false "msisdn"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/ims/session/list [get]
|
||||
func (s *IMSController) UeSessionList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi"`
|
||||
MSISDN string `form:"msisdn"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.IMSUeSessionList(neInfo, map[string]string{
|
||||
"imsi": query.IMSI,
|
||||
"msisdn": query.MSISDN,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// KPI 忙时统计
|
||||
//
|
||||
// GET /kpi/busy-hour
|
||||
//
|
||||
// @Tags network_data/ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param timestamp query int64 false "timestamp"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Busy hour statistics
|
||||
// @Description Busy hour statistics
|
||||
// @Router /neData/ims/kpi/busy-hour [get]
|
||||
func (s IMSController) KPIBusyHour(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
Timestamp int64 `form:"timestamp" binding:"required"` // 时间戳毫秒 年月日返回每小时的总和 年月日时返回该小时的总和
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
if query.Timestamp < 1e12 || query.Timestamp > 1e13 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "timestamp format is ms"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.kpiReportService.IMSBusyHour(neInfo.CoreUID, neInfo.NeUID, query.Timestamp)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -44,7 +44,7 @@ type KPIController struct {
|
||||
// @Security TokenAuth
|
||||
// @Summary Access to statistical data
|
||||
// @Description Access to statistical data
|
||||
// @Router /neData/kpi/data [get]
|
||||
// @Router /ne/data/kpi/data [get]
|
||||
func (s KPIController) KPIData(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.KPIQuery
|
||||
@@ -78,7 +78,7 @@ func (s KPIController) KPIData(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary Get Statistical Headings
|
||||
// @Description Get Statistical Headings
|
||||
// @Router /neData/kpi/title [get]
|
||||
// @Router /ne/data/kpi/title [get]
|
||||
func (s KPIController) KPITitle(c *gin.Context) {
|
||||
neType := c.Query("neType")
|
||||
if neType == "" {
|
||||
@@ -46,7 +46,7 @@ type KPICController struct {
|
||||
// @Security TokenAuth
|
||||
// @Summary Access to statistical data
|
||||
// @Description Access to statistical data
|
||||
// @Router /neData/kpic/data [get]
|
||||
// @Router /ne/data/kpic/data [get]
|
||||
func (s KPICController) KPIData(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.KPICQuery
|
||||
@@ -1,251 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 MMEController 结构体
|
||||
var NewMME = &MMEController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
ueEventService: neDataService.NewUEEvent,
|
||||
}
|
||||
|
||||
// 网元MME
|
||||
//
|
||||
// PATH /mme
|
||||
type MMEController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEvent // UE会话事件服务
|
||||
}
|
||||
|
||||
// UE会话列表
|
||||
//
|
||||
// GET /ue/list
|
||||
//
|
||||
// @Tags ne_data/mme
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neType query string true "NE Type only MME" Enums(MME)
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "imsi"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session List
|
||||
// @Description UE Session List
|
||||
// @Router /neData/mme/ue/list [get]
|
||||
func (s *MMEController) UEList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UE会话删除
|
||||
//
|
||||
// DELETE /ue/:id
|
||||
//
|
||||
// @Tags ne_data/mme
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "list data id, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session Deletion
|
||||
// @Description UE Session Deletion
|
||||
// @Router /neData/mme/ue/{id} [delete]
|
||||
func (s *MMEController) UERemove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
uniqueIDs := parse.RemoveDuplicatesToArray(id, ",")
|
||||
// 转换成int64数组类型
|
||||
ids := make([]int64, 0)
|
||||
for _, v := range uniqueIDs {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.ueEventService.DeleteByIds("MME", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, resp.OkMsg(msg))
|
||||
}
|
||||
|
||||
// UE会话列表导出
|
||||
//
|
||||
// GET /ue/export
|
||||
//
|
||||
// @Tags ne_data/mme
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session List Export
|
||||
// @Description UE Session List Export
|
||||
// @Router /neData/mme/ue/export [get]
|
||||
func (s *MMEController) UEExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("mme_ue_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.ueEventService.ExportMME(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 接入基站信息列表
|
||||
//
|
||||
// GET /nb/list
|
||||
//
|
||||
// @Tags ne_data/mme
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param id query string false "Base Station ID"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Access Base Station Information List
|
||||
// @Description Access Base Station Information List
|
||||
// @Router /neData/mme/nb/list [get]
|
||||
func (s *MMEController) NbInfoList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
NbId string `form:"id"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.MMENbInfoList(neInfo, map[string]string{
|
||||
"id": query.NbId,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 接入基站状态信息列表
|
||||
//
|
||||
// GET /nb/addrs
|
||||
//
|
||||
// @Tags ne_data/mme
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Access to the base station status information list
|
||||
// @Description Access to the base station status information list
|
||||
// @Router /neData/mme/nb/addrs [get]
|
||||
func (s *MMEController) NbStateList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.MMEEnbStateList(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 N3IWFController 结构体
|
||||
var NewN3IWF = &N3IWFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// 网元N3IWF
|
||||
//
|
||||
// PATH /n3iwf
|
||||
type N3IWFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// 在线订阅用户列表信息
|
||||
//
|
||||
// GET /sub/list
|
||||
//
|
||||
// @Tags ne_data/n3iwf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "imsi"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/n3iwf/sub/list [get]
|
||||
func (s N3IWFController) SubUserList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.N3IWFSubInfoList(neInfo, map[string]string{
|
||||
"imsi": query.IMSI,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 NSSFController 结构体
|
||||
var NewNSSF = &NSSFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// 网元NSSF
|
||||
//
|
||||
// PATH /NSSF
|
||||
type NSSFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// 在线订阅用户列表信息
|
||||
//
|
||||
// GET /sub/list
|
||||
//
|
||||
// @Tags ne_data/nssf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/nssf/sub/list [get]
|
||||
func (s NSSFController) SubUserList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.NSSFSubInfoList(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 可用AMF列表信息
|
||||
//
|
||||
// GET /amf/list
|
||||
//
|
||||
// @Tags ne_data/nssf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/nssf/amf/list [get]
|
||||
func (s NSSFController) AvailableList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.NSSFAvailableAMFList(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -1,334 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 PCFController 结构体
|
||||
var NewPCF = &PCFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// 网元PCF
|
||||
//
|
||||
// PATH /pcf
|
||||
type PCFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// 策略配置列表
|
||||
//
|
||||
// GET /rule/list
|
||||
//
|
||||
// @Tags network_data/pcf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "IMSI"
|
||||
// @Param msisdn query string false "MSISDN"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Policy Configuration List
|
||||
// @Description Policy Configuration List
|
||||
// @Router /ne/link/pcf/rule/list [get]
|
||||
func (s PCFController) RuleInfoList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi"`
|
||||
MSISDN string `form:"msisdn"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.PCFRuleInfo(neInfo, map[string]string{
|
||||
"imsi": query.IMSI,
|
||||
"msisdn": query.MSISDN,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 策略配置添加
|
||||
//
|
||||
// POST /rule
|
||||
//
|
||||
// @Tags network_data/pcf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Policy Configuration Additions
|
||||
// @Description Policy Configuration Additions
|
||||
// @Router /ne/link/pcf/rule [post]
|
||||
func (s PCFController) RuleInfoAdd(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
Num int64 `json:"num"` // 批量添加 大于1时imsi/msisdn会累加数值
|
||||
ParamData map[string]any `json:"paramData" binding:"required"` // 参数数据
|
||||
// Imsi string `json:"imsi" binding:"required"`
|
||||
// Msisdn string `json:"msisdn" binding:"required"`
|
||||
// Sar string `json:"sar"` // 根据PCF参数配置Service Area Restriction -> Name
|
||||
// PccRules string `json:"pccRules"` // 根据PCF参数配置PCC Rules -> Rule ID
|
||||
// QosAudio string `json:"qosAudio"` // 根据PCF参数配置QoS Template -> QoS ID
|
||||
// QosVideo string `json:"qosVideo"` // 根据PCF参数配置QoS Template -> QoS ID
|
||||
// SessRules string `json:"sessRules"` // 根据PCF参数配置Session Rules -> Rule ID
|
||||
// HdrEnrich string `json:"hdrEnrich"` // 根据PCF参数配置Header Enrich Template -> Template Name
|
||||
// UePolicy string `json:"uePolicy"` // UE策略模板(样例: uep_001)
|
||||
// Rfsp int64 `json:"rfsp"` // 无线频率选择优先级
|
||||
}
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
var err error
|
||||
if body.Num > 1 { // 批量添加
|
||||
err = neFetchlink.PCFRuleAddBatch(neInfo, body.ParamData, body.Num)
|
||||
} else { // 单条添加
|
||||
err = neFetchlink.PCFRuleAdd(neInfo, body.ParamData)
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// 策略配置更新
|
||||
//
|
||||
// PUT /rule
|
||||
//
|
||||
// @Tags network_data/pcf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Policy Configuration Updates
|
||||
// @Description Policy Configuration Updates
|
||||
// @Router /ne/link/pcf/rule [put]
|
||||
func (s PCFController) RuleInfoEdit(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
CoreUID string `json:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" binding:"required"` // 网元唯一标识
|
||||
Num int64 `json:"num"` // 更新数量
|
||||
ParamData map[string]any `json:"paramData" binding:"required"` // 参数数据
|
||||
// Imsi string `json:"imsi" binding:"required"`
|
||||
// Msisdn string `json:"msisdn" binding:"required"`
|
||||
// Sar string `json:"sar"` // 根据PCF参数配置Service Area Restriction -> Name
|
||||
// PccRules string `json:"pccRules"` // 根据PCF参数配置PCC Rules -> Rule ID
|
||||
// QosAudio string `json:"qosAudio"` // 根据PCF参数配置QoS Template -> QoS ID
|
||||
// QosVideo string `json:"qosVideo"` // 根据PCF参数配置QoS Template -> QoS ID
|
||||
// SessRules string `json:"sessRules"` // 根据PCF参数配置Session Rules -> Rule ID
|
||||
// HdrEnrich string `json:"hdrEnrich"` // 根据PCF参数配置Header Enrich Template -> Template Name
|
||||
// UePolicy string `json:"uePolicy"` // UE策略模板(样例: uep_001)
|
||||
// Rfsp int64 `json:"rfsp"` // 无线频率选择优先级
|
||||
}
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
var err error
|
||||
if body.Num > 0 { // 批量更新
|
||||
err = neFetchlink.PCFRuleUpdateBatch(neInfo, body.ParamData, body.Num)
|
||||
} else { // 单条更新
|
||||
err = neFetchlink.PCFRuleUpdate(neInfo, body.ParamData)
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// 策略配置删除
|
||||
//
|
||||
// DELETE /rule
|
||||
//
|
||||
// @Tags network_data/pcf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string true "IMSi, batch deletion with quantity"
|
||||
// @Param num query number false "Number of deletions"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Policy Configuration Deletion
|
||||
// @Description Policy Configuration Deletion
|
||||
// @Router /ne/link/pcf/rule [delete]
|
||||
func (s PCFController) RuleInfoRemove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi" binding:"required"` // IMSi, 带数量时为批量删除
|
||||
Num int64 `form:"num"` // 删除数量
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
var err error
|
||||
if query.Num > 1 { // 批量删除
|
||||
err = neFetchlink.PCFRuleDeleteBatch(neInfo, query.IMSI, query.Num)
|
||||
} else { // 单条删除
|
||||
err = neFetchlink.PCFRuleDelete(neInfo, query.IMSI)
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// 策略配置导出
|
||||
//
|
||||
// GET /rule/export
|
||||
//
|
||||
// @Tags network_data/pcf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param fileType query string true "File Type" default(txt)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Policy Configuration Export
|
||||
// @Description Policy Configuration Export
|
||||
// @Router /ne/link/pcf/rule/export [get]
|
||||
func (s PCFController) RuleInfoExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
FileType string `form:"fileType" binding:"required,oneof=txt"` // 文件类型
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.PCFRuleExport(neInfo, map[string]string{
|
||||
"fileType": query.FileType,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Set("Content-Disposition", `attachment; filename="pcf_rule_export.txt"`)
|
||||
c.Data(200, "application/octet-stream", data)
|
||||
}
|
||||
|
||||
// 策略配置导入
|
||||
//
|
||||
// PUT /rule/import
|
||||
//
|
||||
// @Tags network_data/pcf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param fileType query string true "File Type" default(txt)
|
||||
// @Param filePath query string true "File Path" default(/tmp/pcfuser.txt)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Policy Configuration Import
|
||||
// @Description Policy Configuration Import
|
||||
// @Router /ne/link/pcf/rule/import [put]
|
||||
func (s PCFController) RuleInfoImport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
CoreUID string `json:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" binding:"required"` // 网元唯一标识
|
||||
FileType string `json:"fileType" binding:"required,oneof=txt"` // 文件类型
|
||||
FilePath string `json:"filePath" binding:"required"` // 网元端文件所在绝对路径
|
||||
}
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
output, err := neFetchlink.PCFRuleImport(neInfo, map[string]any{
|
||||
"type": body.FileType,
|
||||
"filePath": body.FilePath,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.OkMsg(output))
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SGWCController 结构体
|
||||
var NewSGWC = &SGWCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
UDMExtendService: neDataService.NewUDMExtend,
|
||||
}
|
||||
|
||||
// 网元SGWC
|
||||
//
|
||||
// PATH /sgwc
|
||||
type SGWCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
UDMExtendService *neDataService.UDMExtend // UDM用户信息服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags ne_data/sgwc
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neType query string true "NE Type only SGWC" Enums(SGWC)
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "imsi"
|
||||
// @Param msisdn query string false "msisdn"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List
|
||||
// @Description CDR Session List
|
||||
// @Router /neData/sgwc/cdr/list [get]
|
||||
func (s *SGWCController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags ne_data/sgwc
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "list data id, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session Delete
|
||||
// @Description CDR Session Delete
|
||||
// @Router /neData/sgwc/cdr/{id} [delete]
|
||||
func (s *SGWCController) CDRRemove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
uniqueIDs := parse.RemoveDuplicatesToArray(id, ",")
|
||||
// 转换成int64数组类型
|
||||
ids := make([]int64, 0)
|
||||
for _, v := range uniqueIDs {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds("SGWC", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, resp.OkMsg(msg))
|
||||
}
|
||||
|
||||
// CDR会话列表导出
|
||||
//
|
||||
// POST /cdr/export
|
||||
//
|
||||
// @Tags ne_data/sgwc
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List Export
|
||||
// @Description CDR Session List Export
|
||||
// @Router /neData/sgwc/cdr/export [post]
|
||||
func (s *SGWCController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("sgwc_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportSGWC(rows, fileName)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
@@ -1,283 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SMFController 结构体
|
||||
var NewSMF = &SMFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
UDMExtendService: neDataService.NewUDMExtend,
|
||||
}
|
||||
|
||||
// 网元SMF
|
||||
//
|
||||
// PATH /smf
|
||||
type SMFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
UDMExtendService *neDataService.UDMExtend // UDM用户信息服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags ne_data/smf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neType query string true "NE Type only SMF" Enums(SMF)
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param subscriberID query string false "subscriberID is IMSI"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List
|
||||
// @Description CDR Session List
|
||||
// @Router /neData/smf/cdr/list [get]
|
||||
func (s *SMFController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags ne_data/smf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "list data id, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session Delete
|
||||
// @Description CDR Session Delete
|
||||
// @Router /neData/smf/cdr/{id} [delete]
|
||||
func (s *SMFController) CDRRemove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
uniqueIDs := parse.RemoveDuplicatesToArray(id, ",")
|
||||
// 转换成int64数组类型
|
||||
ids := make([]int64, 0)
|
||||
for _, v := range uniqueIDs {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds("SMF", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, resp.OkMsg(msg))
|
||||
}
|
||||
|
||||
// CDR会话列表导出
|
||||
//
|
||||
// GET /cdr/export
|
||||
//
|
||||
// @Tags ne_data/smf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List Export
|
||||
// @Description CDR Session List Export
|
||||
// @Router /neData/smf/cdr/export [get]
|
||||
func (s *SMFController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("smf_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportSMF(rows, fileName)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 在线订阅用户数量
|
||||
//
|
||||
// GET /sub/num
|
||||
//
|
||||
// @Tags ne_data/smf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Number of online session users
|
||||
// @Description Number of online session users
|
||||
// @Router /neData/smf/sub/num [get]
|
||||
func (s *SMFController) SubUserNum(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
num, err := neFetchlink.SMFSubNum(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(num))
|
||||
}
|
||||
|
||||
// 在线订阅用户列表信息
|
||||
//
|
||||
// GET /sub/list
|
||||
//
|
||||
// @Tags ne_data/smf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "imsi"
|
||||
// @Param msisdn query string false "msisdn"
|
||||
// @Param upstate query string false "upstate"
|
||||
// @Param pageNum query string true "pageNum" default(50)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/smf/sub/list [get]
|
||||
func (s *SMFController) SubUserList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi"`
|
||||
MSISDN string `form:"msisdn"`
|
||||
Upstate string `form:"upstate"`
|
||||
PageNum string `form:"pageNum"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.SMFSubInfoList(neInfo, map[string]string{
|
||||
"imsi": query.IMSI,
|
||||
"msisdn": query.MSISDN,
|
||||
"upstate": query.Upstate,
|
||||
"pageNum": query.PageNum,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 对数据进行处理,去掉前缀,并加入imsi拓展信息
|
||||
rows := data["rows"].([]any)
|
||||
if len(rows) > 0 {
|
||||
arr := &rows
|
||||
for i := range *arr {
|
||||
item := (*arr)[i].(map[string]any)
|
||||
if v, ok := item["imsi"]; ok && v != nil {
|
||||
imsiStr := v.(string)
|
||||
imsiStr = strings.TrimPrefix(imsiStr, "imsi-")
|
||||
item["imsi"] = imsiStr
|
||||
// 查UDM拓展信息
|
||||
info := s.UDMExtendService.FindByIMSIAndNeID(neInfo.CoreUID, "%", imsiStr)
|
||||
item["remark"] = info.Remark
|
||||
}
|
||||
if v, ok := item["msisdn"]; ok && v != nil {
|
||||
item["msisdn"] = strings.TrimPrefix(v.(string), "msisdn-")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SMSCController 结构体
|
||||
var NewSMSC = &SMSCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
}
|
||||
|
||||
// 网元SMSC
|
||||
//
|
||||
// PATH /smsc
|
||||
type SMSCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags ne_data/smsc
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neType query string true "NE Type only SMSC" Enums(SMSC)
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param callerParty query string false "callerParty"
|
||||
// @Param calledParty query string false "calledParty"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List
|
||||
// @Description CDR Session List
|
||||
// @Router /neData/smsc/cdr/list [get]
|
||||
func (s *SMSCController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags ne_data/smsc
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "list data id, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session Delete
|
||||
// @Description CDR Session Delete
|
||||
// @Router /neData/smsc/cdr/{id} [delete]
|
||||
func (s *SMSCController) CDRRemove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
uniqueIDs := parse.RemoveDuplicatesToArray(id, ",")
|
||||
// 转换成int64数组类型
|
||||
ids := make([]int64, 0)
|
||||
for _, v := range uniqueIDs {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds("SMSC", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, resp.OkMsg(msg))
|
||||
}
|
||||
|
||||
// CDR会话列表导出
|
||||
//
|
||||
// GET /cdr/export
|
||||
//
|
||||
// @Tags ne_data/smsc
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List Export
|
||||
// @Description CDR Session List Export
|
||||
// @Router /neData/smsc/cdr/export [get]
|
||||
func (s *SMSCController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
coreUid := c.DefaultQuery("coreUid", "")
|
||||
neUid := c.DefaultQuery("neUid", "")
|
||||
if coreUid == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(coreUid, neUid)
|
||||
if neInfo.CoreUID != coreUid || neInfo.NeUID != neUid {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("smsc_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportSMSC(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
@@ -1,565 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/telnet"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neFetchlink "be.ems/src/modules/ne/fetch_link"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 UDMAuthController 结构体
|
||||
var NewUDMAuth = &UDMAuthController{
|
||||
udmAuthService: service.NewUDMAuthUser,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// UDM鉴权用户
|
||||
//
|
||||
// PATH /udm/auth
|
||||
type UDMAuthController struct {
|
||||
udmAuthService *service.UDMAuthUser // UDM鉴权信息服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// UDM鉴权用户重载数据
|
||||
//
|
||||
// PUT /reset
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authentication User Data Refresh
|
||||
// @Description UDM Authenticated User Data List Refresh Synchronization Latest
|
||||
// @Router /ne/link/udm/auth/reset [put]
|
||||
func (s *UDMAuthController) ResetData(c *gin.Context) {
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.udmAuthService.ResetData(query.CoreUID, query.NeUID)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDM鉴权用户列表
|
||||
//
|
||||
// GET /list
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "IMSI"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authentication User List
|
||||
// @Description UDM Authentication User List
|
||||
// @Router /ne/link/udm/auth/list [get]
|
||||
func (s *UDMAuthController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmAuthService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDM鉴权用户信息
|
||||
//
|
||||
// GET /:neId/:imsi
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param coreUid query string true "NE ID" default(001)
|
||||
// @Param neUid query string true "NE ID" default(001)
|
||||
// @Param imsi query string true "IMSI"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authentication User Information
|
||||
// @Description UDM Authentication User Information
|
||||
// @Router /ne/link/udm/auth [get]
|
||||
func (s *UDMAuthController) Info(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("dsp authdat:imsi=%s", query.IMSI)
|
||||
data, err := telnet.ConvertToMap(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
c.JSON(200, resp.ErrMsg("No Auth Data"))
|
||||
return
|
||||
}
|
||||
|
||||
// 解析返回的数据
|
||||
u := s.udmAuthService.ParseInfo(neInfo.CoreUID, neInfo.NeUID, query.IMSI, data)
|
||||
s.udmAuthService.Insert(neInfo.CoreUID, neInfo.NeUID, u)
|
||||
c.JSON(200, resp.OkData(u))
|
||||
}
|
||||
|
||||
// UDM鉴权用户新增
|
||||
//
|
||||
// POST /
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authentication User Added
|
||||
// @Description UDM Authentication User Added
|
||||
// @Router /ne/link/udm/auth [post]
|
||||
func (s *UDMAuthController) Add(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 传入数量大于0时,为批量新增
|
||||
num := parse.Number(c.Query("num"))
|
||||
if num < 0 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: num is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
var body model.UDMAuthUser
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
if body.IMSI == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: imsi is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 批量新增
|
||||
if num > 1 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("baa authdat:start_imsi=%s,sub_num=%d,", body.IMSI, num)
|
||||
cmd += s.udmAuthService.ParseCommandParams(body)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmAuthService.LoadData(neInfo.CoreUID, neInfo.NeUID, body.IMSI, num)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("add authdat:imsi=%s,", body.IMSI)
|
||||
cmd += s.udmAuthService.ParseCommandParams(body)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmAuthService.Insert(neInfo.CoreUID, neInfo.NeUID, body)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDM鉴权用户修改
|
||||
//
|
||||
// PUT /
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authenticated User Modification
|
||||
// @Description UDM Authenticated User Modification
|
||||
// @Router /ne/link/udm/auth [put]
|
||||
func (s *UDMAuthController) Edit(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.UDMAuthUser
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
if len(body.IMSI) != 15 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: IMSI length is not 15 bits"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("mod authdata:imsi=%s,", body.IMSI)
|
||||
cmd += s.udmAuthService.ParseCommandParams(body)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmAuthService.Insert(neInfo.CoreUID, neInfo.NeUID, body)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDM鉴权用户删除
|
||||
//
|
||||
// DELETE /:neId/:imsi
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param value path string true "IMSI, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authenticated User Deletion
|
||||
// @Description UDM Authenticated User Deletion
|
||||
// @Router /ne/link/udm/auth/{neId}/{value} [delete]
|
||||
func (s *UDMAuthController) Remove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi" binding:"required"` // IMSi
|
||||
Num int64 `form:"num"` // 数量 0可拼接imsi多删除 大于1为批量
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
if query.Num > 0 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("bde authdat:start_imsi=%s,sub_num=%d", query.IMSI, query.Num)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmAuthService.LoadData(neInfo.CoreUID, neInfo.NeUID, query.IMSI, query.Num)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
imsiArr := strings.Split(query.IMSI, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(imsiArr)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
}
|
||||
resultData := map[string]string{}
|
||||
for _, imsi := range uniqueIDs {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("del authdat:imsi=%s", imsi)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
resultData[imsi] = err.Error()
|
||||
continue
|
||||
}
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmAuthService.Delete(neInfo.CoreUID, neInfo.NeUID, imsi)
|
||||
}
|
||||
resultData[imsi] = data
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(resultData))
|
||||
}
|
||||
|
||||
// UDM鉴权用户导出
|
||||
//
|
||||
// GET /export
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param type query string true "File Type" Enums(csv,txt) default(txt)
|
||||
// @Param imsi query string false "IMSI"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authenticated User Export
|
||||
// @Description UDM Authenticated User Export
|
||||
// @Router /ne/link/udm/auth/export [get]
|
||||
func (s *UDMAuthController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
neUid := c.Query("neUid")
|
||||
if c.Query("coreUid") == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
fileType := c.Query("type")
|
||||
if !(fileType == "csv" || fileType == "txt") {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "file type error, only support csv,txt"))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmAuthService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
if len(rows) <= 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 文件名
|
||||
fileName := fmt.Sprintf("udm_auth_user_export_%s_%d.%s", neUid, time.Now().UnixMilli(), fileType)
|
||||
filePath := filepath.Join(file.ParseUploadFileDir(constants.UPLOAD_EXPORT), fileName)
|
||||
|
||||
if fileType == "csv" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
data = append(data, []string{"imsi", "ki", "algo", "amf", "opc"})
|
||||
for _, v := range rows {
|
||||
opc := v.Opc
|
||||
if opc == "-" {
|
||||
opc = ""
|
||||
}
|
||||
data = append(data, []string{v.IMSI, v.Ki, v.AlgoIndex, v.Amf, opc})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileCSV(data, filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if fileType == "txt" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
for _, v := range rows {
|
||||
opc := v.Opc
|
||||
if opc == "-" {
|
||||
opc = ""
|
||||
}
|
||||
data = append(data, []string{v.IMSI, v.Ki, v.AlgoIndex, v.Amf, opc})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.FileAttachment(filePath, fileName)
|
||||
}
|
||||
|
||||
// UDM鉴权用户导入
|
||||
//
|
||||
// POST /import
|
||||
//
|
||||
// @Tags network_data/udm/auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authenticated User Import
|
||||
// @Description UDM Authenticated User Import
|
||||
// @Router /ne/link/udm/auth/import [post]
|
||||
func (s *UDMAuthController) Import(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
CoreUID string `json:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" binding:"required"` // 网元唯一标识
|
||||
UploadPath string `json:"uploadPath" binding:"required"` // 上传文件路径
|
||||
TypeVal string `json:"typeVal" binding:"required,oneof=default k4"` // default: 默认导入方式, k4: k4类型导入方式
|
||||
TypeData any `json:"typeData"` // k4类型的数据密钥
|
||||
}
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断文件名
|
||||
if !(strings.HasSuffix(body.UploadPath, ".csv") || strings.HasSuffix(body.UploadPath, ".txt")) {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserAuthFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.CoreUID, neInfo.NeUID)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 本地文件
|
||||
localFilePath := file.ParseUploadFileAbsPath(body.UploadPath)
|
||||
neFilePath := fmt.Sprintf("/tmp/%s", filepath.Base(localFilePath))
|
||||
// 复制到远程
|
||||
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg("error uploading file"))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 结果信息
|
||||
var resultMsg string
|
||||
var resultErr error
|
||||
|
||||
// 默认的情况 发送MML
|
||||
if body.TypeVal == "default" {
|
||||
cmd := fmt.Sprintf("import authdat:path=%s", neFilePath)
|
||||
resultMsg, resultErr = telnet.ConvertToStr(telnetClient, cmd)
|
||||
}
|
||||
|
||||
// K4类型发特定请求
|
||||
if body.TypeVal == "k4" {
|
||||
resultMsg, resultErr = neFetchlink.UDMImportAuth(neInfo.IPAddr, map[string]any{
|
||||
"path": neFilePath, "k4": body.TypeData,
|
||||
})
|
||||
}
|
||||
|
||||
if resultErr != nil {
|
||||
c.JSON(200, resp.ErrMsg(resultErr.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(resultMsg, "ok") {
|
||||
if strings.HasSuffix(body.UploadPath, ".csv") {
|
||||
data := file.ReadFileCSV(localFilePath)
|
||||
go s.udmAuthService.InsertData(neInfo.CoreUID, neInfo.NeUID, "csv", data)
|
||||
}
|
||||
if strings.HasSuffix(body.UploadPath, ".txt") {
|
||||
data := file.ReadFileTXTLine(",", localFilePath)
|
||||
go s.udmAuthService.InsertData(neInfo.CoreUID, neInfo.NeUID, "txt", data)
|
||||
}
|
||||
}
|
||||
c.JSON(200, resp.OkMsg(resultMsg))
|
||||
}
|
||||
@@ -1,546 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/telnet"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 UDMSubController 结构体
|
||||
var NewUDMSub = &UDMSubController{
|
||||
udmSubService: service.NewUDMSubUser,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// UDM签约用户
|
||||
//
|
||||
// PATH /udm/sub
|
||||
type UDMSubController struct {
|
||||
udmSubService *service.UDMSubUser // UDM签约信息服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// UDM签约用户重载数据
|
||||
//
|
||||
// PUT /reset
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User Reload Data
|
||||
// @Description UDM Subscriber User Reload Data
|
||||
// @Router /ne/link/udm/sub/reset [put]
|
||||
func (s *UDMSubController) ResetData(c *gin.Context) {
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.udmSubService.ResetData(query.CoreUID, query.NeUID)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDM签约用户列表
|
||||
//
|
||||
// GET /list
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "IMSI"
|
||||
// @Param msisdn query string false "Msisdn"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User List
|
||||
// @Description UDM Subscriber User List
|
||||
// @Router /ne/link/udm/sub/list [get]
|
||||
func (s *UDMSubController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmSubService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDM签约用户信息
|
||||
//
|
||||
// GET /
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param value path string true "IMSI"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User Information
|
||||
// @Description UDM Subscriber User Information
|
||||
// @Router /ne/link/udm/sub [get]
|
||||
func (s *UDMSubController) Info(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("dsp udmuser:imsi=%s", query.IMSI)
|
||||
data, err := telnet.ConvertToMap(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
c.JSON(200, resp.ErrMsg("No Subs Data"))
|
||||
return
|
||||
}
|
||||
|
||||
// 解析返回的数据
|
||||
u := s.udmSubService.ParseInfo(neInfo.CoreUID, neInfo.NeUID, query.IMSI, data)
|
||||
s.udmSubService.Insert(neInfo.CoreUID, neInfo.NeUID, u)
|
||||
c.JSON(200, resp.OkData(u))
|
||||
}
|
||||
|
||||
// UDM签约用户新增
|
||||
//
|
||||
// POST /
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User Added
|
||||
// @Description UDM Subscriber User Added
|
||||
// @Router /ne/link/udm/sub [post]
|
||||
func (s *UDMSubController) Add(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 传入数量大于0时,为批量新增
|
||||
num := parse.Number(c.Query("num"))
|
||||
if num < 0 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: num is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
var body model.UDMSubUser
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
if len(body.IMSI) != 15 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: IMSI length is not 15 bits"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 批量新增
|
||||
if num > 1 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("baa udmuser:start_imsi=%s,start_msisdn=%s,sub_num=%d,", body.IMSI, body.MSISDN, num)
|
||||
cmd += s.udmSubService.ParseCommandParams(body)
|
||||
// 去除msisdn参数,避免重复
|
||||
omemsisdn := fmt.Sprintf(",msisdn=%s,", body.MSISDN)
|
||||
cmd = strings.Replace(cmd, omemsisdn, ",", 1)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmSubService.LoadData(neInfo.CoreUID, neInfo.NeUID, body.IMSI, num, body.Remark)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("add udmuser:imsi=%s,", body.IMSI)
|
||||
cmd += s.udmSubService.ParseCommandParams(body)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmSubService.Insert(neInfo.CoreUID, neInfo.NeUID, body)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDM签约用户修改
|
||||
//
|
||||
// PUT /
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User Modification
|
||||
// @Description UDM Subscriber User Modification
|
||||
// @Router /ne/link/udm/sub [put]
|
||||
func (s *UDMSubController) Edit(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.UDMSubUser
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
if len(body.IMSI) != 15 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: IMSI length is not 15 bits"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("mod udmuser:imsi=%s,", body.IMSI)
|
||||
cmd += s.udmSubService.ParseCommandParams(body)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmSubService.Insert(neInfo.CoreUID, neInfo.NeUID, body)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDM签约用户删除
|
||||
//
|
||||
// DELETE /
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param value path string true "IMSI, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User Deletion
|
||||
// @Description UDM Subscriber User Deletion
|
||||
// @Router /ne/link/udm/sub [delete]
|
||||
func (s *UDMSubController) Remove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi" binding:"required"` // IMSi
|
||||
Num int64 `form:"num"` // 批量数量
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
if query.Num > 0 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("bde udmuser:start_imsi=%s,sub_num=%d", query.IMSI, query.Num)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmSubService.LoadData(neInfo.CoreUID, neInfo.NeUID, query.IMSI, query.Num, "-(Deleted)-")
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
imsiArr := strings.Split(query.IMSI, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(imsiArr)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
}
|
||||
resultData := map[string]string{}
|
||||
for _, imsi := range uniqueIDs {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("del udmuser:imsi=%s", imsi)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
resultData[imsi] = err.Error()
|
||||
continue
|
||||
}
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmSubService.Delete(neInfo.CoreUID, neInfo.NeUID, imsi)
|
||||
}
|
||||
resultData[imsi] = data
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(resultData))
|
||||
}
|
||||
|
||||
// UDM签约用户导出
|
||||
//
|
||||
// GET /export
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param type query string true "File Type" Enums(csv,txt) default(txt)
|
||||
// @Param imsi query string false "IMSI"
|
||||
// @Param msisdn query string false "Msisdn"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User Export
|
||||
// @Description UDM Subscriber User Export
|
||||
// @Router /ne/link/udm/sub/export [post]
|
||||
func (s *UDMSubController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
neUid := c.Query("neUid")
|
||||
if c.Query("coreUid") == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
fileType := c.Query("type")
|
||||
if !(fileType == "csv" || fileType == "txt") {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "file type error, only support csv,txt"))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmSubService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
if len(rows) <= 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 文件名
|
||||
fileName := fmt.Sprintf("udm_sub_user_export_%s_%d.%s", neUid, time.Now().UnixMilli(), fileType)
|
||||
filePath := filepath.Join(file.ParseUploadFileDir(constants.UPLOAD_EXPORT), fileName)
|
||||
|
||||
if fileType == "csv" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
data = append(data, []string{"IMSI", "MSISDN", "UeAmbrTpl", "NssaiTpl", "AreaForbiddenTpl", "ServiceAreaRestrictionTpl", "RatRestrictions", "CnTypeRestrictions", "SmfSel", "SmData", "EPSDat"})
|
||||
for _, v := range rows {
|
||||
epsDat := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s", v.EpsFlag, v.EpsOdb, v.HplmnOdb, v.Ard, v.Epstpl, v.ContextId, v.ApnContext, v.StaticIp)
|
||||
data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileCSV(data, filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if fileType == "txt" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
for _, v := range rows {
|
||||
epsDat := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s", v.EpsFlag, v.EpsOdb, v.HplmnOdb, v.Ard, v.Epstpl, v.ContextId, v.ApnContext, v.StaticIp)
|
||||
data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.FileAttachment(filePath, fileName)
|
||||
}
|
||||
|
||||
// UDM签约用户导入
|
||||
//
|
||||
// POST /import
|
||||
//
|
||||
// @Tags network_data/udm/sub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Subscriber User Import
|
||||
// @Description UDM Subscriber User Import
|
||||
// @Router /ne/link/udm/sub/import [post]
|
||||
func (s *UDMSubController) Import(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
CoreUID string `json:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" binding:"required"` // 网元唯一标识
|
||||
UploadPath string `json:"uploadPath" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断文件名
|
||||
if !(strings.HasSuffix(body.UploadPath, ".csv") || strings.HasSuffix(body.UploadPath, ".txt")) {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.CoreUID, neInfo.NeUID)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 本地文件
|
||||
localFilePath := file.ParseUploadFileAbsPath(body.UploadPath)
|
||||
neFilePath := fmt.Sprintf("/tmp/%s", filepath.Base(localFilePath))
|
||||
// 复制到远程
|
||||
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg("error uploading file"))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("import udmuser:path=%s", neFilePath)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
if strings.HasSuffix(body.UploadPath, ".csv") {
|
||||
data := file.ReadFileCSV(localFilePath)
|
||||
go s.udmSubService.InsertData(neInfo.CoreUID, neInfo.NeUID, "csv", data)
|
||||
}
|
||||
if strings.HasSuffix(body.UploadPath, ".txt") {
|
||||
data := file.ReadFileTXTLine(",", localFilePath)
|
||||
go s.udmSubService.InsertData(neInfo.CoreUID, neInfo.NeUID, "txt", data)
|
||||
}
|
||||
}
|
||||
c.JSON(200, resp.OkMsg(data))
|
||||
}
|
||||
@@ -1,493 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/telnet"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 UDMVOIPController 结构体
|
||||
var NewUDMVOIP = &UDMVOIPController{
|
||||
udmVOIPService: service.NewUDMVOIPUser,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// UDMVOIP用户
|
||||
//
|
||||
// PATH /udm/voip
|
||||
type UDMVOIPController struct {
|
||||
udmVOIPService *service.UDMVOIPUser // UDMVOIP信息服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// UDMVOIP用户重载数据
|
||||
//
|
||||
// PUT /reset
|
||||
//
|
||||
// @Tags network_data/udm/voip
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param coreUid query string true "CoreUID" default(001)
|
||||
// @Param neUid query string true "NeUID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VOIP User Data Refresh
|
||||
// @Description UDM VOIP User Data List Refresh Synchronization Latest
|
||||
// @Router /ne/link/udm/voip/reset [put]
|
||||
func (s *UDMVOIPController) ResetData(c *gin.Context) {
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.udmVOIPService.ResetData(query.CoreUID, query.NeUID)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDMVOIP用户列表
|
||||
//
|
||||
// GET /list
|
||||
//
|
||||
// @Tags network_data/udm/voip
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param coreUid query string true "CoreUID" default(001)
|
||||
// @Param neUid query string true "NeUID" default(001)
|
||||
// @Param username query string false "User Name"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VOIP User List
|
||||
// @Description UDM VOIP User List
|
||||
// @Router /ne/link/udm/voip/list [get]
|
||||
func (s *UDMVOIPController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmVOIPService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDMVOIP用户信息
|
||||
//
|
||||
// GET /
|
||||
//
|
||||
// @Tags network_data/udm/voip
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param value path string true "User Name"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VOIP User Information
|
||||
// @Description UDM VOIP User Information
|
||||
// @Router /ne/link/udm/voip [get]
|
||||
func (s *UDMVOIPController) Info(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
UserName string `form:"username" binding:"required"` // 用户名
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("dsp voip:username=%s", query.UserName)
|
||||
data, err := telnet.ConvertToMap(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
c.JSON(200, resp.ErrMsg("No VOIP Data"))
|
||||
return
|
||||
}
|
||||
|
||||
// 解析返回的数据
|
||||
u := s.udmVOIPService.ParseInfo(neInfo.CoreUID, neInfo.NeUID, data)
|
||||
if u.ID > 0 {
|
||||
s.udmVOIPService.Insert(neInfo.CoreUID, neInfo.NeUID, u.UserName)
|
||||
c.JSON(200, resp.OkData(u))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.ErrMsg("No VOIP Data"))
|
||||
}
|
||||
|
||||
// UDMVOIP用户新增
|
||||
//
|
||||
// POST /
|
||||
//
|
||||
// @Tags network_data/udm/voip
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VOIP User Added
|
||||
// @Description UDM VOIP User Added
|
||||
// @Router /ne/link/udm/voip [post]
|
||||
func (s *UDMVOIPController) Add(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 传入数量大于0时,为批量新增
|
||||
num := parse.Number(c.Query("num"))
|
||||
if num < 1 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: num is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
var body model.UDMVOIPUser
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
if body.UserName == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: username is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 批量新增
|
||||
if num > 1 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("baa voip:sub_num=%d,start_username=%s,password=%s", num, body.UserName, body.Password)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVOIPService.LoadData(neInfo.CoreUID, neInfo.NeUID, body.UserName, num)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("add voip:username=%s,password=%s", body.UserName, body.Password)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVOIPService.Insert(neInfo.CoreUID, neInfo.NeUID, body.UserName)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDMVOIP用户删除
|
||||
//
|
||||
// DELETE /
|
||||
//
|
||||
// @Tags network_data/udm/voip
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param value path string true "User Name, multiple separated by a , sign"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VOIP User Deletion
|
||||
// @Description UDM VOIP User Deletion
|
||||
// @Router /ne/link/udm/voip [delete]
|
||||
func (s *UDMVOIPController) Remove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
UserName string `form:"username" binding:"required"` // 用户名
|
||||
Num int64 `form:"num"` // 批量数量
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
if query.Num > 1 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("bde voip:start_username=%s,sub_num=%d", query.UserName, query.Num)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVOIPService.LoadData(neInfo.CoreUID, neInfo.NeUID, query.UserName, query.Num)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
imsiArr := strings.Split(query.UserName, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(imsiArr)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, resp.Err(nil))
|
||||
return
|
||||
}
|
||||
resultData := map[string]string{}
|
||||
for _, v := range uniqueIDs {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("del voip:username=%s", v)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
resultData[v] = err.Error()
|
||||
continue
|
||||
}
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVOIPService.Delete(neInfo.CoreUID, neInfo.NeUID, v)
|
||||
}
|
||||
resultData[v] = data
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(resultData))
|
||||
}
|
||||
|
||||
// UDMVOIP用户导出
|
||||
//
|
||||
// GET /export
|
||||
//
|
||||
// @Tags network_data/udm/voip
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param type query string true "File Type" Enums(csv,txt) default(txt)
|
||||
// @Param username query string false "User Name"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VOIP User Export
|
||||
// @Description UDM VOIP User Export
|
||||
// @Router /ne/link/udm/voip/export [get]
|
||||
func (s *UDMVOIPController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
neUid := c.Query("neUid")
|
||||
if c.Query("coreUid") == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
fileType := c.Query("type")
|
||||
if !(fileType == "csv" || fileType == "txt") {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "file type error, only support csv,txt"))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmVOIPService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// rows := s.udmVOIPService.SelectList(model.UDMVOIPUser{NeId: neId})
|
||||
if len(rows) <= 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 文件名
|
||||
fileName := fmt.Sprintf("udm_voip_user_export_%s_%d.%s", neUid, time.Now().UnixMilli(), fileType)
|
||||
filePath := filepath.Join(file.ParseUploadFileDir(constants.UPLOAD_EXPORT), fileName)
|
||||
|
||||
if fileType == "csv" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
data = append(data, []string{"username", "password"})
|
||||
for _, v := range rows {
|
||||
data = append(data, []string{v.UserName, v.Password})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileCSV(data, filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if fileType == "txt" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
for _, v := range rows {
|
||||
data = append(data, []string{v.UserName, v.Password})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.FileAttachment(filePath, fileName)
|
||||
}
|
||||
|
||||
// UDMVOIP用户导入
|
||||
//
|
||||
// POST /import
|
||||
//
|
||||
// @Tags network_data/udm/voip
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VOIP User Import
|
||||
// @Description UDM VOIP User Import
|
||||
// @Router /ne/link/udm/voip/import [post]
|
||||
func (s *UDMVOIPController) Import(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
CoreUID string `json:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" binding:"required"` // 网元唯一标识
|
||||
UploadPath string `json:"uploadPath" binding:"required"` // 上传文件路径
|
||||
}
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断文件名
|
||||
if !(strings.HasSuffix(body.UploadPath, ".csv") || strings.HasSuffix(body.UploadPath, ".txt")) {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserAuthFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.CoreUID, neInfo.NeUID)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 本地文件
|
||||
localFilePath := file.ParseUploadFileAbsPath(body.UploadPath)
|
||||
neFilePath := fmt.Sprintf("/tmp/%s", filepath.Base(localFilePath))
|
||||
// 复制到远程
|
||||
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg("error uploading file"))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 结果信息
|
||||
var resultMsg string
|
||||
var resultErr error
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("import voip:path=%s", neFilePath)
|
||||
resultMsg, resultErr = telnet.ConvertToStr(telnetClient, cmd)
|
||||
if resultErr != nil {
|
||||
c.JSON(200, resp.ErrMsg(resultErr.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(resultMsg, "ok") {
|
||||
if strings.HasSuffix(body.UploadPath, ".csv") {
|
||||
data := file.ReadFileCSV(localFilePath)
|
||||
go s.udmVOIPService.InsertData(neInfo.CoreUID, neInfo.NeUID, "csv", data)
|
||||
}
|
||||
if strings.HasSuffix(body.UploadPath, ".txt") {
|
||||
data := file.ReadFileTXTLine(",", localFilePath)
|
||||
go s.udmVOIPService.InsertData(neInfo.CoreUID, neInfo.NeUID, "txt", data)
|
||||
}
|
||||
}
|
||||
c.JSON(200, resp.OkMsg(resultMsg))
|
||||
}
|
||||
@@ -1,500 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/telnet"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 UDMVolteIMSController 结构体
|
||||
var NewUDMVolteIMS = &UDMVolteIMSController{
|
||||
udmVolteIMSService: service.NewUDMVolteIMSUser,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户
|
||||
//
|
||||
// PATH /udm/volte-ims
|
||||
type UDMVolteIMSController struct {
|
||||
udmVolteIMSService *service.UDMVolteIMSUser // UDMVolteIMS信息服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户重载数据
|
||||
//
|
||||
// PUT /reset
|
||||
//
|
||||
// @Tags network_data/udm/volte-ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param coreUid query string true "CoreUID" default(001)
|
||||
// @Param neUid query string true "NeUID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VolteIMS User Data Refresh
|
||||
// @Description UDM Authenticated User Data List Refresh Synchronization Latest
|
||||
// @Router /ne/link/udm/volte-ims/reset [put]
|
||||
func (s *UDMVolteIMSController) ResetData(c *gin.Context) {
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.udmVolteIMSService.ResetData(query.CoreUID, query.NeUID)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户列表
|
||||
//
|
||||
// GET /list
|
||||
//
|
||||
// @Tags network_data/udm/volte-ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "IMSI"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VolteIMS User List
|
||||
// @Description UDM VolteIMS User List
|
||||
// @Router /ne/link/udm/volte-ims/list [get]
|
||||
func (s *UDMVolteIMSController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmVolteIMSService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户信息
|
||||
//
|
||||
// GET /
|
||||
//
|
||||
// @Tags network_data/udm/volte-ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param value path string true "IMSI"
|
||||
// @Param msisdn query string true "MSISDN"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VolteIMS User Information
|
||||
// @Description UDM VolteIMS User Information
|
||||
// @Router /ne/link/udm/volte-ims [get]
|
||||
func (s *UDMVolteIMSController) Info(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi" binding:"required"` // IMSi
|
||||
MSISDN string `form:"msisdn" binding:"required"` // MSISDN
|
||||
Volte string `form:"volte" binding:"required,oneof=0 1"` // Volte
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("dsp imsuser:imsi=%s,msisdn=%s,volte=%s", query.IMSI, query.MSISDN, query.Volte)
|
||||
data, err := telnet.ConvertToMap(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
c.JSON(200, resp.ErrMsg("No Volte IMS Data"))
|
||||
return
|
||||
}
|
||||
|
||||
// 解析返回的数据
|
||||
u := s.udmVolteIMSService.ParseInfo(neInfo.CoreUID, neInfo.NeUID, data)
|
||||
if u.ID > 0 {
|
||||
s.udmVolteIMSService.InsertByIMSI(neInfo.CoreUID, neInfo.NeUID, query.IMSI)
|
||||
c.JSON(200, resp.OkData(u))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.ErrMsg("No Volte IMS Data"))
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户新增
|
||||
//
|
||||
// POST /
|
||||
//
|
||||
// @Tags network_data/udm/volte-ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId path string true "NE ID" default(001)
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VolteIMS User Added
|
||||
// @Description UDM VolteIMS User Added If VoIP tag=0, then MSISDN and IMSI need to be the same.
|
||||
// @Router /ne/link/udm/volte-ims [post]
|
||||
func (s *UDMVolteIMSController) Add(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 传入数量大于0时,为批量新增
|
||||
num := parse.Number(c.Query("num"))
|
||||
if num < 0 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: num is less than 0"))
|
||||
return
|
||||
}
|
||||
|
||||
var body model.UDMVolteIMSUser
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
if body.IMSI == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: imsi is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 批量新增
|
||||
if num > 1 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("baa imsuser:sub_num=%d,start_imsi=%s,start_msisdn=%s,volte=%s,vni=%s", num, body.IMSI, body.MSISDN, body.Tag, body.VNI)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVolteIMSService.LoadData(neInfo.CoreUID, neInfo.NeUID, body.IMSI, num)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查同IMSI下msisdn是否存在
|
||||
hasMsisdns := s.udmVolteIMSService.Find(model.UDMVolteIMSUser{IMSI: body.IMSI, MSISDN: body.MSISDN, NeUID: neInfo.NeUID})
|
||||
if len(hasMsisdns) > 0 {
|
||||
c.JSON(200, resp.ErrMsg("IMSI and MSISDN already exist"))
|
||||
return
|
||||
}
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("add imsuser:imsi=%s,msisdn=%s,volte=%s,vni=%s", body.IMSI, body.MSISDN, body.Tag, body.VNI)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVolteIMSService.InsertByIMSI(neInfo.CoreUID, neInfo.NeUID, body.IMSI)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户删除
|
||||
//
|
||||
// DELETE /
|
||||
//
|
||||
// @Tags network_data/udm/volte-ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param coreUid query string true "CoreUID" default(001)
|
||||
// @Param neUid query string true "NeUID" default(001)
|
||||
// @Param imsi query string true "IMSI"
|
||||
// @Param num query number true "Number of releases, value includes start imsi"
|
||||
// @Param msisdn query string false "MSISDN"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM VolteIMS User Batch Deletion
|
||||
// @Description UDM VolteIMS User Batch Deletion
|
||||
// @Router /ne/link/udm/volte-ims [delete]
|
||||
func (s *UDMVolteIMSController) Remove(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
IMSI string `form:"imsi" binding:"required"` // IMSi, 带数量时为批量
|
||||
MSISDN string `form:"msisdn" binding:"required"` // MSISDN, 带数量时为批量
|
||||
Tag string `form:"tag" binding:"required,oneof=0 1"` // tag
|
||||
Num int64 `form:"num"` // 批量数量
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(query.CoreUID, query.NeUID)
|
||||
if neInfo.CoreUID != query.CoreUID || neInfo.NeUID != query.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 批量更新
|
||||
if query.Num > 1 {
|
||||
// 发送MML
|
||||
cmd := ""
|
||||
if query.Tag == "0" {
|
||||
cmd = fmt.Sprintf("bde imsuser:start_msisdn=%s,sub_num=%d,volte=0", query.MSISDN, query.Num)
|
||||
}
|
||||
if query.Tag == "1" {
|
||||
cmd = fmt.Sprintf("bde imsuser:start_imsi=%s,start_msisdn=%s,sub_num=%d,volte=1", query.IMSI, query.MSISDN, query.Num)
|
||||
}
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVolteIMSService.LoadData(neInfo.CoreUID, neInfo.NeUID, query.IMSI, query.Num)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
return
|
||||
}
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("del imsuser:imsi=%s,msisdn=%s,volte=%s", query.IMSI, query.MSISDN, query.Tag)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVolteIMSService.Delete(neInfo.CoreUID, neInfo.NeUID, query.IMSI)
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户导出
|
||||
//
|
||||
// GET /export
|
||||
//
|
||||
// @Tags network_data/udm/volte-ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param coreUid query string true "CoreUID" default(001)
|
||||
// @Param neUid query string true "NeUID" default(001)
|
||||
// @Param type query string true "File Type" Enums(csv,txt) default(txt)
|
||||
// @Param imsi query string false "IMSI"
|
||||
// @Param pageNum query number true "pageNum" default(1)
|
||||
// @Param pageSize query number true "pageSize" default(10)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authenticated User Export
|
||||
// @Description UDM Authenticated User Export
|
||||
// @Router /ne/link/udm/volte-ims/export [get]
|
||||
func (s *UDMVolteIMSController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
neUid := c.Query("neUid")
|
||||
if c.Query("coreUid") == "" || neUid == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: coreUid or neUid is empty"))
|
||||
return
|
||||
}
|
||||
fileType := c.Query("type")
|
||||
if !(fileType == "csv" || fileType == "txt") {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "file type error, only support csv,txt"))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
rows, total := s.udmVolteIMSService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
if len(rows) <= 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 文件名
|
||||
fileName := fmt.Sprintf("udm_volte_user_export_%s_%d.%s", neUid, time.Now().UnixMilli(), fileType)
|
||||
filePath := filepath.Join(file.ParseUploadFileDir(constants.UPLOAD_EXPORT), fileName)
|
||||
|
||||
if fileType == "csv" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
data = append(data, []string{"IMSI", "MSISDN", "TAG", "VNI"})
|
||||
for _, v := range rows {
|
||||
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileCSV(data, filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if fileType == "txt" {
|
||||
// 转换数据
|
||||
data := [][]string{}
|
||||
for _, v := range rows {
|
||||
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI})
|
||||
}
|
||||
// 输出到文件
|
||||
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.FileAttachment(filePath, fileName)
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户导入
|
||||
//
|
||||
// POST /import
|
||||
//
|
||||
// @Tags network_data/udm/volte-ims
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary UDM Authenticated User Import
|
||||
// @Description UDM Authenticated User Import
|
||||
// @Router /ne/link/udm/volte-ims/import [post]
|
||||
func (s *UDMVolteIMSController) Import(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body struct {
|
||||
CoreUID string `json:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" binding:"required"` // 网元唯一标识
|
||||
UploadPath string `json:"uploadPath" binding:"required"` // 上传文件路径
|
||||
}
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 判断文件名
|
||||
if !(strings.HasSuffix(body.UploadPath, ".csv") || strings.HasSuffix(body.UploadPath, ".txt")) {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserAuthFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(body.CoreUID, body.NeUID)
|
||||
if neInfo.CoreUID != body.CoreUID || neInfo.NeUID != body.NeUID || neInfo.NeType != "UDM" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
// 网元主机的SSH客户端
|
||||
sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.CoreUID, neInfo.NeUID)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sshClient.Close()
|
||||
// 网元主机的SSH客户端进行文件传输
|
||||
sftpClient, err := sshClient.NewClientSFTP()
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
// 本地文件
|
||||
localFilePath := file.ParseUploadFileAbsPath(body.UploadPath)
|
||||
neFilePath := fmt.Sprintf("/tmp/%s", filepath.Base(localFilePath))
|
||||
// 复制到远程
|
||||
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||
c.JSON(200, resp.ErrMsg("error uploading file"))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元主机的Telnet客户端
|
||||
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.CoreUID, neInfo.NeUID, 1)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
defer telnetClient.Close()
|
||||
|
||||
// 结果信息
|
||||
var resultMsg string
|
||||
var resultErr error
|
||||
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("import imsuser:path=%s", neFilePath)
|
||||
resultMsg, resultErr = telnet.ConvertToStr(telnetClient, cmd)
|
||||
if resultErr != nil {
|
||||
c.JSON(200, resp.ErrMsg(resultErr.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(resultMsg, "ok") {
|
||||
if strings.HasSuffix(body.UploadPath, ".csv") {
|
||||
data := file.ReadFileCSV(localFilePath)
|
||||
go s.udmVolteIMSService.InsertData(neInfo.CoreUID, neInfo.NeUID, "csv", data)
|
||||
}
|
||||
if strings.HasSuffix(body.UploadPath, ".txt") {
|
||||
data := file.ReadFileTXTLine(",", localFilePath)
|
||||
go s.udmVolteIMSService.InsertData(neInfo.CoreUID, neInfo.NeUID, "txt", data)
|
||||
}
|
||||
}
|
||||
c.JSON(200, resp.OkMsg(resultMsg))
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
neDataService "be.ems/src/modules/ne_data/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 UPFController 结构体
|
||||
var NewUPF = &UPFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
kpiReportService: neDataService.NewKpiReport,
|
||||
}
|
||||
|
||||
// 网元UPF
|
||||
//
|
||||
// PATH /upf
|
||||
type UPFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
kpiReportService *neDataService.KpiReport // 统计信息服务
|
||||
}
|
||||
|
||||
// 总流量数 N3上行 N6下行
|
||||
// 单位 字节(Byte)
|
||||
//
|
||||
// GET /kpi/flow-total
|
||||
//
|
||||
// @Tags network_data/upf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param day query number true "Statistical time a few days before" Enums(0, 7, 30)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Total number of flows N3 upstream N6 downstream
|
||||
// @Description Total number of flows N3 upstream N6 downstream
|
||||
// @Router /ne/link/upf/kpi/flow-total [get]
|
||||
func (s UPFController) KPIFlowTotal(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
CoreUID string `form:"coreUid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `form:"neUid" binding:"required"` // 网元唯一标识
|
||||
Day int `form:"day"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
if querys.Day < 0 || querys.Day > 30 {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "day must be between 0 and 30"))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByCoreUidAndNeUid(querys.CoreUID, querys.NeUID)
|
||||
if neInfo.CoreUID != querys.CoreUID || neInfo.NeUID != querys.NeUID {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
up, down := s.kpiReportService.UPFTodayFlowFind(neInfo.NeUID, querys.Day)
|
||||
c.JSON(200, resp.OkData(map[string]int64{"up": up, "down": down}))
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CBCEventStatus int
|
||||
|
||||
// CBCEventStatus CB事件状态枚举
|
||||
const (
|
||||
CBCEventStatusNull CBCEventStatus = iota // 未知状态
|
||||
CBCEventStatusActive
|
||||
CBCEventStatusInactive
|
||||
)
|
||||
|
||||
func (status CBCEventStatus) Enum() string {
|
||||
switch status {
|
||||
case CBCEventStatusNull:
|
||||
return "NULL"
|
||||
case CBCEventStatusActive:
|
||||
return "ACTIVE"
|
||||
case CBCEventStatusInactive:
|
||||
return "INACTIVE"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
func (status CBCEventStatus) String() string {
|
||||
return fmt.Sprintf("%d", status)
|
||||
}
|
||||
|
||||
// ParseCBCEventStatus 将字符串转换为 枚举类型
|
||||
func ParseCBCEventStatus(s string) CBCEventStatus {
|
||||
if i, err := strconv.Atoi(s); err == nil {
|
||||
return CBCEventStatus(i)
|
||||
}
|
||||
// 如果转换失败,则按名称匹配(忽略大小写)
|
||||
switch strings.ToUpper(s) {
|
||||
case "NULL":
|
||||
return CBCEventStatusNull
|
||||
case "ACTIVE":
|
||||
return CBCEventStatusActive
|
||||
case "INACTIVE":
|
||||
return CBCEventStatusInactive
|
||||
case "":
|
||||
// 如果字符串为空,则返回未知状态
|
||||
return CBCEventStatusNull
|
||||
default:
|
||||
// 默认返回未知状态
|
||||
return CBCEventStatusNull
|
||||
}
|
||||
}
|
||||
|
||||
// CBCMessageQuery 查询条件结构体
|
||||
type CBCMessageQuery struct {
|
||||
NeType string `form:"neType"` // 网元类型
|
||||
NeId string `form:"neId"` // 网元ID
|
||||
EventName string `form:"eventName"` // 事件名称
|
||||
Status string `form:"status"` // 消息状态
|
||||
StartTime string `form:"startTime"` // 创建时间范围-起始
|
||||
EndTime string `form:"endTime"` // 创建时间范围-结束
|
||||
PageNum int `form:"pageNum" binding:"required"`
|
||||
PageSize int `form:"pageSize" binding:"required"`
|
||||
}
|
||||
|
||||
// @Description CBCMessage CB消息
|
||||
type CBCMessage struct {
|
||||
Id int64 `json:"id" gorm:"column:id"` // CB消息ID
|
||||
NeType string `json:"neType" gorm:"column:ne_type"` // 网元类型
|
||||
NeId string `json:"neId" gorm:"column:ne_id"` // 网元ID
|
||||
MessageJson json.RawMessage `json:"messageJson" gorm:"column:message_json"` // 消息内容JSON
|
||||
Status CBCEventStatus `json:"status" gorm:"column:status"` // 消息状态
|
||||
Detail string `json:"detail" gorm:"column:detail"` // 详情
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 创建时间
|
||||
UpdatedAt int64 `json:"updatedAt" gorm:"column:updated_at"` // 更新时间
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CBCMessage) TableName() string {
|
||||
return "cbc_message"
|
||||
}
|
||||
|
||||
// Scan 实现 sql.Scanner 接口,支持从数据库字符串转为 CBCEventStatus
|
||||
func (s *CBCEventStatus) Scan(value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
*s = ParseCBCEventStatus(v)
|
||||
return nil
|
||||
case []byte:
|
||||
*s = ParseCBCEventStatus(string(v))
|
||||
return nil
|
||||
case int64:
|
||||
*s = CBCEventStatus(v)
|
||||
return nil
|
||||
case int:
|
||||
*s = CBCEventStatus(v)
|
||||
return nil
|
||||
default:
|
||||
return errors.New("unsupported Scan type for CBCEventStatus")
|
||||
}
|
||||
}
|
||||
|
||||
// Value 实现 driver.Valuer 接口,支持将 CBCEventStatus 存为字符串
|
||||
func (s CBCEventStatus) Value() (driver.Value, error) {
|
||||
return s.Enum(), nil
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package model
|
||||
|
||||
// CDREvent CDR会话对象 cdr_event
|
||||
type CDREvent struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
CoreUID string `json:"coreUid" gorm:"column:core_uid"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" gorm:"column:ne_uid"` // 网元唯一标识
|
||||
NeType string `json:"neType" gorm:"column:ne_type"` // 网元类型
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
CdrJson string `json:"cdrJSON" gorm:"column:cdr_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CDREvent) TableName() string {
|
||||
return "cdr_event"
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package model
|
||||
|
||||
// UDMAuthUser UDM鉴权用户 udm_auth
|
||||
type UDMAuthUser struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||
CoreUID string `json:"coreUid" gorm:"column:core_uid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" gorm:"column:ne_uid" binding:"required"` // 网元唯一标识
|
||||
NeType string `json:"neType" gorm:"column:ne_type" binding:"required,oneof=UDM"` // 网元类型
|
||||
IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID
|
||||
Amf string `json:"amf" gorm:"column:amf"` // AMF
|
||||
Ki string `json:"ki" gorm:"column:ki"` // ki
|
||||
AlgoIndex string `json:"algoIndex" gorm:"column:algo_index"` // algoIndex
|
||||
Opc string `json:"opc" gorm:"column:opc"` // OPC
|
||||
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UDMAuthUser) TableName() string {
|
||||
return "udm_auth"
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package model
|
||||
|
||||
// UDMExtend UDM用户IMSI扩展信息 udm_extend
|
||||
type UDMExtend struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||
CoreUID string `json:"coreUid" gorm:"column:core_uid"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" gorm:"column:ne_uid"` // 网元唯一标识
|
||||
NeType string `json:"neType" gorm:"column:ne_type"` // 网元类型
|
||||
IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID
|
||||
MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码
|
||||
|
||||
Remark string `json:"remark" gorm:"column:remark"` // 备注
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UDMExtend) TableName() string {
|
||||
return "udm_extend"
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package model
|
||||
|
||||
// UDMSubUser UDM签约用户 udm_sub
|
||||
type UDMSubUser struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||
CoreUID string `json:"coreUid" gorm:"column:core_uid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" gorm:"column:ne_uid" binding:"required"` // 网元唯一标识
|
||||
NeType string `json:"neType" gorm:"column:ne_type" binding:"required,oneof=UDM"` // 网元类型
|
||||
IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID
|
||||
MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码
|
||||
|
||||
AmDat string `json:"amDat" gorm:"column:am_dat"` // AmData
|
||||
UeAmbrTpl string `json:"ambr" gorm:"column:ambr"` // AmData SubUeAMBRTemp
|
||||
NssaiTpl string `json:"nssai" gorm:"column:nssai"` // AmData SubSNSSAITemp
|
||||
RatRestrictions string `json:"rat" gorm:"column:rat"` // AmData RAT 0x00:VIRTUAL 0x01:WLAN 0x02:EUTRA 0x03:NR
|
||||
AreaForbiddenTpl string `json:"arfb" gorm:"column:arfb"` // AmData AreaForbidden
|
||||
ServiceAreaRestrictionTpl string `json:"sar" gorm:"column:sar"` // AmData serviceAreaRestrictTemp
|
||||
CnTypeRestrictions string `json:"cnType" gorm:"column:cn_type"` // AmData CNType 0x00:EPC和5GC 0x01:5GC 0x02:EPC 0x03:EPC+5GC
|
||||
RfspIndex string `json:"rfspIndex" gorm:"column:rfsp_index"` // AmData RfspIndex
|
||||
SubsRegTime string `json:"regTimer" gorm:"column:reg_timer"` // AmData RegTimer
|
||||
UeUsageType string `json:"ueUsageType" gorm:"column:ue_usage_type"` // AmData UEUsageType
|
||||
ActiveTime string `json:"activeTime" gorm:"column:active_time"` // AmData ActiveTime
|
||||
MicoAllowed string `json:"mico" gorm:"column:mico"` // AmData MICO
|
||||
OdbPs string `json:"odbPs" gorm:"column:odb_ps"` // AmData ODB_PS 0-all,1-hplmn,2-vplmn
|
||||
GroupId string `json:"groupId" gorm:"column:group_id"` // AmData GroupId
|
||||
|
||||
EpsDat string `json:"epsDat" gorm:"column:eps_dat"` // EpsDat
|
||||
EpsFlag string `json:"epsFlag" gorm:"column:eps_flag"` // EpsDat epsFlag
|
||||
EpsOdb string `json:"epsOdb" gorm:"column:eps_odb"` // EpsDat epsOdb
|
||||
HplmnOdb string `json:"hplmnOdb" gorm:"column:hplmn_odb"` // EpsDat hplmnOdb
|
||||
Ard string `json:"ard" gorm:"column:ard"` // EpsDat Ard
|
||||
Epstpl string `json:"epstpl" gorm:"column:epstpl"` // EpsDat Epstpl
|
||||
ContextId string `json:"contextId" gorm:"column:context_id"` // EpsDat ContextId
|
||||
ApnNum string `json:"apnNum" gorm:"column:apn_mum"` // EpsDat apnNum
|
||||
ApnContext string `json:"apnContext" gorm:"column:apn_context"` // EpsDat apnContext
|
||||
StaticIp string `json:"staticIp" gorm:"column:static_ip"` // EpsDat staticIp 指给4G UE分配的静态IP,没有可不带此字段名
|
||||
|
||||
SmData string `json:"smData" gorm:"column:sm_data"` // smData
|
||||
SmfSel string `json:"smfSel" gorm:"column:smf_sel"` // smfSel
|
||||
Cag string `json:"cag" gorm:"column:cag"` // CAG
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
Remark string `json:"remark,omitempty" gorm:"-"` // 备注
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UDMSubUser) TableName() string {
|
||||
return "udm_sub"
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package model
|
||||
|
||||
// UDMVOIPUser UDMVOIP用户 udm_voip
|
||||
type UDMVOIPUser struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||
CoreUID string `json:"coreUid" gorm:"column:core_uid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" gorm:"column:ne_uid" binding:"required"` // 网元唯一标识
|
||||
NeType string `json:"neType" gorm:"column:ne_type" binding:"required,oneof=UDM"` // 网元类型
|
||||
|
||||
UserName string `json:"username" gorm:"column:username"` // 用户名
|
||||
Password string `json:"password" gorm:"column:password"` // 密码
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UDMVOIPUser) TableName() string {
|
||||
return "udm_voip"
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package model
|
||||
|
||||
// UDMVolteIMSUser UDMVolteIMS用户 udm_volte_ims
|
||||
type UDMVolteIMSUser struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||
CoreUID string `json:"coreUid" gorm:"column:core_uid" binding:"required"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" gorm:"column:ne_uid" binding:"required"` // 网元唯一标识
|
||||
NeType string `json:"neType" gorm:"column:ne_type" binding:"required,oneof=UDM"` // 网元类型
|
||||
IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID
|
||||
MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码
|
||||
|
||||
Tag string `json:"tag" gorm:"column:tag"` // 0=VoIP, 1=VoLTE
|
||||
VNI string `json:"vni" gorm:"column:vni"` // VNI
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UDMVolteIMSUser) TableName() string {
|
||||
return "udm_volte_ims"
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package model
|
||||
|
||||
// UEEvent UE会话对象 ue_event
|
||||
type UEEvent struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
CoreUID string `json:"coreUid" gorm:"column:core_uid"` // 核心网唯一标识
|
||||
NeUID string `json:"neUid" gorm:"column:ne_uid"` // 网元唯一标识
|
||||
NeType string `json:"neType" gorm:"column:ne_type"` // 网元类型
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到时间
|
||||
EventType string `json:"eventType" gorm:"column:event_type"` // 事件类型
|
||||
EventJSONStr string `json:"eventJSON" gorm:"column:event_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UEEvent) TableName() string {
|
||||
return "ue_event"
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/middleware"
|
||||
"be.ems/src/framework/middleware/collectlogs"
|
||||
"be.ems/src/framework/middleware/repeat"
|
||||
"be.ems/src/modules/ne_data/controller"
|
||||
"be.ems/src/modules/ne_data/service"
|
||||
|
||||
@@ -18,7 +17,7 @@ func Setup(router *gin.Engine) {
|
||||
// 启动时需要的初始参数
|
||||
InitLoad()
|
||||
|
||||
neDataGroup := router.Group("/neData")
|
||||
neDataGroup := router.Group("/ne/data")
|
||||
|
||||
// 性能统计信息
|
||||
kpiGroup := neDataGroup.Group("/kpi")
|
||||
@@ -178,425 +177,6 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 网元IMS
|
||||
imsGroup := neDataGroup.Group("/ims")
|
||||
{
|
||||
imsGroup.GET("/cdr/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewIMS.CDRList,
|
||||
)
|
||||
imsGroup.DELETE("/cdr/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.imsCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewIMS.CDRRemove,
|
||||
)
|
||||
imsGroup.GET("/cdr/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.imsCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewIMS.CDRExport,
|
||||
)
|
||||
imsGroup.GET("/session/num",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewIMS.UeSessionNum,
|
||||
)
|
||||
imsGroup.GET("/session/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewIMS.UeSessionList,
|
||||
)
|
||||
imsGroup.GET("/kpi/busy-hour",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewIMS.KPIBusyHour,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元SMSC
|
||||
smscGroup := neDataGroup.Group("/smsc")
|
||||
{
|
||||
smscGroup.GET("/cdr/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewSMSC.CDRList,
|
||||
)
|
||||
smscGroup.DELETE("/cdr/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smscCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSMSC.CDRRemove,
|
||||
)
|
||||
smscGroup.GET("/cdr/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smscCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSMSC.CDRExport,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元SMF
|
||||
smfGroup := neDataGroup.Group("/smf")
|
||||
{
|
||||
smfGroup.GET("/cdr/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewSMF.CDRList,
|
||||
)
|
||||
smfGroup.DELETE("/cdr/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSMF.CDRRemove,
|
||||
)
|
||||
smfGroup.GET("/cdr/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSMF.CDRExport,
|
||||
)
|
||||
smfGroup.GET("/sub/num",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewSMF.SubUserNum,
|
||||
)
|
||||
smfGroup.GET("/sub/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewSMF.SubUserList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元AMF
|
||||
amfGroup := neDataGroup.Group("/amf")
|
||||
{
|
||||
amfGroup.GET("/ue/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAMF.UEList,
|
||||
)
|
||||
amfGroup.DELETE("/ue/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.amfUE", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewAMF.UERemove,
|
||||
)
|
||||
amfGroup.GET("/ue/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.amfUE", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewAMF.UEExport,
|
||||
)
|
||||
amfGroup.GET("/nb/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAMF.NbInfoList,
|
||||
)
|
||||
amfGroup.GET("/nb/addrs",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAMF.NbStateList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元UPF
|
||||
upfGroup := neDataGroup.Group("/upf")
|
||||
{
|
||||
upfGroup.GET("/kpi/flow-total",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUPF.KPIFlowTotal,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元N3IWF
|
||||
n3iwfGroup := neDataGroup.Group("/n3iwf")
|
||||
{
|
||||
n3iwfGroup.GET("/sub/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewN3IWF.SubUserList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元N3IWF
|
||||
nssf := controller.NewNSSF
|
||||
nssfGroup := neDataGroup.Group("/nssf")
|
||||
{
|
||||
nssfGroup.GET("/sub/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
nssf.SubUserList,
|
||||
)
|
||||
nssfGroup.GET("/amf/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
nssf.AvailableList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元UDM 鉴权用户信息
|
||||
udmAuthGroup := neDataGroup.Group("/udm/auth")
|
||||
{
|
||||
udmAuthGroup.PUT("/reset",
|
||||
repeat.RepeatSubmit(5),
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmAuth", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||
controller.NewUDMAuth.ResetData,
|
||||
)
|
||||
udmAuthGroup.GET("/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMAuth.List,
|
||||
)
|
||||
udmAuthGroup.GET("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMAuth.Info,
|
||||
)
|
||||
udmAuthGroup.POST("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmAuth", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewUDMAuth.Add,
|
||||
)
|
||||
udmAuthGroup.PUT("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmAuth", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewUDMAuth.Edit,
|
||||
)
|
||||
udmAuthGroup.DELETE("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmAuth", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewUDMAuth.Remove,
|
||||
)
|
||||
udmAuthGroup.GET("/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmAuth", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewUDMAuth.Export,
|
||||
)
|
||||
udmAuthGroup.POST("/import",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmAuth", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewUDMAuth.Import,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元UDM 签约用户信息
|
||||
udmSubGroup := neDataGroup.Group("/udm/sub")
|
||||
{
|
||||
udmSubGroup.PUT("/reset",
|
||||
repeat.RepeatSubmit(5),
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmSub", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||
controller.NewUDMSub.ResetData,
|
||||
)
|
||||
udmSubGroup.GET("/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMSub.List,
|
||||
)
|
||||
udmSubGroup.GET("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMSub.Info,
|
||||
)
|
||||
udmSubGroup.POST("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmSub", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewUDMSub.Add,
|
||||
)
|
||||
udmSubGroup.PUT("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmSub", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewUDMSub.Edit,
|
||||
)
|
||||
udmSubGroup.DELETE("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmSub", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewUDMSub.Remove,
|
||||
)
|
||||
udmSubGroup.GET("/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmSub", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewUDMSub.Export,
|
||||
)
|
||||
udmSubGroup.POST("/import",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmSub", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewUDMSub.Import,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元UDM VOIP用户信息
|
||||
udmVOIPGroup := neDataGroup.Group("/udm/voip")
|
||||
{
|
||||
udmVOIPGroup.PUT("/reset",
|
||||
repeat.RepeatSubmit(5),
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVOIP", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||
controller.NewUDMVOIP.ResetData,
|
||||
)
|
||||
udmVOIPGroup.GET("/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMVOIP.List,
|
||||
)
|
||||
udmVOIPGroup.GET("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMVOIP.Info,
|
||||
)
|
||||
udmVOIPGroup.POST("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVOIP", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewUDMVOIP.Add,
|
||||
)
|
||||
udmVOIPGroup.DELETE("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVOIP", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewUDMVOIP.Remove,
|
||||
)
|
||||
udmVOIPGroup.GET("/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVOIP", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewUDMVOIP.Export,
|
||||
)
|
||||
udmVOIPGroup.POST("/import",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVOIP", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewUDMVOIP.Import,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元UDM VolteIMS用户信息
|
||||
udmVolteIMSGroup := neDataGroup.Group("/udm/volte-ims")
|
||||
{
|
||||
udmVolteIMSGroup.PUT("/reset",
|
||||
repeat.RepeatSubmit(5),
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVolteIMS", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||
controller.NewUDMVolteIMS.ResetData,
|
||||
)
|
||||
udmVolteIMSGroup.GET("/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMVolteIMS.List,
|
||||
)
|
||||
udmVolteIMSGroup.GET("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUDMVolteIMS.Info,
|
||||
)
|
||||
udmVolteIMSGroup.POST("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVolteIMS", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewUDMVolteIMS.Add,
|
||||
)
|
||||
udmVolteIMSGroup.DELETE("",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVolteIMS", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewUDMVolteIMS.Remove,
|
||||
)
|
||||
udmVolteIMSGroup.GET("/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVolteIMS", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewUDMVolteIMS.Export,
|
||||
)
|
||||
udmVolteIMSGroup.POST("/import",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmVolteIMS", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewUDMVolteIMS.Import,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元MME
|
||||
mmeGroup := neDataGroup.Group("/mme")
|
||||
{
|
||||
mmeGroup.GET("/ue/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewMME.UEList,
|
||||
)
|
||||
mmeGroup.DELETE("/ue/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.mmeUE", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewMME.UERemove,
|
||||
)
|
||||
mmeGroup.GET("/ue/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.mmeUE", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewMME.UEExport,
|
||||
)
|
||||
mmeGroup.GET("/nb/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewMME.NbInfoList,
|
||||
)
|
||||
mmeGroup.GET("/nb/addrs",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewMME.NbStateList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元SGWC
|
||||
sgwcGroup := neDataGroup.Group("/sgwc")
|
||||
{
|
||||
sgwcGroup.GET("/cdr/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewSGWC.CDRList,
|
||||
)
|
||||
sgwcGroup.DELETE("/cdr/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sgwcCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSGWC.CDRRemove,
|
||||
)
|
||||
sgwcGroup.POST("/cdr/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sgwcCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSGWC.CDRExport,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元PCF
|
||||
pcfGroup := neDataGroup.Group("/pcf")
|
||||
{
|
||||
pcfGroup.GET("/rule/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewPCF.RuleInfoList,
|
||||
)
|
||||
pcfGroup.POST("/rule",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.pcfRule", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewPCF.RuleInfoAdd,
|
||||
)
|
||||
pcfGroup.PUT("/rule",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.pcfRule", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewPCF.RuleInfoEdit,
|
||||
)
|
||||
pcfGroup.DELETE("/rule",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.pcfRule", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewPCF.RuleInfoRemove,
|
||||
)
|
||||
pcfGroup.GET("/rule/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.pcfRule", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewPCF.RuleInfoExport,
|
||||
)
|
||||
pcfGroup.PUT("/rule/import",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.pcfRule", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewPCF.RuleInfoImport,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元CBC
|
||||
cbcGroup := neDataGroup.Group("/cbc")
|
||||
{
|
||||
cbcGroup.GET("/message/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewCBC.List,
|
||||
)
|
||||
cbcGroup.GET("/message/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewCBC.ListById,
|
||||
)
|
||||
cbcGroup.POST("/message",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewCBC.Insert,
|
||||
)
|
||||
cbcGroup.PUT("/message/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewCBC.Update,
|
||||
)
|
||||
cbcGroup.PUT("/message/:id/:status",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewCBC.UpdateStatus,
|
||||
)
|
||||
cbcGroup.DELETE("/message/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewCBC.Delete,
|
||||
)
|
||||
cbcGroup.GET("/message/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewCBC.Export,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// InitLoad 初始参数
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEvent 结构体
|
||||
var NewCBCMessage = &CBCMessage{}
|
||||
|
||||
// UEEvent UE会话事件 数据层处理
|
||||
type CBCMessage struct{}
|
||||
|
||||
// SelectCBCMessage 根据条件分页查询CB消息
|
||||
func (s *CBCMessage) SelectByPage(query model.CBCMessageQuery) ([]model.CBCMessage, int, error) {
|
||||
var msg []model.CBCMessage
|
||||
var total int64
|
||||
|
||||
tx := db.DB("").Table("cbc_message")
|
||||
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.NeId != "" {
|
||||
tx = tx.Where("ne_id = ?", query.NeId)
|
||||
}
|
||||
if query.EventName != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(message_json, '$.eventName') = ?", query.EventName)
|
||||
}
|
||||
if query.Status != "" {
|
||||
tx = tx.Where("status = ?", query.Status)
|
||||
}
|
||||
|
||||
var startMicro, endMicro int64
|
||||
var err error
|
||||
if query.StartTime != "" {
|
||||
startMicro, err = parseTimeToMilli(query.StartTime)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("invalid start time: %w", err)
|
||||
}
|
||||
}
|
||||
if query.EndTime != "" {
|
||||
endMicro, err = parseTimeToMilli(query.EndTime)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("invalid end time: %w", err)
|
||||
}
|
||||
}
|
||||
if startMicro > 0 && endMicro > 0 {
|
||||
tx = tx.Where("created_at BETWEEN ? AND ?", startMicro, endMicro)
|
||||
} else if startMicro > 0 {
|
||||
tx = tx.Where("created_at >= ?", startMicro)
|
||||
} else if endMicro > 0 {
|
||||
tx = tx.Where("created_at <= ?", endMicro)
|
||||
}
|
||||
|
||||
// 统计总数
|
||||
if err := tx.Count(&total).Error; err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to count CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (query.PageNum - 1) * query.PageSize
|
||||
if err := tx.Limit(query.PageSize).Offset(offset).Order("created_at desc").Find(&msg).Error; err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to select CBC message: %w", err)
|
||||
}
|
||||
|
||||
return msg, int(total), nil
|
||||
}
|
||||
|
||||
// SelectCBCMessageByPage 分页查询CB消息
|
||||
// @Description 分页查询CB消息
|
||||
// @param page 页码
|
||||
// @param pageSize 每页大小
|
||||
// @return []model.CBCMessage CB消息列表
|
||||
// @return int 总记录数
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// SelectByPage(1, 10)
|
||||
// func (s *CBCMessage) SelectByPage(pageNum int, pageSize int) ([]model.CBCMessage, int, error) {
|
||||
// var tickets []model.CBCMessage
|
||||
// var total int64
|
||||
|
||||
// // 统计总数
|
||||
// if err := db.DB("").Table("cbc_message").Count(&total).Error; err != nil {
|
||||
// return nil, 0, fmt.Errorf("failed to count CBC message: %w", err)
|
||||
// }
|
||||
|
||||
// // 分页查询
|
||||
// offset := (pageNum - 1) * pageSize
|
||||
// if err := db.DB("").Table("cbc_message").
|
||||
// Limit(pageSize).
|
||||
// Offset(offset).
|
||||
// Find(&tickets).Error; err != nil {
|
||||
// return nil, 0, fmt.Errorf("failed to select CBC message: %w", err)
|
||||
// }
|
||||
|
||||
// return tickets, int(total), nil
|
||||
// }
|
||||
|
||||
// InsertCBCMessage 插入CB消息
|
||||
// @Description 插入CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// CBCMessage.InsertCBCMessage(msg)
|
||||
func (s *CBCMessage) Insert(msg model.CBCMessage) error {
|
||||
msg.CreatedAt = time.Now().UnixMilli()
|
||||
// 这里可以使用ORM或其他方式将ticket插入到数据库中
|
||||
if err := db.DB("").Table("cbc_message").Create(&msg).Error; err != nil {
|
||||
return fmt.Errorf("failed to insert CBC message: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectCBCMessageById 根据工单ID查询CB消息
|
||||
// @Description 根据工单ID查询CB消息
|
||||
// @param id 工单ID
|
||||
// @return *model.CBCMessage CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// CBCMessage.SelectCBCMessageById(12345)
|
||||
func (s *CBCMessage) SelectById(id int64) (*model.CBCMessage, error) {
|
||||
var msg model.CBCMessage
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
First(&msg).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to select CBC message: %w", err)
|
||||
}
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// SelectByEventName 根据事件名称查询CB消息
|
||||
func (s *CBCMessage) SelectByEventName(eventName string) (*model.CBCMessage, error) {
|
||||
var msg model.CBCMessage
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("JSON_EXTRACT(message_json, '$.eventName') = ?", eventName).
|
||||
First(&msg).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// mfCBCMessageService.UpdateCBCMessage(msg)
|
||||
func (s *CBCMessage) Update(id int64, messageJson json.RawMessage) (*model.CBCMessage, error) {
|
||||
var msg model.CBCMessage
|
||||
now := time.Now().UnixMilli()
|
||||
|
||||
err := db.DB("").Transaction(func(tx *gorm.DB) error {
|
||||
// 在事务中更新
|
||||
if err := tx.Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
Updates(map[string]any{
|
||||
"message_json": messageJson,
|
||||
"updated_at": now,
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("failed to update CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 在事务中查询更新后的记录
|
||||
if err := tx.Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
First(&msg).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch updated CBC message: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// UpdateCBCMessageDetail(msg)
|
||||
func (s *CBCMessage) UpdateDetail(eventName, detail string) error {
|
||||
now := time.Now().UnixMilli()
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("JSON_EXTRACT(message_json, '$.eventName') = ?", eventName).
|
||||
Updates(map[string]any{
|
||||
"detail": detail,
|
||||
"updated_at": now,
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("failed to update CBC message: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCBCMessage 删除CB消息
|
||||
// @Description 删除CB消息
|
||||
// @param id 工单ID
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// DeleteCBCMessage(12345)
|
||||
func (s *CBCMessage) Delete(id int64) error {
|
||||
// 执行删除操作
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
Delete(&model.CBCMessage{}).Error; err != nil {
|
||||
return fmt.Errorf("failed to delete CBC message: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateStatus(id int64, status model.CBCEventStatus) error {
|
||||
// 更新数据库状态
|
||||
now := time.Now().UnixMilli()
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
Updates(map[string]interface{}{
|
||||
"status": status,
|
||||
"updated_at": now,
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Select 查询所有CB消息
|
||||
func (s *CBCMessage) Select(msgs *[]model.CBCMessage) error {
|
||||
if err := db.DB("").Table("cbc_message").Find(&msgs).Error; err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectByNeId 根据网元ID查询CB消息
|
||||
func (s *CBCMessage) SelectByNeId(neId string, msgs *[]model.CBCMessage) error {
|
||||
if err := db.DB("").Table("cbc_message").Where("ne_id = ?", neId).Find(&msgs).Error; err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 假设 query.StartTime 和 query.EndTime 是 "2006-01-02 15:04:05" 格式字符串
|
||||
func parseTimeToMilli(ts string) (int64, error) {
|
||||
if ts == "" {
|
||||
return 0, nil
|
||||
}
|
||||
t, err := time.ParseInLocation("2006-01-02 15:04:05", ts, time.Local)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return t.UnixMilli(), nil
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
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"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREvent 结构体
|
||||
var NewCDREvent = &CDREvent{}
|
||||
|
||||
// CDREvent CDR会话事件 数据层处理
|
||||
type CDREvent struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r CDREvent) SelectByPage(neType string, query map[string]string) ([]model.CDREvent, int64) {
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["coreUid"]; ok && v != "" {
|
||||
tx = tx.Where("core_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["neUid"]; ok && v != "" {
|
||||
tx = tx.Where("ne_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["beginTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at >= ?", v)
|
||||
}
|
||||
if v, ok := query["endTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at <= ?", v)
|
||||
}
|
||||
|
||||
// 各个网元特殊查询条件
|
||||
switch neType {
|
||||
case "SMSC":
|
||||
if v, ok := query["callerParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["calledParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["recordType"]; ok && v != "" {
|
||||
recordTypes := strings.Split(v, ",")
|
||||
var querytrArr []string
|
||||
for _, recordType := range recordTypes {
|
||||
querytrArr = append(querytrArr, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') = '%s'", recordType))
|
||||
}
|
||||
tx = tx.Where(fmt.Sprintf("( %s )", strings.Join(querytrArr, " OR ")))
|
||||
}
|
||||
case "SMF":
|
||||
if v, ok := query["recordType"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.recordType') = ?", v)
|
||||
}
|
||||
if v, ok := query["subscriberID"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["dnn"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.pDUSessionChargingInformation.dNNID') = ?", v)
|
||||
}
|
||||
case "SGWC":
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedIMSI') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["msisdn"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedMSISDN') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
case "IMS":
|
||||
if v, ok := query["callerParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["calledParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
}
|
||||
|
||||
var total int64 = 0
|
||||
rows := []model.CDREvent{}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := db.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
if pageNum == 0 && pageSize > int(total) {
|
||||
pageSize = int(total)
|
||||
}
|
||||
tx = tx.Offset(int(pageNum * pageSize)).Limit(int(pageSize))
|
||||
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
// 排序
|
||||
if v, ok := query["sortField"]; ok && v != "" {
|
||||
sortField := v
|
||||
sortOrder := "asc"
|
||||
if o, ok := query["sortOrder"]; ok && o != "" {
|
||||
if o == "desc" {
|
||||
sortOrder = "desc"
|
||||
} else {
|
||||
sortOrder = "asc"
|
||||
}
|
||||
}
|
||||
sort.SliceStable(rows, func(i, j int) bool {
|
||||
// 支持的排序字段映射
|
||||
fieldGetters := map[string]func(*model.CDREvent) any{
|
||||
"id": func(row *model.CDREvent) any { return row.ID },
|
||||
"timestamp": func(row *model.CDREvent) any { return row.Timestamp },
|
||||
// 可添加更多支持的字段
|
||||
}
|
||||
|
||||
// 获取字段 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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r CDREvent) SelectByIds(neType string, ids []int64) []model.CDREvent {
|
||||
rows := []model.CDREvent{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r CDREvent) DeleteByIds(neType string, ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.CDREvent{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// Insert 新增信息 返回新增数据ID
|
||||
func (r CDREvent) Insert(param model.CDREvent) int64 {
|
||||
if param.NeType == "" {
|
||||
return 0
|
||||
}
|
||||
if param.CreatedAt == 0 {
|
||||
param.CreatedAt = time.Now().UnixMilli()
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(param.NeType))
|
||||
// 执行插入
|
||||
if err := db.DB("").Table(tableName).Create(¶m).Error; err != nil {
|
||||
logger.Errorf("insert err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return param.ID
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UDMAuthUser 结构体
|
||||
var NewUDMAuthUser = &UDMAuthUser{}
|
||||
|
||||
// UDMAuthUser UDM鉴权信息表 数据层处理
|
||||
type UDMAuthUser struct{}
|
||||
|
||||
// ClearAndInsert 清空ne_id后新增实体
|
||||
func (r *UDMAuthUser) ClearAndInsert(coreUid, neUid string, uArr []model.UDMAuthUser) int64 {
|
||||
// 不指定neID时,用 TRUNCATE 清空表快
|
||||
// _, err := datasource.ExecDB("", "TRUNCATE TABLE udm_auth", nil)
|
||||
result := db.DB("").Where("core_uid = ? and ne_uid = ?", coreUid, neUid).Unscoped().Delete(&model.UDMAuthUser{})
|
||||
if result.Error != nil {
|
||||
logger.Errorf("Delete err => %v", result.Error)
|
||||
}
|
||||
return r.Inserts(uArr)
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r *UDMAuthUser) SelectPage(query map[string]string) ([]model.UDMAuthUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMAuthUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["neUid"]; ok && v != "" {
|
||||
tx = tx.Where("ne_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["coreUid"]; ok && v != "" {
|
||||
tx = tx.Where("core_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["imsis"]; ok && v != "" {
|
||||
arr := strings.Split(v, ",")
|
||||
tx = tx.Where("imsi in ?", arr)
|
||||
// 勾选时,pageSize为勾选的数量
|
||||
query["pageSize"] = fmt.Sprint(len(arr))
|
||||
}
|
||||
|
||||
var total int64 = 0
|
||||
rows := []model.UDMAuthUser{}
|
||||
|
||||
// 查询数量 长度为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
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
func (r *UDMAuthUser) SelectList(u model.UDMAuthUser) []model.UDMAuthUser {
|
||||
tx := db.DB("").Model(&model.UDMAuthUser{})
|
||||
// 查询条件拼接
|
||||
if u.IMSI != "" {
|
||||
tx = tx.Where("imsi = ?", u.IMSI)
|
||||
}
|
||||
if u.NeUID != "" {
|
||||
tx = tx.Where("ne_uid = ?", u.NeUID)
|
||||
}
|
||||
if u.CoreUID != "" {
|
||||
tx = tx.Where("core_uid = ?", u.CoreUID)
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
arr := []model.UDMAuthUser{}
|
||||
if err := tx.Order("imsi asc").Find(&arr).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectByIMSI 通过imsi查询
|
||||
func (r *UDMAuthUser) SelectByIMSI(coreUid, neUid, imsi string) model.UDMAuthUser {
|
||||
tx := db.DB("").Model(&model.UDMAuthUser{})
|
||||
item := model.UDMAuthUser{}
|
||||
// 查询条件拼接
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ?", imsi)
|
||||
// 查询数据
|
||||
if err := tx.Order("imsi asc").Limit(1).Find(&item).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// Insert 批量添加
|
||||
func (r *UDMAuthUser) Inserts(uArr []model.UDMAuthUser) int64 {
|
||||
tx := db.DB("").CreateInBatches(uArr, 500)
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("CreateInBatches err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// Delete 删除实体
|
||||
func (r *UDMAuthUser) DeleteByIMSI(coreUid, neUid, imsi string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ?", imsi)
|
||||
tx.Delete(&model.UDMAuthUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("Delete err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// DeletePrefixByIMSI 删除前缀匹配的实体
|
||||
func (r *UDMAuthUser) DeletePrefixByIMSI(coreUid, neUid, imsiPrefix string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%s%%", imsiPrefix))
|
||||
tx.Delete(&model.UDMAuthUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("DeletePrefixByIMSI err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UDMExtend 结构体
|
||||
var NewUDMExtend = &UDMExtend{}
|
||||
|
||||
// UDMExtend UDM鉴权信息表 数据层处理
|
||||
type UDMExtend struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r UDMExtend) SelectByPage(query map[string]string) ([]model.UDMExtend, int64) {
|
||||
tx := db.DB("").Model(&model.UDMExtend{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["neUid"]; ok && v != "" {
|
||||
tx = tx.Where("ne_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["coreUid"]; ok && v != "" {
|
||||
tx = tx.Where("core_uid = ?", v)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.UDMExtend{}
|
||||
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 排序
|
||||
if v, ok := query["sortField"]; ok && v != "" {
|
||||
sortField := v
|
||||
if o, ok := query["sortOrder"]; ok && o != "" {
|
||||
sortField = sortField + " desc"
|
||||
}
|
||||
tx = tx.Order(sortField)
|
||||
}
|
||||
|
||||
// 查询数据分页
|
||||
pageNum, pageSize := db.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
tx = tx.Limit(pageSize).Offset(pageSize * pageNum)
|
||||
err := tx.Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows, total
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
func (r *UDMExtend) SelectList(u model.UDMExtend) []model.UDMExtend {
|
||||
tx := db.DB("").Model(&model.UDMExtend{})
|
||||
// 构建查询条件
|
||||
if u.IMSI != "" {
|
||||
tx = tx.Where("imsi = ?", u.IMSI)
|
||||
}
|
||||
if u.NeUID != "" {
|
||||
tx = tx.Where("ne_uid = ?", u.NeUID)
|
||||
}
|
||||
if u.CoreUID != "" {
|
||||
tx = tx.Where("core_uid = ?", u.CoreUID)
|
||||
}
|
||||
tx = tx.Order("imsi asc")
|
||||
// 查询数据
|
||||
rows := []model.UDMExtend{}
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// SelectByIMSI 通过imsi查询 neUid为%时模糊imsi查询
|
||||
func (r *UDMExtend) SelectByIMSI(coreUid, neUid, imsi string) model.UDMExtend {
|
||||
tx := db.DB("").Model(&model.UDMExtend{})
|
||||
// 查询条件拼接
|
||||
if neUid == "%" {
|
||||
tx = tx.Where("core_uid = ?", coreUid)
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%s%%", imsi))
|
||||
} else {
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ?", imsi)
|
||||
}
|
||||
// 查询数据
|
||||
rows := []model.UDMExtend{}
|
||||
if err := tx.Limit(1).Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
}
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.UDMExtend{}
|
||||
}
|
||||
|
||||
// Insert 批量添加
|
||||
func (r *UDMExtend) Inserts(uArr []model.UDMExtend) int64 {
|
||||
tx := db.DB("").CreateInBatches(uArr, 500)
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("CreateInBatches err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// Delete 删除实体 neUid为%时模糊imsi前缀
|
||||
func (r *UDMExtend) DeleteByIMSI(coreUid, neUid, imsi string) int64 {
|
||||
tx := db.DB("")
|
||||
// 查询条件拼接
|
||||
if neUid == "%" {
|
||||
tx = tx.Where("core_uid = ?", coreUid)
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%s%%", imsi))
|
||||
} else {
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ?", imsi)
|
||||
}
|
||||
tx = tx.Delete(&model.UDMExtend{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("Delete err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UDMSubUser 结构体
|
||||
var NewUDMSub = &UDMSubUser{}
|
||||
|
||||
// UDMSubUser UDM签约信息表 数据层处理
|
||||
type UDMSubUser struct{}
|
||||
|
||||
// ClearAndInsert 清空ne_id后新增实体
|
||||
func (r *UDMSubUser) ClearAndInsert(coreUid, neUid string, u []model.UDMSubUser) int64 {
|
||||
// 不指定neID时,用 TRUNCATE 清空表快
|
||||
// _, err := datasource.ExecDB("", "TRUNCATE TABLE udm_sub", nil)
|
||||
result := db.DB("").Where("core_uid = ? and ne_uid = ?", neUid).Unscoped().Delete(&model.UDMSubUser{})
|
||||
if result.Error != nil {
|
||||
logger.Errorf("Delete err => %v", result.Error)
|
||||
}
|
||||
return r.Inserts(u)
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询字典类型
|
||||
func (r *UDMSubUser) SelectPage(query map[string]string) ([]model.UDMSubUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMSubUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["msisdn"]; ok && v != "" {
|
||||
tx = tx.Where("msisdn like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["coreUid"]; ok && v != "" {
|
||||
tx = tx.Where("core_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["neUid"]; ok && v != "" {
|
||||
tx = tx.Where("ne_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["imsis"]; ok && v != "" {
|
||||
arr := strings.Split(v, ",")
|
||||
tx = tx.Where("imsi in ?", arr)
|
||||
// 勾选时,pageSize为勾选的数量
|
||||
query["pageSize"] = fmt.Sprint(len(arr))
|
||||
}
|
||||
|
||||
var total int64 = 0
|
||||
rows := []model.UDMSubUser{}
|
||||
|
||||
// 查询数量 长度为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
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
func (r *UDMSubUser) SelectList(u model.UDMSubUser) []model.UDMSubUser {
|
||||
tx := db.DB("").Model(&model.UDMSubUser{})
|
||||
// 查询条件拼接
|
||||
if u.IMSI != "" {
|
||||
tx = tx.Where("imsi = ?", u.IMSI)
|
||||
}
|
||||
if u.NeUID != "" {
|
||||
tx = tx.Where("ne_uid = ?", u.NeUID)
|
||||
}
|
||||
if u.CoreUID != "" {
|
||||
tx = tx.Where("core_uid = ?", u.CoreUID)
|
||||
}
|
||||
// 查询数据
|
||||
arr := []model.UDMSubUser{}
|
||||
if err := tx.Order("imsi asc").Find(&arr).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectByIMSIAndNeID 通过imsi查询
|
||||
func (r *UDMSubUser) SelectByIMSI(coreUid, neUid, imsi string) model.UDMSubUser {
|
||||
tx := db.DB("").Model(&model.UDMSubUser{})
|
||||
item := model.UDMSubUser{}
|
||||
// 查询条件拼接
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ?", imsi)
|
||||
// 查询数据
|
||||
if err := tx.Order("imsi asc").Limit(1).Find(&item).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// Insert 批量添加
|
||||
func (r *UDMSubUser) Inserts(uArr []model.UDMSubUser) int64 {
|
||||
tx := db.DB("").CreateInBatches(uArr, 500)
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("CreateInBatches err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// DeleteByIMSI 删除实体
|
||||
func (r *UDMSubUser) DeleteByIMSI(coreUid, neUid, imsi string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ?", imsi)
|
||||
tx.Delete(&model.UDMSubUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("Delete err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// DeletePrefixByIMSI 删除前缀匹配的实体
|
||||
func (r *UDMSubUser) DeletePrefixByIMSI(coreUid, neUid, imsiPrefix string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%s%%", imsiPrefix))
|
||||
tx.Delete(&model.UDMSubUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("DeletePrefixByIMSI err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UDMVOIPUser 结构体
|
||||
var NewUDMVOIPUser = &UDMVOIPUser{}
|
||||
|
||||
// UDMVOIPUser UDMVOIP用户信息表 数据层处理
|
||||
type UDMVOIPUser struct{}
|
||||
|
||||
// ClearAndInsert 清空ne_id后新增实体
|
||||
func (r UDMVOIPUser) ClearAndInsert(coreUid, neUid string, uArr []model.UDMVOIPUser) int64 {
|
||||
// 不指定neID时,用 TRUNCATE 清空表快
|
||||
// _, err := datasource.ExecDB("", "TRUNCATE TABLE udm_voip", nil)
|
||||
result := db.DB("").Where("core_uid = ? and ne_uid = ?", coreUid, neUid).Unscoped().Delete(&model.UDMVOIPUser{})
|
||||
if result.Error != nil {
|
||||
logger.Errorf("Delete err => %v", result.Error)
|
||||
}
|
||||
return r.Inserts(uArr)
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r UDMVOIPUser) SelectPage(query map[string]string) ([]model.UDMVOIPUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMVOIPUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["username"]; ok && v != "" {
|
||||
tx = tx.Where("username like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["coreUid"]; ok && v != "" {
|
||||
tx = tx.Where("core_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["neUid"]; ok && v != "" {
|
||||
tx = tx.Where("ne_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["usernames"]; ok && v != "" {
|
||||
arr := strings.Split(v, ",")
|
||||
tx = tx.Where("username in ?", arr)
|
||||
// 勾选时,pageSize为勾选的数量
|
||||
query["pageSize"] = fmt.Sprint(len(arr))
|
||||
}
|
||||
|
||||
var total int64 = 0
|
||||
rows := []model.UDMVOIPUser{}
|
||||
|
||||
// 查询数量 长度为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)
|
||||
} else {
|
||||
tx = tx.Order("username asc")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
func (r UDMVOIPUser) SelectList(u model.UDMVOIPUser) []model.UDMVOIPUser {
|
||||
tx := db.DB("").Model(&model.UDMVOIPUser{})
|
||||
// 查询条件拼接
|
||||
if u.UserName != "" {
|
||||
tx = tx.Where("username = ?", u.UserName)
|
||||
}
|
||||
if u.NeUID != "" {
|
||||
tx = tx.Where("ne_uid = ?", u.NeUID)
|
||||
}
|
||||
if u.CoreUID != "" {
|
||||
tx = tx.Where("core_uid = ?", u.CoreUID)
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
arr := []model.UDMVOIPUser{}
|
||||
if err := tx.Order("username asc").Find(&arr).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectByUserName 通过username查询
|
||||
func (r UDMVOIPUser) SelectByUserName(coreUid, neUid, username string) model.UDMVOIPUser {
|
||||
tx := db.DB("").Model(&model.UDMVOIPUser{})
|
||||
item := model.UDMVOIPUser{}
|
||||
// 查询条件拼接
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("username = ?", username)
|
||||
// 查询数据
|
||||
if err := tx.Order("username asc").Limit(1).Find(&item).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// Insert 批量添加
|
||||
func (r UDMVOIPUser) Inserts(uArr []model.UDMVOIPUser) int64 {
|
||||
tx := db.DB("").CreateInBatches(uArr, 500)
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("CreateInBatches err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// DeleteByUserName 删除实体
|
||||
func (r UDMVOIPUser) DeleteByUserName(coreUid, neUid, username string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("username = ?", username)
|
||||
tx.Delete(&model.UDMVOIPUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("Delete err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// DeletePrefixByUserName 删除前缀匹配的实体
|
||||
func (r UDMVOIPUser) DeletePrefixByUserName(coreUid, neUid, usernamePrefix string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("username like ?", fmt.Sprintf("%s%%", usernamePrefix))
|
||||
tx.Delete(&model.UDMVOIPUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("DeletePrefixByUserName err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UDMVolteIMSUser 结构体
|
||||
var NewUDMVolteIMSUser = &UDMVolteIMSUser{}
|
||||
|
||||
// UDMVolteIMSUser UDMVOIP用户信息表 数据层处理
|
||||
type UDMVolteIMSUser struct{}
|
||||
|
||||
// ClearAndInsert 清空ne_id后新增实体
|
||||
func (r UDMVolteIMSUser) ClearAndInsert(coreUid, neUid string, uArr []model.UDMVolteIMSUser) int64 {
|
||||
// 不指定neID时,用 TRUNCATE 清空表快
|
||||
// _, err := datasource.ExecDB("", "TRUNCATE TABLE udm_volte_ims", nil)
|
||||
result := db.DB("").Where("core_uid = ? and ne_uid = ?", coreUid, neUid).Unscoped().Delete(&model.UDMVolteIMSUser{})
|
||||
if result.Error != nil {
|
||||
logger.Errorf("Delete err => %v", result.Error)
|
||||
}
|
||||
return r.Inserts(uArr)
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r UDMVolteIMSUser) SelectPage(query map[string]string) ([]model.UDMVolteIMSUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMVolteIMSUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["msisdn"]; ok && v != "" {
|
||||
tx = tx.Where("msisdn like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["coreUid"]; ok && v != "" {
|
||||
tx = tx.Where("core_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["neUid"]; ok && v != "" {
|
||||
tx = tx.Where("ne_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["tag"]; ok && v != "" {
|
||||
tx = tx.Where("tag = ?", v)
|
||||
}
|
||||
if v, ok := query["vni"]; ok && v != "" {
|
||||
tx = tx.Where("vni like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["imsis"]; ok && v != "" {
|
||||
arr := strings.Split(v, ",")
|
||||
tx = tx.Where("imsi in ?", arr)
|
||||
// 勾选时,pageSize为勾选的数量
|
||||
query["pageSize"] = fmt.Sprint(len(arr))
|
||||
}
|
||||
|
||||
var total int64 = 0
|
||||
rows := []model.UDMVolteIMSUser{}
|
||||
|
||||
// 查询数量 长度为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)
|
||||
} else {
|
||||
tx = tx.Order("imsi asc")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
func (r UDMVolteIMSUser) SelectList(u model.UDMVolteIMSUser) []model.UDMVolteIMSUser {
|
||||
tx := db.DB("").Model(&model.UDMVolteIMSUser{})
|
||||
// 查询条件拼接
|
||||
if u.NeUID != "" {
|
||||
tx = tx.Where("ne_uid = ?", u.NeUID)
|
||||
}
|
||||
if u.CoreUID != "" {
|
||||
tx = tx.Where("core_uid = ?", u.CoreUID)
|
||||
}
|
||||
if u.IMSI != "" {
|
||||
tx = tx.Where("imsi = ?", u.IMSI)
|
||||
}
|
||||
if u.Tag != "" {
|
||||
tx = tx.Where("tag = ?", u.Tag)
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
arr := []model.UDMVolteIMSUser{}
|
||||
if err := tx.Order("imsi asc").Find(&arr).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectByIMSIAndMSISDN 通过imsi,msisdn查询
|
||||
func (r UDMVolteIMSUser) SelectByIMSIAndMSISDN(coreUid, neUid, imsi, msisdn string) model.UDMVolteIMSUser {
|
||||
tx := db.DB("").Model(&model.UDMVolteIMSUser{})
|
||||
item := model.UDMVolteIMSUser{}
|
||||
// 查询条件拼接
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ? and msisdn = ?", imsi, msisdn)
|
||||
// 查询数据
|
||||
if err := tx.Order("imsi asc").Limit(1).Find(&item).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// Insert 批量添加
|
||||
func (r UDMVolteIMSUser) Inserts(uArr []model.UDMVolteIMSUser) int64 {
|
||||
tx := db.DB("").CreateInBatches(uArr, 500)
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("CreateInBatches err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// Delete 删除实体
|
||||
func (r UDMVolteIMSUser) DeleteByIMSI(coreUid, neUid, imsi string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi = ?", imsi)
|
||||
tx.Delete(&model.UDMVolteIMSUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("Delete err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// DeletePrefixByIMSI 删除前缀匹配的实体
|
||||
func (r UDMVolteIMSUser) DeletePrefixByIMSI(coreUid, neUid, imsiPrefix string) int64 {
|
||||
tx := db.DB("")
|
||||
tx = tx.Where("core_uid = ? and ne_uid = ?", coreUid, neUid)
|
||||
tx = tx.Where("imsi like ?", fmt.Sprintf("%s%%", imsiPrefix))
|
||||
tx.Delete(&model.UDMVolteIMSUser{})
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("DeletePrefixByIMSI err => %v", err)
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
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"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEvent 结构体
|
||||
var NewUEEvent = &UEEvent{}
|
||||
|
||||
// UEEvent UE会话事件 数据层处理
|
||||
type UEEvent struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r UEEvent) SelectByPage(neType string, query map[string]string) ([]model.UEEvent, int64) {
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["coreUid"]; ok && v != "" {
|
||||
tx = tx.Where("core_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["neUid"]; ok && v != "" {
|
||||
tx = tx.Where("ne_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["beginTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at >= ?", v)
|
||||
}
|
||||
if v, ok := query["endTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at <= ?", v)
|
||||
}
|
||||
if v, ok := query["eventType"]; ok && v != "" {
|
||||
eventTypes := strings.Split(v, ",")
|
||||
tx = tx.Where("event_type in ?", eventTypes)
|
||||
}
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(event_json, '$.imsi') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.UEEvent{}
|
||||
|
||||
// 查询数量 长度为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 err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
// 排序
|
||||
if v, ok := query["sortField"]; ok && v != "" {
|
||||
sortField := v
|
||||
sortOrder := "asc"
|
||||
if o, ok := query["sortOrder"]; ok && o != "" {
|
||||
if o == "desc" {
|
||||
sortOrder = "desc"
|
||||
} else {
|
||||
sortOrder = "asc"
|
||||
}
|
||||
}
|
||||
sort.SliceStable(rows, func(i, j int) bool {
|
||||
// 支持的排序字段映射
|
||||
fieldGetters := map[string]func(*model.UEEvent) any{
|
||||
"id": func(row *model.UEEvent) any { return row.ID },
|
||||
"timestamp": func(row *model.UEEvent) any { return row.CreatedAt },
|
||||
"createdAt": func(row *model.UEEvent) any { return row.CreatedAt },
|
||||
// 可添加更多支持的字段
|
||||
}
|
||||
|
||||
// 获取字段 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
|
||||
}
|
||||
})
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r UEEvent) SelectByIds(neType string, ids []int64) []model.UEEvent {
|
||||
rows := []model.UEEvent{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.UEEvent{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r UEEvent) DeleteByIds(neType string, ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.UEEvent{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// Insert 新增信息 返回新增数据ID
|
||||
func (r UEEvent) Insert(param model.UEEvent) int64 {
|
||||
if param.NeType == "" {
|
||||
return 0
|
||||
}
|
||||
if param.CreatedAt == 0 {
|
||||
param.CreatedAt = time.Now().UnixMilli()
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(param.NeType))
|
||||
// 执行插入
|
||||
if err := db.DB("").Table(tableName).Create(¶m).Error; err != nil {
|
||||
logger.Errorf("insert err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return param.ID
|
||||
}
|
||||
@@ -1,453 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/file"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 实例化数据层 CBCMessage 结构体
|
||||
var NewCBCMessage = &CBCMessage{
|
||||
cbcMessageRepository: repository.NewCBCMessage,
|
||||
}
|
||||
|
||||
// CBCMessage CB消息 服务层处理
|
||||
type CBCMessage struct {
|
||||
cbcMessageRepository *repository.CBCMessage // UE会话事件数据信息
|
||||
}
|
||||
|
||||
// SelectByPage 根据条件分页查询CB消息
|
||||
func (s *CBCMessage) SelectByPage(query model.CBCMessageQuery) ([]model.CBCMessage, int, error) {
|
||||
return s.cbcMessageRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// SelectCBCMessageById 根据工单ID查询CB消息
|
||||
// @Description 根据工单ID查询CB消息
|
||||
// @param id 工单ID
|
||||
// @return *model.CBCMessage CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// CBCMessage.SelectCBCMessageById(12345)
|
||||
func (s *CBCMessage) SelectById(id int64) (*model.CBCMessage, error) {
|
||||
return s.cbcMessageRepository.SelectById(id)
|
||||
}
|
||||
|
||||
func (s *CBCMessage) Insert(msg model.CBCMessage) error {
|
||||
// 解析messageJson获取eventName
|
||||
var messageData map[string]interface{}
|
||||
if err := json.Unmarshal(msg.MessageJson, &messageData); err != nil {
|
||||
return fmt.Errorf("failed to parse message_json: %w", err)
|
||||
}
|
||||
|
||||
// 提取eventName
|
||||
eventName, ok := messageData["eventName"].(string)
|
||||
if !ok || eventName == "" {
|
||||
return fmt.Errorf("eventName is required in message_json")
|
||||
}
|
||||
|
||||
// 检查是否已存在相同的eventName
|
||||
var err error
|
||||
var existingMsg *model.CBCMessage
|
||||
if existingMsg, err = s.cbcMessageRepository.SelectByEventName(eventName); err != nil {
|
||||
return fmt.Errorf("failed to check existing CBC message: %w", err)
|
||||
}
|
||||
|
||||
if existingMsg != nil {
|
||||
return fmt.Errorf("CBC message with eventName '%s' already exists for neType '%s' and neId '%s'",
|
||||
eventName, existingMsg.NeType, existingMsg.NeId)
|
||||
}
|
||||
return s.cbcMessageRepository.Insert(msg)
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// mfCBCMessageService.UpdateCBCMessage(msg)
|
||||
func (s *CBCMessage) Update(id int64, messageJson json.RawMessage) error {
|
||||
// 解析messageJson获取eventName
|
||||
var messageData map[string]interface{}
|
||||
if err := json.Unmarshal(messageJson, &messageData); err != nil {
|
||||
return fmt.Errorf("failed to parse message_json: %w", err)
|
||||
}
|
||||
// 提取eventName
|
||||
eventName, ok := messageData["eventName"].(string)
|
||||
if !ok || eventName == "" {
|
||||
return fmt.Errorf("eventName is required in message_json")
|
||||
}
|
||||
|
||||
// 检查是否已存在相同的eventName
|
||||
var err error
|
||||
if _, err = s.cbcMessageRepository.SelectByEventName(eventName); err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return fmt.Errorf("no existing CBC message found with eventName: %s", eventName)
|
||||
}
|
||||
return fmt.Errorf("failed to query existing CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 如果存在,更新记录
|
||||
var msg *model.CBCMessage
|
||||
if msg, err = s.cbcMessageRepository.Update(id, messageJson); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 如果状态是ACTIVE,发送更新请求
|
||||
if msg.Status == model.CBCEventStatusActive {
|
||||
if err := s.sendUpdateRequest(*msg); err != nil {
|
||||
return fmt.Errorf("failed to send update request: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// UpdateCBCMessageDetail(msg)
|
||||
func (s *CBCMessage) UpdateDetail(eventName, detail string) error {
|
||||
if err := s.cbcMessageRepository.UpdateDetail(eventName, detail); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message detail: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCBCMessage 删除CB消息
|
||||
// @Description 删除CB消息
|
||||
// @param id 工单ID
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// mfCBCMessageService.DeleteCBCMessage(12345)
|
||||
func (s *CBCMessage) Delete(id int64) error {
|
||||
// 先查询记录状态
|
||||
var err error
|
||||
var msg *model.CBCMessage
|
||||
if msg, err = s.cbcMessageRepository.SelectById(id); err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return fmt.Errorf("CBC message with ID %d not found", id)
|
||||
}
|
||||
return fmt.Errorf("failed to query CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 检查状态是否为ACTIVE
|
||||
if msg.Status == model.CBCEventStatusActive {
|
||||
return fmt.Errorf("cannot delete an active CBC message (ID: %d)", id)
|
||||
}
|
||||
|
||||
// 执行删除操作
|
||||
if err := s.cbcMessageRepository.Delete(id); err != nil {
|
||||
return fmt.Errorf("failed to delete CBC message: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateStatus(id int64, status string) error {
|
||||
newStatus := model.ParseCBCEventStatus(status)
|
||||
|
||||
// 查询所有需要更新的记录
|
||||
var err error
|
||||
var msg *model.CBCMessage
|
||||
if msg, err = s.cbcMessageRepository.SelectById(id); err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return fmt.Errorf("CBC message with ID %d not found", id)
|
||||
}
|
||||
return fmt.Errorf("failed to query CBC message: %w", err)
|
||||
}
|
||||
|
||||
oldStatus := msg.Status
|
||||
|
||||
// 检查状态是否发生变化
|
||||
if oldStatus == newStatus {
|
||||
return fmt.Errorf("CBC message status is already %s", newStatus.Enum())
|
||||
}
|
||||
|
||||
// 更新数据库状态
|
||||
if err := s.cbcMessageRepository.UpdateStatus(id, newStatus); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
// 根据状态变化发送HTTP请求
|
||||
if err := s.handleStatusChange(*msg, oldStatus, newStatus); err != nil {
|
||||
// 记录错误但不中断处理其他消息
|
||||
fmt.Printf("Failed to handle status change for message %d: %v\n", msg.Id, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateStatusByNeId(neId string, status string) error {
|
||||
newStatus := model.ParseCBCEventStatus(status)
|
||||
|
||||
// 查询所有需要更新的记录
|
||||
msgs := make([]model.CBCMessage, 0)
|
||||
if err := s.cbcMessageRepository.SelectByNeId(neId, &msgs); err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
oldStatus := msg.Status
|
||||
|
||||
// 检查状态是否发生变化
|
||||
if oldStatus == newStatus {
|
||||
continue // 状态没有变化,跳过
|
||||
}
|
||||
|
||||
// 更新数据库状态
|
||||
if err := s.cbcMessageRepository.UpdateStatus(msg.Id, newStatus); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
// 根据状态变化发送HTTP请求
|
||||
if err := s.handleStatusChange(msg, oldStatus, newStatus); err != nil {
|
||||
// 记录错误但不中断处理其他消息
|
||||
fmt.Printf("Failed to handle status change for message %d: %v\n", msg.Id, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateAllStatus(status string) error {
|
||||
newStatus := model.ParseCBCEventStatus(status)
|
||||
|
||||
// 查询所有需要更新的记录
|
||||
msgs := make([]model.CBCMessage, 0)
|
||||
if err := s.cbcMessageRepository.Select(&msgs); err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
oldStatus := msg.Status
|
||||
|
||||
// 检查状态是否发生变化
|
||||
if oldStatus == newStatus {
|
||||
continue // 状态没有变化,跳过
|
||||
}
|
||||
|
||||
// 更新数据库状态
|
||||
if err := s.cbcMessageRepository.UpdateStatus(msg.Id, newStatus); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
// 根据状态变化发送HTTP请求
|
||||
if err := s.handleStatusChange(msg, oldStatus, newStatus); err != nil {
|
||||
// 记录错误但不中断处理其他消息
|
||||
fmt.Printf("Failed to handle status change for message %d: %v\n", msg.Id, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r CBCMessage) ExportXlsx(rows []model.CBCMessage, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": i18n.TKey(language, "alarm.export.alarmType"),
|
||||
"B1": i18n.TKey(language, "alarm.export.origSeverity"),
|
||||
"C1": i18n.TKey(language, "alarm.export.alarmTitle"),
|
||||
"D1": i18n.TKey(language, "alarm.export.eventTime"),
|
||||
"E1": i18n.TKey(language, "alarm.export.alarmId"),
|
||||
"F1": i18n.TKey(language, "alarm.export.alarmCode"),
|
||||
"G1": i18n.TKey(language, "ne.common.neType"),
|
||||
"H1": i18n.TKey(language, "ne.common.neName"),
|
||||
"I1": i18n.TKey(language, "ne.common.neId"),
|
||||
}
|
||||
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
|
||||
cells := map[string]any{
|
||||
"A" + idx: row.NeType,
|
||||
"B" + idx: row.NeId,
|
||||
"C" + idx: row.MessageJson, // 这里假设 MessageJson 已经是字符串格式
|
||||
"D" + idx: row.Status.Enum(),
|
||||
"E" + idx: row.Detail,
|
||||
"F" + idx: time.UnixMilli(row.CreatedAt).Format(time.RFC3339),
|
||||
"G" + idx: time.UnixMilli(row.UpdatedAt).Format(time.RFC3339),
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, cells)
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// handleStatusChange 处理状态变化时的HTTP请求
|
||||
func (s *CBCMessage) handleStatusChange(msg model.CBCMessage, oldStatus, newStatus model.CBCEventStatus) error {
|
||||
// 从NULL/INACTIVE状态修改为ACTIVE
|
||||
if (oldStatus == model.CBCEventStatusNull || oldStatus == model.CBCEventStatusInactive) &&
|
||||
newStatus == model.CBCEventStatusActive {
|
||||
return s.sendActivateRequest(msg)
|
||||
}
|
||||
|
||||
// 从ACTIVE更改为INACTIVE状态
|
||||
if oldStatus == model.CBCEventStatusActive && newStatus == model.CBCEventStatusInactive {
|
||||
return s.sendDeactivateRequest(msg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCBCNetworkElement 获取CBC网元的IP和端口信息
|
||||
// 这个方法需要根据你的实际网元管理系统来实现
|
||||
func (s *CBCMessage) getCBCNetworkElement(neId string) (string, int64, error) {
|
||||
// 查询网元信息
|
||||
neInfo := neService.NewNeInfo.FindByCoreUidAndNeUid("CBC", neId)
|
||||
if neInfo.IPAddr == "" {
|
||||
return "", 0, fmt.Errorf("CBC network element not found for neId: %s", neId)
|
||||
}
|
||||
return neInfo.IPAddr, neInfo.Port, nil
|
||||
}
|
||||
|
||||
// CBCHTTPClient CBC网元HTTP客户端
|
||||
type CBCHTTPClient struct {
|
||||
client *http.Client
|
||||
baseURL string
|
||||
}
|
||||
|
||||
// NewCBCHTTPClient 创建CBC HTTP客户端
|
||||
func NewCBCHTTPClient(baseURL string) *CBCHTTPClient {
|
||||
return &CBCHTTPClient{
|
||||
client: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
baseURL: baseURL,
|
||||
}
|
||||
}
|
||||
|
||||
// PostMessage 发送POST请求创建消息
|
||||
func (c *CBCHTTPClient) PostMessage(messageData []byte) error {
|
||||
url := fmt.Sprintf("%s/api/v1/cbe/message", c.baseURL)
|
||||
return c.sendRequest("POST", url, messageData)
|
||||
}
|
||||
|
||||
// PutMessage 发送PUT请求更新消息
|
||||
func (c *CBCHTTPClient) PutMessage(messageData []byte) error {
|
||||
url := fmt.Sprintf("%s/api/v1/cbe/message", c.baseURL)
|
||||
return c.sendRequest("PUT", url, messageData)
|
||||
}
|
||||
|
||||
// DeleteMessage 发送DELETE请求删除消息
|
||||
func (c *CBCHTTPClient) DeleteMessage(eventName string, deletePayload []byte) error {
|
||||
url := fmt.Sprintf("%s/api/v1/cbe/message/%s", c.baseURL, eventName)
|
||||
return c.sendRequest("DELETE", url, deletePayload)
|
||||
}
|
||||
|
||||
// sendRequest 发送HTTP请求
|
||||
func (c *CBCHTTPClient) sendRequest(method, url string, body []byte) error {
|
||||
req, err := http.NewRequest(method, url, bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create %s request: %w", method, err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send %s request: %w", method, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return fmt.Errorf("%s request failed with status: %d, body: %s",
|
||||
method, resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 在CBCMessageService中添加方法
|
||||
func (s *CBCMessage) getCBCHTTPClient(neId string) (*CBCHTTPClient, error) {
|
||||
cbcIP, cbcPort, err := s.getCBCNetworkElement(neId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get CBC network element info: %w", err)
|
||||
}
|
||||
|
||||
baseURL := fmt.Sprintf("http://%s:%d", cbcIP, cbcPort)
|
||||
return NewCBCHTTPClient(baseURL), nil
|
||||
}
|
||||
|
||||
// 重构后的激活请求
|
||||
func (s *CBCMessage) sendActivateRequest(msg model.CBCMessage) error {
|
||||
client, err := s.getCBCHTTPClient(msg.NeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 直接使用 MessageJson 发送POST请求
|
||||
return client.PostMessage(msg.MessageJson)
|
||||
}
|
||||
|
||||
// 重构后的更新请求
|
||||
func (s *CBCMessage) sendUpdateRequest(msg model.CBCMessage) error {
|
||||
client, err := s.getCBCHTTPClient(msg.NeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 直接使用 MessageJson 发送POST请求
|
||||
return client.PostMessage(msg.MessageJson)
|
||||
}
|
||||
|
||||
// 重构后的停用请求
|
||||
func (s *CBCMessage) sendDeactivateRequest(msg model.CBCMessage) error {
|
||||
client, err := s.getCBCHTTPClient(msg.NeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析和构造删除载荷的逻辑保持不变
|
||||
var messageData map[string]interface{}
|
||||
if err := json.Unmarshal(msg.MessageJson, &messageData); err != nil {
|
||||
return fmt.Errorf("failed to parse message_json: %w", err)
|
||||
}
|
||||
|
||||
eventName, ok := messageData["eventName"].(string)
|
||||
if !ok || eventName == "" {
|
||||
return fmt.Errorf("eventName not found in message_json")
|
||||
}
|
||||
|
||||
deletePayload := make(map[string]interface{})
|
||||
if messageIdProfile, exists := messageData["messageIdProfile"]; exists {
|
||||
deletePayload["messageIdProfile"] = messageIdProfile
|
||||
}
|
||||
if warningAreaList, exists := messageData["warningAreaList"]; exists {
|
||||
deletePayload["warningAreaList"] = warningAreaList
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(deletePayload)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal delete payload: %w", err)
|
||||
}
|
||||
|
||||
return client.DeleteMessage(eventName, payloadBytes)
|
||||
}
|
||||
@@ -1,645 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREvent 结构体
|
||||
var NewCDREvent = &CDREvent{
|
||||
cdrEventRepository: repository.NewCDREvent,
|
||||
}
|
||||
|
||||
// CDREvent CDR会话事件 服务层处理
|
||||
type CDREvent struct {
|
||||
cdrEventRepository *repository.CDREvent // CDR会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r CDREvent) FindByPage(neType string, query map[string]string) ([]model.CDREvent, int64) {
|
||||
return r.cdrEventRepository.SelectByPage(neType, query)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r CDREvent) DeleteByIds(neType string, ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.cdrEventRepository.SelectByIds(neType, ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("not data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.cdrEventRepository.DeleteByIds(neType, ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (s CDREvent) Insert(param model.CDREvent) int64 {
|
||||
return s.cdrEventRepository.Insert(param)
|
||||
}
|
||||
|
||||
// ExportSMSC 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportSMSC(rows []model.CDREvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Record Behavior",
|
||||
"D1": "Service Type",
|
||||
"E1": "Caller",
|
||||
"F1": "Called",
|
||||
"G1": "Result",
|
||||
"H1": "Time",
|
||||
}
|
||||
// 读取字典数据 CDR 原因码
|
||||
dictCDRCauseCode := sysService.NewSysDictData.FindByType("cdr_cause_code")
|
||||
// 从第二行开始的数据
|
||||
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.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
// 服务类型
|
||||
serviceType := ""
|
||||
if v, ok := cdrJSON["serviceType"]; ok && v != nil {
|
||||
serviceType = 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)
|
||||
}
|
||||
// 呼叫结果 0失败,1成功
|
||||
callResult := "Fail"
|
||||
if v, ok := cdrJSON["result"]; ok && v != nil {
|
||||
resultVal := parse.Number(v)
|
||||
if resultVal == 1 {
|
||||
callResult = "Success"
|
||||
}
|
||||
}
|
||||
// 结果原因
|
||||
if v, ok := cdrJSON["cause"]; ok && v != nil && callResult == "Fail" {
|
||||
cause := fmt.Sprint(v)
|
||||
for _, v := range dictCDRCauseCode {
|
||||
if cause == v.DataValue {
|
||||
callResult = fmt.Sprintf("%s, %s", callResult, i18n.TKey(language, v.DataLabel))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if v, ok := cdrJSON["updateTime"]; ok && v != nil {
|
||||
if releaseTime := parse.Number(v); releaseTime > 0 {
|
||||
timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeUID,
|
||||
"C" + idx: recordType,
|
||||
"D" + idx: serviceType,
|
||||
"E" + idx: caller,
|
||||
"F" + idx: called,
|
||||
"G" + idx: callResult,
|
||||
"H" + idx: timeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// ExportSMF 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportSMF(rows []model.CDREvent, fileName string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "Charging ID",
|
||||
"C1": "NE Name",
|
||||
"D1": "Resource Unique ID",
|
||||
"E1": "Subscriber ID Data",
|
||||
"F1": "Subscriber ID Type",
|
||||
"G1": "Data Volume Uplink",
|
||||
"H1": "Data Volume Downlink",
|
||||
"I1": "Data Total Volume",
|
||||
"J1": "Duration",
|
||||
"K1": "Invocation Time",
|
||||
"L1": "User Identifier",
|
||||
"M1": "SSC Mode",
|
||||
"N1": "DNN ID",
|
||||
"O1": "PDU Type",
|
||||
"P1": "RAT Type",
|
||||
"Q1": "PDU IPv4 Address",
|
||||
"R1": "Network Function IPv4",
|
||||
"S1": "PDU IPv6 Address Swith Prefix",
|
||||
"T1": "Record Network Function ID",
|
||||
"U1": "Record Type",
|
||||
"V1": "Record Opening Time",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
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.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 计费ID
|
||||
chargingID := ""
|
||||
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
|
||||
chargingID = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 订阅 ID 类型
|
||||
subscriptionIDType := "-"
|
||||
// 订阅 ID 数据
|
||||
subscriptionIDData := "-"
|
||||
if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil {
|
||||
if sub, subOk := v.(map[string]any); subOk && sub != nil {
|
||||
subscriptionIDType = sub["subscriptionIDType"].(string)
|
||||
subscriptionIDData = sub["subscriptionIDData"].(string)
|
||||
}
|
||||
}
|
||||
|
||||
// 网络功能 IPv4 地址
|
||||
networkFunctionIPv4Address := ""
|
||||
if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil {
|
||||
if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil {
|
||||
networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string)
|
||||
}
|
||||
}
|
||||
|
||||
// 数据量上行链路
|
||||
var dataVolumeUplink int64 = 0
|
||||
// 数据量下行链路
|
||||
var dataVolumeDownlink int64 = 0
|
||||
// 数据总量
|
||||
var dataTotalVolume int64 = 0
|
||||
if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil {
|
||||
usageList := v.([]any)
|
||||
if len(usageList) > 0 {
|
||||
for _, used := range usageList {
|
||||
usedUnit := used.(map[string]any)
|
||||
usedUnitList := usedUnit["usedUnitContainer"].([]any)
|
||||
if len(usedUnitList) > 0 {
|
||||
for _, data := range usedUnitList {
|
||||
udata := data.(map[string]any)
|
||||
if dup, dupOk := udata["dataVolumeUplink"]; dupOk {
|
||||
dataVolumeUplink += parse.Number(dup)
|
||||
}
|
||||
if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk {
|
||||
dataVolumeDownlink += parse.Number(ddown)
|
||||
}
|
||||
if dt, dtOk := udata["dataTotalVolume"]; dtOk {
|
||||
dataTotalVolume += parse.Number(dt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["duration"]; ok && v != nil {
|
||||
duration = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 调用时间
|
||||
invocationTimestamp := ""
|
||||
if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil {
|
||||
invocationTimestamp = v.(string)
|
||||
}
|
||||
// 记录打开时间
|
||||
User_Identifier := ""
|
||||
SSC_Mode := ""
|
||||
RAT_Type := ""
|
||||
DNN_ID := ""
|
||||
PDU_Type := ""
|
||||
PDU_IPv4 := ""
|
||||
PDU_IPv6 := ""
|
||||
if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil {
|
||||
pduInfo := v.(map[string]any)
|
||||
|
||||
if v, ok := pduInfo["userIdentifier"]; ok && v != nil {
|
||||
User_Identifier = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["sSCMode"]; ok && v != nil {
|
||||
SSC_Mode = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["rATType"]; ok && v != nil {
|
||||
RAT_Type = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["dNNID"]; ok && v != nil {
|
||||
DNN_ID = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["pDUType"]; ok && v != nil {
|
||||
PDU_Type = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["pDUAddress"]; ok && v != nil {
|
||||
pDUAddress := v.(map[string]any)
|
||||
if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil {
|
||||
PDU_IPv4 = addr.(string)
|
||||
}
|
||||
if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil {
|
||||
PDU_IPv6 = addr.(string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 记录网络参数ID
|
||||
recordNFID := ""
|
||||
if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil {
|
||||
recordNFID = v.(string)
|
||||
}
|
||||
|
||||
//记录开始时间
|
||||
recordOpeningTime := ""
|
||||
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
|
||||
recordOpeningTime = v.(string)
|
||||
}
|
||||
|
||||
//记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: chargingID,
|
||||
"C" + idx: row.CoreUID,
|
||||
"D" + idx: row.NeUID,
|
||||
"E" + idx: subscriptionIDData,
|
||||
"F" + idx: subscriptionIDType,
|
||||
"G" + idx: dataVolumeUplink,
|
||||
"H" + idx: dataVolumeDownlink,
|
||||
"I" + idx: dataTotalVolume,
|
||||
"J" + idx: duration,
|
||||
"K" + idx: invocationTimestamp,
|
||||
"L" + idx: User_Identifier,
|
||||
"M" + idx: SSC_Mode,
|
||||
"N" + idx: DNN_ID,
|
||||
"O" + idx: PDU_Type,
|
||||
"P" + idx: RAT_Type,
|
||||
"Q" + idx: PDU_IPv4,
|
||||
"R" + idx: networkFunctionIPv4Address,
|
||||
"S" + idx: PDU_IPv6,
|
||||
"T" + idx: recordNFID,
|
||||
"U" + idx: recordType,
|
||||
"V" + idx: recordOpeningTime,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// ExportSGWC 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportSGWC(rows []model.CDREvent, fileName string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Resource Unique ID",
|
||||
"D1": "Charging ID",
|
||||
"E1": "IMSI",
|
||||
"F1": "MSISDN",
|
||||
"G1": "GPRS Uplink",
|
||||
"H1": "GPRS Downlink",
|
||||
"I1": "Duration",
|
||||
"J1": "Invocation Time",
|
||||
"K1": "PGW Address",
|
||||
"L1": "SGW Address",
|
||||
"M1": "RAT Type",
|
||||
"N1": "PDPPDN Type",
|
||||
"O1": "PDPPDN Address",
|
||||
"P1": "Node Address",
|
||||
"Q1": "Node Type",
|
||||
"R1": "Record Access Point Name NI",
|
||||
"S1": "Record Cause For Rec Closing",
|
||||
"T1": "Record Sequence Number",
|
||||
"U1": "Local Record Sequence Number",
|
||||
"V1": "Record Type",
|
||||
"W1": "Record Opening Time",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
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.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 计费ID
|
||||
chargingID := ""
|
||||
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
|
||||
chargingID = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// IMSI
|
||||
servedIMSI := ""
|
||||
if v, ok := cdrJSON["servedIMSI"]; ok && v != nil {
|
||||
servedIMSI = fmt.Sprint(v)
|
||||
}
|
||||
// MSISDN
|
||||
servedMSISDN := ""
|
||||
if v, ok := cdrJSON["servedMSISDN"]; ok && v != nil {
|
||||
servedMSISDN = fmt.Sprint(v)
|
||||
}
|
||||
// pGWAddressUsed
|
||||
pGWAddressUsed := ""
|
||||
if v, ok := cdrJSON["pGWAddressUsed"]; ok && v != nil {
|
||||
pGWAddressUsed = fmt.Sprint(v)
|
||||
headerCells["K1"] = "PGW Address"
|
||||
}
|
||||
if v, ok := cdrJSON["GGSNAddress"]; ok && v != nil {
|
||||
pGWAddressUsed = fmt.Sprint(v)
|
||||
headerCells["K1"] = "GGSN Address"
|
||||
}
|
||||
// sGWAddress
|
||||
sGWAddress := ""
|
||||
if v, ok := cdrJSON["sGWAddress"]; ok && v != nil {
|
||||
sGWAddress = fmt.Sprint(v)
|
||||
headerCells["L1"] = "SGW Address"
|
||||
}
|
||||
if v, ok := cdrJSON["SGSNAddress"]; ok && v != nil {
|
||||
sGWAddress = fmt.Sprint(v)
|
||||
headerCells["L1"] = "SGSN Address"
|
||||
}
|
||||
// recordType
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = fmt.Sprint(v)
|
||||
}
|
||||
// rATType
|
||||
rATType := ""
|
||||
if v, ok := cdrJSON["rATType"]; ok && v != nil {
|
||||
rATType = fmt.Sprint(v)
|
||||
}
|
||||
// pdpPDNType
|
||||
pdpPDNType := ""
|
||||
if v, ok := cdrJSON["pdpPDNType"]; ok && v != nil {
|
||||
pdpPDNType = fmt.Sprint(v)
|
||||
}
|
||||
// servedPDPPDNAddress
|
||||
servedPDPPDNAddress := ""
|
||||
if v, ok := cdrJSON["servedPDPPDNAddress"]; ok && v != nil {
|
||||
servedPDPPDNAddress = fmt.Sprint(v)
|
||||
}
|
||||
// servedPDPPDNAddress
|
||||
servingNodeAddress := []string{}
|
||||
if v, ok := cdrJSON["servingNodeAddress"]; ok && v != nil {
|
||||
for _, v := range v.([]any) {
|
||||
servingNodeAddress = append(servingNodeAddress, fmt.Sprint(v))
|
||||
}
|
||||
}
|
||||
// servingNodeType
|
||||
servingNodeType := []string{}
|
||||
if v, ok := cdrJSON["servingNodeType"]; ok && v != nil {
|
||||
for _, v := range v.([]any) {
|
||||
if v, ok := v.(map[string]any)["servingNodeType"]; ok && v != nil {
|
||||
servingNodeType = append(servingNodeType, fmt.Sprint(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
// accessPointNameNI
|
||||
accessPointNameNI := ""
|
||||
if v, ok := cdrJSON["accessPointNameNI"]; ok && v != nil {
|
||||
accessPointNameNI = fmt.Sprint(v)
|
||||
}
|
||||
// causeForRecClosing
|
||||
causeForRecClosing := ""
|
||||
if v, ok := cdrJSON["causeForRecClosing"]; ok && v != nil {
|
||||
causeForRecClosing = fmt.Sprint(v)
|
||||
}
|
||||
// recordSequenceNumber
|
||||
recordSequenceNumber := ""
|
||||
if v, ok := cdrJSON["recordSequenceNumber"]; ok && v != nil {
|
||||
recordSequenceNumber = fmt.Sprint(v)
|
||||
}
|
||||
// localRecordSequenceNumber
|
||||
localRecordSequenceNumber := ""
|
||||
if v, ok := cdrJSON["localRecordSequenceNumber"]; ok && v != nil {
|
||||
localRecordSequenceNumber = fmt.Sprint(v)
|
||||
}
|
||||
// 数据量上行链路
|
||||
var dataVolumeGPRSUplink int64 = 0
|
||||
// 数据量下行链路
|
||||
var dataVolumeGPRSDownlink int64 = 0
|
||||
if v, ok := cdrJSON["listOfTrafficVolumes"]; ok && v != nil {
|
||||
usageList := v.([]any)
|
||||
if len(usageList) > 0 {
|
||||
for _, used := range usageList {
|
||||
usedUnit := used.(map[string]any)
|
||||
if dup, dupOk := usedUnit["dataVolumeGPRSUplink"]; dupOk {
|
||||
dataVolumeGPRSUplink = parse.Number(dup)
|
||||
}
|
||||
if ddown, ddownOk := usedUnit["dataVolumeGPRSDownlink"]; ddownOk {
|
||||
dataVolumeGPRSDownlink = parse.Number(ddown)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["duration"]; ok && v != nil {
|
||||
duration = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 调用时间
|
||||
invocationTimestamp := ""
|
||||
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
|
||||
invocationTimestamp = v.(string)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeUID,
|
||||
"C" + idx: row.CoreUID,
|
||||
"D" + idx: chargingID,
|
||||
"E" + idx: servedIMSI,
|
||||
"F" + idx: servedMSISDN,
|
||||
"G" + idx: dataVolumeGPRSUplink,
|
||||
"H" + idx: dataVolumeGPRSDownlink,
|
||||
"I" + idx: duration,
|
||||
"J" + idx: invocationTimestamp,
|
||||
"K" + idx: pGWAddressUsed,
|
||||
"L" + idx: sGWAddress,
|
||||
"M" + idx: rATType,
|
||||
"N" + idx: pdpPDNType,
|
||||
"O" + idx: servedPDPPDNAddress,
|
||||
"P" + idx: strings.Join(servingNodeAddress, ","),
|
||||
"Q" + idx: strings.Join(servingNodeType, ","),
|
||||
"R" + idx: accessPointNameNI,
|
||||
"S" + idx: causeForRecClosing,
|
||||
"T" + idx: recordSequenceNumber,
|
||||
"U" + idx: localRecordSequenceNumber,
|
||||
"V" + idx: recordType,
|
||||
"W" + idx: invocationTimestamp,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// ExportIMS 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportIMS(rows []model.CDREvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Record Behavior",
|
||||
"D1": "Type",
|
||||
"E1": "Caller",
|
||||
"F1": "Called",
|
||||
"G1": "Duration",
|
||||
"H1": "Result Code",
|
||||
"I1": "Result Cause",
|
||||
"J1": "Call Start Time",
|
||||
"K1": "Hangup Time",
|
||||
}
|
||||
// 读取字典数据 CDR SIP响应代码类别类型
|
||||
dictCDRSipCode := sysService.NewSysDictData.FindByType("cdr_sip_code")
|
||||
// 读取字典数据 CDR SIP响应代码类别类型原因
|
||||
dictCDRSipCodeCause := sysService.NewSysDictData.FindByType("cdr_sip_code_cause")
|
||||
// 读取字典数据 CDR 呼叫类型
|
||||
dictCDRCallType := sysService.NewSysDictData.FindByType("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]any
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
// 呼叫类型
|
||||
callType := "sms"
|
||||
callTypeLable := "SMS"
|
||||
if v, ok := cdrJSON["callType"]; ok && v != nil {
|
||||
callType = v.(string)
|
||||
for _, v := range dictCDRCallType {
|
||||
if callType == v.DataValue {
|
||||
callTypeLable = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 被叫
|
||||
called := ""
|
||||
if v, ok := cdrJSON["calledParty"]; ok && v != nil {
|
||||
called = v.(string)
|
||||
}
|
||||
// 主叫
|
||||
caller := ""
|
||||
if v, ok := cdrJSON["callerParty"]; ok && v != nil {
|
||||
caller = v.(string)
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" {
|
||||
duration = fmt.Sprintf("%ds", parse.Number(v))
|
||||
}
|
||||
// 呼叫结果 非短信都有code作为结果 sms短信都ok
|
||||
callResult := "Other"
|
||||
callCause := "Call failure for other reason"
|
||||
if callType == "sms" {
|
||||
callResult = "Success"
|
||||
callCause = "Normal Send"
|
||||
} else {
|
||||
if v, ok := cdrJSON["cause"]; ok && v != nil {
|
||||
cause := fmt.Sprint(v)
|
||||
for _, v := range dictCDRSipCode {
|
||||
if cause == v.DataValue {
|
||||
callResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, v := range dictCDRSipCodeCause {
|
||||
if cause == v.DataValue {
|
||||
callCause = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 呼叫时间
|
||||
seizureTimeStr := ""
|
||||
if v, ok := cdrJSON["seizureTime"]; ok && v != nil {
|
||||
if seizureTime := parse.Number(v); seizureTime > 0 {
|
||||
seizureTimeStr = date.ParseDateToStr(seizureTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
seizureTimeStr = v.(string)
|
||||
}
|
||||
}
|
||||
// 挂断时间
|
||||
releaseTimeStr := ""
|
||||
if v, ok := cdrJSON["releaseTime"]; ok && v != nil {
|
||||
if releaseTime := parse.Number(v); releaseTime > 0 {
|
||||
releaseTimeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
releaseTimeStr = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeUID,
|
||||
"C" + idx: recordType,
|
||||
"D" + idx: callTypeLable,
|
||||
"E" + idx: caller,
|
||||
"F" + idx: called,
|
||||
"G" + idx: duration,
|
||||
"H" + idx: callResult,
|
||||
"I" + idx: callCause,
|
||||
"J" + idx: seizureTimeStr,
|
||||
"K" + idx: releaseTimeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/utils/date"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 UDMAuthUser 结构体
|
||||
var NewUDMAuthUser = &UDMAuthUser{
|
||||
udmAuthRepository: repository.NewUDMAuthUser,
|
||||
}
|
||||
|
||||
// UDM鉴权信息 服务层处理
|
||||
type UDMAuthUser struct {
|
||||
// UDM鉴权信息数据信息
|
||||
udmAuthRepository *repository.UDMAuthUser
|
||||
}
|
||||
|
||||
// dataByRedis UDM鉴权用户 db:0 中 ausf:*
|
||||
func (r *UDMAuthUser) dataByRedis(coreUid, neUid, imsi string) []model.UDMAuthUser {
|
||||
arr := []model.UDMAuthUser{}
|
||||
key := fmt.Sprintf("ausf:%s", imsi)
|
||||
source := fmt.Sprintf("UDM_%s", neUid)
|
||||
|
||||
// 网元主机的Redis客户端
|
||||
redisClient, err := neService.NewNeInfo.NeRunRedisClient(coreUid, neUid)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
defer func() {
|
||||
redisClient.Close()
|
||||
redis.ConnectPush(source, nil)
|
||||
}()
|
||||
redis.ConnectPush(source, redisClient.Client)
|
||||
|
||||
ausfArr, err := redis.GetKeys(source, key)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
mkv, err := redis.GetHashBatch(source, ausfArr)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
|
||||
for k, m := range mkv {
|
||||
if len(k) != 20 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 跳过-号数据 ausf:360000100000130
|
||||
imsi, hasPrefix := strings.CutPrefix(k, "ausf:")
|
||||
if strings.Contains(imsi, "-") || !hasPrefix {
|
||||
continue
|
||||
}
|
||||
|
||||
amf := ""
|
||||
if v, ok := m["amf"]; ok {
|
||||
amf = strings.Replace(v, "\r\n", "", 1)
|
||||
}
|
||||
// 创建时间
|
||||
var createTime int64 = 0
|
||||
if v, ok := m["create_time"]; ok {
|
||||
t := date.ParseStrToDate(v, time.RFC3339)
|
||||
createTime = t.UnixMilli()
|
||||
} else {
|
||||
createTime = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
a := model.UDMAuthUser{
|
||||
CoreUID: coreUid,
|
||||
NeUID: neUid,
|
||||
NeType: "UDM",
|
||||
IMSI: imsi,
|
||||
Amf: amf,
|
||||
Ki: m["ki"],
|
||||
AlgoIndex: m["algo"],
|
||||
Opc: m["opc"],
|
||||
CreateTime: createTime,
|
||||
}
|
||||
arr = append(arr, a)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据
|
||||
func (r *UDMAuthUser) ResetData(coreUid, neUid string) int64 {
|
||||
authArr := r.dataByRedis(coreUid, neUid, "*")
|
||||
// 数据清空后添加
|
||||
go r.udmAuthRepository.ClearAndInsert(coreUid, neUid, authArr)
|
||||
return int64(len(authArr))
|
||||
}
|
||||
|
||||
// ParseInfo 解析单个用户imsi鉴权信息 data从命令MML得到的结果
|
||||
func (r *UDMAuthUser) ParseInfo(coreUid, neUid, imsi string, data map[string]string) model.UDMAuthUser {
|
||||
u := r.udmAuthRepository.SelectByIMSI(coreUid, neUid, imsi)
|
||||
u.CoreUID = coreUid
|
||||
u.NeUID = neUid
|
||||
u.NeType = "UDM"
|
||||
// 用于更新
|
||||
u.Amf = data["amf"]
|
||||
u.Ki = data["ki"]
|
||||
u.AlgoIndex = data["algo"]
|
||||
u.Opc = data["opc"]
|
||||
return u
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r *UDMAuthUser) FindByPage(query map[string]string) ([]model.UDMAuthUser, int64) {
|
||||
return r.udmAuthRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
// Find 查询数据库
|
||||
func (r *UDMAuthUser) Find(u model.UDMAuthUser) []model.UDMAuthUser {
|
||||
return r.udmAuthRepository.SelectList(u)
|
||||
}
|
||||
|
||||
// Insert 从数据中读取后删除imsi再存入数据库
|
||||
// imsi长度15,ki长度32,opc长度0或者32
|
||||
func (r *UDMAuthUser) Insert(coreUid, neUid string, u model.UDMAuthUser) int64 {
|
||||
uArr := r.dataByRedis(coreUid, neUid, u.IMSI)
|
||||
if len(uArr) > 0 {
|
||||
r.udmAuthRepository.DeleteByIMSI(coreUid, neUid, u.IMSI)
|
||||
return r.udmAuthRepository.Inserts(uArr)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InsertData 导入文件数据 dataType目前两种:txt/csv
|
||||
func (r *UDMAuthUser) InsertData(coreUid, neUid, dataType string, data any) int64 {
|
||||
// imsi截取前缀,重新获取部分数据
|
||||
prefixes := make(map[string]struct{})
|
||||
|
||||
if dataType == "csv" {
|
||||
for _, v := range data.([]map[string]string) {
|
||||
imsi := v["imsi"]
|
||||
if len(imsi) < 6 {
|
||||
continue
|
||||
}
|
||||
prefix := imsi[:len(imsi)-4]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
if dataType == "txt" {
|
||||
for _, v := range data.([][]string) {
|
||||
imsi := v[0]
|
||||
if len(imsi) < 6 {
|
||||
continue
|
||||
}
|
||||
prefix := imsi[:len(imsi)-4]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据前缀重新加载插入
|
||||
var num int64 = 0
|
||||
for prefix := range prefixes {
|
||||
// 直接删除前缀的记录
|
||||
r.udmAuthRepository.DeletePrefixByIMSI(coreUid, neUid, prefix)
|
||||
// keys ausf:4600001000004*
|
||||
arr := r.dataByRedis(coreUid, neUid, prefix+"*")
|
||||
if len(arr) > 0 {
|
||||
num += r.udmAuthRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// Delete 删除单个不重新加载
|
||||
func (r *UDMAuthUser) Delete(coreUid, neUid, imsi string) int64 {
|
||||
return r.udmAuthRepository.DeleteByIMSI(coreUid, neUid, imsi)
|
||||
}
|
||||
|
||||
// LoadData 重新加载从imsi开始num的数据
|
||||
func (r *UDMAuthUser) LoadData(coreUid, neUid, imsi string, num int64) {
|
||||
startIMSI, _ := strconv.ParseInt(imsi, 10, 64)
|
||||
var i int64
|
||||
for i = 0; i < num; i++ {
|
||||
keyIMSI := fmt.Sprintf("%015d", startIMSI+i)
|
||||
// 删除原数据
|
||||
r.udmAuthRepository.DeleteByIMSI(coreUid, neUid, keyIMSI)
|
||||
// 加载数据
|
||||
arr := r.dataByRedis(coreUid, neUid, keyIMSI)
|
||||
if len(arr) < 1 {
|
||||
continue
|
||||
}
|
||||
r.udmAuthRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseCommandParams 解析数据组成命令参数 ki=xx,xx=xx,...
|
||||
func (r *UDMAuthUser) ParseCommandParams(item model.UDMAuthUser) string {
|
||||
var conditions []string
|
||||
if item.Ki != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("ki=%s", item.Ki))
|
||||
}
|
||||
|
||||
if item.Amf != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("amf=%s", item.Amf))
|
||||
}
|
||||
if item.AlgoIndex != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("algo=%s", item.AlgoIndex))
|
||||
}
|
||||
if item.Opc != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("opc=%s", item.Opc))
|
||||
}
|
||||
return strings.Join(conditions, ",")
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 UDMExtend 结构体
|
||||
var NewUDMExtend = &UDMExtend{
|
||||
UDMExtendRepository: repository.NewUDMExtend,
|
||||
}
|
||||
|
||||
// UDM用户IMSI拓展信息 服务层处理
|
||||
type UDMExtend struct {
|
||||
// UDM用户IMSI信息数据信息
|
||||
UDMExtendRepository *repository.UDMExtend
|
||||
}
|
||||
|
||||
// FindByIMSIAndNeID 通过IMSI和网元标识查询信息 neId为%时模糊imsi查询
|
||||
func (r UDMExtend) FindByIMSIAndNeID(coreUid, neUid, imsi string) model.UDMExtend {
|
||||
return r.UDMExtendRepository.SelectByIMSI(coreUid, neUid, imsi)
|
||||
}
|
||||
|
||||
// Save 新增或修改信息
|
||||
func (r UDMExtend) Save(u model.UDMExtend) bool {
|
||||
r.UDMExtendRepository.DeleteByIMSI(u.CoreUID, u.NeUID, u.IMSI)
|
||||
return r.UDMExtendRepository.Inserts([]model.UDMExtend{u}) > 0
|
||||
}
|
||||
|
||||
// Delete 删除信息 neId为%时模糊imsi查询
|
||||
func (r UDMExtend) Delete(coreUid, neUid, imsi string) int64 {
|
||||
return r.UDMExtendRepository.DeleteByIMSI(coreUid, neUid, imsi)
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 UDMSubUser 结构体
|
||||
var NewUDMSubUser = &UDMSubUser{
|
||||
udmSubRepository: repository.NewUDMSub,
|
||||
UDMExtendRepository: repository.NewUDMExtend,
|
||||
}
|
||||
|
||||
// UDM签约信息 服务层处理
|
||||
type UDMSubUser struct {
|
||||
udmSubRepository *repository.UDMSubUser // UDM签约信息数据信息
|
||||
UDMExtendRepository *repository.UDMExtend // UDM用户IMSI信息数据信息
|
||||
}
|
||||
|
||||
// dataByRedis UDM签约用户 db:0 中 udm-sd:*
|
||||
func (r *UDMSubUser) dataByRedis(coreUid, neUid, imsi string) []model.UDMSubUser {
|
||||
arr := []model.UDMSubUser{}
|
||||
key := fmt.Sprintf("udm-sd:%s", imsi)
|
||||
source := fmt.Sprintf("UDM_%s", neUid)
|
||||
|
||||
// 网元主机的Redis客户端
|
||||
redisClient, err := neService.NewNeInfo.NeRunRedisClient(coreUid, neUid)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
defer func() {
|
||||
redisClient.Close()
|
||||
redis.ConnectPush(source, nil)
|
||||
}()
|
||||
redis.ConnectPush(source, redisClient.Client)
|
||||
|
||||
udmsdArr, err := redis.GetKeys(source, key)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
mkv, err := redis.GetHashBatch(source, udmsdArr)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
|
||||
for k, m := range mkv {
|
||||
if len(k) != 22 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 跳过-号数据 udm-sd:360000100000130
|
||||
imsi, hasPrefix := strings.CutPrefix(k, "udm-sd:")
|
||||
if strings.Contains(imsi, "-") || !hasPrefix {
|
||||
continue
|
||||
}
|
||||
|
||||
a := model.UDMSubUser{
|
||||
CoreUID: coreUid,
|
||||
NeUID: neUid,
|
||||
NeType: "UDM",
|
||||
IMSI: imsi, // udm-sd:360000100000130
|
||||
MSISDN: m["gpsi"], // 8612300000130
|
||||
SmfSel: m["smf-sel"], // def_snssai
|
||||
SmData: m["sm-dat"], // 1-000001&cmnet&ims&3gnet
|
||||
Cag: m["cag"], // def_cag
|
||||
}
|
||||
|
||||
// def_ambr,def_nssai,0,def_arfb,def_sar,3,1,12000,1,1000,0,1,-
|
||||
if v, ok := m["am-dat"]; ok {
|
||||
arr := strings.Split(v, ",")
|
||||
a.AmDat = v
|
||||
a.UeAmbrTpl = arr[0]
|
||||
a.NssaiTpl = arr[1]
|
||||
a.RatRestrictions = arr[2]
|
||||
a.AreaForbiddenTpl = arr[3]
|
||||
a.ServiceAreaRestrictionTpl = arr[4]
|
||||
a.CnTypeRestrictions = arr[5]
|
||||
a.RfspIndex = arr[6]
|
||||
a.SubsRegTime = arr[7]
|
||||
a.UeUsageType = arr[8]
|
||||
a.ActiveTime = arr[9]
|
||||
a.MicoAllowed = "0" // arr[10]
|
||||
a.OdbPs = "1" // arr[11]
|
||||
a.GroupId = "-" // arr[12]
|
||||
if len(arr) > 10 {
|
||||
a.MicoAllowed = arr[10]
|
||||
}
|
||||
if len(arr) > 11 {
|
||||
a.OdbPs = arr[11]
|
||||
}
|
||||
if len(arr) > 12 && arr[12] != "-" {
|
||||
a.GroupId = arr[12]
|
||||
}
|
||||
}
|
||||
// 1,64,24,65,def_eps,1,2,010200000000,-
|
||||
if v, ok := m["eps-dat"]; ok {
|
||||
arr := strings.Split(v, ",")
|
||||
// 跳过非常规数据
|
||||
if len(arr) > 9 {
|
||||
continue
|
||||
}
|
||||
a.EpsDat = v
|
||||
a.EpsFlag = arr[0]
|
||||
a.EpsOdb = arr[1]
|
||||
a.HplmnOdb = arr[2]
|
||||
a.Ard = arr[3]
|
||||
a.Epstpl = arr[4]
|
||||
a.ContextId = arr[5]
|
||||
a.ApnNum = arr[6] // 导入和导出不用
|
||||
a.ApnContext = arr[7]
|
||||
if len(arr) >= 9 {
|
||||
a.StaticIp = arr[8]
|
||||
}
|
||||
}
|
||||
|
||||
arr = append(arr, a)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据
|
||||
func (r *UDMSubUser) ResetData(coreUid, neUid string) int64 {
|
||||
subArr := r.dataByRedis(coreUid, neUid, "*")
|
||||
// 数据清空后添加
|
||||
go r.udmSubRepository.ClearAndInsert(coreUid, neUid, subArr)
|
||||
return int64(len(subArr))
|
||||
}
|
||||
|
||||
// ParseInfo 解析单个用户imsi签约信息 data从命令MML得到的结果
|
||||
func (r *UDMSubUser) ParseInfo(coreUid, neUid, imsi string, data map[string]string) model.UDMSubUser {
|
||||
u := r.udmSubRepository.SelectByIMSI(coreUid, neUid, imsi)
|
||||
|
||||
cnType, _ := strconv.ParseInt(data["CNType"][:4], 0, 64) // 0x03(EPC|5GC)
|
||||
rat, _ := strconv.ParseInt(data["RAT"][:4], 0, 64) // 0x00(VIRTUAL|WLAN|EUTRA|NR)
|
||||
msisdn := data["MSISDN"]
|
||||
if imsMsisdnLen := strings.Index(msisdn, ","); imsMsisdnLen != -1 {
|
||||
msisdn = msisdn[:imsMsisdnLen]
|
||||
}
|
||||
|
||||
// 用于更新
|
||||
u.CoreUID = coreUid
|
||||
u.NeUID = neUid
|
||||
u.NeType = "UDM"
|
||||
u.IMSI = imsi
|
||||
u.MSISDN = msisdn
|
||||
u.UeAmbrTpl = data["AMBR"]
|
||||
u.NssaiTpl = data["NSSAI"]
|
||||
u.AreaForbiddenTpl = data["AreaForbidden"]
|
||||
u.ServiceAreaRestrictionTpl = data["ServiceAreaRestriction"]
|
||||
u.CnTypeRestrictions = fmt.Sprint(cnType)
|
||||
u.RatRestrictions = fmt.Sprint(rat)
|
||||
u.MicoAllowed = data["MICO"]
|
||||
u.SmData = data["SM-Data(snssai+dnn[1..n])"]
|
||||
u.SmfSel = data["Smf-Selection"]
|
||||
u.Cag = data["cag"]
|
||||
|
||||
// 1,64,24,65,def_eps,1,2,010200000000,-
|
||||
if v, ok := data["EPS-Data"]; ok {
|
||||
u.EpsDat = v
|
||||
arr := strings.Split(v, ",")
|
||||
u.EpsFlag = arr[0]
|
||||
u.EpsOdb = arr[1]
|
||||
u.HplmnOdb = arr[2]
|
||||
u.Ard = arr[3]
|
||||
u.Epstpl = arr[4]
|
||||
u.ContextId = arr[5]
|
||||
u.ApnNum = arr[6] // 导入和导出不用
|
||||
u.ApnContext = arr[7]
|
||||
u.StaticIp = arr[8]
|
||||
}
|
||||
|
||||
// 补充用户拓展信息
|
||||
info := r.UDMExtendRepository.SelectByIMSI(coreUid, neUid, imsi)
|
||||
if info.IMSI == imsi {
|
||||
u.Remark = info.Remark
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r *UDMSubUser) FindByPage(query map[string]string) ([]model.UDMSubUser, int64) {
|
||||
return r.udmSubRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
// Find 查询数据库
|
||||
func (r *UDMSubUser) Find(u model.UDMSubUser) []model.UDMSubUser {
|
||||
return r.udmSubRepository.SelectList(u)
|
||||
}
|
||||
|
||||
// Insert 从数据中读取后删除imsi再存入数据库
|
||||
// imsi长度15,ki长度32,opc长度0或者32
|
||||
func (r *UDMSubUser) Insert(coreUid, neUid string, u model.UDMSubUser) int64 {
|
||||
uArr := r.dataByRedis(coreUid, neUid, u.IMSI)
|
||||
if len(uArr) > 0 {
|
||||
r.udmSubRepository.DeleteByIMSI(coreUid, neUid, u.IMSI)
|
||||
// 新增到拓展信息
|
||||
if u.Remark != "" {
|
||||
r.UDMExtendRepository.DeleteByIMSI(coreUid, "%", u.IMSI)
|
||||
r.UDMExtendRepository.Inserts([]model.UDMExtend{{
|
||||
CoreUID: u.CoreUID,
|
||||
NeUID: u.NeUID,
|
||||
NeType: u.NeType,
|
||||
IMSI: u.IMSI,
|
||||
MSISDN: u.MSISDN,
|
||||
Remark: u.Remark,
|
||||
}})
|
||||
}
|
||||
return r.udmSubRepository.Inserts(uArr)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InsertData 导入文件数据 dataType目前两种:txt/csv
|
||||
func (r *UDMSubUser) InsertData(coreUid, neUid, dataType string, data any) int64 {
|
||||
// imsi截取前缀,重新获取部分数据
|
||||
prefixes := make(map[string]struct{})
|
||||
|
||||
if dataType == "csv" {
|
||||
for _, v := range data.([]map[string]string) {
|
||||
imsi := v["imsi"]
|
||||
if len(imsi) < 6 {
|
||||
continue
|
||||
}
|
||||
prefix := imsi[:len(imsi)-4]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
if dataType == "txt" {
|
||||
for _, v := range data.([][]string) {
|
||||
imsi := v[0]
|
||||
if len(imsi) < 6 {
|
||||
continue
|
||||
}
|
||||
prefix := imsi[:len(imsi)-4]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据前缀重新加载插入
|
||||
var num int64 = 0
|
||||
for prefix := range prefixes {
|
||||
// keys udm-sd:4600001000004*
|
||||
arr := r.dataByRedis(coreUid, neUid, prefix+"*")
|
||||
if len(arr) > 0 {
|
||||
r.udmSubRepository.DeletePrefixByIMSI(coreUid, neUid, prefix)
|
||||
num += r.udmSubRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// Delete 删除单个不重新加载
|
||||
func (r *UDMSubUser) Delete(coreUid, neUid, imsi string) int64 {
|
||||
// 删除拓展信息
|
||||
r.UDMExtendRepository.DeleteByIMSI(coreUid, neUid, imsi)
|
||||
return r.udmSubRepository.DeleteByIMSI(coreUid, neUid, imsi)
|
||||
}
|
||||
|
||||
// LoadData 重新加载从imsi开始num的数据
|
||||
// remark不为空,则新增到拓展信息,删除标记为-(Deleted)-
|
||||
func (r *UDMSubUser) LoadData(coreUid, neUid, imsi string, num int64, remark string) {
|
||||
startIMSI, _ := strconv.ParseInt(imsi, 10, 64)
|
||||
var i int64
|
||||
for i = 0; i < num; i++ {
|
||||
keyIMSI := fmt.Sprintf("%015d", startIMSI+i)
|
||||
// 删除原数据
|
||||
r.udmSubRepository.DeleteByIMSI(coreUid, neUid, keyIMSI)
|
||||
if remark == "-(Deleted)-" {
|
||||
r.UDMExtendRepository.DeleteByIMSI(coreUid, "%", keyIMSI)
|
||||
}
|
||||
// 加载数据,删除标记为-(Deleted)-加载为空不插入
|
||||
arr := r.dataByRedis(coreUid, neUid, keyIMSI)
|
||||
if len(arr) < 1 {
|
||||
continue
|
||||
}
|
||||
r.udmSubRepository.Inserts(arr)
|
||||
// 拓展信息
|
||||
if remark != "" {
|
||||
uarr := make([]model.UDMExtend, 0, len(arr))
|
||||
for _, v := range arr {
|
||||
uarr = append(uarr, model.UDMExtend{
|
||||
CoreUID: v.CoreUID,
|
||||
NeUID: v.NeUID,
|
||||
NeType: v.NeType,
|
||||
IMSI: v.IMSI,
|
||||
MSISDN: v.MSISDN,
|
||||
Remark: remark,
|
||||
})
|
||||
}
|
||||
r.UDMExtendRepository.DeleteByIMSI(coreUid, neUid, keyIMSI)
|
||||
r.UDMExtendRepository.Inserts(uarr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ParseCommandParams 解析数据组成命令参数 msisdn=xx,xx=xx,...
|
||||
func (r *UDMSubUser) ParseCommandParams(item model.UDMSubUser) string {
|
||||
var conditions []string
|
||||
if item.MSISDN != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("msisdn=%s", item.MSISDN))
|
||||
}
|
||||
|
||||
// AmData
|
||||
if item.UeAmbrTpl != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("ambr=%s", item.UeAmbrTpl))
|
||||
}
|
||||
if item.NssaiTpl != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("nssai=%s", item.NssaiTpl))
|
||||
}
|
||||
if item.AreaForbiddenTpl != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("arfb=%s", item.AreaForbiddenTpl))
|
||||
}
|
||||
if item.ServiceAreaRestrictionTpl != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("sar=%s", item.ServiceAreaRestrictionTpl))
|
||||
}
|
||||
if item.RatRestrictions != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("rat=%s", item.RatRestrictions))
|
||||
}
|
||||
if item.CnTypeRestrictions != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("cn=%s", item.CnTypeRestrictions))
|
||||
}
|
||||
if item.RfspIndex != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("rfsp=%s", item.RfspIndex))
|
||||
}
|
||||
if item.UeUsageType != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("usagetype=%s", item.UeUsageType))
|
||||
}
|
||||
if item.MicoAllowed != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("mico=%s", item.MicoAllowed))
|
||||
}
|
||||
|
||||
// EpsDat
|
||||
// if item.EpsDat != "" {
|
||||
// conditions = append(conditions, fmt.Sprintf("eps_dat=%s", item.EpsDat))
|
||||
// }
|
||||
if item.EpsFlag != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("eps_flag=%s", item.EpsFlag))
|
||||
}
|
||||
if item.EpsOdb != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("eps_odb=%s", item.EpsOdb))
|
||||
}
|
||||
if item.HplmnOdb != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("hplmn_odb=%s", item.HplmnOdb))
|
||||
}
|
||||
if item.Epstpl != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("epstpl=%s", item.Epstpl))
|
||||
}
|
||||
if item.Ard != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("ard=%s", item.Ard))
|
||||
}
|
||||
if item.ContextId != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("context_id=%s", item.ContextId))
|
||||
}
|
||||
if item.ApnContext != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("apn_context=%s", item.ApnContext))
|
||||
}
|
||||
// static_ip指给4G UE分配的静态IP,没有可不带此字段名,批量添加IP会自动递增
|
||||
if item.StaticIp != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("static_ip=%s", item.StaticIp))
|
||||
}
|
||||
|
||||
// 其他
|
||||
if item.SmfSel != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("smf_sel=%s", item.SmfSel))
|
||||
}
|
||||
if item.SmData != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("sm_data=%s", item.SmData))
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("cag=%s", item.Cag))
|
||||
|
||||
return strings.Join(conditions, ",")
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 UDMVOIPUser 结构体
|
||||
var NewUDMVOIPUser = &UDMVOIPUser{
|
||||
udmVOIPRepository: repository.NewUDMVOIPUser,
|
||||
}
|
||||
|
||||
// UDMVOIP信息 服务层处理
|
||||
type UDMVOIPUser struct {
|
||||
// UDMVOIP信息数据信息
|
||||
udmVOIPRepository *repository.UDMVOIPUser
|
||||
}
|
||||
|
||||
// dataByRedis UDMVOIP用户 db:0 中 voip:*
|
||||
func (r UDMVOIPUser) dataByRedis(coreUid, neUid, username string) []model.UDMVOIPUser {
|
||||
arr := []model.UDMVOIPUser{}
|
||||
key := fmt.Sprintf("voip:%s", username)
|
||||
source := fmt.Sprintf("UDM_%s", neUid)
|
||||
|
||||
// 网元主机的Redis客户端
|
||||
redisClient, err := neService.NewNeInfo.NeRunRedisClient(coreUid, neUid)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
defer func() {
|
||||
redisClient.Close()
|
||||
redis.ConnectPush(source, nil)
|
||||
}()
|
||||
redis.ConnectPush(source, redisClient.Client)
|
||||
|
||||
voipArr, err := redis.GetKeys(source, key)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
mkv, err := redis.GetHashBatch(source, voipArr)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
|
||||
for k, m := range mkv {
|
||||
// 跳过-号数据 voip:360000100000130
|
||||
username, hasPrefix := strings.CutPrefix(k, "voip:")
|
||||
if strings.Contains(username, "-") || !hasPrefix {
|
||||
continue
|
||||
}
|
||||
|
||||
a := model.UDMVOIPUser{
|
||||
CoreUID: coreUid,
|
||||
NeUID: neUid,
|
||||
NeType: "UDM",
|
||||
UserName: username,
|
||||
Password: m["password"],
|
||||
}
|
||||
arr = append(arr, a)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// ResetData 重置VOIP用户数据,清空数据库重新同步Redis数据
|
||||
func (r UDMVOIPUser) ResetData(coreUid, neUid string) int64 {
|
||||
arr := r.dataByRedis(coreUid, neUid, "*")
|
||||
// 数据清空后添加
|
||||
go r.udmVOIPRepository.ClearAndInsert(coreUid, neUid, arr)
|
||||
return int64(len(arr))
|
||||
}
|
||||
|
||||
// ParseInfo 解析单个用户userName信息 data从命令MML得到的结果
|
||||
func (r UDMVOIPUser) ParseInfo(coreUid, neUid string, data map[string]string) model.UDMVOIPUser {
|
||||
u := model.UDMVOIPUser{
|
||||
CoreUID: coreUid,
|
||||
NeUID: neUid,
|
||||
NeType: "UDM",
|
||||
UserName: data["username"],
|
||||
Password: data["password"],
|
||||
}
|
||||
// 赋予ID
|
||||
item := r.udmVOIPRepository.SelectByUserName(coreUid, neUid, u.UserName)
|
||||
if item.ID > 0 {
|
||||
u.ID = item.ID
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r UDMVOIPUser) FindByPage(query map[string]string) ([]model.UDMVOIPUser, int64) {
|
||||
return r.udmVOIPRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
// Find 查询数据库
|
||||
func (r UDMVOIPUser) Find(u model.UDMVOIPUser) []model.UDMVOIPUser {
|
||||
return r.udmVOIPRepository.SelectList(u)
|
||||
}
|
||||
|
||||
// Insert 从数据中读取后删除username再存入数据库
|
||||
func (r UDMVOIPUser) Insert(coreUid, neUid string, username string) int64 {
|
||||
uArr := r.dataByRedis(coreUid, neUid, username)
|
||||
if len(uArr) > 0 {
|
||||
r.udmVOIPRepository.DeleteByUserName(coreUid, neUid, username)
|
||||
return r.udmVOIPRepository.Inserts(uArr)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InsertData 导入文件数据 dataType目前两种:txt/csv
|
||||
func (r UDMVOIPUser) InsertData(coreUid, neUid, dataType string, data any) int64 {
|
||||
// imsi截取前缀,重新获取部分数据
|
||||
prefixes := make(map[string]struct{})
|
||||
|
||||
if dataType == "csv" {
|
||||
for _, v := range data.([]map[string]string) {
|
||||
username := v["username"]
|
||||
if len(username) < 4 {
|
||||
continue
|
||||
}
|
||||
prefix := username[:len(username)-3]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
if dataType == "txt" {
|
||||
for _, v := range data.([][]string) {
|
||||
username := v[0]
|
||||
if len(username) < 4 {
|
||||
continue
|
||||
}
|
||||
prefix := username[:len(username)-3]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据前缀重新加载插入
|
||||
var num int64 = 0
|
||||
for prefix := range prefixes {
|
||||
// 直接删除前缀的记录
|
||||
r.udmVOIPRepository.DeletePrefixByUserName(coreUid, neUid, prefix)
|
||||
// keys voip:4600001000004*
|
||||
arr := r.dataByRedis(coreUid, neUid, prefix+"*")
|
||||
if len(arr) > 0 {
|
||||
num += r.udmVOIPRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// Delete 删除单个不重新加载
|
||||
func (r UDMVOIPUser) Delete(coreUid, neUid, username string) int64 {
|
||||
return r.udmVOIPRepository.DeleteByUserName(coreUid, neUid, username)
|
||||
}
|
||||
|
||||
// LoadData 重新加载从username开始num的数据
|
||||
func (r UDMVOIPUser) LoadData(coreUid, neUid, username string, num int64) {
|
||||
startUserName, _ := strconv.ParseInt(username, 10, 64)
|
||||
var i int64
|
||||
for i = 0; i < num; i++ {
|
||||
keyUserName := fmt.Sprintf("%d", startUserName+i)
|
||||
// 删除原数据
|
||||
r.udmVOIPRepository.DeleteByUserName(coreUid, neUid, keyUserName)
|
||||
// 加载数据
|
||||
arr := r.dataByRedis(coreUid, neUid, keyUserName)
|
||||
if len(arr) < 1 {
|
||||
continue
|
||||
}
|
||||
r.udmVOIPRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
neService "be.ems/src/modules/ne/service"
|
||||
"be.ems/src/modules/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 UDMVolteIMSUser 结构体
|
||||
var NewUDMVolteIMSUser = &UDMVolteIMSUser{
|
||||
udmVolteIMSRepository: repository.NewUDMVolteIMSUser,
|
||||
}
|
||||
|
||||
// UDMVolteIMS信息 服务层处理
|
||||
type UDMVolteIMSUser struct {
|
||||
// UDMVolteIMS信息数据信息
|
||||
udmVolteIMSRepository *repository.UDMVolteIMSUser
|
||||
}
|
||||
|
||||
// dataByRedis UDMVolteIMS用户 db:0 中 volte:*
|
||||
func (r UDMVolteIMSUser) dataByRedis(coreUid, neUid, imsi string) []model.UDMVolteIMSUser {
|
||||
arr := []model.UDMVolteIMSUser{}
|
||||
key := fmt.Sprintf("volte:%s", imsi)
|
||||
source := fmt.Sprintf("UDM_%s", neUid)
|
||||
|
||||
// 网元主机的Redis客户端
|
||||
redisClient, err := neService.NewNeInfo.NeRunRedisClient(coreUid, neUid)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
defer func() {
|
||||
redisClient.Close()
|
||||
redis.ConnectPush(source, nil)
|
||||
}()
|
||||
redis.ConnectPush(source, redisClient.Client)
|
||||
|
||||
volteArr, err := redis.GetKeys(source, key)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
mkv, err := redis.GetHashBatch(source, volteArr)
|
||||
if err != nil {
|
||||
return arr
|
||||
}
|
||||
|
||||
for k, m := range mkv {
|
||||
// volte:360000100000130:8612300000130
|
||||
keys := strings.Split(k, ":")
|
||||
if len(keys) != 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
// "110011200004217@ims.mnc001.mcc110.3gppnetwork.org"
|
||||
vni := ""
|
||||
impiParts := strings.Split(m["impi"], "@")
|
||||
if len(impiParts) > 1 {
|
||||
vni = impiParts[1]
|
||||
}
|
||||
|
||||
a := model.UDMVolteIMSUser{
|
||||
CoreUID: coreUid,
|
||||
NeUID: neUid,
|
||||
NeType: "UDM",
|
||||
IMSI: keys[1],
|
||||
MSISDN: keys[2],
|
||||
Tag: m["tag"], // volte = tag
|
||||
VNI: vni,
|
||||
}
|
||||
arr = append(arr, a)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// ResetData 重置VolteIMS用户数据,清空数据库重新同步Redis数据
|
||||
func (r UDMVolteIMSUser) ResetData(coreUid, neUid string) int64 {
|
||||
authArr := r.dataByRedis(coreUid, neUid, "*")
|
||||
// 数据清空后添加
|
||||
go r.udmVolteIMSRepository.ClearAndInsert(coreUid, neUid, authArr)
|
||||
return int64(len(authArr))
|
||||
}
|
||||
|
||||
// ParseInfo 解析单个用户imsi信息 data从命令MML得到的结果
|
||||
func (r UDMVolteIMSUser) ParseInfo(coreUid, neUid string, data map[string]string) model.UDMVolteIMSUser {
|
||||
// "110011200004217@ims.mnc001.mcc110.3gppnetwork.org"
|
||||
vni := ""
|
||||
impiParts := strings.Split(data["impi"], "@")
|
||||
if len(impiParts) > 1 {
|
||||
vni = impiParts[1]
|
||||
}
|
||||
if vni == "" {
|
||||
return model.UDMVolteIMSUser{}
|
||||
}
|
||||
|
||||
u := model.UDMVolteIMSUser{
|
||||
CoreUID: coreUid,
|
||||
NeUID: neUid,
|
||||
IMSI: data["imsi"],
|
||||
MSISDN: data["msisdn"],
|
||||
Tag: data["volte_tag"],
|
||||
VNI: vni,
|
||||
}
|
||||
// 赋予ID
|
||||
item := r.udmVolteIMSRepository.SelectByIMSIAndMSISDN(coreUid, neUid, u.IMSI, u.MSISDN)
|
||||
if item.ID > 0 {
|
||||
u.ID = item.ID
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r UDMVolteIMSUser) FindByPage(query map[string]string) ([]model.UDMVolteIMSUser, int64) {
|
||||
return r.udmVolteIMSRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
// Find 查询数据库
|
||||
func (r UDMVolteIMSUser) Find(u model.UDMVolteIMSUser) []model.UDMVolteIMSUser {
|
||||
return r.udmVolteIMSRepository.SelectList(u)
|
||||
}
|
||||
|
||||
// InsertByIMSI 从数据中读取后删除imsi再存入数据库
|
||||
// imsi长度15
|
||||
func (r UDMVolteIMSUser) InsertByIMSI(coreUid, neUid, imsi string) int64 {
|
||||
uArr := r.dataByRedis(coreUid, neUid, imsi+":*")
|
||||
if len(uArr) > 0 {
|
||||
r.udmVolteIMSRepository.DeleteByIMSI(coreUid, neUid, imsi)
|
||||
return r.udmVolteIMSRepository.Inserts(uArr)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InsertData 导入文件数据 dataType目前两种:txt/csv
|
||||
func (r UDMVolteIMSUser) InsertData(coreUid, neUid, dataType string, data any) int64 {
|
||||
// imsi截取前缀,重新获取部分数据
|
||||
prefixes := make(map[string]struct{})
|
||||
|
||||
if dataType == "csv" {
|
||||
for _, v := range data.([]map[string]string) {
|
||||
imsi := v["imsi"]
|
||||
if len(imsi) < 6 {
|
||||
continue
|
||||
}
|
||||
prefix := imsi[:len(imsi)-4]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
if dataType == "txt" {
|
||||
for _, v := range data.([][]string) {
|
||||
imsi := v[0]
|
||||
if len(imsi) < 6 {
|
||||
continue
|
||||
}
|
||||
prefix := imsi[:len(imsi)-4]
|
||||
prefixes[prefix] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据前缀重新加载插入
|
||||
var num int64 = 0
|
||||
for prefix := range prefixes {
|
||||
// 直接删除前缀的记录
|
||||
r.udmVolteIMSRepository.DeletePrefixByIMSI(coreUid, neUid, prefix)
|
||||
// keys voip:4600001000004*
|
||||
arr := r.dataByRedis(coreUid, neUid, prefix+"*")
|
||||
if len(arr) > 0 {
|
||||
num += r.udmVolteIMSRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// Delete 删除单个不重新加载
|
||||
func (r UDMVolteIMSUser) Delete(coreUid, neUid, imsi string) int64 {
|
||||
return r.udmVolteIMSRepository.DeleteByIMSI(coreUid, neUid, imsi)
|
||||
}
|
||||
|
||||
// LoadData 重新加载从imsi开始num的数据
|
||||
func (r UDMVolteIMSUser) LoadData(coreUid, neUid, imsiOrMsisdn string, num int64) {
|
||||
startIMSIOrMsisdn, _ := strconv.ParseInt(imsiOrMsisdn, 10, 64)
|
||||
var i int64
|
||||
for i = 0; i < num; i++ {
|
||||
keyIMSI := fmt.Sprintf("%015d", startIMSIOrMsisdn+i)
|
||||
if !strings.HasPrefix(imsiOrMsisdn, "0") {
|
||||
keyIMSI = fmt.Sprintf("%d", startIMSIOrMsisdn+i)
|
||||
}
|
||||
// 删除原数据
|
||||
r.udmVolteIMSRepository.DeleteByIMSI(coreUid, neUid, keyIMSI)
|
||||
// 加载数据
|
||||
arr := r.dataByRedis(coreUid, neUid, keyIMSI+":*")
|
||||
if len(arr) < 1 {
|
||||
continue
|
||||
}
|
||||
r.udmVolteIMSRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
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/ne_data/model"
|
||||
"be.ems/src/modules/ne_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
"github.com/tsmask/go-oam"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEvent 结构体
|
||||
var NewUEEvent = &UEEvent{
|
||||
ueEventRepository: repository.NewUEEvent,
|
||||
}
|
||||
|
||||
// UEEvent UE会话事件 服务层处理
|
||||
type UEEvent struct {
|
||||
ueEventRepository *repository.UEEvent // UE会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r UEEvent) FindByPage(neType string, query map[string]string) ([]model.UEEvent, int64) {
|
||||
return r.ueEventRepository.SelectByPage(neType, query)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r UEEvent) DeleteByIds(neType string, ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.ueEventRepository.SelectByIds(neType, ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("no data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.ueEventRepository.DeleteByIds(neType, ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (r UEEvent) Insert(param model.UEEvent) int64 {
|
||||
return r.ueEventRepository.Insert(param)
|
||||
}
|
||||
|
||||
// ExportAMF 导出数据到 xlsx 文件
|
||||
func (r UEEvent) ExportAMF(rows []model.UEEvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "IMSI",
|
||||
"C1": "Event Type",
|
||||
"D1": "Result",
|
||||
"E1": "Time",
|
||||
}
|
||||
// 读取字典数据 UE 事件类型
|
||||
dictUEEventType := sysService.NewSysDictData.FindByType("ue_event_type")
|
||||
// 读取字典数据 UE 事件认证代码类型
|
||||
dictUEAauthCode := sysService.NewSysDictData.FindByType("ue_auth_code")
|
||||
// 读取字典数据 UE 事件CM状态
|
||||
dictUEEventCmState := sysService.NewSysDictData.FindByType("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.DataValue {
|
||||
eventType = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
// 取结果
|
||||
eventResult := ""
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if row.EventType == oam.UENB_TYPE_AUTH {
|
||||
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.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if row.EventType == oam.UENB_TYPE_DETACH {
|
||||
if v, ok := eventJSON["detachTime"]; ok && v != nil {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
eventResult = "Success"
|
||||
}
|
||||
if row.EventType == oam.UENB_TYPE_CM {
|
||||
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.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
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, "")
|
||||
}
|
||||
|
||||
// ExportMME 导出数据到 xlsx 文件
|
||||
func (r UEEvent) ExportMME(rows []model.UEEvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "IMSI",
|
||||
"C1": "Event Type",
|
||||
"D1": "Result",
|
||||
"E1": "Time",
|
||||
}
|
||||
// 读取字典数据 UE 事件类型
|
||||
dictUEEventType := sysService.NewSysDictData.FindByType("ue_event_type")
|
||||
// 读取字典数据 UE 事件认证代码类型
|
||||
dictUEAauthCode := sysService.NewSysDictData.FindByType("ue_auth_code")
|
||||
// 读取字典数据 UE 事件CM状态
|
||||
dictUEEventCmState := sysService.NewSysDictData.FindByType("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.DataValue {
|
||||
eventType = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
// 取结果
|
||||
eventResult := ""
|
||||
if v, ok := eventJSON["result"]; ok && v != nil {
|
||||
eventResult = v.(string)
|
||||
if row.EventType == oam.UENB_TYPE_AUTH {
|
||||
for _, v := range dictUEAauthCode {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if row.EventType == oam.UENB_TYPE_CM {
|
||||
for _, v := range dictUEEventCmState {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
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, "")
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package ne_data
|
||||
|
||||
import (
|
||||
"crypto/des"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// UDM K4加密
|
||||
func encrypt(origData, key []byte) ([]byte, error) {
|
||||
if len(origData) < 1 || len(key) < 1 {
|
||||
return nil, errors.New("wrong data or key")
|
||||
}
|
||||
block, err := des.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bs := block.BlockSize()
|
||||
if len(origData)%bs != 0 {
|
||||
return nil, errors.New("wrong padding")
|
||||
}
|
||||
out := make([]byte, len(origData))
|
||||
dst := out
|
||||
for len(origData) > 0 {
|
||||
block.Encrypt(dst, origData[:bs])
|
||||
origData = origData[bs:]
|
||||
dst = dst[bs:]
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func TestEncrypt(t *testing.T) {
|
||||
// key := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}
|
||||
// 0123456789abcdef
|
||||
|
||||
// ki := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}
|
||||
// 0123456789abcdef0123456789abcdef
|
||||
|
||||
// k4 password
|
||||
key := []byte{0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34}
|
||||
// 1234123412341234
|
||||
|
||||
// k4 crypt ki
|
||||
ki := []byte{0x80, 0x5D, 0xAD, 0xC6, 0xE8, 0xA5, 0x4A, 0x0D, 0x59, 0xD6, 0x22, 0xC7, 0xA0, 0x4D, 0x08, 0xE0}
|
||||
// 805DADC6E8A54A0D59D622C7A04D08E0
|
||||
|
||||
kis, err := encrypt(ki, key)
|
||||
|
||||
// 加密后的,放导入导入文件里ki
|
||||
t.Errorf("kis: %x\n", kis)
|
||||
// 3e479135bb16f45dc874a18831b54d71
|
||||
|
||||
t.Errorf("err: %v\n", err)
|
||||
}
|
||||
Reference in New Issue
Block a user