feat: support mf calling api

This commit is contained in:
zhangsz
2025-05-17 18:07:58 +08:00
parent 4ce712a7e2
commit 1b2d8c9d58
7 changed files with 158 additions and 3 deletions

View File

@@ -49,3 +49,10 @@ mf:
filter: ""
display: "Domain"
comment: "ip:port"
- name: "onlineStatus"
type: "bool"
value: "false"
access: "read-only"
filter: '{"0":"false", "1":"true"}'
display: "Online Status"
comment: "Online Status"

View File

@@ -5,6 +5,7 @@ import (
"be.ems/features/lm"
"be.ems/features/nbi"
"be.ems/features/pm"
"be.ems/features/ue"
"be.ems/lib/log"
"github.com/gin-gonic/gin"
)
@@ -18,5 +19,6 @@ func InitServiceEngine(r *gin.Engine) {
lm.InitSubServiceRoute(r)
cm.InitSubServiceRoute(r)
nbi.InitSubServiceRoute(r)
ue.InitSubServiceRoute(r)
// return featuresGroup
}

18
features/ue/api.go Normal file
View File

@@ -0,0 +1,18 @@
// log management package
package ue
import (
"be.ems/features/ue/mf_calling"
"be.ems/lib/log"
"github.com/gin-gonic/gin"
)
func InitSubServiceRoute(r *gin.Engine) {
log.Info("======init UE management group gin.Engine")
mfGroup := r.Group("/psap/v1/mf")
mf_calling.Register(mfGroup)
// register other sub modules routes
}

View File

@@ -0,0 +1,66 @@
package mf_calling
import (
"be.ems/src/framework/i18n"
"be.ems/src/framework/middleware"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo/result"
"github.com/gin-gonic/gin"
neService "be.ems/src/modules/network_element/service"
)
// @Description Register Routes for mf calling
func Register(r *gin.RouterGroup) {
mfCallingGroup := r.Group("/callings")
{
var m *MfCallingInfo
mfCallingGroup.GET("/:neId/list",
middleware.PreAuthorize(nil),
m.List,
)
}
}
func (s *MfCallingInfo) List(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeId string `form:"neId" binding:"required"`
TenantName string `form:"tenantName"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 处理租户逻辑
loginUser, _ := ctx.LoginUser(c)
if len(loginUser.User.Roles) > 0 {
for _, v := range loginUser.User.Roles {
if v.RoleKey == "tenant" {
querys.TenantName = loginUser.User.UserName
break
}
}
}
// 查询网元信息
neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID("MF", querys.NeId)
if neInfo.NeId != querys.NeId || neInfo.IP == "" {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
// 1. 调用服务层方法向网元MF发起API请求
data, total, err := s.GetCallingInfoFromMF(neInfo)
if err != nil {
c.JSON(500, result.ErrMsg(err.Error()))
return
}
// 2. 返回前端
c.JSON(200, result.Ok(gin.H{
"total": total,
"rows": data,
}))
}

View File

@@ -0,0 +1,24 @@
package mf_calling
// @Description VoLTE用户信息
type MfCallingInfo struct {
AnsweredTime string `json:"answeredTime" gorm:"column:answered_time"` // 接听时间
BLegUuid string `json:"bLegUuid" gorm:"column:b_leg_uuid"` // BLeg UUID
CallDuration string `json:"callDuration" gorm:"column:call_duration"` // 通话时长
CallState string `json:"callState" gorm:"column:call_state"` // 通话状态
CalleeIdName string `json:"calleeIdName" gorm:"column:callee_id_name"` // 被叫用户名称
CalleeIdNumber string `json:"calleeIdNumber" gorm:"column:callee_id_number"` // 被叫用户电话号码
CallerIdName string `json:"callerIdName" gorm:"column:caller_id_name"` // 主叫用户名称
CallerIdNumber string `json:"callerIdNumber" gorm:"column:caller_id_number"` // 主叫用户电话号码
CreatedTime string `json:"createdTime" gorm:"column:created_time"` // 创建时间
Direction string `json:"direction" gorm:"column:direction"` // 通话方向
Uuid string `json:"uuid" gorm:"column:uuid"` // uuid
TenantID string `json:"tenantID" gorm:"column:tenant_id"`
TenantName string `json:"tenantName" gorm:"-"`
}
// TableName 表名称
func (*MfCallingInfo) TableName() string {
return "mf_calling_info"
}

View File

@@ -0,0 +1,38 @@
package mf_calling
import (
"encoding/json"
"fmt"
"io"
"net/http"
neModel "be.ems/src/modules/network_element/model"
)
func (s *MfCallingInfo) GetCallingInfoFromMF(neInfo neModel.NeInfo) ([]MfCallingInfo, int, error) {
// 构造网元MF的API地址
url := fmt.Sprintf("http://%s:%d/api/rest/psap/v1/mf/callingInfo", neInfo.IP, neInfo.Port)
// 可根据querys拼接更多参数
resp, err := http.Get(url)
if err != nil {
return nil, 0, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, 0, err
}
// 假设MF返回格式为 {"totalCalls": 10, "Data": [...]}
var mfResp struct {
TotalCalls int `json:"totalCalls"`
Data []MfCallingInfo `json:"data"`
}
if err := json.Unmarshal(body, &mfResp); err != nil {
return nil, 0, err
}
return mfResp.Data, mfResp.TotalCalls, nil
}

View File

@@ -32,7 +32,7 @@ rest:
webServer:
enabled: true
rootDir: /home/simon/omc.git/fe.ems.vue3/dist # front-end build dist directory
rootDir: /home/simon/psap.git/fe.ems.vue3/dist # front-end build dist directory
listen:
- addr: :8080
schema: http
@@ -47,7 +47,7 @@ database:
type: mysql
user: root
password: "1000omc@kp!"
host: "127.0.0.1"
host: "192.168.2.223"
port: 33066
name: omc_db
connParam: charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&interpolateParams=True
@@ -59,7 +59,7 @@ redis:
# OMC system db
default:
port: 6379 # Redis port
host: "127.0.0.1" # Redis host
host: "192.168.2.223" # Redis host
password: "helloearth"
db: 10 # Redis db_num
# used to specify the default data source for multiple data resourece