From 63433e6e0eb6cd3547b0724d846b6c02648d3061 Mon Sep 17 00:00:00 2001 From: zhangsz Date: Thu, 10 Apr 2025 21:16:54 +0800 Subject: [PATCH] fix: ims user tag 0/1: VoIP/VoLTE --- database/install/u_ims_user.sql | 6 ++-- database/upgrade/upg_u_ims_user.sql | 6 ++-- features/ue/controller/ims_user.go | 10 +++--- features/ue/ims_user/controller.go | 17 +++++----- features/ue/ims_user/model.go | 4 +-- features/ue/ims_user/repository.go | 4 +-- features/ue/ims_user/service.go | 28 ++++++++-------- features/ue/model/ims_user.go | 51 ++++++++++++++++++++++++----- features/ue/repository/ims_user.go | 6 ++-- features/ue/service/ims_user.go | 14 ++++---- 10 files changed, 90 insertions(+), 56 deletions(-) diff --git a/database/install/u_ims_user.sql b/database/install/u_ims_user.sql index 98cf7227..e5e6e5a9 100755 --- a/database/install/u_ims_user.sql +++ b/database/install/u_ims_user.sql @@ -11,7 +11,7 @@ Target Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2) File Encoding : 65001 - Date: 09/04/2025 09:22:00 + Date: 10/04/2025 20:59:15 */ SET NAMES utf8mb4; @@ -26,11 +26,11 @@ CREATE TABLE `u_ims_user` ( `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM/USIMID', `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', - `volte` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', + `tag` tinyint(4) NULL DEFAULT NULL COMMENT '0: VoIP, 1: VoLTE', `vni` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', `tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'multi-tenancy refer to sys_tenant.tenant_id', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_imsi_ne`(`imsi`, `ne_id`) USING BTREE COMMENT 'imsi_neid' -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 371900 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_u_ims_user.sql b/database/upgrade/upg_u_ims_user.sql index e0eea667..c442d68c 100755 --- a/database/upgrade/upg_u_ims_user.sql +++ b/database/upgrade/upg_u_ims_user.sql @@ -11,7 +11,7 @@ Target Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2) File Encoding : 65001 - Date: 09/04/2025 09:22:00 + Date: 10/04/2025 20:59:34 */ SET NAMES utf8mb4; @@ -25,11 +25,11 @@ CREATE TABLE IF NOT EXISTS `u_ims_user` ( `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM/USIMID', `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', - `volte` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', + `tag` tinyint(4) NULL DEFAULT NULL COMMENT '0: VoIP, 1: VoLTE', `vni` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', `tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'multi-tenancy refer to sys_tenant.tenant_id', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_imsi_ne`(`imsi`, `ne_id`) USING BTREE COMMENT 'imsi_neid' -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 371900 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; diff --git a/features/ue/controller/ims_user.go b/features/ue/controller/ims_user.go index 165cddcf..83a0a35d 100644 --- a/features/ue/controller/ims_user.go +++ b/features/ue/controller/ims_user.go @@ -115,7 +115,7 @@ func (s *IMSUserController) Add(c *gin.Context) { var body model.IMSUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || (len(body.IMSI) < model.IMSI_MAX_LENGTH && body.VoLTE == model.TAG_VoLTE) { + if err != nil || (len(body.IMSI) < model.IMSI_MAX_LENGTH && body.Tag == model.TAG_VoLTE) { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -162,7 +162,7 @@ func (s *IMSUserController) Adds(c *gin.Context) { var body model.IMSUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || (len(body.IMSI) < model.IMSI_MAX_LENGTH && body.VoLTE == model.TAG_VoLTE) { + if err != nil || (len(body.IMSI) < model.IMSI_MAX_LENGTH && body.Tag == model.TAG_VoLTE) { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -381,9 +381,9 @@ func (s *IMSUserController) Export(c *gin.Context) { if fileType == "csv" { // 转换数据 data := [][]string{} - data = append(data, []string{"IMSI", "MSISDN", "VoLTE", "VNI"}) + data = append(data, []string{"IMSI", "MSISDN", "Tag", "VNI"}) for _, v := range rows { - data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Tag.String(), v.VNI}) } // 输出到文件 if err := file.WriterFileCSV(data, filePath); err != nil { @@ -396,7 +396,7 @@ func (s *IMSUserController) Export(c *gin.Context) { // 转换数据 data := [][]string{} for _, v := range rows { - data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Tag.String(), v.VNI}) } // 输出到文件 if err := file.WriterFileTXT(data, ",", filePath); err != nil { diff --git a/features/ue/ims_user/controller.go b/features/ue/ims_user/controller.go index a7bb2286..48251db7 100644 --- a/features/ue/ims_user/controller.go +++ b/features/ue/ims_user/controller.go @@ -20,16 +20,16 @@ import ( // 实例化控制层 Controller 结构体 var NewController = &Controller{ - volteUserService: NewVoLTEService, - neInfoService: neService.NewNeInfo, + volteUserService: NewVoLTEService, + neInfoService: neService.NewNeInfo, } // IMS用户信息 控制层处理 // // @Description IMS用户信息 控制层处理 type Controller struct { - volteUserService *Service // IMS User信息服务 - neInfoService *neService.NeInfo // 网元信息服务 + volteUserService *Service // IMS User信息服务 + neInfoService *neService.NeInfo // 网元信息服务 } func (s *Controller) ResetData(c *gin.Context) { @@ -44,7 +44,6 @@ func (s *Controller) ResetData(c *gin.Context) { c.JSON(200, result.OkData(data)) } - func (s *Controller) List(c *gin.Context) { querys := ctx.QueryMap(c) // querys["userName"] = ctx.LoginUserToUserName(c) @@ -94,7 +93,7 @@ func (s *Controller) Info(c *gin.Context) { } if len(data) == 0 { - c.JSON(200, result.ErrMsg("Not found VoLTE user data")) + c.JSON(200, result.ErrMsg("Not found IMS user data")) return } @@ -380,9 +379,9 @@ func (s *Controller) Export(c *gin.Context) { if fileType == "csv" { // 转换数据 data := [][]string{} - data = append(data, []string{"IMSI", "MSISDN", "VoLTE", "VNI"}) + data = append(data, []string{"IMSI", "MSISDN", "Tag", "VNI"}) for _, v := range rows { - data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI}) } // 输出到文件 if err := file.WriterFileCSV(data, filePath); err != nil { @@ -395,7 +394,7 @@ func (s *Controller) Export(c *gin.Context) { // 转换数据 data := [][]string{} for _, v := range rows { - data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI}) } // 输出到文件 if err := file.WriterFileTXT(data, ",", filePath); err != nil { diff --git a/features/ue/ims_user/model.go b/features/ue/ims_user/model.go index d89b411d..5dbb1858 100644 --- a/features/ue/ims_user/model.go +++ b/features/ue/ims_user/model.go @@ -13,8 +13,8 @@ type VoLTEUser struct { NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识 IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码 - VoLTE string `json:"volte" gorm:"column:volte"` // VoLTE - VNI string `json:"vni" gorm:"column:vni"` // VNI + Tag string `json:"tag" gorm:"column:tag"` // Tag: 0=VoIP, 1=VoLTE + VNI string `json:"vni" gorm:"column:vni"` // VNI TenantID string `json:"tenantID" gorm:"column:tenant_id"` TenantName string `json:"tenantName" gorm:"-"` diff --git a/features/ue/ims_user/repository.go b/features/ue/ims_user/repository.go index b43385a3..66dc0e34 100644 --- a/features/ue/ims_user/repository.go +++ b/features/ue/ims_user/repository.go @@ -15,7 +15,7 @@ import ( // 实例化数据层 Repository 结构体 var NewVoLTERepository = &Repository{ selectSql: `select - s.id, s.ne_id, s.imsi, s.msisdn, s.volte, s.vni, + s.id, s.ne_id, s.imsi, s.msisdn, s.tag, s.vni, t.tenant_id, t.tenant_name from u_ims_user s left join sys_tenant t on t.tenant_id = s.tenant_id and t.status = 1`, @@ -25,7 +25,7 @@ var NewVoLTERepository = &Repository{ "ne_id": "NeId", "imsi": "IMSI", "msisdn": "MSISDN", - "volte": "VoLTE", + "tag": "Tag", "vni": "VNI", "tenant_id": "TenantID", diff --git a/features/ue/ims_user/service.go b/features/ue/ims_user/service.go index fb5cde2a..a88af231 100644 --- a/features/ue/ims_user/service.go +++ b/features/ue/ims_user/service.go @@ -11,12 +11,12 @@ import ( // 实例化服务层 Service 结构体 var NewVoLTEService = &Service{ - volteRepository: NewVoLTERepository, + volteRepository: NewVoLTERepository, } // VoLTE用户信息 服务层处理 type Service struct { - volteRepository *Repository // VoLTE用户信息数据信息 + volteRepository *Repository // VoLTE用户信息数据信息 } // dataByRedis UDM签约用户 db:0 中 volte:* @@ -48,12 +48,12 @@ func (r *Service) dataByRedis(imsi, neId string) []VoLTEUser { for k, m := range mkv { var imsi, msisdn string KeyParts := strings.Split(k, ":") - switch len(KeyParts) { + switch len(KeyParts) { case 0, 1: // 处理单个部分的情况 continue case 2: - // 处理两个部分的情况 + // 处理两个部分的情况 imsi = KeyParts[1] msisdn = "-" case 3: @@ -69,14 +69,14 @@ func (r *Service) dataByRedis(imsi, neId string) []VoLTEUser { var vni string = "-" impiParts := strings.Split(m["impi"], "@") if len(impiParts) > 1 { - vni = impiParts[1] // 输出: ims.mnc001.mcc110.3gppnetwork.org - } + vni = impiParts[1] // 输出: ims.mnc001.mcc110.3gppnetwork.org + } a := VoLTEUser{ NeId: neId, - IMSI: imsi, // volte:360000100000130:8612300000130 - MSISDN: msisdn, // 8612300000130 - VoLTE: m["tag"], // volte = tag - VNI: vni, // ims.mnc001.mcc110.3gppnetwork.org + IMSI: imsi, // volte:360000100000130:8612300000130 + MSISDN: msisdn, // 8612300000130 + Tag: m["tag"], // volte = tag + VNI: vni, // ims.mnc001.mcc110.3gppnetwork.org } arr = append(arr, a) } @@ -95,7 +95,7 @@ func (r *Service) ResetData(neId string) int64 { func (r *Service) ParseInfo(imsi, neId string, data map[string]string) VoLTEUser { u := r.volteRepository.SelectByIMSIAndNeID(imsi, neId) - msisdn := data["MSISDN"] + msisdn := data["msisdn"] if imsMsisdnLen := strings.Index(msisdn, ","); imsMsisdnLen != -1 { msisdn = msisdn[:imsMsisdnLen] } @@ -104,7 +104,7 @@ func (r *Service) ParseInfo(imsi, neId string, data map[string]string) VoLTEUser u.NeId = neId u.IMSI = imsi u.MSISDN = msisdn - u.VoLTE = data["VoLTE"] + u.Tag = data["volte_tag"] u.VNI = data["VNI"] return u } @@ -198,8 +198,8 @@ func (r *Service) ParseCommandParams(item VoLTEUser) string { conditions = append(conditions, fmt.Sprintf("msisdn=%s", item.MSISDN)) } - if item.VoLTE != "" { - conditions = append(conditions, fmt.Sprintf("volte=%s", item.VoLTE)) + if item.Tag != "" { + conditions = append(conditions, fmt.Sprintf("volte=%s", item.Tag)) } if item.VNI != "" { conditions = append(conditions, fmt.Sprintf("vni=%s", item.VNI)) diff --git a/features/ue/model/ims_user.go b/features/ue/model/ims_user.go index 188b9f45..71feee01 100644 --- a/features/ue/model/ims_user.go +++ b/features/ue/model/ims_user.go @@ -1,22 +1,57 @@ package model +import ( + "fmt" + "strconv" +) + const ( // IMSI 号码长度 IMSI_MAX_LENGTH = 15 // MSISDN 号码长度 MSISDN_MAX_LENGTH = 15 - TAG_VoLTE = "1" // VoLTE标记 - TAG_VOIP = "0" // VoIP标记 ) +type CallTag int + +const ( + TAG_VOIP CallTag = iota // VoIP标记 + TAG_VoLTE // VoLTE标记 +) + +func (ct CallTag) Enum() string { + switch ct { + case TAG_VOIP: + return "VoIP" + case TAG_VoLTE: + return "VoLTE" + default: + return "unknown" + } +} + +func (ct CallTag) String() string { + return fmt.Sprintf("%d", ct) +} + +// ParseCallTag 将字符串转换为 CallTag 枚举类型 +func ParseCallTag(s string) CallTag { + // 如果为空或转换失败,可以返回默认值,例如 VoIP + i, err := strconv.Atoi(s) + if err != nil { + return TAG_VOIP + } + return CallTag(i) +} + // @Description VoLTE用户信息 type IMSUser struct { - ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键 - NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识 - IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID - MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码 - VoLTE string `json:"volte" gorm:"column:volte"` // VoLTE - VNI string `json:"vni" gorm:"column:vni"` // VNI + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键 + NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识 + IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID + MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码 + Tag CallTag `json:"tag" gorm:"column:tag"` // tag: 0=VoIP, 1=VoLTE + VNI string `json:"vni" gorm:"column:vni"` // VNI TenantID string `json:"tenantID" gorm:"column:tenant_id"` TenantName string `json:"tenantName" gorm:"-"` diff --git a/features/ue/repository/ims_user.go b/features/ue/repository/ims_user.go index 0c5cacac..08667e91 100644 --- a/features/ue/repository/ims_user.go +++ b/features/ue/repository/ims_user.go @@ -4,19 +4,19 @@ import ( "fmt" "strings" + "be.ems/features/ue/model" dborm "be.ems/lib/core/datasource" "be.ems/lib/log" "be.ems/src/framework/datasource" "be.ems/src/framework/logger" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" - "be.ems/features/ue/model" ) // 实例化数据层 IMSUserRepository 结构体 var NewIMSUserRepository = &IMSUserRepository{ selectSql: `select - s.id, s.ne_id, s.imsi, s.msisdn, s.volte, s.vni, + s.id, s.ne_id, s.imsi, s.msisdn, s.tag, s.vni, t.tenant_id, t.tenant_name from u_ims_user s left join sys_tenant t on t.tenant_id = s.tenant_id and t.status = 1`, @@ -26,7 +26,7 @@ var NewIMSUserRepository = &IMSUserRepository{ "ne_id": "NeId", "imsi": "IMSI", "msisdn": "MSISDN", - "volte": "VoLTE", + "tag": "Tag", "vni": "VNI", "tenant_id": "TenantID", diff --git a/features/ue/service/ims_user.go b/features/ue/service/ims_user.go index 52fc8bbd..71e94293 100644 --- a/features/ue/service/ims_user.go +++ b/features/ue/service/ims_user.go @@ -75,10 +75,10 @@ func (r *IMSUserService) dataByRedis(imsi, neId string) []model.IMSUser { } a := model.IMSUser{ NeId: neId, - IMSI: imsi, // volte:360000100000130:8612300000130 - MSISDN: msisdn, // 8612300000130 - VoLTE: m["tag"], // volte = tag - VNI: vni, // ims.mnc001.mcc110.3gppnetwork.org + IMSI: imsi, // volte:360000100000130:8612300000130 + MSISDN: msisdn, // 8612300000130 + Tag: model.ParseCallTag(m["tag"]), // volte = tag + VNI: vni, // ims.mnc001.mcc110.3gppnetwork.org } arr = append(arr, a) } @@ -111,7 +111,7 @@ func (r *IMSUserService) ParseInfo(imsi, neId string, data map[string]string) mo u.NeId = neId u.IMSI = imsi u.MSISDN = msisdn - u.VoLTE = data["volte_tag"] + u.Tag = model.ParseCallTag(data["volte_tag"]) u.VNI = vni return u } @@ -205,8 +205,8 @@ func (r *IMSUserService) ParseCommandParams(item model.IMSUser) string { conditions = append(conditions, fmt.Sprintf("msisdn=%s", item.MSISDN)) } - if item.VoLTE != "" { - conditions = append(conditions, fmt.Sprintf("volte=%s", item.VoLTE)) + if item.Tag != model.ParseCallTag("") { + conditions = append(conditions, fmt.Sprintf("volte=%d", item.Tag)) } if item.VNI != "" { conditions = append(conditions, fmt.Sprintf("vni=%s", item.VNI))