ref: 网元数据将网元特有拆分直连模块
This commit is contained in:
233
src/modules/network_link/controller/amf.go
Normal file
233
src/modules/network_link/controller/amf.go
Normal file
@@ -0,0 +1,233 @@
|
||||
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"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
neFetchlink "be.ems/src/modules/network_link/fetch_link"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 AMFController 结构体
|
||||
var NewAMF = &AMFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
ueEventService: neDataService.NewUEEventAMF,
|
||||
}
|
||||
|
||||
// 网元AMF
|
||||
//
|
||||
// PATH /amf
|
||||
type AMFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEventAMF // UE会话事件服务
|
||||
}
|
||||
|
||||
// UE会话列表
|
||||
//
|
||||
// GET /ue/list
|
||||
//
|
||||
// @Tags network_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) {
|
||||
var querys model.UEEventAMFQuery
|
||||
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
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UE会话删除
|
||||
//
|
||||
// DELETE /ue/:id
|
||||
//
|
||||
// @Tags network_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(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会话列表导出
|
||||
//
|
||||
// POST /ue/export
|
||||
//
|
||||
// @Tags network_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 [post]
|
||||
func (s *AMFController) UEExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.UEEventAMFQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&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.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
}
|
||||
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
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.ExportXlsx(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 接入基站信息列表
|
||||
//
|
||||
// GET /nb/list
|
||||
//
|
||||
// @Tags network_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/list-cfg
|
||||
//
|
||||
// @Tags network_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/list-cfg [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))
|
||||
}
|
||||
237
src/modules/network_link/controller/ims.go
Normal file
237
src/modules/network_link/controller/ims.go
Normal file
@@ -0,0 +1,237 @@
|
||||
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"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
neFetchlink "be.ems/src/modules/network_link/fetch_link"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 IMSController 结构体
|
||||
var NewIMS = &IMSController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventIMS,
|
||||
}
|
||||
|
||||
// 网元IMS
|
||||
//
|
||||
// PATH /ims
|
||||
type IMSController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventIMS // CDR会话事件服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags network_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) {
|
||||
var querys model.CDREventIMSQuery
|
||||
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
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags network_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(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 network_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 [post]
|
||||
func (s *IMSController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventIMSQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&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.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
}
|
||||
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
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.ExportXlsx(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 在线会话用户数量
|
||||
//
|
||||
// GET /session/num
|
||||
//
|
||||
// @Tags network_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 network_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))
|
||||
}
|
||||
233
src/modules/network_link/controller/mme.go
Normal file
233
src/modules/network_link/controller/mme.go
Normal file
@@ -0,0 +1,233 @@
|
||||
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"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
neFetchlink "be.ems/src/modules/network_link/fetch_link"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 MMEController 结构体
|
||||
var NewMME = &MMEController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
ueEventService: neDataService.NewUEEventMME,
|
||||
}
|
||||
|
||||
// 网元MME
|
||||
//
|
||||
// PATH /mme
|
||||
type MMEController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEventMME // UE会话事件服务
|
||||
}
|
||||
|
||||
// UE会话列表
|
||||
//
|
||||
// GET /ue/list
|
||||
//
|
||||
// @Tags network_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) {
|
||||
var querys model.UEEventMMEQuery
|
||||
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
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UE会话删除
|
||||
//
|
||||
// DELETE /ue/:id
|
||||
//
|
||||
// @Tags network_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(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会话列表导出
|
||||
//
|
||||
// POST /ue/export
|
||||
//
|
||||
// @Tags network_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 [post]
|
||||
func (s *MMEController) UEExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.UEEventMMEQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&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.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
}
|
||||
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
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.ExportXlsx(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 接入基站信息列表
|
||||
//
|
||||
// GET /nb/list
|
||||
//
|
||||
// @Tags network_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/list-cfg
|
||||
//
|
||||
// @Tags network_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/list-cfg [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))
|
||||
}
|
||||
334
src/modules/network_link/controller/pcf.go
Normal file
334
src/modules/network_link/controller/pcf.go
Normal file
@@ -0,0 +1,334 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
neFetchlink "be.ems/src/modules/network_link/fetch_link"
|
||||
|
||||
"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 /neData/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 /neData/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"` // 批量添加,默认0单条,大于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 > 0 { // 批量添加
|
||||
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 /neData/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 /neData/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 > 0 { // 批量删除
|
||||
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 /neData/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 /neData/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))
|
||||
}
|
||||
147
src/modules/network_link/controller/sgwc.go
Normal file
147
src/modules/network_link/controller/sgwc.go
Normal file
@@ -0,0 +1,147 @@
|
||||
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"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"be.ems/src/modules/network_link/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SGWCController 结构体
|
||||
var NewSGWC = &SGWCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventSGWC,
|
||||
UDMExtendService: service.NewUDMExtend,
|
||||
}
|
||||
|
||||
// 网元SGWC
|
||||
//
|
||||
// PATH /sgwc
|
||||
type SGWCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventSGWC // CDR会话事件服务
|
||||
UDMExtendService *service.UDMExtend // UDM用户信息服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags network_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) {
|
||||
var querys model.CDREventSGWCQuery
|
||||
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
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags network_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(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 network_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)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventSGWCQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&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.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
}
|
||||
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
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.ExportXlsx(rows, fileName)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
266
src/modules/network_link/controller/smf.go
Normal file
266
src/modules/network_link/controller/smf.go
Normal file
@@ -0,0 +1,266 @@
|
||||
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"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
neFetchlink "be.ems/src/modules/network_link/fetch_link"
|
||||
"be.ems/src/modules/network_link/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SMFController 结构体
|
||||
var NewSMF = &SMFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventSMF,
|
||||
UDMExtendService: service.NewUDMExtend,
|
||||
}
|
||||
|
||||
// 网元SMF
|
||||
//
|
||||
// PATH /smf
|
||||
type SMFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventSMF // CDR会话事件服务
|
||||
UDMExtendService *service.UDMExtend // UDM用户信息服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags network_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) {
|
||||
var querys model.CDREventSMFQuery
|
||||
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
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags network_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(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 network_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 [post]
|
||||
func (s *SMFController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventSMFQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&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.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
}
|
||||
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
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.ExportXlsx(rows, fileName)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 在线订阅用户数量
|
||||
//
|
||||
// GET /sub/num
|
||||
//
|
||||
// @Tags network_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 network_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/session/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(query.CoreUID, query.NeUID, 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))
|
||||
}
|
||||
145
src/modules/network_link/controller/smsc.go
Normal file
145
src/modules/network_link/controller/smsc.go
Normal file
@@ -0,0 +1,145 @@
|
||||
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"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 SMSCController 结构体
|
||||
var NewSMSC = &SMSCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventSMSC,
|
||||
}
|
||||
|
||||
// 网元SMSC
|
||||
//
|
||||
// PATH /smsc
|
||||
type SMSCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventSMSC // CDR会话事件服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
//
|
||||
// GET /cdr/list
|
||||
//
|
||||
// @Tags network_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) {
|
||||
var querys model.CDREventSMSCQuery
|
||||
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
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// CDR会话删除
|
||||
//
|
||||
// DELETE /cdr/:id
|
||||
//
|
||||
// @Tags network_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(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 network_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 [post]
|
||||
func (s *SMSCController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventSMSCQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&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.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
}
|
||||
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
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.ExportXlsx(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
565
src/modules/network_link/controller/udm_auth.go
Normal file
565
src/modules/network_link/controller/udm_auth.go
Normal file
@@ -0,0 +1,565 @@
|
||||
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/network_element/service"
|
||||
neFetchlink "be.ems/src/modules/network_link/fetch_link"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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 /neData/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 /neData/udm/auth/list [get]
|
||||
func (s *UDMAuthController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmAuthService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
}
|
||||
|
||||
// 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 /neData/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 /neData/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 /neData/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 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()
|
||||
|
||||
// 发送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 /neData/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"` // 批量数量
|
||||
}
|
||||
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 /neData/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(200, resp.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := 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 /neData/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))
|
||||
}
|
||||
551
src/modules/network_link/controller/udm_sub.go
Normal file
551
src/modules/network_link/controller/udm_sub.go
Normal file
@@ -0,0 +1,551 @@
|
||||
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/network_element/service"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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 /neData/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 /neData/udm/sub/list [get]
|
||||
func (s *UDMSubController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmSubService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
}
|
||||
|
||||
// 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 /neData/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 /neData/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 /neData/udm/sub [put]
|
||||
func (s *UDMSubController) Edit(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
neId := c.Param("neId")
|
||||
if neId == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: neId 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()
|
||||
|
||||
// 发送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 /neData/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))
|
||||
}
|
||||
|
||||
// 处理字符转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 /neData/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(200, resp.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := 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 /neData/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))
|
||||
}
|
||||
493
src/modules/network_link/controller/udm_voip.go
Normal file
493
src/modules/network_link/controller/udm_voip.go
Normal file
@@ -0,0 +1,493 @@
|
||||
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/network_element/service"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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 /neData/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 /neData/udm/voip/list [get]
|
||||
func (s *UDMVOIPController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmVOIPService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
}
|
||||
|
||||
// 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 /neData/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 != "" {
|
||||
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 /neData/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 /neData/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 /neData/udm/voip/export [get]
|
||||
func (s *UDMVOIPController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
neId := c.Query("neId")
|
||||
fileType := c.Query("type")
|
||||
if neId == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: neId is empty"))
|
||||
return
|
||||
}
|
||||
if !(fileType == "csv" || fileType == "txt") {
|
||||
c.JSON(200, resp.ErrMsg("file type error, only support csv,txt"))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := 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", neId, 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 /neData/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))
|
||||
}
|
||||
520
src/modules/network_link/controller/udm_volte_ims.go
Normal file
520
src/modules/network_link/controller/udm_volte_ims.go
Normal file
@@ -0,0 +1,520 @@
|
||||
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/network_element/service"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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 /neData/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 /neData/udm/volte-ims/list [get]
|
||||
func (s *UDMVolteIMSController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmVolteIMSService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
}
|
||||
|
||||
// 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 /neData/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
|
||||
}
|
||||
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", query.IMSI, query.MSISDN)
|
||||
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 != "" {
|
||||
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 /neData/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(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
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 /neData/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"` // MSISDN, 精确msisdn删除
|
||||
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()
|
||||
|
||||
// 精确msisdn删除
|
||||
if query.MSISDN != "" {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("del imsuser:imsi=%s,msisdn=%s", query.IMSI, query.MSISDN)
|
||||
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))
|
||||
return
|
||||
}
|
||||
|
||||
// 批量更新
|
||||
if query.Num > 0 {
|
||||
// 发送MML
|
||||
cmd := fmt.Sprintf("bde imsuser: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.udmVolteIMSService.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 imsuser:imsi=%s", imsi)
|
||||
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||
if err != nil {
|
||||
resultData[imsi] = err.Error()
|
||||
continue
|
||||
}
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
s.udmVolteIMSService.Delete(neInfo.CoreUID, neInfo.NeUID, imsi)
|
||||
}
|
||||
resultData[imsi] = data
|
||||
}
|
||||
c.JSON(200, resp.OkData(resultData))
|
||||
}
|
||||
|
||||
// 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 /neData/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(200, resp.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := 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 /neData/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))
|
||||
}
|
||||
71
src/modules/network_link/controller/upf.go
Normal file
71
src/modules/network_link/controller/upf.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/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下行
|
||||
// 单位 比特(bit)
|
||||
//
|
||||
// GET /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 /neData/upf/flow-total [get]
|
||||
func (s UPFController) FlowTotal(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}))
|
||||
}
|
||||
39
src/modules/network_link/fetch_link/alarm.go
Normal file
39
src/modules/network_link/fetch_link/alarm.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// AlarmHistory 告警历史记录
|
||||
func AlarmHistory(neInfo model.NeInfo) ([]map[string]any, error) {
|
||||
// 网元参数配置信息
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", neInfo.IPAddr, neInfo.Port, strings.ToLower(neInfo.NeType))
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
var resData []map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("AlarmHistory Get \"%s\"", neUrl)
|
||||
if !(strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "202") || strings.HasPrefix(errStr, "204")) {
|
||||
logger.Errorf("AlarmHistory %s", err.Error())
|
||||
return nil, fmt.Errorf("NeService Alarm History Info API Error")
|
||||
}
|
||||
}
|
||||
|
||||
if len(resBytes) == 0 {
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("AlarmHistory Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
105
src/modules/network_link/fetch_link/amf.go
Normal file
105
src/modules/network_link/fetch_link/amf.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// AMFNbInfoList AMF基站信息
|
||||
//
|
||||
// 查询参数 {"id":"7"}
|
||||
//
|
||||
// 返回结果 []
|
||||
func AMFNbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/amf/objectType/nbInfo", neInfo.IPAddr, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["id"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("nbId=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
var resData map[string]any
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("AMFNbInfoList Get \"%s\"", neUrl)
|
||||
logger.Errorf("AMFNbInfoList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService AMF API Error")
|
||||
}
|
||||
|
||||
// 序列化结果 {"data":[{"id":"7","name":"NR-SA-GNB","address":"192.168.5.100:60110","ueNum":0}]}
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("AMFNbInfoList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if arr := v.([]any); len(arr) > 0 {
|
||||
result := make([]map[string]any, len(arr))
|
||||
for i, item := range arr {
|
||||
result[i] = item.(map[string]any)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
|
||||
// AMFGnbStateList AMF基站状态信息,对比配置项gnbList
|
||||
//
|
||||
// 返回结果 []
|
||||
func AMFGnbStateList(neInfo model.NeInfo) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/amf/objectType/nbState", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("AMFGnbStateList Get \"%s\"", neUrl)
|
||||
logger.Errorf("AMFGnbStateList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService AMF API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
// {
|
||||
// "data": [
|
||||
// {
|
||||
// "index": 1,
|
||||
// "name": "Gnb",
|
||||
// "address": "192.168.8.1",
|
||||
// "position": "Area-B",
|
||||
// "offTime": "2024-12-30T16:31:57+08:00",
|
||||
// "onTime": "2024-12-30T15:41:59+08:00",
|
||||
// "state": "OFF",
|
||||
// "nbName": "SA",
|
||||
// "ueNum": 1
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("AMFGnbStateList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if arr := v.([]any); len(arr) > 0 {
|
||||
result := make([]map[string]any, len(arr))
|
||||
for i, item := range arr {
|
||||
result[i] = item.(map[string]any)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
68
src/modules/network_link/fetch_link/hlr.go
Normal file
68
src/modules/network_link/fetch_link/hlr.go
Normal file
@@ -0,0 +1,68 @@
|
||||
// 网元HLR服务8080端口。
|
||||
// 融合到UDM网元,也许是UDM的HLR服务。
|
||||
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// HLRTraceStart HLR跟踪任务开始
|
||||
//
|
||||
// data参数 {traceID:"跟踪任务ID", imsi:"IMSI和MSISDN必填一个,都带的话以IMSI为准", msisdn:""}
|
||||
func HLRTraceStart(neInfo model.NeInfo, data map[string]any) (string, error) {
|
||||
// 网元参数配置新增(array)
|
||||
neUrl := fmt.Sprintf("http://%s:%d/trace-manage/v1/add-task", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.PostJSON(neUrl, data, nil)
|
||||
var resData map[string]string
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("HLRTraceStart Post \"%s\"", neUrl)
|
||||
logger.Errorf("HLRTraceStart %s", errStr)
|
||||
return "", fmt.Errorf("NeService HLR API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("HLRTraceStart Unmarshal %s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
if v, ok := resData["code"]; ok && v == "0" {
|
||||
return strings.TrimSpace(strings.ToLower(resData["message"])), nil
|
||||
}
|
||||
return "", fmt.Errorf("%s", resData["message"])
|
||||
}
|
||||
|
||||
// HLRTraceStop HLR跟踪任务停止
|
||||
//
|
||||
// data参数 {traceIDArray: ["跟踪任务ID数组"]}
|
||||
func HLRTraceStop(neInfo model.NeInfo, data map[string]any) (string, error) {
|
||||
// 网元参数配置新增(array)
|
||||
neUrl := fmt.Sprintf("http://%s:%d/trace-manage/v1/delete-task", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.PostJSON(neUrl, data, nil)
|
||||
var resData map[string]string
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("HLRTraceStop Post \"%s\"", neUrl)
|
||||
logger.Errorf("HLRTraceStop %s", errStr)
|
||||
return "", fmt.Errorf("NeService HLR API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("HLRTraceStop Unmarshal %s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
if v, ok := resData["code"]; ok && v == "0" {
|
||||
return strings.TrimSpace(strings.ToLower(resData["message"])), nil
|
||||
}
|
||||
return "", fmt.Errorf("%s", resData["message"])
|
||||
}
|
||||
100
src/modules/network_link/fetch_link/ims.go
Normal file
100
src/modules/network_link/fetch_link/ims.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// IMSUeSessionNum IMS会话数量
|
||||
//
|
||||
// 返回结果 0
|
||||
func IMSUeSessionNum(neInfo model.NeInfo) (int64, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/ims/objectType/ueNum", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("IMSUeSessionNum Get \"%s\"", neUrl)
|
||||
logger.Errorf("IMSUeSessionNum %s", errStr)
|
||||
return 0, fmt.Errorf("NeService IMS API Error")
|
||||
}
|
||||
// 序列化结果 {"data":{"ueNum":0}}
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("IMSUeSessionNum Unmarshal %s", err.Error())
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
var ueNum int64 = 0
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if num := v.(map[string]any)["ueNum"]; num != nil {
|
||||
ueNum = parse.Number(num)
|
||||
}
|
||||
}
|
||||
return ueNum, nil
|
||||
}
|
||||
|
||||
// IMSUeSessionList IMS会话列表
|
||||
//
|
||||
// 查询参数 {"imsi":"460001230000002","msisdn":"12307551232"}
|
||||
//
|
||||
// 返回结果 []
|
||||
func IMSUeSessionList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/ims/objectType/ueInfo", neInfo.IPAddr, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["imsi"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("imsi=%s", v))
|
||||
}
|
||||
if v, ok := data["msisdn"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("msisdn=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("IMSUeSessionList Get \"%s\"", neUrl)
|
||||
logger.Errorf("IMSUeSessionList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService IMS API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
// { "data":[
|
||||
// {
|
||||
// "activeTime": "2023-11-29 17:04:54",
|
||||
// "barring": 0,
|
||||
// "impu": "sip:12307551232@ims.mnc000.mcc460.3gppnetwork.org",
|
||||
// "imsi": "460001230000002",
|
||||
// "msisdn": "12307551232",
|
||||
// "regState": 1
|
||||
// }
|
||||
// ] }
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("IMSUeSessionList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if arr := v.([]any); len(arr) > 0 {
|
||||
result := make([]map[string]any, len(arr))
|
||||
for i, item := range arr {
|
||||
result[i] = item.(map[string]any)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
105
src/modules/network_link/fetch_link/mme.go
Normal file
105
src/modules/network_link/fetch_link/mme.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// MMENbInfoList MME基站信息
|
||||
//
|
||||
// 查询参数 {"id":"7"}
|
||||
//
|
||||
// 返回结果 []
|
||||
func MMENbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/mme/objectType/nbInfo", neInfo.IPAddr, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["id"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("nbId=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
var resData map[string]any
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("MMENbInfoList Get \"%s\"", neUrl)
|
||||
logger.Errorf("MMENbInfoList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService MME API Error")
|
||||
}
|
||||
|
||||
// 序列化结果 {"data":[{"id":"7","name":"NR-SA-GNB","address":"192.168.5.100:60110","ueNum":0}]}
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("MMENbInfoList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if arr := v.([]any); len(arr) > 0 {
|
||||
result := make([]map[string]any, len(arr))
|
||||
for i, item := range arr {
|
||||
result[i] = item.(map[string]any)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
|
||||
// MMEEnbStateList MME基站状态信息,对比配置项enbList
|
||||
//
|
||||
// 返回结果 []
|
||||
func MMEEnbStateList(neInfo model.NeInfo) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/mme/objectType/nbState", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("MMEEnbStateList Get \"%s\"", neUrl)
|
||||
logger.Errorf("MMEEnbStateList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService MME API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
// {
|
||||
// "data": [
|
||||
// {
|
||||
// "index": 1,
|
||||
// "name": "Enb",
|
||||
// "address": "192.168.8.1",
|
||||
// "position": "Area-B",
|
||||
// "offTime": "2024-12-30T16:31:57+08:00",
|
||||
// "onTime": "2024-12-30T15:41:59+08:00",
|
||||
// "state": "OFF",
|
||||
// "nbName": "SA",
|
||||
// "ueNum": 1
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("MMEEnbStateList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if arr := v.([]any); len(arr) > 0 {
|
||||
result := make([]map[string]any, len(arr))
|
||||
for i, item := range arr {
|
||||
result[i] = item.(map[string]any)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
170
src/modules/network_link/fetch_link/ne_config.go
Normal file
170
src/modules/network_link/fetch_link/ne_config.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// NeConfigOMC 网元配置对端网管信息
|
||||
func NeConfigOMC(neInfo model.NeInfo) (map[string]any, error) {
|
||||
// 网元配置对端网管信息
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig", neInfo.IPAddr, neInfo.Port, strings.ToLower(neInfo.NeType))
|
||||
resBytes, err := fetch.PutJSON(neUrl, map[string]any{
|
||||
"neId": neInfo.ID,
|
||||
"neName": neInfo.NeName,
|
||||
"port": neInfo.Port,
|
||||
"province": neInfo.Province,
|
||||
"pvFlag": neInfo.PvFlag,
|
||||
"rmUID": neInfo.NeUID,
|
||||
"vendorName": neInfo.VendorName,
|
||||
"dn": neInfo.Dn,
|
||||
}, nil)
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
if strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "204") {
|
||||
return resData, nil
|
||||
}
|
||||
logger.Warnf("NeConfigOMC Put \"%s\"", neUrl)
|
||||
logger.Errorf("NeConfigOMC %s", errStr)
|
||||
return nil, fmt.Errorf("NeService Config OMC Update API Error")
|
||||
}
|
||||
|
||||
// 200 成功无数据时
|
||||
if len(resBytes) == 0 {
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeConfigOMC Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// NeConfigInfo 网元配置信息
|
||||
func NeConfigInfo(neInfo model.NeInfo, paramName string) (map[string]any, error) {
|
||||
// 网元参数配置信息
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/%s", neInfo.IPAddr, neInfo.Port, strings.ToLower(neInfo.NeType), paramName)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 30_000)
|
||||
if err != nil {
|
||||
logger.Warnf("NeConfigInfo Get \"%s\"", neUrl)
|
||||
logger.Errorf("NeConfigInfo %s", err.Error())
|
||||
return nil, fmt.Errorf("NeService Config Info API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeConfigInfo Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
// 网元参数配置信息为空时是{},需要补充data属性
|
||||
if _, ok := resData["data"]; !ok {
|
||||
resData["data"] = []map[string]any{}
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// NeConfigUpdate 网元配置更新
|
||||
func NeConfigUpdate(neInfo model.NeInfo, paramName, loc string, data map[string]any) (map[string]any, error) {
|
||||
// array需要层级
|
||||
if loc != "" {
|
||||
loc = fmt.Sprintf("?loc=%v", loc)
|
||||
}
|
||||
// 网元参数配置新增(array)
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/%s%s", neInfo.IPAddr, neInfo.Port, strings.ToLower(neInfo.NeType), paramName, loc)
|
||||
resBytes, err := fetch.PutJSON(neUrl, data, nil)
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("NeConfigUpdate Put \"%s\"", neUrl)
|
||||
if strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "204") {
|
||||
return resData, nil
|
||||
}
|
||||
logger.Errorf("NeConfigUpdate %s", errStr)
|
||||
return nil, fmt.Errorf("NeService Config Update API Error")
|
||||
}
|
||||
|
||||
// 200 成功无数据时
|
||||
if len(resBytes) == 0 {
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeConfigUpdate Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// NeConfigAdd 网元配置新增 array
|
||||
func NeConfigAdd(neInfo model.NeInfo, paramName, loc string, data map[string]any) (map[string]any, error) {
|
||||
// 网元参数配置新增(array)
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/%s?loc=%v", neInfo.IPAddr, neInfo.Port, strings.ToLower(neInfo.NeType), paramName, loc)
|
||||
resBytes, err := fetch.PostJSON(neUrl, data, nil)
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("NeConfigAdd Post \"%s\"", neUrl)
|
||||
if strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "204") {
|
||||
return resData, nil
|
||||
}
|
||||
logger.Errorf("NeConfigAdd %s", errStr)
|
||||
return nil, fmt.Errorf("NeService Config Add API Error")
|
||||
}
|
||||
|
||||
// 200 成功无数据时
|
||||
if len(resBytes) == 0 {
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeConfigAdd Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// NeConfigDelete 网元配置删除 array
|
||||
func NeConfigDelete(neInfo model.NeInfo, paramName, loc string) (map[string]any, error) {
|
||||
// 网元参数配置删除(array)
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/%s?loc=%v", neInfo.IPAddr, neInfo.Port, strings.ToLower(neInfo.NeType), paramName, loc)
|
||||
resBytes, err := fetch.Delete(neUrl, nil)
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("NeConfigDelete Delete \"%s\"", neUrl)
|
||||
if strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "204") {
|
||||
return resData, nil
|
||||
}
|
||||
logger.Errorf("NeConfigDelete %s", errStr)
|
||||
return nil, fmt.Errorf("NeService Config Update API Error")
|
||||
}
|
||||
|
||||
// 200 成功无数据时
|
||||
if len(resBytes) == 0 {
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeConfigInfoDel Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
60
src/modules/network_link/fetch_link/ne_state.go
Normal file
60
src/modules/network_link/fetch_link/ne_state.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// NeState 获取网元端服务状态
|
||||
func NeState(neInfo model.NeInfo) (map[string]any, error) {
|
||||
// 网元状态
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/systemState", neInfo.IPAddr, neInfo.Port, strings.ToLower(neInfo.NeType))
|
||||
resBytes, err := fetch.Get(neUrl, nil, 1000)
|
||||
if err != nil {
|
||||
logger.Errorf("NeState %s", err.Error())
|
||||
return nil, fmt.Errorf("NeService System State API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeState Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查是否有许可时间
|
||||
if v, ok := resData["expiryDate"]; ok && v != nil {
|
||||
expiryDate := v.(string)
|
||||
// UPF存在2000的许可时间,MME会有空字符
|
||||
if strings.HasPrefix(expiryDate, "2000") || expiryDate == "" {
|
||||
logger.Warnf("NeState %s License Expiration Aanomaly. Get \"%s\"", neInfo.NeType, neUrl)
|
||||
return nil, fmt.Errorf("%s License Expiration Aanomaly", neInfo.NeType)
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"coreUid": neInfo.CoreUID,
|
||||
"neUid": neInfo.NeUID,
|
||||
"neType": neInfo.NeType,
|
||||
"neName": neInfo.NeName,
|
||||
"neIP": neInfo.IPAddr,
|
||||
"refreshTime": time.Now().UnixMilli(), // 获取时间
|
||||
"standby": resData["standby"], // 是否备用服务
|
||||
"version": resData["version"],
|
||||
"capability": resData["capability"],
|
||||
"sn": resData["serialNum"],
|
||||
"expire": resData["expiryDate"],
|
||||
"hostname": resData["hostName"],
|
||||
"os": resData["osInfo"],
|
||||
"cpu": resData["cpuUsage"],
|
||||
"mem": resData["memUsage"],
|
||||
"disk": resData["diskSpace"],
|
||||
}, nil
|
||||
}
|
||||
69
src/modules/network_link/fetch_link/ne_trace.go
Normal file
69
src/modules/network_link/fetch_link/ne_trace.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// NeTraceAdd 网元跟踪任务新增
|
||||
func NeTraceAdd(neInfo model.NeInfo, data any) (map[string]any, error) {
|
||||
// 跟踪任务创建
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/traceManagement/v2/%s/subscriptions", neInfo.IPAddr, neInfo.Port, neInfo.NeType)
|
||||
resBytes, err := fetch.PostJSON(neUrl, data, nil)
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
if !(strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "400")) {
|
||||
logger.Warnf("NeTraceAdd POST \"%s\"", neUrl)
|
||||
logger.Errorf("NeTraceAdd %s", errStr)
|
||||
return nil, fmt.Errorf("NeService Trace Add API Error")
|
||||
}
|
||||
}
|
||||
|
||||
// 200 成功无数据时
|
||||
if len(resBytes) == 0 {
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeTraceAdd Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// NeTraceDelete 网元跟踪任务删除
|
||||
func NeTraceDelete(neInfo model.NeInfo, traceId string) (map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/traceManagement/v2/%s/subscriptions?id=%s", neInfo.IPAddr, neInfo.Port, neInfo.NeType, traceId)
|
||||
resBytes, err := fetch.Delete(neUrl, nil)
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
if strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "204") {
|
||||
return resData, nil
|
||||
}
|
||||
logger.Warnf("NeTraceDelete Delete \"%s\"", neUrl)
|
||||
logger.Errorf("NeTraceDelete %s", errStr)
|
||||
return nil, fmt.Errorf("NeService Trace Delete API Error")
|
||||
}
|
||||
|
||||
// 200 成功无数据时
|
||||
if len(resBytes) == 0 {
|
||||
return resData, nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("NeTraceDelete Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
280
src/modules/network_link/fetch_link/pcf.go
Normal file
280
src/modules/network_link/fetch_link/pcf.go
Normal file
@@ -0,0 +1,280 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// PCFRuleInfo PCF策略配置查询信息
|
||||
func PCFRuleInfo(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo", neInfo.IPAddr, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["imsi"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("imsi=%s", v))
|
||||
}
|
||||
if v, ok := data["msisdn"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("msisdn=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
var resData map[string]any
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("PCFRuleInfo Get \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleInfo %s", errStr)
|
||||
return nil, fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleInfo Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if arr := v.([]any); len(arr) > 0 {
|
||||
result := make([]map[string]any, len(arr))
|
||||
for i, item := range arr {
|
||||
result[i] = item.(map[string]any)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
|
||||
// PCFRuleAdd PCF策略配置添加
|
||||
func PCFRuleAdd(neInfo model.NeInfo, data any) error {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.PostJSON(neUrl, data, nil)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
// 正常
|
||||
if strings.HasPrefix(errStr, "201") {
|
||||
return nil
|
||||
}
|
||||
// 错误结果
|
||||
if strings.HasPrefix(errStr, "400") {
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleAdd Unmarshal %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s", resData["cause"])
|
||||
}
|
||||
|
||||
logger.Warnf("PCFRuleAdd Put \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleAdd %s", errStr)
|
||||
return fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PCFRuleAddBatch PCF策略配置批量添加
|
||||
func PCFRuleAddBatch(neInfo model.NeInfo, data map[string]any, num int64) error {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/%d", neInfo.IPAddr, neInfo.Port, num)
|
||||
resBytes, err := fetch.PostJSON(neUrl, data, nil)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
// 正常
|
||||
if strings.HasPrefix(errStr, "201") {
|
||||
return nil
|
||||
}
|
||||
// 错误结果
|
||||
if strings.HasPrefix(errStr, "400") {
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleAddBatch Unmarshal %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s", resData["cause"])
|
||||
}
|
||||
|
||||
logger.Warnf("PCFRuleAddBatch Put \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleAddBatch %s", errStr)
|
||||
return fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PCFRuleUpdate PCF策略配置修改
|
||||
func PCFRuleUpdate(neInfo model.NeInfo, data map[string]any) error {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.PutJSON(neUrl, data, nil)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
// 错误结果
|
||||
if strings.HasPrefix(errStr, "400") {
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleUpdate Unmarshal %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s", resData["cause"])
|
||||
}
|
||||
|
||||
logger.Warnf("PCFRuleUpdate Put \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleUpdate %s", errStr)
|
||||
return fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PCFRuleUpdateBatch PCF策略配置批量修改
|
||||
func PCFRuleUpdateBatch(neInfo model.NeInfo, data map[string]any, num int64) error {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/%d", neInfo.IPAddr, neInfo.Port, num)
|
||||
resBytes, err := fetch.PutJSON(neUrl, data, nil)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
// 错误结果
|
||||
if strings.HasPrefix(errStr, "400") {
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleUpdateBatch Unmarshal %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s", resData["cause"])
|
||||
}
|
||||
|
||||
logger.Warnf("PCFRuleUpdateBatch Put \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleUpdateBatch %s", errStr)
|
||||
return fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PCFRuleDelete PCF策略配置删除
|
||||
func PCFRuleDelete(neInfo model.NeInfo, imsi string) error {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?imsi=%s", neInfo.IPAddr, neInfo.Port, imsi)
|
||||
resBytes, err := fetch.Delete(neUrl, nil)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
// 正常
|
||||
if strings.HasPrefix(errStr, "204") {
|
||||
return nil
|
||||
}
|
||||
// 错误结果
|
||||
if strings.HasPrefix(errStr, "400") {
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleDelete Unmarshal %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s", resData["cause"])
|
||||
}
|
||||
|
||||
logger.Warnf("PCFRuleDelete Delete \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleDelete %s", errStr)
|
||||
return fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PCFRuleDeleteBatch PCF策略配置批量删除
|
||||
func PCFRuleDeleteBatch(neInfo model.NeInfo, imsi string, num int64) error {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/%d?imsi=%s", neInfo.IPAddr, neInfo.Port, num, imsi)
|
||||
resBytes, err := fetch.Delete(neUrl, nil)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
// 正常
|
||||
if strings.HasPrefix(errStr, "204") {
|
||||
return nil
|
||||
}
|
||||
// 错误结果
|
||||
if strings.HasPrefix(errStr, "400") {
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleDeleteBatch Unmarshal %s", err.Error())
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("%s", resData["cause"])
|
||||
}
|
||||
|
||||
logger.Warnf("PCFRuleDeleteBatch Delete \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleDeleteBatch %s", errStr)
|
||||
return fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PCFRuleExport PCF策略配置导出
|
||||
func PCFRuleExport(neInfo model.NeInfo, data map[string]string) ([]byte, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/file/export", neInfo.IPAddr, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["fileType"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("fileType=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
resBytes, err := fetch.Get(neUrl, nil, 30_000)
|
||||
if err != nil {
|
||||
logger.Warnf("PCFRuleExport Get \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleExport %s", err.Error())
|
||||
return nil, fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
return resBytes, nil
|
||||
}
|
||||
|
||||
// PCFRuleImport PCF策略配置导入
|
||||
func PCFRuleImport(neInfo model.NeInfo, data map[string]any) (string, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/file/import", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.PutJSON(neUrl, data, nil)
|
||||
var resData map[string]any
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
// 错误结果
|
||||
if strings.HasPrefix(errStr, "400") {
|
||||
// 序列化结果
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleDeleteBatch Unmarshal %s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
return "", fmt.Errorf("%s", resData["cause"])
|
||||
}
|
||||
|
||||
logger.Warnf("PCFRuleImport Put \"%s\"", neUrl)
|
||||
logger.Errorf("PCFRuleImport %s", errStr)
|
||||
return "", fmt.Errorf("NeService PCF API Error")
|
||||
}
|
||||
|
||||
// 200 成功无数据时
|
||||
if len(resBytes) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("PCFRuleImport Unmarshal %s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprint(resData["data"]), nil
|
||||
}
|
||||
98
src/modules/network_link/fetch_link/smf.go
Normal file
98
src/modules/network_link/fetch_link/smf.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// SMFSubNum SMF在线订阅用户数量 只含5G用户数据
|
||||
//
|
||||
// 返回结果 0
|
||||
func SMFSubNum(neInfo model.NeInfo) (int64, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/smf/objectType/ueNum", neInfo.IPAddr, neInfo.Port)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("SMFSubNum Get \"%s\"", neUrl)
|
||||
logger.Errorf("SMFSubNum %s", errStr)
|
||||
return 0, fmt.Errorf("NeService SMF API Error")
|
||||
}
|
||||
// 序列化结果 {"data":{"ueNum":0}}
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("IMSUeSession Unmarshal %s", err.Error())
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
var ueNum int64 = 0
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if num := v.(map[string]any)["ueNum"]; num != nil {
|
||||
ueNum = parse.Number(num)
|
||||
}
|
||||
}
|
||||
return ueNum, nil
|
||||
}
|
||||
|
||||
// SMFSubInfoList SMF在线订阅用户列表信息
|
||||
//
|
||||
// 查询参数 {"imsi":"360000100000130","msisdn":"8612300000130","upstate":"Inactive","pageNum":"1"}
|
||||
//
|
||||
// 返回结果 {"rows":[],"total":0}
|
||||
func SMFSubInfoList(neInfo model.NeInfo, data map[string]string) (map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo", neInfo.IPAddr, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["imsi"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("imsi=%s", v))
|
||||
}
|
||||
if v, ok := data["msisdn"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("msisdn=%s", v))
|
||||
}
|
||||
if v, ok := data["upstate"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("upstate=%s", v))
|
||||
}
|
||||
// 固定页数量50条
|
||||
if v, ok := data["pageNum"]; ok && v != "" {
|
||||
pageNum := parse.Number(v)
|
||||
query = append(query, fmt.Sprintf("pageNum=%d", pageNum))
|
||||
}
|
||||
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
logger.Warnf("SMFSubInfo Get \"%s\"", neUrl)
|
||||
logger.Errorf("SMFSubInfo %s", err.Error())
|
||||
return nil, fmt.Errorf("NeService SMF API Error")
|
||||
}
|
||||
|
||||
// 序列化结果 {"data":[],"total":0}
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("SMFSubInfo Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
resData["rows"] = v.([]any)
|
||||
delete(resData, "data")
|
||||
} else {
|
||||
resData["rows"] = []any{}
|
||||
}
|
||||
if v, ok := resData["total"]; !ok || v == nil {
|
||||
resData["total"] = 0
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
39
src/modules/network_link/fetch_link/udm.go
Normal file
39
src/modules/network_link/fetch_link/udm.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// 网元UDM服务,可能是8080、33030端口服务
|
||||
// 融合的UDM网元视情况调整。
|
||||
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
)
|
||||
|
||||
// UDMImportAuth UDM导入鉴权数据
|
||||
//
|
||||
// data参数 {path:"服务器文件路径", k4:"可选,k4为空时Ki不加密。"}
|
||||
func UDMImportAuth(udmIP string, data map[string]any) (string, error) {
|
||||
// 网元参数配置新增(array)
|
||||
neUrl := fmt.Sprintf("http://%s:8080/ue-manage/v1/import-auth", udmIP)
|
||||
resBytes, err := fetch.PostJSON(neUrl, data, nil)
|
||||
var resData map[string]string
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("UDMImportAuth Post \"%s\"", neUrl)
|
||||
logger.Errorf("UDMImportAuth %s", errStr)
|
||||
return "", fmt.Errorf("NeService UDM API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
if err = json.Unmarshal(resBytes, &resData); err != nil {
|
||||
logger.Errorf("UDMImportAuth Unmarshal %s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
if v, ok := resData["code"]; ok && v == "00000" {
|
||||
return strings.TrimSpace(strings.ToLower(resData["message"])), nil
|
||||
}
|
||||
return "", fmt.Errorf("%s", resData["message"])
|
||||
}
|
||||
19
src/modules/network_link/model/udm_auth.go
Normal file
19
src/modules/network_link/model/udm_auth.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
// UDMAuthUser UDM鉴权用户 udm_auth
|
||||
type UDMAuthUser struct {
|
||||
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UDMAuthUser) TableName() string {
|
||||
return "udm_auth"
|
||||
}
|
||||
17
src/modules/network_link/model/udm_extend.go
Normal file
17
src/modules/network_link/model/udm_extend.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package model
|
||||
|
||||
// UDMExtend UDM用户IMSI扩展信息 udm_extend
|
||||
type UDMExtend struct {
|
||||
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID
|
||||
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"
|
||||
}
|
||||
50
src/modules/network_link/model/udm_sub.go
Normal file
50
src/modules/network_link/model/udm_sub.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package model
|
||||
|
||||
// UDMSubUser UDM签约用户 udm_sub
|
||||
type UDMSubUser struct {
|
||||
ID string `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"` // 用户电话号码
|
||||
|
||||
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"
|
||||
}
|
||||
17
src/modules/network_link/model/udm_voip.go
Normal file
17
src/modules/network_link/model/udm_voip.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package model
|
||||
|
||||
// UDMVOIPUser UDMVOIP用户 udm_voip
|
||||
type UDMVOIPUser struct {
|
||||
ID string `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"` // 网元类型
|
||||
|
||||
UserName string `json:"username" gorm:"column:username"` // 用户名
|
||||
Password string `json:"password" gorm:"column:password"` // 密码
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UDMVOIPUser) TableName() string {
|
||||
return "udm_voip"
|
||||
}
|
||||
19
src/modules/network_link/model/udm_volte_ims.go
Normal file
19
src/modules/network_link/model/udm_volte_ims.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
// UDMVolteIMSUser UDMVolteIMS用户 udm_volte_ims
|
||||
type UDMVolteIMSUser struct {
|
||||
ID string `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"` // 用户电话号码
|
||||
|
||||
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"
|
||||
}
|
||||
373
src/modules/network_link/network_link.go
Normal file
373
src/modules/network_link/network_link.go
Normal file
@@ -0,0 +1,373 @@
|
||||
package networklink
|
||||
|
||||
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/network_link/controller"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 模块路由注册
|
||||
func Setup(router *gin.Engine) {
|
||||
logger.Infof("开始加载 ====> network_link 模块路由")
|
||||
|
||||
neDataGroup := router.Group("/ne/link")
|
||||
|
||||
// 网元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.POST("/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,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元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.POST("/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.POST("/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.POST("/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/list-cfg",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAMF.NbStateList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元UPF
|
||||
upfGroup := neDataGroup.Group("/upf")
|
||||
{
|
||||
upfGroup.GET("/flow-total",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewUPF.FlowTotal,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元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("/resetData/:neId",
|
||||
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.POST("/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/list-cfg",
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
149
src/modules/network_link/repository/udm_auth.go
Normal file
149
src/modules/network_link/repository/udm_auth.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_link/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_id = ?", 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) (int64, []model.UDMAuthUser) {
|
||||
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_id = ?", 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 total, rows
|
||||
}
|
||||
|
||||
// 分页
|
||||
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 total, rows
|
||||
}
|
||||
|
||||
// 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和ne_id查询
|
||||
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
|
||||
}
|
||||
130
src/modules/network_link/repository/udm_extend.go
Normal file
130
src/modules/network_link/repository/udm_extend.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_link/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和ne_id查询 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
|
||||
}
|
||||
151
src/modules/network_link/repository/udm_sub.go
Normal file
151
src/modules/network_link/repository/udm_sub.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_link/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) (int64, []model.UDMSubUser) {
|
||||
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 total, rows
|
||||
}
|
||||
|
||||
// 分页
|
||||
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 total, rows
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
151
src/modules/network_link/repository/udm_voip.go
Normal file
151
src/modules/network_link/repository/udm_voip.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_link/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) (int64, []model.UDMVOIPUser) {
|
||||
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 total, rows
|
||||
}
|
||||
|
||||
// 分页
|
||||
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 total, rows
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
163
src/modules/network_link/repository/udm_volte_ims.go
Normal file
163
src/modules/network_link/repository/udm_volte_ims.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_link/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) (int64, []model.UDMVolteIMSUser) {
|
||||
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 total, rows
|
||||
}
|
||||
|
||||
// 分页
|
||||
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 total, rows
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
203
src/modules/network_link/service/udm_auth.go
Normal file
203
src/modules/network_link/service/udm_auth.go
Normal file
@@ -0,0 +1,203 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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)
|
||||
}
|
||||
a := model.UDMAuthUser{
|
||||
CoreUID: coreUid,
|
||||
NeUID: neUid,
|
||||
NeType: "UDM",
|
||||
IMSI: imsi,
|
||||
Amf: amf,
|
||||
Ki: m["ki"],
|
||||
AlgoIndex: m["algo"],
|
||||
Opc: m["opc"],
|
||||
}
|
||||
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) (int64, []model.UDMAuthUser) {
|
||||
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, ",")
|
||||
}
|
||||
33
src/modules/network_link/service/udm_extend.go
Normal file
33
src/modules/network_link/service/udm_extend.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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)
|
||||
}
|
||||
372
src/modules/network_link/service/udm_sub.go
Normal file
372
src/modules/network_link/service/udm_sub.go
Normal file
@@ -0,0 +1,372 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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) (int64, []model.UDMSubUser) {
|
||||
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.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, ",")
|
||||
}
|
||||
175
src/modules/network_link/service/udm_voip.go
Normal file
175
src/modules/network_link/service/udm_voip.go
Normal file
@@ -0,0 +1,175 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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 != "" {
|
||||
u.ID = item.ID
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r UDMVOIPUser) FindByPage(query map[string]string) (int64, []model.UDMVOIPUser) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
196
src/modules/network_link/service/udm_volte_ims.go
Normal file
196
src/modules/network_link/service/udm_volte_ims.go
Normal file
@@ -0,0 +1,196 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/redis"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"be.ems/src/modules/network_link/model"
|
||||
"be.ems/src/modules/network_link/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 != "" {
|
||||
u.ID = item.ID
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r UDMVolteIMSUser) FindByPage(query map[string]string) (int64, []model.UDMVolteIMSUser) {
|
||||
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("%d", startIMSIOrMsisdn+i)
|
||||
// 删除原数据
|
||||
r.udmVolteIMSRepository.DeleteByIMSI(coreUid, neUid, keyIMSI)
|
||||
// 加载数据
|
||||
arr := r.dataByRedis(coreUid, neUid, keyIMSI+":*")
|
||||
if len(arr) < 1 {
|
||||
continue
|
||||
}
|
||||
r.udmVolteIMSRepository.Inserts(arr)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user