fix: ims user tag 0/1: VoIP/VoLTE

This commit is contained in:
zhangsz
2025-04-10 21:16:54 +08:00
parent 8913970d01
commit 63433e6e0e
10 changed files with 90 additions and 56 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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:"-"`

View File

@@ -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",

View File

@@ -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))

View File

@@ -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:"-"`

View File

@@ -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",

View File

@@ -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))