package service import ( "fmt" "strings" "time" "be.ems/src/framework/database/redis" "be.ems/src/framework/utils/date" "be.ems/src/modules/network_data/model" "be.ems/src/modules/network_data/repository" neService "be.ems/src/modules/network_element/service" ) // 实例化服务层 UDMAuthUser 结构体 var NewUDMAuthUser = &UDMAuthUser{ udmAuthRepository: repository.NewUDMAuthUser, } // UDM鉴权信息 服务层处理 type UDMAuthUser struct { // UDM鉴权信息数据信息 udmAuthRepository *repository.UDMAuthUser } // dataByRedis UDM鉴权用户 db:0 中 ausf:* func (r *UDMAuthUser) dataByRedis(imsi, neId string) []model.UDMAuthUser { arr := []model.UDMAuthUser{} key := fmt.Sprintf("ausf:%s", imsi) source := fmt.Sprintf("UDM_%s", neId) // 网元主机的Redis客户端 redisClient, err := neService.NewNeInfo.NeRunRedisClient("UDM", neId) if err != nil { return arr } defer func() { redisClient.Close() redis.ConnectPush(source, nil) }() redis.ConnectPush(source, redisClient.Client) ausfArr, err := redis.GetKeys(source, key) if err != nil { return arr } mkv, err := redis.GetHashBatch(source, ausfArr) if err != nil { return arr } for k, m := range mkv { if len(k) != 20 { continue } // 跳过-号数据 ausf:360000100000130 imsi, hasPrefix := strings.CutPrefix(k, "ausf:") if strings.Contains(imsi, "-") || !hasPrefix { continue } amf := "" if v, ok := m["amf"]; ok { amf = strings.Replace(v, "\r\n", "", 1) } var createTime int64 = 0 if v, ok := m["create_time"]; ok { t := date.ParseStrToDate(v, date.YYYY_MM_DDTHH_MM_SSZ) createTime = t.UnixMilli() } else { createTime = time.Now().UnixMilli() } a := model.UDMAuthUser{ CreateTime: createTime, NeId: neId, IMSI: imsi, Amf: amf, Ki: m["ki"], AlgoIndex: m["algo"], Opc: m["opc"], } arr = append(arr, a) } return arr } // ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 func (r *UDMAuthUser) ResetData(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 := r.udmAuthRepository.SelectByIMSIAndNeID(imsi, neId) // 用于更新 u.IMSI = imsi u.NeId = neId u.Amf = data["amf"] u.Ki = data["ki"] u.AlgoIndex = data["algo"] u.Opc = data["opc"] return u } // FindByPage 分页查询数据库 func (r *UDMAuthUser) FindByPage(query map[string]string) ([]model.UDMAuthUser, int64) { return r.udmAuthRepository.SelectPage(query) } // Find 查询数据库 func (r *UDMAuthUser) Find(u model.UDMAuthUser) []model.UDMAuthUser { return r.udmAuthRepository.SelectList(u) } // Insert 从数据中读取后删除imsi再存入数据库 // imsi长度15,ki长度32,opc长度0或者32 func (r *UDMAuthUser) Insert(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(prefix, neId) // 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) { // 直接删除前缀的记录 index := len(imsi) - len(num) - 1 prefix := imsi[:index] r.udmAuthRepository.DeletePrefixByIMSI(prefix, neId) // 加载数据 arr := r.dataByRedis(prefix+"*", neId) if len(arr) > 0 { r.udmAuthRepository.Inserts(arr) } } // ParseCommandParams 解析数据组成命令参数 ki=xx,xx=xx,... func (r *UDMAuthUser) ParseCommandParams(item model.UDMAuthUser) string { var conditions []string if item.Ki != "" { conditions = append(conditions, fmt.Sprintf("ki=%s", item.Ki)) } if item.Amf != "" { conditions = append(conditions, fmt.Sprintf("amf=%s", item.Amf)) } if item.AlgoIndex != "" { conditions = append(conditions, fmt.Sprintf("algo=%s", item.AlgoIndex)) } if item.Opc != "" { conditions = append(conditions, fmt.Sprintf("opc=%s", item.Opc)) } return strings.Join(conditions, ",") }