From 6da5ac6c22966296aa9dee3d15e3b316cbfa5b8d Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Thu, 19 Sep 2024 11:20:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20UDM=E7=94=A8=E6=88=B7=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0imsi=E6=8B=93=E5=B1=95=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_data/controller/udm_auth.go | 41 +-- .../network_data/controller/udm_sub.go | 104 +++---- src/modules/network_data/model/udm_auth.go | 21 +- src/modules/network_data/model/udm_sub.go | 52 ++-- .../network_data/model/udm_user_info.go | 15 + .../network_data/repository/udm_auth.go | 208 +++++++++++++- .../network_data/repository/udm_sub.go | 231 ++++++++++++++- .../network_data/repository/udm_sub.impl.go | 211 -------------- .../{udm_auth.impl.go => udm_user_info.go} | 73 ++--- src/modules/network_data/service/udm_auth.go | 180 ++++++++++-- .../network_data/service/udm_auth.impl.go | 146 ---------- src/modules/network_data/service/udm_sub.go | 262 ++++++++++++++++-- .../network_data/service/udm_sub.impl.go | 164 ----------- .../network_data/service/udm_user_info.go | 33 +++ 14 files changed, 986 insertions(+), 755 deletions(-) create mode 100644 src/modules/network_data/model/udm_user_info.go delete mode 100644 src/modules/network_data/repository/udm_sub.impl.go rename src/modules/network_data/repository/{udm_auth.impl.go => udm_user_info.go} (71%) delete mode 100644 src/modules/network_data/service/udm_auth.impl.go delete mode 100644 src/modules/network_data/service/udm_sub.impl.go create mode 100644 src/modules/network_data/service/udm_user_info.go diff --git a/src/modules/network_data/controller/udm_auth.go b/src/modules/network_data/controller/udm_auth.go index d2272d7b..c893129c 100644 --- a/src/modules/network_data/controller/udm_auth.go +++ b/src/modules/network_data/controller/udm_auth.go @@ -23,7 +23,7 @@ import ( // 实例化控制层 UDMAuthController 结构体 var NewUDMAuth = &UDMAuthController{ - udmAuthService: neDataService.NewUDMAuthImpl, + udmAuthService: neDataService.NewUDMAuthUser, neInfoService: neService.NewNeInfoImpl, } @@ -32,7 +32,7 @@ var NewUDMAuth = &UDMAuthController{ // PATH /udm/auth type UDMAuthController struct { // UDM鉴权信息服务 - udmAuthService neDataService.IUDMAuth + udmAuthService *neDataService.UDMAuthUser // 网元信息服务 neInfoService neService.INeInfo } @@ -103,26 +103,9 @@ func (s *UDMAuthController) Info(c *gin.Context) { } neId = "" - u := model.UDMAuth{ - IMSI: imsi, - Amf: data["amf"], - Status: "1", - Ki: data["ki"], - AlgoIndex: data["algo"], - Opc: data["opc"], - NeId: neId, - } - - // 查询imsi存在赋予id用于更新 - list := s.udmAuthService.SelectList(u) - if len(list) > 0 { - item := list[0] - if item.ID != "" { - u.ID = item.ID - } - } - go s.udmAuthService.Insert(neId, u) - + // 解析返回的数据 + u := s.udmAuthService.ParseInfo(imsi, neId, data) + s.udmAuthService.Insert(neId, u) c.JSON(200, result.OkData(u)) } @@ -137,7 +120,7 @@ func (s *UDMAuthController) Add(c *gin.Context) { return } - var body model.UDMAuth + var body model.UDMAuthUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.IMSI == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -169,7 +152,7 @@ func (s *UDMAuthController) Add(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmAuthService.Insert(neId, body) + s.udmAuthService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -186,7 +169,7 @@ func (s *UDMAuthController) Adds(c *gin.Context) { return } - var body model.UDMAuth + var body model.UDMAuthUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.IMSI == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -234,7 +217,7 @@ func (s *UDMAuthController) Edit(c *gin.Context) { return } - var body model.UDMAuth + var body model.UDMAuthUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.IMSI == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -279,7 +262,7 @@ func (s *UDMAuthController) Edit(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmAuthService.Insert(neId, body) + s.udmAuthService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -330,7 +313,7 @@ func (s *UDMAuthController) Remove(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmAuthService.Delete(neId, imsi) + s.udmAuthService.Delete(imsi, neId) } resultData[imsi] = data } @@ -402,7 +385,7 @@ func (s *UDMAuthController) Export(c *gin.Context) { } neId := "" - list := s.udmAuthService.SelectList(model.UDMAuth{NeId: neId}) + list := s.udmAuthService.SelectList(model.UDMAuthUser{NeId: neId}) // 文件名 fileName := fmt.Sprintf("udm_auth_user_export_%s_%d.%s", neId, time.Now().UnixMilli(), body.Type) filePath := fmt.Sprintf("%s/%s", file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName) diff --git a/src/modules/network_data/controller/udm_sub.go b/src/modules/network_data/controller/udm_sub.go index bfd71a09..7833ea35 100644 --- a/src/modules/network_data/controller/udm_sub.go +++ b/src/modules/network_data/controller/udm_sub.go @@ -3,7 +3,6 @@ package controller import ( "fmt" "path/filepath" - "strconv" "strings" "time" @@ -23,7 +22,7 @@ import ( // 实例化控制层 UDMSubController 结构体 var NewUDMSub = &UDMSubController{ - udmSubService: neDataService.NewUDMSubImpl, + udmSubService: neDataService.NewUDMSub, neInfoService: neService.NewNeInfoImpl, } @@ -32,7 +31,7 @@ var NewUDMSub = &UDMSubController{ // PATH /udm/sub type UDMSubController struct { // UDM签约信息服务 - udmSubService neDataService.IUDMSub + udmSubService *neDataService.UDMSubUser // 网元信息服务 neInfoService neService.INeInfo } @@ -102,53 +101,10 @@ func (s *UDMSubController) Info(c *gin.Context) { return } - // 解析返回的数据 - cnType, _ := strconv.ParseInt(data["CNType"][:4], 0, 64) - rat, _ := strconv.ParseInt(data["RAT"][:4], 0, 64) - msisdn := data["MSISDN"] - imsMsisdnLen := strings.Index(msisdn, ",") - if imsMsisdnLen != -1 { - msisdn = msisdn[:imsMsisdnLen] - } neId = "" - u := model.UDMSub{ - IMSI: imsi, - Msisdn: msisdn, - Ambr: data["AMBR"], - Arfb: data["AreaForbidden"], - Cn: fmt.Sprint(cnType), - SmData: data["SM-Data(snssai+dnn[1..n])"], - Sar: data["ServiceAreaRestriction"], - Nssai: data["NSSAI"], - SmfSel: data["Smf-Selection"], - Rat: fmt.Sprint(rat), - NeId: neId, - } - // 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.ApnContext = arr[7] - // [6] 是不要的,导入和导出不用 - u.StaticIp = arr[8] - } - - // 查询imsi存在赋予id用于更新 - list := s.udmSubService.SelectList(u) - if len(list) > 0 { - item := list[0] - if item.ID != "" { - u.ID = item.ID - } - } - go s.udmSubService.Insert(neId, u) - + // 解析返回的数据 + u := s.udmSubService.ParseInfo(imsi, neId, data) + s.udmSubService.Insert(neId, u) c.JSON(200, result.OkData(u)) } @@ -163,9 +119,9 @@ func (s *UDMSubController) Add(c *gin.Context) { return } - var body model.UDMSub + var body model.UDMSubUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.IMSI == "" { + if err != nil || len(body.IMSI) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -185,8 +141,8 @@ func (s *UDMSubController) Add(c *gin.Context) { defer telnetClient.Close() // 发送MML - cmd := fmt.Sprintf("add udmuser:imsi=%s,msisdn=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s", - body.IMSI, body.Msisdn, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext) + cmd := fmt.Sprintf("add udmuser:imsi=%s,msisdn=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s,cag=%s", + body.IMSI, body.MSISDN, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext, body.Cag) // static_ip指给4G UE分配的静态IP,没有可不带此字段名,批量添加IP会自动递增 if body.StaticIp != "" { cmd += fmt.Sprintf(",static_ip=%s", body.StaticIp) @@ -200,7 +156,8 @@ func (s *UDMSubController) Add(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.Insert(neId, body) + body.NeId = neId + s.udmSubService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -217,9 +174,9 @@ func (s *UDMSubController) Adds(c *gin.Context) { return } - var body model.UDMSub + var body model.UDMSubUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.IMSI == "" { + if err != nil || len(body.IMSI) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -239,8 +196,8 @@ func (s *UDMSubController) Adds(c *gin.Context) { defer telnetClient.Close() // 发送MML - cmd := fmt.Sprintf("baa udmuser:start_imsi=%s,start_msisdn=%s,sub_num=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s", - body.IMSI, body.Msisdn, num, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext) + cmd := fmt.Sprintf("baa udmuser:start_imsi=%s,start_msisdn=%s,sub_num=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s,cag=%s", + body.IMSI, body.MSISDN, num, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext, body.Cag) // static_ip指给4G UE分配的静态IP,没有可不带此字段名,批量添加IP会自动递增 if body.StaticIp != "" { cmd += fmt.Sprintf(",static_ip=%s", body.StaticIp) @@ -254,7 +211,7 @@ func (s *UDMSubController) Adds(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.LoadData(neId, body.IMSI, num) + go s.udmSubService.LoadData(neId, body.IMSI, num, body.Remark) } c.JSON(200, result.OkData(data)) } @@ -270,9 +227,9 @@ func (s *UDMSubController) Edit(c *gin.Context) { return } - var body model.UDMSub + var body model.UDMSubUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.IMSI == "" { + if err != nil || len(body.IMSI) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -294,8 +251,8 @@ func (s *UDMSubController) Edit(c *gin.Context) { // 发送MML cmd := fmt.Sprintf("mod udmuser:imsi=%s", body.IMSI) // 修改的参数名称 - if body.Msisdn != "" { - cmd += fmt.Sprintf(",msisdn=%s", body.Msisdn) + if body.MSISDN != "" { + cmd += fmt.Sprintf(",msisdn=%s", body.MSISDN) } if body.Ambr != "" { cmd += fmt.Sprintf(",ambr=%s", body.Ambr) @@ -345,6 +302,9 @@ func (s *UDMSubController) Edit(c *gin.Context) { if body.ApnContext != "" { cmd += fmt.Sprintf(",apn_context=%s", body.ApnContext) } + if body.Cag != "" { + cmd += fmt.Sprintf(",cag=%s", body.Cag) + } if body.StaticIp != "" { cmd += fmt.Sprintf(",static_ip=%s", body.StaticIp) } @@ -357,7 +317,8 @@ func (s *UDMSubController) Edit(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.Insert(neId, body) + body.NeId = neId + s.udmSubService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -369,7 +330,7 @@ func (s *UDMSubController) Remove(c *gin.Context) { language := ctx.AcceptLanguage(c) neId := c.Param("neId") imsi := c.Param("imsi") - if neId == "" || imsi == "" { + if neId == "" || len(imsi) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -408,7 +369,7 @@ func (s *UDMSubController) Remove(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.Delete(neId, imsi) + s.udmSubService.Delete(neId, imsi) } resultData[imsi] = data } @@ -424,7 +385,7 @@ func (s *UDMSubController) Removes(c *gin.Context) { neId := c.Param("neId") imsi := c.Param("imsi") num := c.Param("num") - if neId == "" || imsi == "" || num == "" { + if neId == "" || len(imsi) < 15 || num == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -454,7 +415,8 @@ func (s *UDMSubController) Removes(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.LoadData(neId, imsi, num) + go s.udmSubService.LoadData(neId, imsi, num, "-(Deleted)-") + } c.JSON(200, result.OkData(data)) } @@ -480,7 +442,7 @@ func (s *UDMSubController) Export(c *gin.Context) { } neId := "" - list := s.udmSubService.SelectList(model.UDMSub{NeId: neId}) + list := s.udmSubService.SelectList(model.UDMSubUser{NeId: neId}) // 文件名 fileName := fmt.Sprintf("udm_sub_user_export_%s_%d.%s", neId, time.Now().UnixMilli(), body.Type) filePath := fmt.Sprintf("%s/%s", file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName) @@ -491,7 +453,7 @@ func (s *UDMSubController) Export(c *gin.Context) { data = append(data, []string{"imsi", "msisdn", "ambr", "nssai", "arfb", "sar", "rat", "cn", "smf_sel", "sm_dat", "eps_dat"}) for _, v := range list { 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.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) } // 输出到文件 err = file.WriterFileCSV(data, filePath) @@ -506,7 +468,7 @@ func (s *UDMSubController) Export(c *gin.Context) { data := [][]string{} for _, v := range list { 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.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) } // 输出到文件 err = file.WriterFileTXT(data, ",", filePath) diff --git a/src/modules/network_data/model/udm_auth.go b/src/modules/network_data/model/udm_auth.go index 6f7c1d17..57ee012b 100644 --- a/src/modules/network_data/model/udm_auth.go +++ b/src/modules/network_data/model/udm_auth.go @@ -1,17 +1,18 @@ package model -// UDMAuth UDM鉴权用户对象 u_auth_user -type UDMAuth struct { +// UDMAuthUser UDM鉴权用户 u_auth_user +type UDMAuthUser struct { ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID - IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡号 - Amf string `json:"amf" gorm:"column:amf"` // ANF - Status string `json:"status" gorm:"column:status"` // 状态 默认给1 - 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 - NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 + IMSI string `json:"imsi" gorm:"imsi"` // SIM卡/USIM卡ID + NeId string `json:"neId" gorm:"ne_id"` // UDM网元标识 + Amf string `json:"amf" gorm:"amf"` // AMF + Status string `json:"status" gorm:"status"` // 状态 + Ki string `json:"ki" gorm:"ki"` // ki + AlgoIndex string `json:"algoIndex" gorm:"algo_index"` // algoIndex + Opc string `json:"opc" gorm:"opc"` // OPC } -func (UDMAuth) TableName() string { +// TableName 表名称 +func (*UDMAuthUser) TableName() string { return "u_auth_user" } diff --git a/src/modules/network_data/model/udm_sub.go b/src/modules/network_data/model/udm_sub.go index a4f3acd7..415f0583 100644 --- a/src/modules/network_data/model/udm_sub.go +++ b/src/modules/network_data/model/udm_sub.go @@ -1,34 +1,36 @@ package model -// UDMSub UDM签约用户对象 u_sub_user -type UDMSub struct { - ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` - Msisdn string `json:"msisdn" gorm:"column:msisdn"` // 相当手机号 - IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡号 - Ambr string `json:"ambr" gorm:"column:ambr"` - Nssai string `json:"nssai" gorm:"column:nssai"` - Rat string `json:"rat" gorm:"column:rat"` - Arfb string `json:"arfb" gorm:"column:arfb"` - Sar string `json:"sar" gorm:"column:sar"` - Cn string `json:"cn" gorm:"column:cn"` - SmData string `json:"smData" gorm:"column:sm_data"` - SmfSel string `json:"smfSel" gorm:"column:smf_sel"` - EpsDat string `json:"epsDat" gorm:"column:eps_dat"` - NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 - - EpsFlag string `json:"epsFlag" gorm:"column:eps_flag"` - EpsOdb string `json:"epsOdb" gorm:"column:eps_odb"` - HplmnOdb string `json:"hplmnOdb" gorm:"column:hplmn_odb"` - Ard string `json:"ard" gorm:"column:ard"` - Epstpl string `json:"epstpl" gorm:"column:epstpl"` - ContextId string `json:"contextId" gorm:"column:context_id"` - ApnContext string `json:"apnContext" gorm:"column:apn_context"` - StaticIp string `json:"staticIp" gorm:"column:static_ip"` +// UDMSubUser UDM签约用户 u_sub_user +type UDMSubUser struct { + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键 + IMSI string `json:"imsi" gorm:"imsi"` // SIM卡/USIM卡ID + MSISDN string `json:"msisdn" gorm:"msisdn"` // 用户电话号码 + NeId string `json:"neId" gorm:"ne_id"` // UDM网元标识 + Ambr string `json:"ambr" gorm:"ambr"` // SubUeAMBRTemp + Nssai string `json:"nssai" gorm:"nssai"` // SubSNSSAITemp + Rat string `json:"rat" gorm:"rat"` // rat VIRTUAL|WLAN|EUTRA|NR + Arfb string `json:"arfb" gorm:"arfb"` // forbiddenAreasTemp + Sar string `json:"sar" gorm:"sar"` // serviceAreaRestrictTemp + Cn string `json:"cn" gorm:"cn"` // cnType EPC|5GC + SmData string `json:"smData" gorm:"sm_data"` // smData + SmfSel string `json:"smfSel" gorm:"smf_sel"` // smfSel + EpsDat string `json:"epsDat" gorm:"eps_dat"` // Eps + EpsFlag string `json:"epsFlag" gorm:"eps_flag"` // epsFlag + EpsOdb string `json:"epsOdb" gorm:"eps_odb"` // epsOdb + HplmnOdb string `json:"hplmnOdb" gorm:"hplmn_odb"` // hplmnOdb + Ard string `json:"ard" gorm:"ard"` // Ard + Epstpl string `json:"epstpl" gorm:"epstpl"` // Epstpl + ContextId string `json:"contextId" gorm:"context_id"` // ContextId + ApnContext string `json:"apnContext" gorm:"apn_context"` // apnContext + StaticIp string `json:"staticIp" gorm:"static_ip"` // staticIpstatic_ip指给4G UE分配的静态IP,没有可不带此字段名 + Cag string `json:"cag" gorm:"cag"` // CAG // ====== 非数据库字段属性 ====== + Remark string `json:"remark,omitempty" gorm:"-"` // 备注 } -func (UDMSub) TableName() string { +// TableName 表名称 +func (*UDMSubUser) TableName() string { return "u_sub_user" } diff --git a/src/modules/network_data/model/udm_user_info.go b/src/modules/network_data/model/udm_user_info.go new file mode 100644 index 00000000..470a9abc --- /dev/null +++ b/src/modules/network_data/model/udm_user_info.go @@ -0,0 +1,15 @@ +package model + +// UDMUserInfo UDM用户IMSI扩展信息 u_user_info +type UDMUserInfo struct { + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID + IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID + MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码 + NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 + Remark string `json:"remark" gorm:"remark"` // 备注 +} + +// TableName 表名称 +func (*UDMUserInfo) TableName() string { + return "u_user_info" +} diff --git a/src/modules/network_data/repository/udm_auth.go b/src/modules/network_data/repository/udm_auth.go index 90a3bea8..25f46684 100644 --- a/src/modules/network_data/repository/udm_auth.go +++ b/src/modules/network_data/repository/udm_auth.go @@ -1,26 +1,206 @@ package repository import ( + "fmt" + "strings" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" "be.ems/src/modules/network_data/model" ) -// UDM鉴权信息 数据层接口 -type IUDMAuth interface { - // ClearAndInsert 清空ne_id后新增实体 - ClearAndInsert(neId string, uArr []model.UDMAuth) int64 +// 实例化数据层 UDMAuthUser 结构体 +var NewUDMAuthUser = &UDMAuthUser{ + selectSql: `select id, imsi, ne_id, amf, status, ki, algo_index, opc from u_auth_user`, - // SelectPage 根据条件分页查询 - SelectPage(query map[string]any) map[string]any + resultMap: map[string]string{ + "id": "ID", + "imsi": "IMSI", + "ne_id": "NeId", + "amf": "Amf", + "status": "Status", + "ki": "Ki", + "algo_index": "AlgoIndex", + "opc": "Opc", + }, +} - // SelectList 根据实体查询 - SelectList(u model.UDMAuth) []model.UDMAuth +// UDMAuthUser UDM鉴权信息表 数据层处理 +type UDMAuthUser struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} - // Insert 批量添加 - Inserts(uArr []model.UDMAuth) int64 +// convertResultRows 将结果记录转实体结果组 +func (r *UDMAuthUser) convertResultRows(rows []map[string]any) []model.UDMAuthUser { + arr := make([]model.UDMAuthUser, 0) + for _, row := range rows { + item := model.UDMAuthUser{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} - // Delete 删除实体 - Delete(neId, imsi string) int64 +// ClearAndInsert 清空ne_id后新增实体 +func (r *UDMAuthUser) ClearAndInsert(neId string, uArr []model.UDMAuthUser) int64 { + // 不指定neID时,用 TRUNCATE 清空表快 + _, err := datasource.ExecDB("", "TRUNCATE TABLE u_auth_user", nil) + if err != nil { + logger.Errorf("TRUNCATE err => %v", err) + } + return r.Inserts(uArr) +} - // DeletePrefixByIMSI 删除前缀匹配的实体 - DeletePrefixByIMSI(neId, imsi string) int64 +// SelectPage 根据条件分页查询 +func (r *UDMAuthUser) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["imsi"]; ok && v != "" { + conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["neId"]; ok && v != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.UDMAuthUser{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from u_auth_user" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + return result + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return result + } else { + result["total"] = total + } + + // 分页 + pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 排序 + orderSql := "" + if v, ok := query["sortField"]; ok && v != "" { + sortSql := v.(string) + if o, ok := query["sortOrder"]; ok && o != nil && v != "" { + if o == "desc" { + sortSql += " desc " + } else { + sortSql += " asc " + } + } + orderSql = fmt.Sprintf(" order by %s ", sortSql) + } + + // 查询数据 + querySql := r.selectSql + whereSql + orderSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectList 根据实体查询 +func (r *UDMAuthUser) SelectList(u model.UDMAuthUser) []model.UDMAuthUser { + // 查询条件拼接 + var conditions []string + var params []any + if u.IMSI != "" { + conditions = append(conditions, "imsi = ?") + params = append(params, u.IMSI) + } + if u.NeId != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, u.NeId) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by imsi asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIMSIAndNeID 通过imsi和ne_id查询 +func (r *UDMAuthUser) SelectByIMSIAndNeID(imsi, neId string) model.UDMAuthUser { + querySql := r.selectSql + " where imsi = ? and ne_id = ?" + results, err := datasource.RawDB("", querySql, []any{imsi, neId}) + if err != nil { + logger.Errorf("query err => %v", err) + return model.UDMAuthUser{} + } + // 转换实体 + rows := r.convertResultRows(results) + if len(rows) > 0 { + return rows[0] + } + return model.UDMAuthUser{} +} + +// Insert 批量添加 +func (r *UDMAuthUser) Inserts(uArr []model.UDMAuthUser) int64 { + tx := datasource.DefaultDB().CreateInBatches(uArr, 3000) + if err := tx.Error; err != nil { + logger.Errorf("CreateInBatches err => %v", err) + } + return tx.RowsAffected +} + +// Delete 删除实体 +func (r *UDMAuthUser) Delete(imsi, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMAuthUser{}) + if err := tx.Error; err != nil { + logger.Errorf("Delete err => %v", err) + } + return tx.RowsAffected +} + +// DeletePrefixByIMSI 删除前缀匹配的实体 +func (r *UDMAuthUser) DeletePrefixByIMSI(neId, imsi string) int64 { + tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsi, neId).Delete(&model.UDMAuthUser{}) + if err := tx.Error; err != nil { + logger.Errorf("DeletePrefixByIMSI err => %v", err) + } + return tx.RowsAffected } diff --git a/src/modules/network_data/repository/udm_sub.go b/src/modules/network_data/repository/udm_sub.go index db8db0f8..9c9e7704 100644 --- a/src/modules/network_data/repository/udm_sub.go +++ b/src/modules/network_data/repository/udm_sub.go @@ -1,26 +1,229 @@ package repository import ( + "fmt" + "strings" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" "be.ems/src/modules/network_data/model" ) -// UDM签约信息 数据层接口 -type IUDMSub interface { - // ClearAndInsert 清空ne_id后新增实体 - ClearAndInsert(neId string, uArr []model.UDMSub) int64 +// 实例化数据层 UDMSubUser 结构体 +var NewUDMSub = &UDMSubUser{ + selectSql: `select + id, imsi, msisdn, ne_id, ambr, nssai, rat, arfb, sar, cn, sm_data, smf_sel, + eps_dat, eps_flag, eps_odb, hplmn_odb, ard, epstpl, context_id, apn_context, static_ip, cag + from u_sub_user`, - // SelectPage 根据条件分页查询 - SelectPage(query map[string]any) map[string]any + resultMap: map[string]string{ + "id": "ID", + "imsi": "IMSI", + "msisdn": "MSISDN", + "ne_id": "NeId", + "ambr": "Ambr", + "nssai": "Nssai", + "rat": "Rat", + "arfb": "Arfb", + "sar": "Sar", + "cn": "Cn", + "sm_data": "SmData", + "smf_sel": "SmfSel", + "eps_dat": "EpsDat", + "eps_flag": "EpsFlag", + "eps_odb": "EpsOdb", + "hplmn_odb": "HplmnOdb", + "ard": "Ard", + "epstpl": "Epstpl", + "context_id": "ContextId", + "apn_context": "ApnContext", + "static_ip": "StaticIp", + "cag": "Cag", + }, +} - // SelectList 根据实体查询 - SelectList(u model.UDMSub) []model.UDMSub +// UDMSubUser UDM签约信息表 数据层处理 +type UDMSubUser struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} - // Insert 批量添加 - Inserts(uArr []model.UDMSub) int64 +// convertResultRows 将结果记录转实体结果组 +func (r *UDMSubUser) convertResultRows(rows []map[string]any) []model.UDMSubUser { + arr := make([]model.UDMSubUser, 0) + for _, row := range rows { + item := model.UDMSubUser{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} - // Delete 删除实体 - Delete(neId, imsi string) int64 +// ClearAndInsert 清空ne_id后新增实体 +func (r *UDMSubUser) ClearAndInsert(neID string, u []model.UDMSubUser) int64 { + // 不指定neID时,用 TRUNCATE 清空表快 + _, err := datasource.ExecDB("", "TRUNCATE TABLE u_sub_user", nil) + if err != nil { + logger.Errorf("TRUNCATE err => %v", err) + } - // DeletePrefixByIMSI 删除前缀匹配的实体 - DeletePrefixByIMSI(neId, imsi string) int64 + return r.Inserts(u) +} + +// SelectPage 根据条件分页查询字典类型 +func (r *UDMSubUser) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["imsi"]; ok && v != "" { + conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["msisdn"]; ok && v != "" { + conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["neId"]; ok && v != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.UDMSubUser{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from u_sub_user" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + return result + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return result + } else { + result["total"] = total + } + + // 分页 + pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 排序 + orderSql := "" + if v, ok := query["sortField"]; ok && v != "" { + sortSql := v.(string) + if o, ok := query["sortOrder"]; ok && o != nil && v != "" { + if o == "desc" { + sortSql += " desc " + } else { + sortSql += " asc " + } + } + orderSql = fmt.Sprintf(" order by %s ", sortSql) + } + + // 查询数据 + querySql := r.selectSql + whereSql + orderSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + return result + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectList 根据实体查询 +func (r *UDMSubUser) SelectList(u model.UDMSubUser) []model.UDMSubUser { + // 查询条件拼接 + var conditions []string + var params []any + if u.IMSI != "" { + conditions = append(conditions, "imsi = ?") + params = append(params, u.IMSI) + } + if u.NeId != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, u.NeId) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by imsi asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIMSIAndNeID 通过imsi和ne_id查询 +func (r *UDMSubUser) SelectByIMSIAndNeID(imsi, neId string) model.UDMSubUser { + querySql := r.selectSql + " where imsi = ? and ne_id = ?" + results, err := datasource.RawDB("", querySql, []any{imsi, neId}) + if err != nil { + logger.Errorf("query err => %v", err) + return model.UDMSubUser{} + } + // 转换实体 + rows := r.convertResultRows(results) + if len(rows) > 0 { + return rows[0] + } + return model.UDMSubUser{} +} + +// Insert 批量添加 +func (r *UDMSubUser) Inserts(uArr []model.UDMSubUser) int64 { + tx := datasource.DefaultDB().CreateInBatches(uArr, 2000) + if err := tx.Error; err != nil { + logger.Errorf("CreateInBatches err => %v", err) + } + return tx.RowsAffected +} + +// Delete 删除实体 +func (r *UDMSubUser) Delete(imsi, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMSubUser{}) + if err := tx.Error; err != nil { + logger.Errorf("Delete err => %v", err) + } + return tx.RowsAffected +} + +// DeletePrefixByIMSI 删除前缀匹配的实体 +func (r *UDMSubUser) DeletePrefixByIMSI(imsiPrefix, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsiPrefix, neId).Delete(&model.UDMSubUser{}) + if err := tx.Error; err != nil { + logger.Errorf("DeletePrefixByIMSI err => %v", err) + } + return tx.RowsAffected } diff --git a/src/modules/network_data/repository/udm_sub.impl.go b/src/modules/network_data/repository/udm_sub.impl.go deleted file mode 100644 index c5ddda82..00000000 --- a/src/modules/network_data/repository/udm_sub.impl.go +++ /dev/null @@ -1,211 +0,0 @@ -package repository - -import ( - "fmt" - "strings" - - "be.ems/src/framework/datasource" - "be.ems/src/framework/logger" - "be.ems/src/framework/utils/parse" - "be.ems/src/framework/utils/repo" - "be.ems/src/modules/network_data/model" -) - -// 实例化数据层 UDMSubImpl 结构体 -var NewUDMSubImpl = &UDMSubImpl{ - selectSql: `select - id, msisdn, imsi, ambr, nssai, rat, arfb, sar, cn, sm_data, smf_sel, eps_dat, ne_id, eps_flag, eps_odb, hplmn_odb, ard, epstpl, context_id, apn_context, static_ip - from u_sub_user`, - - resultMap: map[string]string{ - "id": "ID", - "msisdn": "Msisdn", - "imsi": "IMSI", - "ambr": "Ambr", - "nssai": "Nssai", - "rat": "Rat", - "arfb": "Arfb", - "sar": "Sar", - "cn": "Cn", - "sm_data": "SmData", - "smf_sel": "SmfSel", - "eps_dat": "EpsDat", - "ne_id": "NeId", - "eps_flag": "EpsFlag", - "eps_odb": "EpsOdb", - "hplmn_odb": "HplmnOdb", - "ard": "Ard", - "epstpl": "Epstpl", - "context_id": "ContextId", - "apn_context": "ApnContext", - "static_ip": "StaticIp", - }, -} - -// UDMSubImpl UDM签约信息表 数据层处理 -type UDMSubImpl struct { - // 查询视图对象SQL - selectSql string - // 结果字段与实体映射 - resultMap map[string]string -} - -// convertResultRows 将结果记录转实体结果组 -func (r *UDMSubImpl) convertResultRows(rows []map[string]any) []model.UDMSub { - arr := make([]model.UDMSub, 0) - for _, row := range rows { - item := model.UDMSub{} - for key, value := range row { - if keyMapper, ok := r.resultMap[key]; ok { - repo.SetFieldValue(&item, keyMapper, value) - } - } - arr = append(arr, item) - } - return arr -} - -// ClearAndInsert 清空ne_id后新增实体 -func (r *UDMSubImpl) ClearAndInsert(neID string, u []model.UDMSub) int64 { - // 不指定neID时,用 TRUNCATE 清空表快 - _, err := datasource.ExecDB("", "TRUNCATE TABLE u_sub_user", nil) - if err != nil { - logger.Errorf("TRUNCATE err => %v", err) - } - - return r.Inserts(u) -} - -// SelectPage 根据条件分页查询字典类型 -func (r *UDMSubImpl) SelectPage(query map[string]any) map[string]any { - // 查询条件拼接 - var conditions []string - var params []any - if v, ok := query["msisdn"]; ok && v != "" { - conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')") - params = append(params, strings.Trim(v.(string), " ")) - } - if v, ok := query["imsi"]; ok && v != "" { - conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") - params = append(params, strings.Trim(v.(string), " ")) - } - if v, ok := query["neId"]; ok && v != "" { - conditions = append(conditions, "ne_id = ?") - params = append(params, v) - } - - // 构建查询条件语句 - whereSql := "" - if len(conditions) > 0 { - whereSql += " where " + strings.Join(conditions, " and ") - } - - result := map[string]any{ - "total": 0, - "rows": []model.UDMSub{}, - } - - // 查询数量 长度为0直接返回 - totalSql := "select count(1) as 'total' from u_sub_user" - totalRows, err := datasource.RawDB("", totalSql+whereSql, params) - if err != nil { - logger.Errorf("total err => %v", err) - return result - } - total := parse.Number(totalRows[0]["total"]) - if total == 0 { - return result - } else { - result["total"] = total - } - - // 分页 - pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"]) - pageSql := " limit ?,? " - params = append(params, pageNum*pageSize) - params = append(params, pageSize) - - // 排序 - orderSql := "" - if v, ok := query["sortField"]; ok && v != "" { - sortSql := v.(string) - if o, ok := query["sortOrder"]; ok && o != nil && v != "" { - if o == "desc" { - sortSql += " desc " - } else { - sortSql += " asc " - } - } - orderSql = fmt.Sprintf(" order by %s ", sortSql) - } - - // 查询数据 - querySql := r.selectSql + whereSql + orderSql + pageSql - results, err := datasource.RawDB("", querySql, params) - if err != nil { - logger.Errorf("query err => %v", err) - return result - } - - // 转换实体 - result["rows"] = r.convertResultRows(results) - return result -} - -// SelectList 根据实体查询 -func (r *UDMSubImpl) SelectList(u model.UDMSub) []model.UDMSub { - // 查询条件拼接 - var conditions []string - var params []any - if u.IMSI != "" { - conditions = append(conditions, "imsi = ?") - params = append(params, u.IMSI) - } - if u.NeId != "" { - conditions = append(conditions, "ne_id = ?") - params = append(params, u.NeId) - } - - // 构建查询条件语句 - whereSql := "" - if len(conditions) > 0 { - whereSql += " where " + strings.Join(conditions, " and ") - } - - // 查询数据 - querySql := r.selectSql + whereSql + " order by imsi asc " - results, err := datasource.RawDB("", querySql, params) - if err != nil { - logger.Errorf("query err => %v", err) - } - - // 转换实体 - return r.convertResultRows(results) -} - -// Insert 批量添加 -func (r *UDMSubImpl) Inserts(uArr []model.UDMSub) int64 { - tx := datasource.DefaultDB().CreateInBatches(uArr, 2000) - if err := tx.Error; err != nil { - logger.Errorf("CreateInBatches err => %v", err) - } - return tx.RowsAffected -} - -// Delete 删除实体 -func (r *UDMSubImpl) Delete(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMSub{}) - if err := tx.Error; err != nil { - logger.Errorf("Delete err => %v", err) - } - return tx.RowsAffected -} - -// DeletePrefixByIMSI 删除前缀匹配的实体 -func (r *UDMSubImpl) DeletePrefixByIMSI(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsi, neId).Delete(&model.UDMSub{}) - if err := tx.Error; err != nil { - logger.Errorf("DeletePrefixByIMSI err => %v", err) - } - return tx.RowsAffected -} diff --git a/src/modules/network_data/repository/udm_auth.impl.go b/src/modules/network_data/repository/udm_user_info.go similarity index 71% rename from src/modules/network_data/repository/udm_auth.impl.go rename to src/modules/network_data/repository/udm_user_info.go index 5fee2f0d..c7aead43 100644 --- a/src/modules/network_data/repository/udm_auth.impl.go +++ b/src/modules/network_data/repository/udm_user_info.go @@ -11,24 +11,21 @@ import ( "be.ems/src/modules/network_data/model" ) -// 实例化数据层 UDMAuthImpl 结构体 -var NewUDMAuthImpl = &UDMAuthImpl{ - selectSql: `select id, imsi, amf, status, ki, algo_index, opc, ne_id from u_auth_user`, +// 实例化数据层 UDMUserInfo 结构体 +var NewUDMUserInfo = &UDMUserInfo{ + selectSql: `select id, imsi, msisdn, ne_id, remark from u_user_info`, resultMap: map[string]string{ - "id": "ID", - "imsi": "IMSI", - "amf": "Amf", - "status": "Status", - "ki": "Ki", - "algo_index": "AlgoIndex", - "opc": "Opc", - "ne_id": "NeId", + "id": "ID", + "imsi": "IMSI", + "msisdn": "MSISDN", + "ne_id": "NeId", + "remark": "Remark", }, } -// UDMAuthImpl UDM鉴权信息表 数据层处理 -type UDMAuthImpl struct { +// UDMUserInfo UDM鉴权信息表 数据层处理 +type UDMUserInfo struct { // 查询视图对象SQL selectSql string // 结果字段与实体映射 @@ -36,10 +33,10 @@ type UDMAuthImpl struct { } // convertResultRows 将结果记录转实体结果组 -func (r *UDMAuthImpl) convertResultRows(rows []map[string]any) []model.UDMAuth { - arr := make([]model.UDMAuth, 0) +func (r *UDMUserInfo) convertResultRows(rows []map[string]any) []model.UDMUserInfo { + arr := make([]model.UDMUserInfo, 0) for _, row := range rows { - item := model.UDMAuth{} + item := model.UDMUserInfo{} for key, value := range row { if keyMapper, ok := r.resultMap[key]; ok { repo.SetFieldValue(&item, keyMapper, value) @@ -50,18 +47,8 @@ func (r *UDMAuthImpl) convertResultRows(rows []map[string]any) []model.UDMAuth { return arr } -// ClearAndInsert 清空ne_id后新增实体 -func (r *UDMAuthImpl) ClearAndInsert(neId string, uArr []model.UDMAuth) int64 { - // 不指定neID时,用 TRUNCATE 清空表快 - _, err := datasource.ExecDB("", "TRUNCATE TABLE u_auth_user", nil) - if err != nil { - logger.Errorf("TRUNCATE err => %v", err) - } - return r.Inserts(uArr) -} - // SelectPage 根据条件分页查询 -func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { +func (r *UDMUserInfo) SelectPage(query map[string]any) map[string]any { // 查询条件拼接 var conditions []string var params []any @@ -82,11 +69,11 @@ func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { result := map[string]any{ "total": 0, - "rows": []model.UDMAuth{}, + "rows": []model.UDMUserInfo{}, } // 查询数量 长度为0直接返回 - totalSql := "select count(1) as 'total' from u_auth_user" + totalSql := "select count(1) as 'total' from u_user_info" totalRows, err := datasource.RawDB("", totalSql+whereSql, params) if err != nil { logger.Errorf("total err => %v", err) @@ -132,7 +119,7 @@ func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { } // SelectList 根据实体查询 -func (r *UDMAuthImpl) SelectList(u model.UDMAuth) []model.UDMAuth { +func (r *UDMUserInfo) SelectList(u model.UDMUserInfo) []model.UDMUserInfo { // 查询条件拼接 var conditions []string var params []any @@ -162,8 +149,24 @@ func (r *UDMAuthImpl) SelectList(u model.UDMAuth) []model.UDMAuth { return r.convertResultRows(results) } +// SelectByIMSIAndNeID 通过imsi和ne_id查询 +func (r *UDMUserInfo) SelectByIMSIAndNeID(imsi, neId string) model.UDMUserInfo { + querySql := r.selectSql + " where imsi = ? and ne_id = ?" + results, err := datasource.RawDB("", querySql, []any{imsi, neId}) + if err != nil { + logger.Errorf("query err => %v", err) + return model.UDMUserInfo{} + } + // 转换实体 + rows := r.convertResultRows(results) + if len(rows) > 0 { + return rows[0] + } + return model.UDMUserInfo{} +} + // Insert 批量添加 -func (r *UDMAuthImpl) Inserts(uArr []model.UDMAuth) int64 { +func (r *UDMUserInfo) Inserts(uArr []model.UDMUserInfo) int64 { tx := datasource.DefaultDB().CreateInBatches(uArr, 3000) if err := tx.Error; err != nil { logger.Errorf("CreateInBatches err => %v", err) @@ -172,8 +175,8 @@ func (r *UDMAuthImpl) Inserts(uArr []model.UDMAuth) int64 { } // Delete 删除实体 -func (r *UDMAuthImpl) Delete(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMAuth{}) +func (r *UDMUserInfo) Delete(imsi, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMUserInfo{}) if err := tx.Error; err != nil { logger.Errorf("Delete err => %v", err) } @@ -181,8 +184,8 @@ func (r *UDMAuthImpl) Delete(neId, imsi string) int64 { } // DeletePrefixByIMSI 删除前缀匹配的实体 -func (r *UDMAuthImpl) DeletePrefixByIMSI(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsi, neId).Delete(&model.UDMAuth{}) +func (r *UDMUserInfo) DeletePrefixByIMSI(imsiPrefix, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsiPrefix, neId).Delete(&model.UDMUserInfo{}) if err := tx.Error; err != nil { logger.Errorf("DeletePrefixByIMSI err => %v", err) } diff --git a/src/modules/network_data/service/udm_auth.go b/src/modules/network_data/service/udm_auth.go index 6e2b14e1..8e35bdd8 100644 --- a/src/modules/network_data/service/udm_auth.go +++ b/src/modules/network_data/service/udm_auth.go @@ -1,28 +1,172 @@ package service -import "be.ems/src/modules/network_data/model" +import ( + "fmt" + "strconv" + "strings" -// UDM鉴权信息 服务层接口 -type IUDMAuth interface { - // ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 - ResetData(neId string) int64 + "be.ems/src/framework/redis" + "be.ems/src/modules/network_data/model" + "be.ems/src/modules/network_data/repository" +) - // SelectPage 分页查询数据库 - SelectPage(query map[string]any) map[string]any +// 实例化服务层 UDMAuthUser 结构体 +var NewUDMAuthUser = &UDMAuthUser{ + udmAuthRepository: repository.NewUDMAuthUser, +} - // SelectList 查询数据库 - SelectList(u model.UDMAuth) []model.UDMAuth +// UDM鉴权信息 服务层处理 +type UDMAuthUser struct { + // UDM鉴权信息数据信息 + udmAuthRepository *repository.UDMAuthUser +} - // Insert 从数据中读取后删除imsi再存入数据库 - // imsi长度15,ki长度32,opc长度0或者32 - Insert(neId string, u model.UDMAuth) int64 +// dataByRedis UDM鉴权用户 db:0 中 ausf:* +func (r *UDMAuthUser) dataByRedis(imsi, neId string) []model.UDMAuthUser { + arr := []model.UDMAuthUser{} + key := fmt.Sprintf("ausf:%s", imsi) + ausfArr, err := redis.GetKeys("udmuser", key) + if err != nil { + return arr + } + for _, key := range ausfArr { + m, err := redis.GetHash("udmuser", key) + if err != nil { + continue + } - // InsertData 导入文件数据 dataType目前两种:txt/csv - InsertData(neId, dataType string, data any) int64 + // 跳过-号数据 ausf:360000100000130 + imsi := key[5:] + if strings.Contains(imsi, "-") { + continue + } - // Delete 删除单个不重新加载 - Delete(neID, imsi string) int64 + amf := "" + if v, ok := m["amf"]; ok { + amf = strings.Replace(v, "\r\n", "", 1) + } + a := model.UDMAuthUser{ + IMSI: imsi, + Amf: amf, + Status: "1", // 默认给1 + Ki: m["ki"], + AlgoIndex: m["algo"], + Opc: m["opc"], + NeId: neId, + } + arr = append(arr, a) + } + return arr +} - // LoadData 删除范围后重新加载 num表示imsi后几位 - LoadData(neID, imsi, num string) int64 +// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 +func (r *UDMAuthUser) ResetData(neId string) int64 { + authArr := r.dataByRedis("*", neId) + // 数据清空后添加 + go r.udmAuthRepository.ClearAndInsert(neId, authArr) + return int64(len(authArr)) +} + +// ParseInfo 解析单个用户imsi鉴权信息 data从命令MML得到的结果 +func (r *UDMAuthUser) ParseInfo(imsi, neId string, data map[string]string) model.UDMAuthUser { + u := model.UDMAuthUser{ + IMSI: imsi, + NeId: neId, + Amf: data["amf"], + Status: "1", + Ki: data["ki"], + AlgoIndex: data["algo"], + Opc: data["opc"], + } + + // 补充用户ID用于更新 + auth := r.udmAuthRepository.SelectByIMSIAndNeID(imsi, neId) + if auth.IMSI == imsi { + u.ID = auth.ID + } + return u +} + +// SelectPage 分页查询数据库 +func (r *UDMAuthUser) SelectPage(query map[string]any) map[string]any { + return r.udmAuthRepository.SelectPage(query) +} + +// SelectList 查询数据库 +func (r *UDMAuthUser) SelectList(u model.UDMAuthUser) []model.UDMAuthUser { + return r.udmAuthRepository.SelectList(u) +} + +// Insert 从数据中读取后删除imsi再存入数据库 +// imsi长度15,ki长度32,opc长度0或者32 +func (r *UDMAuthUser) Insert(neId string, u model.UDMAuthUser) int64 { + uArr := r.dataByRedis(u.IMSI, neId) + if len(uArr) > 0 { + r.udmAuthRepository.Delete(u.IMSI, neId) + return r.udmAuthRepository.Inserts(uArr) + } + return 0 +} + +// InsertData 导入文件数据 dataType目前两种:txt/csv +func (r *UDMAuthUser) InsertData(neId, 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(neId, prefix) + // keys ausf:4600001000004* + arr := r.dataByRedis(prefix+"*", neId) + if len(arr) > 0 { + num += r.udmAuthRepository.Inserts(arr) + } + } + return num +} + +// Delete 删除单个不重新加载 +func (r *UDMAuthUser) Delete(imsi, neId string) int64 { + return r.udmAuthRepository.Delete(imsi, neId) +} + +// LoadData 重新加载从imsi开始num的数据 +func (r *UDMAuthUser) LoadData(neId, imsi, num string) { + startIMSI, _ := strconv.ParseInt(imsi, 10, 64) + subNum, _ := strconv.ParseInt(num, 10, 64) + var i int64 + for i = 0; i < subNum; i++ { + keyIMSI := fmt.Sprintf("%015d", startIMSI+i) + // 删除原数据 + r.udmAuthRepository.Delete(keyIMSI, neId) + // 加载数据 + arr := r.dataByRedis(keyIMSI, neId) + if len(arr) < 1 { + continue + } + r.udmAuthRepository.Inserts(arr) + } } diff --git a/src/modules/network_data/service/udm_auth.impl.go b/src/modules/network_data/service/udm_auth.impl.go deleted file mode 100644 index d7998a10..00000000 --- a/src/modules/network_data/service/udm_auth.impl.go +++ /dev/null @@ -1,146 +0,0 @@ -package service - -import ( - "fmt" - "strings" - - "be.ems/src/framework/redis" - "be.ems/src/modules/network_data/model" - "be.ems/src/modules/network_data/repository" -) - -// 实例化服务层 UDMAuthImpl 结构体 -var NewUDMAuthImpl = &UDMAuthImpl{ - udmAuthRepository: repository.NewUDMAuthImpl, -} - -// UDM鉴权信息 服务层处理 -type UDMAuthImpl struct { - // UDM鉴权信息数据信息 - udmAuthRepository repository.IUDMAuth -} - -// dataByRedis UDM鉴权用户 db:0 中 ausf:* -func (r *UDMAuthImpl) dataByRedis(imsi, neId string) []model.UDMAuth { - arr := []model.UDMAuth{} - key := fmt.Sprintf("ausf:%s", imsi) - ausfArr, err := redis.GetKeys("udmuser", key) - if err != nil { - return arr - } - for _, key := range ausfArr { - m, err := redis.GetHash("udmuser", key) - if err != nil { - continue - } - - // 跳过-号数据 - imsi := key[5:] - if strings.Contains(imsi, "-") { - continue - } - - amf := "" - if v, ok := m["amf"]; ok { - amf = strings.Replace(v, "\r\n", "", 1) - } - a := model.UDMAuth{ - IMSI: imsi, - Amf: amf, - Status: "1", // 默认给1 - Ki: m["ki"], - AlgoIndex: m["algo"], - Opc: m["opc"], - NeId: neId, - } - arr = append(arr, a) - } - return arr -} - -// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 -func (r *UDMAuthImpl) ResetData(neId string) int64 { - authArr := r.dataByRedis("*", neId) - // 数据清空后添加 - go r.udmAuthRepository.ClearAndInsert(neId, authArr) - return int64(len(authArr)) -} - -// SelectPage 分页查询数据库 -func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { - return r.udmAuthRepository.SelectPage(query) -} - -// SelectList 查询数据库 -func (r *UDMAuthImpl) SelectList(u model.UDMAuth) []model.UDMAuth { - return r.udmAuthRepository.SelectList(u) -} - -// Insert 从数据中读取后删除imsi再存入数据库 -// imsi长度15,ki长度32,opc长度0或者32 -func (r *UDMAuthImpl) Insert(neId string, u model.UDMAuth) int64 { - uArr := r.dataByRedis(u.IMSI, neId) - if len(uArr) > 0 { - r.udmAuthRepository.Delete(neId, u.IMSI) - return r.udmAuthRepository.Inserts(uArr) - } - return 0 -} - -// InsertData 导入文件数据 dataType目前两种:txt/csv -func (r *UDMAuthImpl) InsertData(neId, 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(neId, prefix) - // keys ausf:4600001000004* - authArr := r.dataByRedis(prefix+"*", neId) - if len(authArr) > 0 { - num += r.udmAuthRepository.Inserts(authArr) - } - } - return num -} - -// Delete 删除单个不重新加载 -func (r *UDMAuthImpl) Delete(neId, imsi string) int64 { - return r.udmAuthRepository.Delete(neId, imsi) -} - -// LoadData 删除范围后重新加载 num表示imsi后几位 -func (r *UDMAuthImpl) LoadData(neId, imsi, num string) int64 { - prefix := imsi[:len(imsi)-len(num)-1] - // 直接删除前缀的记录 - delNum := r.udmAuthRepository.DeletePrefixByIMSI(neId, prefix) - // keys ausf:4600001000004* - authArr := r.dataByRedis(prefix+"*", neId) - if len(authArr) > 0 { - return r.udmAuthRepository.Inserts(authArr) - } - return delNum -} diff --git a/src/modules/network_data/service/udm_sub.go b/src/modules/network_data/service/udm_sub.go index cb03afe7..8aebea35 100644 --- a/src/modules/network_data/service/udm_sub.go +++ b/src/modules/network_data/service/udm_sub.go @@ -1,28 +1,254 @@ package service -import "be.ems/src/modules/network_data/model" +import ( + "fmt" + "strconv" + "strings" -// UDM签约用户信息 服务层接口 -type IUDMSub interface { - // ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 - ResetData(neId string) int64 + "be.ems/src/framework/redis" + "be.ems/src/modules/network_data/model" + "be.ems/src/modules/network_data/repository" +) - // SelectPage 分页查询数据库 - SelectPage(query map[string]any) map[string]any +// 实例化服务层 UDMSubUser 结构体 +var NewUDMSub = &UDMSubUser{ + udmSubRepository: repository.NewUDMSub, + udmUserInfoRepository: repository.NewUDMUserInfo, +} - // SelectList 查询数据库 - SelectList(u model.UDMSub) []model.UDMSub +// UDM签约信息 服务层处理 +type UDMSubUser struct { + // UDM签约信息数据信息 + udmSubRepository *repository.UDMSubUser + // UDM用户IMSI信息数据信息 + udmUserInfoRepository *repository.UDMUserInfo +} - // Insert 从数据中读取后删除imsi再存入数据库 - // imsi长度15,ki长度32,opc长度0或者32 - Insert(neId string, u model.UDMSub) int64 +// dataByRedis UDM签约用户 db:0 中 udm-sd:* +func (r *UDMSubUser) dataByRedis(imsi, neId string) []model.UDMSubUser { + arr := []model.UDMSubUser{} + key := fmt.Sprintf("udm-sd:%s", imsi) + udmsdArr, err := redis.GetKeys("udmuser", key) + if err != nil { + return arr + } + for _, key := range udmsdArr { + m, err := redis.GetHash("udmuser", key) + if err != nil { + continue + } - // InsertData 导入文件数据 dataType目前两种:txt/csv - InsertData(neId, dataType string, data any) int64 + a := model.UDMSubUser{ + IMSI: key[7:], // udm-sd:360000100000130 + MSISDN: m["gpsi"], // 8612300000130 + NeId: neId, + SmfSel: m["smf-sel"], // def_snssai + SmData: m["sm-dat"], // 1-000001&cmnet&ims&3gnet + Cag: m["cag"], // def_cag + } - // Delete 删除单个不重新加载 - Delete(neId, imsi string) int64 + // 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.Ambr = arr[0] + a.Nssai = arr[1] + a.Rat = arr[2] + a.Arfb = arr[3] + a.Sar = arr[4] + a.Cn = arr[5] + } + // 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.ApnContext = arr[7] + // [6] 是不要的,导入和导出不用 + a.StaticIp = arr[8] + } - // LoadData 删除范围后重新加载 num表示imsi后几位 - LoadData(neId, imsi, num string) int64 + arr = append(arr, a) + } + return arr +} + +// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 +func (r *UDMSubUser) ResetData(neId string) int64 { + subArr := r.dataByRedis("*", neId) + // 数据清空后添加 + go r.udmSubRepository.ClearAndInsert(neId, subArr) + return int64(len(subArr)) +} + +// ParseInfo 解析单个用户imsi签约信息 data从命令MML得到的结果 +func (r *UDMSubUser) ParseInfo(imsi, neId string, data map[string]string) model.UDMSubUser { + cnType, _ := strconv.ParseInt(data["CNType"][:4], 0, 64) + rat, _ := strconv.ParseInt(data["RAT"][:4], 0, 64) + msisdn := data["MSISDN"] + if imsMsisdnLen := strings.Index(msisdn, ","); imsMsisdnLen != -1 { + msisdn = msisdn[:imsMsisdnLen] + } + + u := model.UDMSubUser{ + IMSI: imsi, + MSISDN: msisdn, + NeId: neId, + Ambr: data["AMBR"], + Arfb: data["AreaForbidden"], + Cn: fmt.Sprint(cnType), + SmData: data["SM-Data(snssai+dnn[1..n])"], + Sar: data["ServiceAreaRestriction"], + Nssai: data["NSSAI"], + SmfSel: data["Smf-Selection"], + Cag: data["cag"], + Rat: fmt.Sprint(rat), + } + // 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.ApnContext = arr[7] + // [6] 是不要的,导入和导出不用 + u.StaticIp = arr[8] + } + + // 补充用户ID用于更新 + sub := r.udmSubRepository.SelectByIMSIAndNeID(imsi, neId) + if sub.IMSI == imsi { + u.ID = sub.ID + } + // 补充用户拓展信息 + info := r.udmUserInfoRepository.SelectByIMSIAndNeID(imsi, neId) + if info.IMSI == imsi { + u.Remark = info.Remark + } + return u +} + +// SelectPage 分页查询数据库 +func (r *UDMSubUser) SelectPage(query map[string]any) map[string]any { + return r.udmSubRepository.SelectPage(query) +} + +// SelectList 查询数据库 +func (r *UDMSubUser) SelectList(u model.UDMSubUser) []model.UDMSubUser { + return r.udmSubRepository.SelectList(u) +} + +// Insert 从数据中读取后删除imsi再存入数据库 +// imsi长度15,ki长度32,opc长度0或者32 +func (r *UDMSubUser) Insert(neId string, u model.UDMSubUser) int64 { + uArr := r.dataByRedis(u.IMSI, neId) + if len(uArr) > 0 { + r.udmSubRepository.Delete(u.IMSI, neId) + // 新增到拓展信息 + if u.Remark != "" { + r.udmUserInfoRepository.Delete(u.IMSI, neId) + r.udmUserInfoRepository.Inserts([]model.UDMUserInfo{{ + IMSI: u.IMSI, + MSISDN: u.MSISDN, + NeId: u.NeId, + Remark: u.Remark, + }}) + } + return r.udmSubRepository.Inserts(uArr) + } + return 0 +} + +// InsertData 导入文件数据 dataType目前两种:txt/csv +func (r *UDMSubUser) InsertData(neId, 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(prefix+"*", neId) + if len(arr) > 0 { + r.udmSubRepository.DeletePrefixByIMSI(prefix, neId) + num += r.udmSubRepository.Inserts(arr) + } + } + return num +} + +// Delete 删除单个不重新加载 +func (r *UDMSubUser) Delete(neId, imsi string) int64 { + // 删除拓展信息 + r.udmUserInfoRepository.Delete(imsi, neId) + return r.udmSubRepository.Delete(imsi, neId) +} + +// LoadData 重新加载从imsi开始num的数据 +// remark不为空,则新增到拓展信息,删除标记为-(Deleted)- +func (r *UDMSubUser) LoadData(neId, imsi, num, remark string) { + startIMSI, _ := strconv.ParseInt(imsi, 10, 64) + subNum, _ := strconv.ParseInt(num, 10, 64) + var i int64 + for i = 0; i < subNum; i++ { + keyIMSI := fmt.Sprintf("%015d", startIMSI+i) + // 删除原数据 + r.udmSubRepository.Delete(keyIMSI, neId) + if remark == "-(Deleted)-" { + r.udmUserInfoRepository.Delete(keyIMSI, neId) + } + // 加载数据 + arr := r.dataByRedis(keyIMSI, neId) + if len(arr) < 1 { + continue + } + r.udmSubRepository.Inserts(arr) + // 拓展信息 + if remark != "" { + uarr := make([]model.UDMUserInfo, 0, len(arr)) + for _, v := range arr { + uarr = append(uarr, model.UDMUserInfo{ + IMSI: v.IMSI, + MSISDN: v.MSISDN, + NeId: v.NeId, + Remark: remark, + }) + } + r.udmUserInfoRepository.Delete(keyIMSI, neId) + r.udmUserInfoRepository.Inserts(uarr) + } + } } diff --git a/src/modules/network_data/service/udm_sub.impl.go b/src/modules/network_data/service/udm_sub.impl.go deleted file mode 100644 index 768e48a8..00000000 --- a/src/modules/network_data/service/udm_sub.impl.go +++ /dev/null @@ -1,164 +0,0 @@ -package service - -import ( - "fmt" - "strings" - - "be.ems/src/framework/redis" - "be.ems/src/modules/network_data/model" - "be.ems/src/modules/network_data/repository" -) - -// 实例化服务层 UDMSubImpl 结构体 -var NewUDMSubImpl = &UDMSubImpl{ - udmSubRepository: repository.NewUDMSubImpl, -} - -// UDM签约信息 服务层处理 -type UDMSubImpl struct { - // UDM签约信息数据信息 - udmSubRepository repository.IUDMSub -} - -// dataByRedis UDM签约用户 db:0 中 udm-sd:* -func (r *UDMSubImpl) dataByRedis(imsi, neId string) []model.UDMSub { - arr := []model.UDMSub{} - key := fmt.Sprintf("udm-sd:%s", imsi) - udmsdArr, err := redis.GetKeys("udmuser", key) - if err != nil { - return arr - } - for _, key := range udmsdArr { - m, err := redis.GetHash("udmuser", key) - if err != nil { - continue - } - - a := model.UDMSub{ - IMSI: key[7:], - Msisdn: m["gpsi"], // 46003550072 - SmfSel: m["smf-sel"], - SmData: m["sm-dat"], // 1-000001&cmnet&ims&3gnet - NeId: neId, - } - - // 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.Ambr = arr[0] - a.Nssai = arr[1] - a.Rat = arr[2] - a.Arfb = arr[3] - a.Sar = arr[4] - a.Cn = arr[5] - } - // 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.ApnContext = arr[7] - // [6] 是不要的,导入和导出不用 - a.StaticIp = arr[8] - } - - arr = append(arr, a) - } - return arr -} - -// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 -func (r *UDMSubImpl) ResetData(neId string) int64 { - subArr := r.dataByRedis("*", neId) - // 数据清空后添加 - go r.udmSubRepository.ClearAndInsert(neId, subArr) - return int64(len(subArr)) -} - -// SelectPage 分页查询数据库 -func (r *UDMSubImpl) SelectPage(query map[string]any) map[string]any { - return r.udmSubRepository.SelectPage(query) -} - -// SelectList 查询数据库 -func (r *UDMSubImpl) SelectList(u model.UDMSub) []model.UDMSub { - return r.udmSubRepository.SelectList(u) -} - -// Insert 从数据中读取后删除imsi再存入数据库 -// imsi长度15,ki长度32,opc长度0或者32 -func (r *UDMSubImpl) Insert(neId string, u model.UDMSub) int64 { - uArr := r.dataByRedis(u.IMSI, neId) - if len(uArr) > 0 { - r.udmSubRepository.Delete(neId, u.IMSI) - return r.udmSubRepository.Inserts(uArr) - } - return 0 -} - -// InsertData 导入文件数据 dataType目前两种:txt/csv -func (r *UDMSubImpl) InsertData(neId, 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.udmSubRepository.DeletePrefixByIMSI(neId, prefix) - // keys udm-sd:4600001000004* - subArr := r.dataByRedis(prefix+"*", neId) - if len(subArr) > 0 { - num += r.udmSubRepository.Inserts(subArr) - } - } - return num -} - -// Delete 删除单个不重新加载 -func (r *UDMSubImpl) Delete(neId, imsi string) int64 { - return r.udmSubRepository.Delete(neId, imsi) -} - -// LoadData 删除范围后重新加载 num表示imsi后几位 -func (r *UDMSubImpl) LoadData(neId, imsi, num string) int64 { - prefix := imsi[:len(imsi)-len(num)-1] - // 直接删除前缀的记录 - delNum := r.udmSubRepository.DeletePrefixByIMSI(neId, prefix) - // keys udm-sd:4600001000004* - authArr := r.dataByRedis(prefix+"*", neId) - if len(authArr) > 0 { - return r.udmSubRepository.Inserts(authArr) - } - return delNum -} diff --git a/src/modules/network_data/service/udm_user_info.go b/src/modules/network_data/service/udm_user_info.go new file mode 100644 index 00000000..da610724 --- /dev/null +++ b/src/modules/network_data/service/udm_user_info.go @@ -0,0 +1,33 @@ +package service + +import ( + "be.ems/src/modules/network_data/model" + "be.ems/src/modules/network_data/repository" +) + +// 实例化服务层 UDMUserInfo 结构体 +var NewUDMUserInfo = &UDMUserInfo{ + udmUserInfoRepository: repository.NewUDMUserInfo, +} + +// UDM用户IMSI拓展信息 服务层处理 +type UDMUserInfo struct { + // UDM用户IMSI信息数据信息 + udmUserInfoRepository *repository.UDMUserInfo +} + +// SelectByIMSIAndNeID 通过IMSI和网元标识查询信息 +func (r *UDMUserInfo) SelectByIMSIAndNeID(imsi, neId string) model.UDMUserInfo { + return r.udmUserInfoRepository.SelectByIMSIAndNeID(imsi, neId) +} + +// Save 新增或修改信息 +func (r *UDMUserInfo) Save(u model.UDMUserInfo) bool { + r.udmUserInfoRepository.Delete(u.IMSI, u.NeId) + return r.udmUserInfoRepository.Inserts([]model.UDMUserInfo{u}) > 0 +} + +// Delete 删除信息 +func (r *UDMUserInfo) Delete(imsi, neId string) int64 { + return r.udmUserInfoRepository.Delete(imsi, neId) +}