Merge branch 'main-v2' into lite
This commit is contained in:
@@ -23,38 +23,84 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
|
||||
// 账号身份操作
|
||||
account := controller.NewAccount
|
||||
accountGroup := router.Group("/auth")
|
||||
{
|
||||
router.POST("/auth/login",
|
||||
accountGroup.POST("/login",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 180,
|
||||
Count: 15,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewAccount.Login,
|
||||
account.Login,
|
||||
)
|
||||
router.POST("/auth/logout",
|
||||
accountGroup.POST("/logout",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 120,
|
||||
Count: 15,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewAccount.Logout,
|
||||
account.Logout,
|
||||
)
|
||||
router.POST("/auth/refresh-token",
|
||||
accountGroup.POST("/refresh-token",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 60,
|
||||
Count: 5,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
controller.NewAccount.RefreshToken,
|
||||
account.RefreshToken,
|
||||
)
|
||||
router.GET("/me",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAccount.Me,
|
||||
account.Me,
|
||||
)
|
||||
router.GET("/router",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAccount.Router,
|
||||
account.Router,
|
||||
)
|
||||
}
|
||||
|
||||
// 登录认证源
|
||||
{
|
||||
accountGroup.GET("/login/source",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 300,
|
||||
Count: 60,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
account.LoginSource,
|
||||
)
|
||||
accountGroup.POST("/login/ldap",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 180,
|
||||
Count: 15,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
account.LDAP,
|
||||
)
|
||||
accountGroup.POST("/login/smtp",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 180,
|
||||
Count: 15,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
account.SMTP,
|
||||
)
|
||||
accountGroup.GET("/login/oauth2/authorize",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 180,
|
||||
Count: 15,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
account.OAuth2CodeURL,
|
||||
)
|
||||
accountGroup.POST("/login/oauth2/token",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 180,
|
||||
Count: 15,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
account.OAuth2Token,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -70,4 +116,62 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 客户端授权管理
|
||||
oauth2Client := controller.NewOauth2Client
|
||||
oauth2ClientGroup := router.Group("/oauth2/client")
|
||||
{
|
||||
oauth2ClientGroup.GET("/list",
|
||||
middleware.AuthorizeUser(map[string][]string{"matchRoles": {"admin"}}),
|
||||
oauth2Client.List,
|
||||
)
|
||||
oauth2ClientGroup.GET("/:clientId",
|
||||
middleware.AuthorizeUser(map[string][]string{"matchRoles": {"admin"}}),
|
||||
oauth2Client.Info,
|
||||
)
|
||||
oauth2ClientGroup.POST("",
|
||||
middleware.AuthorizeUser(map[string][]string{"matchRoles": {"admin"}}),
|
||||
middleware.OperateLog(middleware.OptionNew("log.operate.title.oauth2client", middleware.BUSINESS_TYPE_INSERT)),
|
||||
oauth2Client.Add,
|
||||
)
|
||||
oauth2ClientGroup.PUT("",
|
||||
middleware.AuthorizeUser(map[string][]string{"matchRoles": {"admin"}}),
|
||||
middleware.OperateLog(middleware.OptionNew("log.operate.title.oauth2client", middleware.BUSINESS_TYPE_UPDATE)),
|
||||
oauth2Client.Edit,
|
||||
)
|
||||
oauth2ClientGroup.DELETE("/:id",
|
||||
middleware.AuthorizeUser(map[string][]string{"matchRoles": {"admin"}}),
|
||||
middleware.OperateLog(middleware.OptionNew("log.operate.title.oauth2client", middleware.BUSINESS_TYPE_DELETE)),
|
||||
oauth2Client.Remove,
|
||||
)
|
||||
}
|
||||
|
||||
// 授权认证
|
||||
oauth2 := controller.NewOauth2
|
||||
oauth2Group := router.Group("/oauth2")
|
||||
{
|
||||
oauth2Group.GET("/authorize",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 60,
|
||||
Count: 30,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
oauth2.Authorize,
|
||||
)
|
||||
oauth2Group.POST("/token",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 180,
|
||||
Count: 15,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
oauth2.Token,
|
||||
)
|
||||
oauth2Group.POST("/refresh-token",
|
||||
middleware.RateLimit(middleware.LimitOption{
|
||||
Time: 60,
|
||||
Count: 5,
|
||||
Type: middleware.LIMIT_IP,
|
||||
}),
|
||||
oauth2.RefreshToken,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,13 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/auth/model"
|
||||
"be.ems/src/modules/auth/service"
|
||||
systemModelVO "be.ems/src/modules/system/model/vo"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -33,95 +30,6 @@ type AccountController struct {
|
||||
sysLogLoginService *systemService.SysLogLogin // 系统登录访问
|
||||
}
|
||||
|
||||
// Login 系统登录
|
||||
//
|
||||
// POST /auth/login
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary System Login
|
||||
// @Description System Login
|
||||
// @Router /auth/login [post]
|
||||
func (s AccountController) Login(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.LoginBody
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 校验验证码 根据错误信息,创建系统访问记录
|
||||
if err := s.accountService.ValidateCaptcha(body.Code, body.UUID); err != nil {
|
||||
msg := fmt.Sprintf("%s code %s", err.Error(), body.Code)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, msg,
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
info, err := s.accountService.ByUsername(body.Username, body.Password)
|
||||
if err != nil {
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, err.Error(),
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]any{}
|
||||
|
||||
if !config.IsSystemUser(info.UserId) {
|
||||
// 强制改密码
|
||||
forcePasswdChange, err := s.accountService.PasswordCountOrExpireTime(info.User.LoginCount, info.User.PasswordUpdateTime)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
if forcePasswdChange {
|
||||
data["forcePasswdChange"] = true
|
||||
}
|
||||
}
|
||||
|
||||
deviceFingerprint := reqctx.DeviceFingerprint(c, info.UserId)
|
||||
|
||||
// 生成访问令牌
|
||||
accessToken, expiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "access")
|
||||
if accessToken == "" || expiresIn == 0 {
|
||||
c.JSON(200, resp.ErrMsg("token generation failed"))
|
||||
return
|
||||
}
|
||||
// 生成刷新令牌
|
||||
refreshToken, refreshExpiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "refresh")
|
||||
|
||||
// 记录令牌,创建系统访问记录
|
||||
token.UserInfoCreate(&info, deviceFingerprint, [4]string{ipaddr, location, os, browser})
|
||||
s.accountService.UpdateLoginDateAndIP(info)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_YES, "app.common.loginSuccess",
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
|
||||
data["tokenType"] = constants.HEADER_PREFIX
|
||||
data["accessToken"] = accessToken
|
||||
data["expiresIn"] = expiresIn
|
||||
data["refreshToken"] = refreshToken
|
||||
data["refreshExpiresIn"] = refreshExpiresIn
|
||||
data["userId"] = info.UserId
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// Logout 系统登出
|
||||
//
|
||||
// POST /auth/logout
|
||||
@@ -222,82 +130,10 @@ func (s AccountController) RefreshToken(c *gin.Context) {
|
||||
}))
|
||||
}
|
||||
|
||||
// Me 登录用户信息
|
||||
// LoginSource 登录认证源
|
||||
//
|
||||
// GET /me
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Login User Information
|
||||
// @Description Login User Information
|
||||
// @Router /me [get]
|
||||
func (s AccountController) Me(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
info, err := reqctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 角色权限集合,系统管理员拥有所有权限
|
||||
isSystemUser := config.IsSystemUser(info.UserId)
|
||||
roles, perms := s.accountService.RoleAndMenuPerms(info.UserId, isSystemUser)
|
||||
|
||||
info.User.NickName = i18n.TKey(language, info.User.NickName)
|
||||
info.User.Remark = i18n.TKey(language, info.User.Remark)
|
||||
info.User.Dept.DeptName = i18n.TKey(language, info.User.Dept.DeptName)
|
||||
for ri := range info.User.Roles {
|
||||
info.User.Roles[ri].RoleName = i18n.TKey(language, info.User.Roles[ri].RoleName)
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"user": info.User,
|
||||
"roles": roles,
|
||||
"permissions": perms,
|
||||
}
|
||||
if !isSystemUser {
|
||||
// 强制改密码
|
||||
forcePasswdChange, _ := s.accountService.PasswordCountOrExpireTime(info.User.LoginCount, info.User.PasswordUpdateTime)
|
||||
if forcePasswdChange {
|
||||
data["forcePasswdChange"] = true
|
||||
}
|
||||
}
|
||||
// GET /auth/login/source
|
||||
func (s AccountController) LoginSource(c *gin.Context) {
|
||||
data := s.accountService.LoginSource()
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// Router 登录用户路由信息
|
||||
//
|
||||
// GET /router
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Login User Routing Information
|
||||
// @Description Login User Routing Information
|
||||
// @Router /router [get]
|
||||
func (s AccountController) Router(c *gin.Context) {
|
||||
loginUserId := reqctx.LoginUserToUserID(c)
|
||||
|
||||
// 前端路由,系统管理员拥有所有
|
||||
isSystemUser := config.IsSystemUser(loginUserId)
|
||||
buildMenus := s.accountService.RouteMenus(loginUserId, isSystemUser)
|
||||
// 闭包函数处理多语言
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var converI18n func(language string, arr *[]systemModelVO.Router)
|
||||
converI18n = func(language string, arr *[]systemModelVO.Router) {
|
||||
for i := range *arr {
|
||||
(*arr)[i].Meta.Title = i18n.TKey(language, (*arr)[i].Meta.Title)
|
||||
if len((*arr)[i].Children) > 0 {
|
||||
converI18n(language, &(*arr)[i].Children)
|
||||
}
|
||||
}
|
||||
}
|
||||
converI18n(language, &buildMenus)
|
||||
|
||||
c.JSON(200, resp.OkData(buildMenus))
|
||||
}
|
||||
|
||||
93
src/modules/auth/controller/account_info.go
Normal file
93
src/modules/auth/controller/account_info.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
systemModelVO "be.ems/src/modules/system/model/vo"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Me 登录用户信息
|
||||
//
|
||||
// GET /me
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Login User Information
|
||||
// @Description Login User Information
|
||||
// @Router /me [get]
|
||||
func (s AccountController) Me(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
info, err := reqctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 角色权限集合,系统管理员拥有所有权限
|
||||
isSystemUser := config.IsSystemUser(info.UserId)
|
||||
roles, perms := s.accountService.RoleAndMenuPerms(info.UserId, isSystemUser)
|
||||
|
||||
info.User.NickName = i18n.TKey(language, info.User.NickName)
|
||||
info.User.Remark = i18n.TKey(language, info.User.Remark)
|
||||
if info.User.Dept != nil {
|
||||
info.User.Dept.DeptName = i18n.TKey(language, info.User.Dept.DeptName)
|
||||
}
|
||||
for ri := range info.User.Roles {
|
||||
info.User.Roles[ri].RoleName = i18n.TKey(language, info.User.Roles[ri].RoleName)
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"user": info.User,
|
||||
"roles": roles,
|
||||
"permissions": perms,
|
||||
}
|
||||
if !isSystemUser {
|
||||
// 强制改密码
|
||||
forcePasswdChange, _ := s.accountService.PasswordCountOrExpireTime(info.User.LoginCount, info.User.PasswordUpdateTime)
|
||||
if forcePasswdChange {
|
||||
data["forcePasswdChange"] = true
|
||||
}
|
||||
}
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// Router 登录用户路由信息
|
||||
//
|
||||
// GET /router
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Login User Routing Information
|
||||
// @Description Login User Routing Information
|
||||
// @Router /router [get]
|
||||
func (s AccountController) Router(c *gin.Context) {
|
||||
loginUserId := reqctx.LoginUserToUserID(c)
|
||||
|
||||
// 前端路由,系统管理员拥有所有
|
||||
isSystemUser := config.IsSystemUser(loginUserId)
|
||||
buildMenus := s.accountService.RouteMenus(loginUserId, isSystemUser)
|
||||
// 闭包函数处理多语言
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var converI18n func(language string, arr *[]systemModelVO.Router)
|
||||
converI18n = func(language string, arr *[]systemModelVO.Router) {
|
||||
for i := range *arr {
|
||||
(*arr)[i].Meta.Title = i18n.TKey(language, (*arr)[i].Meta.Title)
|
||||
if len((*arr)[i].Children) > 0 {
|
||||
converI18n(language, &(*arr)[i].Children)
|
||||
}
|
||||
}
|
||||
}
|
||||
converI18n(language, &buildMenus)
|
||||
|
||||
c.JSON(200, resp.OkData(buildMenus))
|
||||
}
|
||||
80
src/modules/auth/controller/account_ldap.go
Normal file
80
src/modules/auth/controller/account_ldap.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/modules/auth/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// LDAP LDAP认证登录
|
||||
//
|
||||
// POST /auth/ldap
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary System Login
|
||||
// @Description System Login
|
||||
// @Router /auth/ldap [post]
|
||||
func (s AccountController) LDAP(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.LoginSourceBody
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 登录用户信息
|
||||
info, err := s.accountService.ByLDAP(body)
|
||||
if err != nil {
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, err.Error(),
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]any{}
|
||||
|
||||
deviceFingerprint := reqctx.DeviceFingerprint(c, info.UserId)
|
||||
|
||||
// 生成访问令牌
|
||||
accessToken, expiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "access")
|
||||
if accessToken == "" || expiresIn == 0 {
|
||||
c.JSON(200, resp.ErrMsg("token generation failed"))
|
||||
return
|
||||
}
|
||||
// 生成刷新令牌
|
||||
refreshToken, refreshExpiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "refresh")
|
||||
|
||||
// 记录令牌,创建系统访问记录
|
||||
token.UserInfoCreate(&info, deviceFingerprint, [4]string{ipaddr, location, os, browser})
|
||||
s.accountService.UpdateLoginDateAndIP(info)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_YES, "app.common.loginSuccess",
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
|
||||
data["tokenType"] = constants.HEADER_PREFIX
|
||||
data["accessToken"] = accessToken
|
||||
data["expiresIn"] = expiresIn
|
||||
data["refreshToken"] = refreshToken
|
||||
data["refreshExpiresIn"] = refreshExpiresIn
|
||||
data["userId"] = info.UserId
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
107
src/modules/auth/controller/account_oauth2.go
Normal file
107
src/modules/auth/controller/account_oauth2.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/modules/auth/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// OAuth2CodeURL OAuth2认证跳转登录URL
|
||||
//
|
||||
// GET /auth/login/oauth2/authorize
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary System Login
|
||||
// @Description System Login
|
||||
// @Router /auth/login/oauth2/authorize [get]
|
||||
func (s AccountController) OAuth2CodeURL(c *gin.Context) {
|
||||
state := c.Query("state")
|
||||
if state == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: state is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
redirectURL, err := s.accountService.ByOAuth2CodeURL(state)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.Redirect(302, redirectURL)
|
||||
}
|
||||
|
||||
// OAuth2 OAuth2认证登录
|
||||
//
|
||||
// POST /auth/login/oauth2/token
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary System Login
|
||||
// @Description System Login
|
||||
// @Router /auth/login/oauth2/token [post]
|
||||
func (s AccountController) OAuth2Token(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.LoginSourceOauth2Body
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 登录用户信息
|
||||
info, err := s.accountService.ByOAuth2(body)
|
||||
if err != nil {
|
||||
s.sysLogLoginService.Insert(
|
||||
body.State, constants.STATUS_NO, err.Error(),
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]any{}
|
||||
|
||||
deviceFingerprint := reqctx.DeviceFingerprint(c, info.UserId)
|
||||
|
||||
// 生成访问令牌
|
||||
accessToken, expiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "access")
|
||||
if accessToken == "" || expiresIn == 0 {
|
||||
c.JSON(200, resp.ErrMsg("token generation failed"))
|
||||
return
|
||||
}
|
||||
// 生成刷新令牌
|
||||
refreshToken, refreshExpiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "refresh")
|
||||
|
||||
// 记录令牌,创建系统访问记录
|
||||
token.UserInfoCreate(&info, deviceFingerprint, [4]string{ipaddr, location, os, browser})
|
||||
s.accountService.UpdateLoginDateAndIP(info)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.State, constants.STATUS_YES, "app.common.loginSuccess",
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
|
||||
data["tokenType"] = constants.HEADER_PREFIX
|
||||
data["accessToken"] = accessToken
|
||||
data["expiresIn"] = expiresIn
|
||||
data["refreshToken"] = refreshToken
|
||||
data["refreshExpiresIn"] = refreshExpiresIn
|
||||
data["userId"] = info.UserId
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
80
src/modules/auth/controller/account_smtp.go
Normal file
80
src/modules/auth/controller/account_smtp.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/modules/auth/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// SMTP SMTP认证登录
|
||||
//
|
||||
// POST /auth/smtp
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary System Login
|
||||
// @Description System Login
|
||||
// @Router /auth/smtp [post]
|
||||
func (s AccountController) SMTP(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.LoginSourceBody
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 登录用户信息
|
||||
info, err := s.accountService.BySMTP(body)
|
||||
if err != nil {
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, err.Error(),
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]any{}
|
||||
|
||||
deviceFingerprint := reqctx.DeviceFingerprint(c, info.UserId)
|
||||
|
||||
// 生成访问令牌
|
||||
accessToken, expiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "access")
|
||||
if accessToken == "" || expiresIn == 0 {
|
||||
c.JSON(200, resp.ErrMsg("token generation failed"))
|
||||
return
|
||||
}
|
||||
// 生成刷新令牌
|
||||
refreshToken, refreshExpiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "refresh")
|
||||
|
||||
// 记录令牌,创建系统访问记录
|
||||
token.UserInfoCreate(&info, deviceFingerprint, [4]string{ipaddr, location, os, browser})
|
||||
s.accountService.UpdateLoginDateAndIP(info)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_YES, "app.common.loginSuccess",
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
|
||||
data["tokenType"] = constants.HEADER_PREFIX
|
||||
data["accessToken"] = accessToken
|
||||
data["expiresIn"] = expiresIn
|
||||
data["refreshToken"] = refreshToken
|
||||
data["refreshExpiresIn"] = refreshExpiresIn
|
||||
data["userId"] = info.UserId
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
104
src/modules/auth/controller/account_system.go
Normal file
104
src/modules/auth/controller/account_system.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/modules/auth/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Login 系统登录
|
||||
//
|
||||
// POST /auth/login
|
||||
//
|
||||
// @Tags common/authorization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body object true "Request Param"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Summary System Login
|
||||
// @Description System Login
|
||||
// @Router /auth/login [post]
|
||||
func (s AccountController) Login(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var body model.LoginBody
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 当前请求信息
|
||||
ipaddr, location := reqctx.IPAddrLocation(c)
|
||||
os, browser := reqctx.UaOsBrowser(c)
|
||||
|
||||
// 校验验证码 根据错误信息,创建系统访问记录
|
||||
if err := s.accountService.ValidateCaptcha(body.Code, body.UUID); err != nil {
|
||||
msg := fmt.Sprintf("%s code %s", err.Error(), body.Code)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, msg,
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
info, err := s.accountService.ByUsername(body.Username, body.Password)
|
||||
if err != nil {
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_NO, err.Error(),
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
|
||||
data := map[string]any{}
|
||||
|
||||
if !config.IsSystemUser(info.UserId) {
|
||||
// 强制改密码
|
||||
forcePasswdChange, err := s.accountService.PasswordCountOrExpireTime(info.User.LoginCount, info.User.PasswordUpdateTime)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
if forcePasswdChange {
|
||||
data["forcePasswdChange"] = true
|
||||
}
|
||||
}
|
||||
|
||||
deviceFingerprint := reqctx.DeviceFingerprint(c, info.UserId)
|
||||
|
||||
// 生成访问令牌
|
||||
accessToken, expiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "access")
|
||||
if accessToken == "" || expiresIn == 0 {
|
||||
c.JSON(200, resp.ErrMsg("token generation failed"))
|
||||
return
|
||||
}
|
||||
// 生成刷新令牌
|
||||
refreshToken, refreshExpiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "refresh")
|
||||
|
||||
// 记录令牌,创建系统访问记录
|
||||
token.UserInfoCreate(&info, deviceFingerprint, [4]string{ipaddr, location, os, browser})
|
||||
s.accountService.UpdateLoginDateAndIP(info)
|
||||
s.sysLogLoginService.Insert(
|
||||
body.Username, constants.STATUS_YES, "app.common.loginSuccess",
|
||||
[4]string{ipaddr, location, os, browser},
|
||||
)
|
||||
|
||||
data["tokenType"] = constants.HEADER_PREFIX
|
||||
data["accessToken"] = accessToken
|
||||
data["expiresIn"] = expiresIn
|
||||
data["refreshToken"] = refreshToken
|
||||
data["refreshExpiresIn"] = refreshExpiresIn
|
||||
data["userId"] = info.UserId
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/service"
|
||||
"be.ems/src/modules/auth/model"
|
||||
"be.ems/src/modules/auth/service"
|
||||
)
|
||||
|
||||
// NewOauth2 实例化控制层
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/service"
|
||||
"be.ems/src/modules/auth/model"
|
||||
"be.ems/src/modules/auth/service"
|
||||
)
|
||||
|
||||
// NewOauth2Client 实例化控制层
|
||||
@@ -2,15 +2,8 @@ package model
|
||||
|
||||
// LoginBody 用户登录对象
|
||||
type LoginBody struct {
|
||||
// Username 用户名
|
||||
Username string `json:"username" binding:"required"`
|
||||
|
||||
// Password 用户密码
|
||||
Password string `json:"password" binding:"required"`
|
||||
|
||||
// Code 验证码
|
||||
Code string `json:"code"`
|
||||
|
||||
// UUID 验证码唯一标识
|
||||
UUID string `json:"uuid"`
|
||||
Username string `json:"username" binding:"required"` // Username 用户名
|
||||
Password string `json:"password" binding:"required"` // Password 用户密码
|
||||
Code string `json:"code"` // Code 验证码
|
||||
UUID string `json:"uuid"` // UUID 验证码唯一标识
|
||||
}
|
||||
|
||||
22
src/modules/auth/model/login_source_body.go
Normal file
22
src/modules/auth/model/login_source_body.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package model
|
||||
|
||||
// LoginSourceVo 认证源登录对象
|
||||
type LoginSourceVo struct {
|
||||
UID string `json:"uid"` // UID 认证源UID
|
||||
Name string `json:"name"` // Name 认证源名称
|
||||
Type string `json:"type"` // Type 认证源类型
|
||||
Icon string `json:"icon"` // Icon 认证源图标
|
||||
}
|
||||
|
||||
// LoginSourceBody 认证源用户登录对象
|
||||
type LoginSourceBody struct {
|
||||
Username string `json:"username" binding:"required"` // Username 用户名
|
||||
Password string `json:"password" binding:"required"` // Password 用户密码
|
||||
UID string `json:"uid" binding:"required"` // UID 认证源唯一标识
|
||||
}
|
||||
|
||||
// LoginSourceOauth2Body 认证源OAuth2用户登录对象
|
||||
type LoginSourceOauth2Body struct {
|
||||
Code string `json:"code" binding:"required"` // Code 授权码
|
||||
State string `json:"state" binding:"required"` // State 状态-认证源唯一标识
|
||||
}
|
||||
@@ -8,3 +8,10 @@ type TokenBody struct {
|
||||
Code string `json:"code"` // 授权拿到的code值
|
||||
RefreshToken string `json:"refreshToken"` // 刷新令牌
|
||||
}
|
||||
|
||||
// CodeQuery 重定向授权码参数
|
||||
type CodeQuery struct {
|
||||
RedirectUrl string `form:"redirectUrl" binding:"required"` // 授权回调地址
|
||||
ClientId string `form:"clientId" binding:"required"` // 申请得到的客户端ID
|
||||
State string `form:"state" binding:"required"` // 随机字符串,认证服务器会原封不动地返回这个值
|
||||
}
|
||||
@@ -2,21 +2,10 @@ package model
|
||||
|
||||
// RegisterBody 用户注册对象
|
||||
type RegisterBody struct {
|
||||
// Username 用户名
|
||||
Username string `json:"username" binding:"required"`
|
||||
|
||||
// Password 用户密码
|
||||
Password string `json:"password" binding:"required"`
|
||||
|
||||
// ConfirmPassword 用户确认密码
|
||||
ConfirmPassword string `json:"confirmPassword" binding:"required"`
|
||||
|
||||
// Code 验证码
|
||||
Code string `json:"code"`
|
||||
|
||||
// UUID 验证码唯一标识
|
||||
UUID string `json:"uuid"`
|
||||
|
||||
// UserType 标记用户类型
|
||||
UserType string `json:"userType"`
|
||||
Username string `json:"username" binding:"required"` // Username 用户名
|
||||
Password string `json:"password" binding:"required"` // Password 用户密码
|
||||
ConfirmPassword string `json:"confirmPassword" binding:"required"` // ConfirmPassword 用户确认密码
|
||||
Code string `json:"code"` // Code 验证码
|
||||
UUID string `json:"uuid"` // UUID 验证码唯一标识
|
||||
UserType string `json:"userType"` // UserType 标记用户类型
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/auth/model"
|
||||
)
|
||||
|
||||
// NewOauth2Client 实例化数据层
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/auth/model"
|
||||
)
|
||||
|
||||
// NewOauth2LogLogin 实例化数据层
|
||||
@@ -69,9 +69,10 @@ func (r Oauth2LogLoginRepository) SelectByPage(query map[string]string) ([]model
|
||||
sortOrder := sortOrderArr[i]
|
||||
// 排序字段
|
||||
sort := "id"
|
||||
if sortBy == "loginIp" {
|
||||
switch sortBy {
|
||||
case "loginIp":
|
||||
sort = "login_ip"
|
||||
} else if sortBy == "createTime" {
|
||||
case "createTime":
|
||||
sort = "create_time"
|
||||
}
|
||||
// 排序方式
|
||||
@@ -2,102 +2,32 @@ package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
systemModelVO "be.ems/src/modules/system/model/vo"
|
||||
"be.ems/src/modules/auth/model"
|
||||
systemModel "be.ems/src/modules/system/model"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化服务层 Account 结构体
|
||||
var NewAccount = &Account{
|
||||
sysUserService: systemService.NewSysUser,
|
||||
sysConfigService: systemService.NewSysConfig,
|
||||
sysRoleService: systemService.NewSysRole,
|
||||
sysMenuService: systemService.NewSysMenu,
|
||||
sysUserService: systemService.NewSysUser,
|
||||
sysConfigService: systemService.NewSysConfig,
|
||||
sysRoleService: systemService.NewSysRole,
|
||||
sysMenuService: systemService.NewSysMenu,
|
||||
sysLogSourceService: systemService.NewSysLoginSource,
|
||||
}
|
||||
|
||||
// 账号身份操作服务 服务层处理
|
||||
type Account struct {
|
||||
sysUserService *systemService.SysUser // 用户信息服务
|
||||
sysConfigService *systemService.SysConfig // 参数配置服务
|
||||
sysRoleService *systemService.SysRole // 角色服务
|
||||
sysMenuService *systemService.SysMenu // 菜单服务
|
||||
}
|
||||
|
||||
// ValidateCaptcha 校验验证码
|
||||
func (s *Account) ValidateCaptcha(code, uuid string) error {
|
||||
// 验证码检查,从数据库配置获取验证码开关 true开启,false关闭
|
||||
captchaEnabledStr := s.sysConfigService.FindValueByKey("sys.account.captchaEnabled")
|
||||
if !parse.Boolean(captchaEnabledStr) {
|
||||
return nil
|
||||
}
|
||||
if code == "" || uuid == "" {
|
||||
// 验证码信息错误
|
||||
return fmt.Errorf("captcha.err")
|
||||
}
|
||||
verifyKey := constants.CACHE_CAPTCHA_CODE + ":" + uuid
|
||||
captcha, _ := redis.Get("", verifyKey)
|
||||
if captcha == "" {
|
||||
// 验证码已失效
|
||||
return fmt.Errorf("captcha.errValid")
|
||||
}
|
||||
_ = redis.Del("", verifyKey)
|
||||
if captcha != code {
|
||||
// 验证码错误
|
||||
return fmt.Errorf("captcha.err")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByUsername 登录创建用户信息
|
||||
func (s Account) ByUsername(username, password string) (token.UserInfo, error) {
|
||||
info := token.UserInfo{}
|
||||
|
||||
// 检查密码重试次数
|
||||
retryKey, retryCount, lockTime, err := s.passwordRetryCount(username)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.FindByUserName(username)
|
||||
if sysUser.UserName != username {
|
||||
return info, fmt.Errorf("login.errNameOrPasswd")
|
||||
}
|
||||
if sysUser.DelFlag == constants.STATUS_YES {
|
||||
return info, fmt.Errorf("login.errDelFlag")
|
||||
}
|
||||
if sysUser.StatusFlag == constants.STATUS_NO {
|
||||
return info, fmt.Errorf("login.errStatus")
|
||||
}
|
||||
|
||||
// 检验用户密码
|
||||
compareBool := crypto.BcryptCompare(password, sysUser.Password)
|
||||
if compareBool {
|
||||
s.CleanLoginRecordCache(sysUser.UserName) // 清除错误记录次数
|
||||
} else {
|
||||
_ = redis.Set("", retryKey, retryCount+1, lockTime)
|
||||
return info, fmt.Errorf("login.errNameOrPasswd")
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
info.UserId = sysUser.UserId
|
||||
info.DeptId = sysUser.DeptId
|
||||
info.User = sysUser
|
||||
// 用户权限组标识
|
||||
if config.IsSystemUser(sysUser.UserId) {
|
||||
info.Permissions = []string{constants.SYS_PERMISSION_SYSTEM}
|
||||
} else {
|
||||
perms := s.sysMenuService.FindPermsByUserId(sysUser.UserId)
|
||||
info.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
return info, nil
|
||||
sysUserService *systemService.SysUser // 用户信息服务
|
||||
sysConfigService *systemService.SysConfig // 参数配置服务
|
||||
sysRoleService *systemService.SysRole // 角色服务
|
||||
sysMenuService *systemService.SysMenu // 菜单服务
|
||||
sysLogSourceService *systemService.SysLoginSource // 认证源
|
||||
}
|
||||
|
||||
// ByUserId 用户ID刷新令牌创建用户信息
|
||||
@@ -140,86 +70,43 @@ func (s Account) UpdateLoginDateAndIP(info token.UserInfo) bool {
|
||||
return s.sysUserService.Update(user) > 0
|
||||
}
|
||||
|
||||
// CleanLoginRecordCache 清除错误记录次数
|
||||
func (s Account) CleanLoginRecordCache(userName string) bool {
|
||||
cacheKey := fmt.Sprintf("%s:%s", constants.CACHE_PWD_ERR_COUNT, userName)
|
||||
hasKey, err := redis.Has("", cacheKey)
|
||||
if hasKey > 0 && err == nil {
|
||||
return redis.Del("", cacheKey) == nil
|
||||
// LoginSource 登录认证源
|
||||
func (s Account) LoginSource() []model.LoginSourceVo {
|
||||
rows := s.sysLogSourceService.FindByActive("")
|
||||
data := make([]model.LoginSourceVo, 0)
|
||||
for _, v := range rows {
|
||||
data = append(data, model.LoginSourceVo{
|
||||
UID: v.UID,
|
||||
Name: v.Name,
|
||||
Type: v.Type,
|
||||
Icon: v.Icon,
|
||||
})
|
||||
}
|
||||
return false
|
||||
return data
|
||||
}
|
||||
|
||||
// passwordRetryCount 密码重试次数
|
||||
func (s Account) passwordRetryCount(userName string) (string, int64, time.Duration, error) {
|
||||
// 从数据库配置获取登录次数和错误锁定时间
|
||||
maxRetryCountStr := s.sysConfigService.FindValueByKey("sys.user.maxRetryCount")
|
||||
lockTimeStr := s.sysConfigService.FindValueByKey("sys.user.lockTime")
|
||||
// 验证登录次数和错误锁定时间
|
||||
maxRetryCount := parse.Number(maxRetryCountStr)
|
||||
lockTime := parse.Number(lockTimeStr)
|
||||
// initLoginSourceUser 初始化登录源用户
|
||||
func (s *Account) initLoginSourceUser(uid, sType, username, password string) systemModel.SysUser {
|
||||
sysUser := systemModel.SysUser{
|
||||
UserName: username,
|
||||
NickName: username, // 昵称使用名称账号
|
||||
Password: password, // 原始密码
|
||||
UserType: sType,
|
||||
UserSource: uid,
|
||||
Sex: "0", // 性别未选择
|
||||
StatusFlag: constants.STATUS_YES, // 账号状态激活
|
||||
DeptId: 101, // 归属部门为根节点
|
||||
CreateBy: sType, // 创建来源
|
||||
}
|
||||
|
||||
// 验证缓存记录次数
|
||||
retryKey := fmt.Sprintf("%s:%s", constants.CACHE_PWD_ERR_COUNT, userName)
|
||||
retryCount, err := redis.Get("", retryKey)
|
||||
if retryCount == "" || err != nil {
|
||||
retryCount = "0"
|
||||
// 新增用户的角色管理
|
||||
sysUser.RoleIds = []int64{5}
|
||||
// 新增用户的岗位管理
|
||||
sysUser.PostIds = []int64{}
|
||||
|
||||
insertId := s.sysUserService.Insert(sysUser)
|
||||
if insertId > 0 {
|
||||
sysUser.UserId = insertId
|
||||
}
|
||||
// 是否超过错误值
|
||||
retryCountInt64 := parse.Number(retryCount)
|
||||
if retryCountInt64 >= int64(maxRetryCount) {
|
||||
// msg := fmt.Sprintf("密码输入错误 %d 次,帐户锁定 %d 分钟", maxRetryCount, lockTime)
|
||||
msg := fmt.Errorf("login.errRetryPasswd") // 密码输入错误多次,帐户已被锁定
|
||||
return retryKey, retryCountInt64, time.Duration(lockTime) * time.Minute, fmt.Errorf("%s", msg)
|
||||
}
|
||||
return retryKey, retryCountInt64, time.Duration(lockTime) * time.Minute, nil
|
||||
}
|
||||
|
||||
// PasswordCountOrExpireTime 首次登录或密码过期时间
|
||||
func (s Account) PasswordCountOrExpireTime(loginCount, passwordUpdateTime int64) (bool, error) {
|
||||
forcePasswdChange := false
|
||||
// 从数据库配置获取-首次登录密码修改
|
||||
fristPasswdChangeStr := s.sysConfigService.FindValueByKey("sys.user.fristPasswdChange")
|
||||
if parse.Boolean(fristPasswdChangeStr) {
|
||||
forcePasswdChange = loginCount < 1 || passwordUpdateTime == 0
|
||||
}
|
||||
|
||||
// 非首次登录,判断密码是否过期
|
||||
if !forcePasswdChange {
|
||||
alert, err := s.sysUserService.ValidatePasswordExpireTime(passwordUpdateTime)
|
||||
if err != nil {
|
||||
return alert, err
|
||||
}
|
||||
forcePasswdChange = alert
|
||||
}
|
||||
return forcePasswdChange, nil
|
||||
}
|
||||
|
||||
// RoleAndMenuPerms 角色和菜单数据权限
|
||||
func (s Account) RoleAndMenuPerms(userId int64, isSystemUser bool) ([]string, []string) {
|
||||
if isSystemUser {
|
||||
return []string{constants.SYS_ROLE_SYSTEM_KEY}, []string{constants.SYS_PERMISSION_SYSTEM}
|
||||
}
|
||||
// 角色key
|
||||
var roleGroup []string
|
||||
roles := s.sysRoleService.FindByUserId(userId)
|
||||
for _, role := range roles {
|
||||
roleGroup = append(roleGroup, role.RoleKey)
|
||||
}
|
||||
// 菜单权限key
|
||||
perms := s.sysMenuService.FindPermsByUserId(userId)
|
||||
return parse.RemoveDuplicates(roleGroup), parse.RemoveDuplicates(perms)
|
||||
}
|
||||
|
||||
// RouteMenus 前端路由所需要的菜单
|
||||
func (s Account) RouteMenus(userId int64, isSystemUser bool) []systemModelVO.Router {
|
||||
var buildMenus []systemModelVO.Router
|
||||
if isSystemUser {
|
||||
menus := s.sysMenuService.BuildTreeMenusByUserId(0)
|
||||
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
|
||||
} else {
|
||||
menus := s.sysMenuService.BuildTreeMenusByUserId(userId)
|
||||
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
|
||||
}
|
||||
return buildMenus
|
||||
return s.sysUserService.FindByUserName(username, sType, uid)
|
||||
}
|
||||
|
||||
36
src/modules/auth/service/account_info.go
Normal file
36
src/modules/auth/service/account_info.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
systemModelVO "be.ems/src/modules/system/model/vo"
|
||||
)
|
||||
|
||||
// RoleAndMenuPerms 角色和菜单数据权限
|
||||
func (s Account) RoleAndMenuPerms(userId int64, isSystemUser bool) ([]string, []string) {
|
||||
if isSystemUser {
|
||||
return []string{constants.SYS_ROLE_SYSTEM_KEY}, []string{constants.SYS_PERMISSION_SYSTEM}
|
||||
}
|
||||
// 角色key
|
||||
var roleGroup []string
|
||||
roles := s.sysRoleService.FindByUserId(userId)
|
||||
for _, role := range roles {
|
||||
roleGroup = append(roleGroup, role.RoleKey)
|
||||
}
|
||||
// 菜单权限key
|
||||
perms := s.sysMenuService.FindPermsByUserId(userId)
|
||||
return parse.RemoveDuplicates(roleGroup), parse.RemoveDuplicates(perms)
|
||||
}
|
||||
|
||||
// RouteMenus 前端路由所需要的菜单
|
||||
func (s Account) RouteMenus(userId int64, isSystemUser bool) []systemModelVO.Router {
|
||||
var buildMenus []systemModelVO.Router
|
||||
if isSystemUser {
|
||||
menus := s.sysMenuService.BuildTreeMenusByUserId(0)
|
||||
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
|
||||
} else {
|
||||
menus := s.sysMenuService.BuildTreeMenusByUserId(userId)
|
||||
buildMenus = s.sysMenuService.BuildRouteMenus(menus, "")
|
||||
}
|
||||
return buildMenus
|
||||
}
|
||||
108
src/modules/auth/service/account_ldap.go
Normal file
108
src/modules/auth/service/account_ldap.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/auth/model"
|
||||
systemModelVo "be.ems/src/modules/system/model/vo"
|
||||
)
|
||||
|
||||
// ByLDAP 登录创建用户信息
|
||||
func (s *Account) ByLDAP(body model.LoginSourceBody) (token.UserInfo, error) {
|
||||
info := token.UserInfo{}
|
||||
rows := s.sysLogSourceService.FindByActive(body.UID)
|
||||
if len(rows) != 1 {
|
||||
return info, fmt.Errorf("ldap auth source not exist")
|
||||
}
|
||||
item := rows[0]
|
||||
if item.Config == "" {
|
||||
return info, fmt.Errorf("ldap auth source config is empty")
|
||||
}
|
||||
var source systemModelVo.SysLoginSourceLDAP
|
||||
if err := json.Unmarshal([]byte(item.Config), &source); err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 校验LDAP用户
|
||||
err := ldapAuth(source, body.Username, body.Password)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.FindByUserName(body.Username, item.Type, item.UID)
|
||||
if sysUser.UserId == 0 || sysUser.UserName == "" {
|
||||
sysUser = s.initLoginSourceUser(item.UID, item.Type, body.Username, body.Password)
|
||||
}
|
||||
if sysUser.UserId == 0 || sysUser.UserName != body.Username {
|
||||
return info, fmt.Errorf("login.errNameOrPasswd")
|
||||
}
|
||||
if sysUser.DelFlag == constants.STATUS_YES {
|
||||
return info, fmt.Errorf("login.errDelFlag")
|
||||
}
|
||||
if sysUser.StatusFlag == constants.STATUS_NO {
|
||||
return info, fmt.Errorf("login.errStatus")
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
info.UserId = sysUser.UserId
|
||||
info.DeptId = sysUser.DeptId
|
||||
info.User = sysUser
|
||||
// 用户权限组标识
|
||||
if config.IsSystemUser(sysUser.UserId) {
|
||||
info.Permissions = []string{constants.SYS_PERMISSION_SYSTEM}
|
||||
} else {
|
||||
perms := s.sysMenuService.FindPermsByUserId(sysUser.UserId)
|
||||
info.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// ldapAuth 校验LDAP用户
|
||||
func ldapAuth(source systemModelVo.SysLoginSourceLDAP, username, password string) error {
|
||||
// 连接LDAP
|
||||
l, err := ldap.DialURL(source.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
// 绑定DN校验
|
||||
if source.BindDN != "" && source.BindPassword != "" {
|
||||
if err := l.Bind(source.BindDN, source.BindPassword); err != nil {
|
||||
return fmt.Errorf("ldap user bind %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索用户
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
source.BaseDN,
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf(source.UserFilter, ldap.EscapeFilter(username)),
|
||||
[]string{"dn", "uid"},
|
||||
nil,
|
||||
)
|
||||
sr, err := l.Search(searchRequest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ldap user search %s", err)
|
||||
}
|
||||
// for _, entry := range sr.Entries {
|
||||
// fmt.Printf("%s ==== %v\n", entry.DN, entry.GetAttributeValue("uid"))
|
||||
// }
|
||||
if len(sr.Entries) != 1 {
|
||||
return fmt.Errorf("ldap user does not exist or too many entries returned")
|
||||
}
|
||||
|
||||
// 校验密码
|
||||
if err = l.Bind(sr.Entries[0].DN, password); err != nil {
|
||||
return fmt.Errorf("ldap user bind %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
168
src/modules/auth/service/account_oauth2.go
Normal file
168
src/modules/auth/service/account_oauth2.go
Normal file
@@ -0,0 +1,168 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/auth/model"
|
||||
systemModelVo "be.ems/src/modules/system/model/vo"
|
||||
)
|
||||
|
||||
// ByOAuth2CodeURL 获取OAuth2登录URL
|
||||
func (s *Account) ByOAuth2CodeURL(state string) (string, error) {
|
||||
rows := s.sysLogSourceService.FindByActive(state)
|
||||
if len(rows) != 1 {
|
||||
return "", fmt.Errorf("oauth2 auth source not exist")
|
||||
}
|
||||
item := rows[0]
|
||||
if item.Config == "" {
|
||||
return "", fmt.Errorf("oauth2 auth source config is empty")
|
||||
}
|
||||
var source systemModelVo.SysLoginSourceOAuth2
|
||||
json.Unmarshal([]byte(item.Config), &source)
|
||||
|
||||
conf := oauth2.Config{
|
||||
ClientID: source.ClientID,
|
||||
ClientSecret: source.ClientSecret,
|
||||
RedirectURL: source.RedirectURL,
|
||||
Scopes: source.Scopes,
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: source.AuthURL,
|
||||
TokenURL: source.TokenURL,
|
||||
},
|
||||
}
|
||||
return conf.AuthCodeURL(state, oauth2.AccessTypeOffline), nil
|
||||
}
|
||||
|
||||
// ByOAuth2 登录创建用户信息
|
||||
func (s *Account) ByOAuth2(body model.LoginSourceOauth2Body) (token.UserInfo, error) {
|
||||
info := token.UserInfo{}
|
||||
rows := s.sysLogSourceService.FindByActive(body.State)
|
||||
if len(rows) != 1 {
|
||||
return info, fmt.Errorf("oauth2 auth source not exist")
|
||||
}
|
||||
item := rows[0]
|
||||
if item.Config == "" {
|
||||
return info, fmt.Errorf("oauth2 auth source config is empty")
|
||||
}
|
||||
var source systemModelVo.SysLoginSourceOAuth2
|
||||
if err := json.Unmarshal([]byte(item.Config), &source); err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 校验OAuth2用户
|
||||
account, err := oauth2Auth(source, body.Code)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.FindByUserName(account, item.Type, item.UID)
|
||||
if sysUser.UserId == 0 || sysUser.UserName == "" {
|
||||
sysUser = s.initLoginSourceUser(item.UID, item.Type, account, account)
|
||||
}
|
||||
if sysUser.UserId == 0 || sysUser.UserName != account {
|
||||
return info, fmt.Errorf("login.errNameOrPasswd")
|
||||
}
|
||||
if sysUser.DelFlag == constants.STATUS_YES {
|
||||
return info, fmt.Errorf("login.errDelFlag")
|
||||
}
|
||||
if sysUser.StatusFlag == constants.STATUS_NO {
|
||||
return info, fmt.Errorf("login.errStatus")
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
info.UserId = sysUser.UserId
|
||||
info.DeptId = sysUser.DeptId
|
||||
info.User = sysUser
|
||||
// 用户权限组标识
|
||||
if config.IsSystemUser(sysUser.UserId) {
|
||||
info.Permissions = []string{constants.SYS_PERMISSION_SYSTEM}
|
||||
} else {
|
||||
perms := s.sysMenuService.FindPermsByUserId(sysUser.UserId)
|
||||
info.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// oauth2Auth 校验OAuth2用户
|
||||
func oauth2Auth(source systemModelVo.SysLoginSourceOAuth2, code string) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
conf := oauth2.Config{
|
||||
ClientID: source.ClientID,
|
||||
ClientSecret: source.ClientSecret,
|
||||
RedirectURL: source.RedirectURL,
|
||||
Scopes: source.Scopes,
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: source.AuthURL,
|
||||
TokenURL: source.TokenURL,
|
||||
},
|
||||
}
|
||||
token, err := conf.Exchange(ctx, code)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// 使用token创建HTTP客户端 请求用户信息
|
||||
resp, err := conf.Client(ctx, token).Get(source.UserURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
// 解析用户信息
|
||||
var userInfo map[string]any
|
||||
if err := json.NewDecoder(resp.Body).Decode(&userInfo); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 读取嵌套数据
|
||||
value, found := getValueByPath(userInfo, source.AccountField)
|
||||
if !found {
|
||||
return "", fmt.Errorf("oauth2 auth source account field not exist")
|
||||
}
|
||||
return fmt.Sprintf("%v", value), nil
|
||||
}
|
||||
|
||||
// getValueByPath 从嵌套的 map[string]any 获取嵌套键对应的值
|
||||
func getValueByPath(data map[string]any, path string) (any, bool) {
|
||||
keys := strings.Split(path, ".") // 按照 "." 拆分路径
|
||||
return getValue(data, keys)
|
||||
}
|
||||
|
||||
// getValue 是递归查找嵌套 map 的函数
|
||||
func getValue(data map[string]any, keys []string) (any, bool) {
|
||||
if len(keys) == 0 {
|
||||
return data, false
|
||||
}
|
||||
|
||||
// 获取当前键
|
||||
key := keys[0]
|
||||
|
||||
// 获取当前键的值
|
||||
val, ok := data[key]
|
||||
if !ok {
|
||||
return nil, false // 找不到键,返回 false
|
||||
}
|
||||
|
||||
// 如果还有嵌套键,继续查找
|
||||
if len(keys) > 1 {
|
||||
// 递归查找嵌套 map
|
||||
if reflect.TypeOf(val).Kind() == reflect.Map {
|
||||
// 将 `any` 转换为 `map[string]any` 类型
|
||||
if nestedMap, ok := val.(map[string]any); ok {
|
||||
return getValue(nestedMap, keys[1:])
|
||||
}
|
||||
}
|
||||
}
|
||||
return val, true
|
||||
}
|
||||
88
src/modules/auth/service/account_smtp.go
Normal file
88
src/modules/auth/service/account_smtp.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/wneessen/go-mail"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/auth/model"
|
||||
systemModelVo "be.ems/src/modules/system/model/vo"
|
||||
)
|
||||
|
||||
// BySMTP 登录创建用户信息
|
||||
func (s *Account) BySMTP(body model.LoginSourceBody) (token.UserInfo, error) {
|
||||
info := token.UserInfo{}
|
||||
rows := s.sysLogSourceService.FindByActive(body.UID)
|
||||
if len(rows) != 1 {
|
||||
return info, fmt.Errorf("smtp auth source not exist")
|
||||
}
|
||||
item := rows[0]
|
||||
if item.Config == "" {
|
||||
return info, fmt.Errorf("smtp auth source config is empty")
|
||||
}
|
||||
var source systemModelVo.SysLoginSourceSMTP
|
||||
if err := json.Unmarshal([]byte(item.Config), &source); err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 校验SMTP用户
|
||||
err := smtpAuth(source, body.Username, body.Password)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.FindByUserName(body.Username, item.Type, item.UID)
|
||||
if sysUser.UserId == 0 || sysUser.UserName == "" {
|
||||
sysUser = s.initLoginSourceUser(item.UID, item.Type, body.Username, body.Password)
|
||||
}
|
||||
if sysUser.UserId == 0 || sysUser.UserName != body.Username {
|
||||
return info, fmt.Errorf("login.errNameOrPasswd")
|
||||
}
|
||||
if sysUser.DelFlag == constants.STATUS_YES {
|
||||
return info, fmt.Errorf("login.errDelFlag")
|
||||
}
|
||||
if sysUser.StatusFlag == constants.STATUS_NO {
|
||||
return info, fmt.Errorf("login.errStatus")
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
info.UserId = sysUser.UserId
|
||||
info.DeptId = sysUser.DeptId
|
||||
info.User = sysUser
|
||||
// 用户权限组标识
|
||||
if config.IsSystemUser(sysUser.UserId) {
|
||||
info.Permissions = []string{constants.SYS_PERMISSION_SYSTEM}
|
||||
} else {
|
||||
perms := s.sysMenuService.FindPermsByUserId(sysUser.UserId)
|
||||
info.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// smtpAuth 校验SMTP用户
|
||||
func smtpAuth(source systemModelVo.SysLoginSourceSMTP, username, password string) error {
|
||||
client, err := mail.NewClient(source.Host,
|
||||
mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover),
|
||||
mail.WithUsername(username),
|
||||
mail.WithPort(source.Port),
|
||||
mail.WithPassword(password),
|
||||
mail.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create mail client %s", err)
|
||||
}
|
||||
// 连接到邮件SMTP服务器
|
||||
if err = client.DialWithContext(context.Background()); err != nil {
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
return nil
|
||||
}
|
||||
138
src/modules/auth/service/account_sysstem.go
Normal file
138
src/modules/auth/service/account_sysstem.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/config"
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
)
|
||||
|
||||
// ValidateCaptcha 校验验证码
|
||||
func (s Account) ValidateCaptcha(code, uuid string) error {
|
||||
// 验证码检查,从数据库配置获取验证码开关 true开启,false关闭
|
||||
captchaEnabledStr := s.sysConfigService.FindValueByKey("sys.account.captchaEnabled")
|
||||
if !parse.Boolean(captchaEnabledStr) {
|
||||
return nil
|
||||
}
|
||||
if code == "" || uuid == "" {
|
||||
// 验证码信息错误
|
||||
return fmt.Errorf("captcha.err")
|
||||
}
|
||||
verifyKey := constants.CACHE_CAPTCHA_CODE + ":" + uuid
|
||||
captcha, _ := redis.Get("", verifyKey)
|
||||
if captcha == "" {
|
||||
// 验证码已失效
|
||||
return fmt.Errorf("captcha.errValid")
|
||||
}
|
||||
_ = redis.Del("", verifyKey)
|
||||
if captcha != code {
|
||||
// 验证码错误
|
||||
return fmt.Errorf("captcha.err")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByUsername 登录创建用户信息
|
||||
func (s Account) ByUsername(username, password string) (token.UserInfo, error) {
|
||||
info := token.UserInfo{}
|
||||
|
||||
// 检查密码重试次数
|
||||
retryKey, retryCount, lockTime, err := s.passwordRetryCount(username)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
||||
// 查询用户登录账号
|
||||
sysUser := s.sysUserService.FindByUserName(username, "System", "#")
|
||||
if sysUser.UserName != username {
|
||||
return info, fmt.Errorf("login.errNameOrPasswd")
|
||||
}
|
||||
if sysUser.DelFlag == constants.STATUS_YES {
|
||||
return info, fmt.Errorf("login.errDelFlag")
|
||||
}
|
||||
if sysUser.StatusFlag == constants.STATUS_NO {
|
||||
return info, fmt.Errorf("login.errStatus")
|
||||
}
|
||||
|
||||
// 检验用户密码
|
||||
compareBool := crypto.BcryptCompare(password, sysUser.Password)
|
||||
if compareBool {
|
||||
s.CleanLoginRecordCache(sysUser.UserName) // 清除错误记录次数
|
||||
} else {
|
||||
_ = redis.Set("", retryKey, retryCount+1, lockTime)
|
||||
return info, fmt.Errorf("login.errNameOrPasswd")
|
||||
}
|
||||
|
||||
// 登录用户信息
|
||||
info.UserId = sysUser.UserId
|
||||
info.DeptId = sysUser.DeptId
|
||||
info.User = sysUser
|
||||
// 用户权限组标识
|
||||
if config.IsSystemUser(sysUser.UserId) {
|
||||
info.Permissions = []string{constants.SYS_PERMISSION_SYSTEM}
|
||||
} else {
|
||||
perms := s.sysMenuService.FindPermsByUserId(sysUser.UserId)
|
||||
info.Permissions = parse.RemoveDuplicates(perms)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// CleanLoginRecordCache 清除错误记录次数
|
||||
func (s Account) CleanLoginRecordCache(userName string) bool {
|
||||
cacheKey := fmt.Sprintf("%s:%s", constants.CACHE_PWD_ERR_COUNT, userName)
|
||||
hasKey, err := redis.Has("", cacheKey)
|
||||
if hasKey > 0 && err == nil {
|
||||
return redis.Del("", cacheKey) == nil
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// passwordRetryCount 密码重试次数
|
||||
func (s Account) passwordRetryCount(userName string) (string, int64, time.Duration, error) {
|
||||
// 从数据库配置获取登录次数和错误锁定时间
|
||||
maxRetryCountStr := s.sysConfigService.FindValueByKey("sys.user.maxRetryCount")
|
||||
lockTimeStr := s.sysConfigService.FindValueByKey("sys.user.lockTime")
|
||||
// 验证登录次数和错误锁定时间
|
||||
maxRetryCount := parse.Number(maxRetryCountStr)
|
||||
lockTime := parse.Number(lockTimeStr)
|
||||
|
||||
// 验证缓存记录次数
|
||||
retryKey := fmt.Sprintf("%s:%s", constants.CACHE_PWD_ERR_COUNT, userName)
|
||||
retryCount, err := redis.Get("", retryKey)
|
||||
if retryCount == "" || err != nil {
|
||||
retryCount = "0"
|
||||
}
|
||||
// 是否超过错误值
|
||||
retryCountInt64 := parse.Number(retryCount)
|
||||
if retryCountInt64 >= int64(maxRetryCount) {
|
||||
// msg := fmt.Sprintf("密码输入错误 %d 次,帐户锁定 %d 分钟", maxRetryCount, lockTime)
|
||||
msg := fmt.Errorf("login.errRetryPasswd") // 密码输入错误多次,帐户已被锁定
|
||||
return retryKey, retryCountInt64, time.Duration(lockTime) * time.Minute, fmt.Errorf("%s", msg)
|
||||
}
|
||||
return retryKey, retryCountInt64, time.Duration(lockTime) * time.Minute, nil
|
||||
}
|
||||
|
||||
// PasswordCountOrExpireTime 首次登录或密码过期时间
|
||||
func (s Account) PasswordCountOrExpireTime(loginCount, passwordUpdateTime int64) (bool, error) {
|
||||
forcePasswdChange := false
|
||||
// 从数据库配置获取-首次登录密码修改
|
||||
fristPasswdChangeStr := s.sysConfigService.FindValueByKey("sys.user.fristPasswdChange")
|
||||
if parse.Boolean(fristPasswdChangeStr) {
|
||||
forcePasswdChange = loginCount < 1 || passwordUpdateTime == 0
|
||||
}
|
||||
|
||||
// 非首次登录,判断密码是否过期
|
||||
if !forcePasswdChange {
|
||||
alert, err := s.sysUserService.ValidatePasswordExpireTime(passwordUpdateTime)
|
||||
if err != nil {
|
||||
return alert, err
|
||||
}
|
||||
forcePasswdChange = alert
|
||||
}
|
||||
return forcePasswdChange, nil
|
||||
}
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"be.ems/src/framework/token"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
"be.ems/src/framework/utils/generate"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/repository"
|
||||
"be.ems/src/modules/auth/model"
|
||||
"be.ems/src/modules/auth/repository"
|
||||
)
|
||||
|
||||
// NewOauth2Service 实例化服务层
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/utils/generate"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/repository"
|
||||
"be.ems/src/modules/auth/model"
|
||||
"be.ems/src/modules/auth/repository"
|
||||
)
|
||||
|
||||
// NewOauth2ClientService 实例化服务层
|
||||
@@ -55,11 +55,11 @@ func (s Oauth2ClientService) DeleteByIds(ids []int64) (int64, error) {
|
||||
arr := s.oauth2ClientRepository.SelectByIds(ids)
|
||||
if len(arr) <= 0 {
|
||||
// return 0, fmt.Errorf("没有权限访问用户授权第三方应用数据!")
|
||||
return 0, fmt.Errorf("No permission to access user-authorized third-party application data!")
|
||||
return 0, fmt.Errorf("no permission to access user-authorized third-party application data")
|
||||
}
|
||||
if len(arr) == len(ids) {
|
||||
return s.oauth2ClientRepository.DeleteByIds(ids), nil
|
||||
}
|
||||
// return 0, fmt.Errorf("删除用户授权第三方应用信息失败!")
|
||||
return 0, fmt.Errorf("Failed to delete user-authorized third-party application information!")
|
||||
return 0, fmt.Errorf("failed to delete user-authorized third-party application information")
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/modules/oauth2/model"
|
||||
"be.ems/src/modules/oauth2/repository"
|
||||
"be.ems/src/modules/auth/model"
|
||||
"be.ems/src/modules/auth/repository"
|
||||
)
|
||||
|
||||
// NewOauth2LogLogin 实例化服务层
|
||||
@@ -61,12 +61,14 @@ func (s Register) ByUserName(username, password string) (int64, error) {
|
||||
|
||||
sysUser := systemModel.SysUser{
|
||||
UserName: username,
|
||||
NickName: username, // 昵称使用名称账号
|
||||
Password: password, // 原始密码
|
||||
NickName: username, // 昵称使用名称账号
|
||||
Password: password, // 原始密码
|
||||
UserType: "System",
|
||||
UserSource: "#",
|
||||
Sex: "0", // 性别未选择
|
||||
StatusFlag: constants.STATUS_YES, // 账号状态激活
|
||||
DeptId: 100, // 归属部门为根节点
|
||||
CreateBy: "register", // 创建来源
|
||||
DeptId: 101, // 归属部门为根节点
|
||||
CreateBy: "System", // 创建来源
|
||||
}
|
||||
|
||||
// 新增用户的角色管理
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neDataModel "be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neModel "be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
@@ -23,26 +22,20 @@ import (
|
||||
)
|
||||
|
||||
var NewProcessor = &BackupExportCDRProcessor{
|
||||
count: 0,
|
||||
backupService: neDataService.NewBackup,
|
||||
sysDictService: systemService.NewSysDictData,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
imsCDREventService: neDataService.NewCDREventIMS,
|
||||
smscCDREventService: neDataService.NewCDREventSMSC,
|
||||
smfCDREventService: neDataService.NewCDREventSMF,
|
||||
sgwcCDREventService: neDataService.NewCDREventSGWC,
|
||||
count: 0,
|
||||
backupService: neDataService.NewBackup,
|
||||
sysDictService: systemService.NewSysDictData,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
}
|
||||
|
||||
// BackupExportCDR 队列任务处理
|
||||
type BackupExportCDRProcessor struct {
|
||||
count int // 执行次数
|
||||
backupService *neDataService.Backup // 备份相关服务
|
||||
sysDictService *systemService.SysDictData // 字典类型数据服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
imsCDREventService *neDataService.CDREventIMS // IMS-CDR会话事件服务
|
||||
smscCDREventService *neDataService.CDREventSMSC // SMSC-CDR会话事件服务
|
||||
smfCDREventService *neDataService.CDREventSMF // SMF-CDR会话事件服务
|
||||
sgwcCDREventService *neDataService.CDREventSGWC // SGWC-CDR会话事件服务
|
||||
count int // 执行次数
|
||||
backupService *neDataService.Backup // 备份相关服务
|
||||
sysDictService *systemService.SysDictData // 字典类型数据服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
}
|
||||
|
||||
func (s *BackupExportCDRProcessor) Execute(data any) (any, error) {
|
||||
@@ -104,16 +97,16 @@ func (s BackupExportCDRProcessor) exportIMS(hour int, rmUID, fileType string) st
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
language := "en"
|
||||
query := neDataModel.CDREventIMSQuery{
|
||||
SortField: "timestamp",
|
||||
SortOrder: "asc",
|
||||
RmUID: rmUID,
|
||||
BeginTime: start.UnixMilli(),
|
||||
EndTime: end.UnixMilli(),
|
||||
PageNum: 1,
|
||||
PageSize: 30000,
|
||||
query := map[string]string{
|
||||
"sortField": "timestamp",
|
||||
"sortOrder": "asc",
|
||||
"rmUID": rmUID,
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
"pageNum": fmt.Sprint(1),
|
||||
"pageSize": fmt.Sprint(30000),
|
||||
}
|
||||
rows, total := s.imsCDREventService.FindByPage(query)
|
||||
rows, total := s.cdrEventService.FindByPage("IMS", query)
|
||||
if total == 0 {
|
||||
return "no data"
|
||||
}
|
||||
@@ -393,16 +386,16 @@ func (s BackupExportCDRProcessor) exportSMSC(hour int, rmUID, fileType string) s
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
language := "en"
|
||||
query := neDataModel.CDREventSMSCQuery{
|
||||
SortField: "timestamp",
|
||||
SortOrder: "asc",
|
||||
RmUID: rmUID,
|
||||
BeginTime: start.UnixMilli(),
|
||||
EndTime: end.UnixMilli(),
|
||||
PageNum: 1,
|
||||
PageSize: 30000,
|
||||
query := map[string]string{
|
||||
"sortField": "timestamp",
|
||||
"sortOrder": "asc",
|
||||
"rmUID": rmUID,
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
"pageNum": fmt.Sprint(1),
|
||||
"pageSize": fmt.Sprint(30000),
|
||||
}
|
||||
rows, total := s.smscCDREventService.FindByPage(query)
|
||||
rows, total := s.cdrEventService.FindByPage("SMSC", query)
|
||||
if total == 0 {
|
||||
return "no data"
|
||||
}
|
||||
@@ -609,16 +602,16 @@ func (s BackupExportCDRProcessor) exportSMF(hour int, rmUID, fileType string) st
|
||||
end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
query := neDataModel.CDREventSMFQuery{
|
||||
SortField: "timestamp",
|
||||
SortOrder: "asc",
|
||||
RmUID: rmUID,
|
||||
BeginTime: start.UnixMilli(),
|
||||
EndTime: end.UnixMilli(),
|
||||
PageNum: 1,
|
||||
PageSize: 30000,
|
||||
query := map[string]string{
|
||||
"sortField": "timestamp",
|
||||
"sortOrder": "asc",
|
||||
"rmUID": rmUID,
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
"pageNum": fmt.Sprint(1),
|
||||
"pageSize": fmt.Sprint(30000),
|
||||
}
|
||||
rows, total := s.smfCDREventService.FindByPage(query)
|
||||
rows, total := s.cdrEventService.FindByPage("SMF", query)
|
||||
if total == 0 {
|
||||
return "no data"
|
||||
}
|
||||
@@ -1017,16 +1010,16 @@ func (s BackupExportCDRProcessor) exportSGWC(hour int, rmUID, fileType string) s
|
||||
end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
query := neDataModel.CDREventSGWCQuery{
|
||||
SortField: "timestamp",
|
||||
SortOrder: "asc",
|
||||
RmUID: rmUID,
|
||||
BeginTime: start.UnixMilli(),
|
||||
EndTime: end.UnixMilli(),
|
||||
PageNum: 1,
|
||||
PageSize: 30000,
|
||||
query := map[string]string{
|
||||
"sortField": "timestamp",
|
||||
"sortOrder": "asc",
|
||||
"rmUID": rmUID,
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
"pageNum": fmt.Sprint(1),
|
||||
"pageSize": fmt.Sprint(30000),
|
||||
}
|
||||
rows, total := s.sgwcCDREventService.FindByPage(query)
|
||||
rows, total := s.cdrEventService.FindByPage("SGWC", query)
|
||||
if total == 0 {
|
||||
return "no data"
|
||||
}
|
||||
|
||||
@@ -15,21 +15,22 @@ import (
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neDataModel "be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
systemModel "be.ems/src/modules/system/model"
|
||||
systemService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
var NewProcessor = &BackupExportTableProcessor{
|
||||
backupService: neDataService.NewBackup,
|
||||
count: 0,
|
||||
backupService: neDataService.NewBackup,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// BackupExportTable 备份导出数据表
|
||||
type BackupExportTableProcessor struct {
|
||||
backupService *neDataService.Backup // 备份相关服务
|
||||
count int // 执行次数
|
||||
backupService *neDataService.Backup // 备份相关服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
count int // 执行次数
|
||||
}
|
||||
|
||||
func (s *BackupExportTableProcessor) Execute(data any) (any, error) {
|
||||
@@ -197,13 +198,13 @@ func (s BackupExportTableProcessor) exportSMF(hour int, columns []string, filePa
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
// 查询数据
|
||||
rows := []neDataModel.CDREventSMF{}
|
||||
tx := db.DB("").Model(&neDataModel.CDREventSMF{})
|
||||
tx = tx.Where("created_at >= ? and created_at <= ?", start.UnixMilli(), end.UnixMilli())
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(rows) <= 0 {
|
||||
rows, total := s.cdrEventService.FindByPage("SMF", map[string]string{
|
||||
"sortField": "created_at",
|
||||
"sortOrder": "asc",
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
})
|
||||
if total <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -417,7 +418,7 @@ func (s BackupExportTableProcessor) exportSMF(hour int, columns []string, filePa
|
||||
|
||||
err := file.WriterFileCSV(data, filePath)
|
||||
|
||||
return tx.RowsAffected, err
|
||||
return total, err
|
||||
}
|
||||
|
||||
// exportIMS 导出csv
|
||||
@@ -428,13 +429,13 @@ func (s BackupExportTableProcessor) exportIMS(hour int, columns []string, filePa
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
// 查询数据
|
||||
rows := []neDataModel.CDREventIMS{}
|
||||
tx := db.DB("").Model(&neDataModel.CDREventIMS{})
|
||||
tx = tx.Where("created_at >= ? and created_at <= ?", start.UnixMilli(), end.UnixMilli())
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(rows) <= 0 {
|
||||
rows, total := s.cdrEventService.FindByPage("IMS", map[string]string{
|
||||
"sortField": "created_at",
|
||||
"sortOrder": "asc",
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
})
|
||||
if total <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -561,7 +562,7 @@ func (s BackupExportTableProcessor) exportIMS(hour int, columns []string, filePa
|
||||
|
||||
err := file.WriterFileCSV(data, filePath)
|
||||
|
||||
return tx.RowsAffected, err
|
||||
return total, err
|
||||
}
|
||||
|
||||
// exportSMSC 导出csv
|
||||
@@ -572,13 +573,13 @@ func (s BackupExportTableProcessor) exportSMSC(hour int, columns []string, fileP
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
// 查询数据
|
||||
rows := []neDataModel.CDREventSMSC{}
|
||||
tx := db.DB("").Model(&neDataModel.CDREventSMSC{})
|
||||
tx = tx.Where("created_at >= ? and created_at <= ?", start.UnixMilli(), end.UnixMilli())
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(rows) <= 0 {
|
||||
rows, total := s.cdrEventService.FindByPage("SMS", map[string]string{
|
||||
"sortField": "created_at",
|
||||
"sortOrder": "asc",
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
})
|
||||
if total <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -686,7 +687,7 @@ func (s BackupExportTableProcessor) exportSMSC(hour int, columns []string, fileP
|
||||
|
||||
err := file.WriterFileCSV(data, filePath)
|
||||
|
||||
return tx.RowsAffected, err
|
||||
return total, err
|
||||
}
|
||||
|
||||
// exportSGWC 导出csv
|
||||
@@ -697,13 +698,13 @@ func (s BackupExportTableProcessor) exportSGWC(hour int, columns []string, fileP
|
||||
start := end.Add(-time.Duration(hour) * time.Hour)
|
||||
|
||||
// 查询数据
|
||||
rows := []neDataModel.CDREventSMSC{}
|
||||
tx := db.DB("").Model(&neDataModel.CDREventSMSC{})
|
||||
tx = tx.Where("created_at >= ? and created_at <= ?", start.UnixMilli(), end.UnixMilli())
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(rows) <= 0 {
|
||||
rows, total := s.cdrEventService.FindByPage("SGWC", map[string]string{
|
||||
"sortField": "created_at",
|
||||
"sortOrder": "asc",
|
||||
"beginTime": fmt.Sprint(start.UnixMilli()),
|
||||
"endTime": fmt.Sprint(end.UnixMilli()),
|
||||
})
|
||||
if total <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -923,5 +924,5 @@ func (s BackupExportTableProcessor) exportSGWC(hour int, columns []string, fileP
|
||||
|
||||
err := file.WriterFileCSV(data, filePath)
|
||||
|
||||
return tx.RowsAffected, err
|
||||
return total, err
|
||||
}
|
||||
|
||||
@@ -5,33 +5,26 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/tsmask/go-oam"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/cron"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
|
||||
neDataModel "be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neModel "be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
wsService "be.ems/src/modules/ws/service"
|
||||
oamService "be.ems/src/modules/oam/service"
|
||||
)
|
||||
|
||||
var NewProcessor = &NeAlarmStateCheckProcessor{
|
||||
neConfigBackupService: neService.NewNeConfigBackup,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
alarmService: neDataService.NewAlarm,
|
||||
wsSendService: wsService.NewWSSend,
|
||||
count: 0,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// NeAlarmStateCheckProcessor 网元告警状态检查
|
||||
type NeAlarmStateCheckProcessor struct {
|
||||
neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
alarmService *neDataService.Alarm // 告警信息服务
|
||||
wsSendService *wsService.WSSend // ws发送服务
|
||||
count int // 执行次数
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
count int // 执行次数
|
||||
}
|
||||
|
||||
// alarmParams 告警参数
|
||||
@@ -69,104 +62,37 @@ func (s *NeAlarmStateCheckProcessor) Execute(data any) (any, error) {
|
||||
if neInfo.CreateTime == 0 {
|
||||
continue
|
||||
}
|
||||
neTypeAndId := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId)
|
||||
|
||||
// 网元在线状态
|
||||
isOnline := parse.Boolean(neInfo.ServerState["online"])
|
||||
// 告警ID
|
||||
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_STATE_CHECK, neInfo.CreateTime)
|
||||
// 检查网元告警ID是否唯一
|
||||
alarmIdArr := s.alarmService.Find(neDataModel.Alarm{
|
||||
NeType: neInfo.NeType,
|
||||
NeId: neInfo.NeId,
|
||||
AlarmId: params.AlarmId,
|
||||
})
|
||||
// 告警状态
|
||||
alarmStatus := ""
|
||||
if len(alarmIdArr) > 0 {
|
||||
alarmStatus = fmt.Sprint(alarmIdArr[0].AlarmStatus)
|
||||
}
|
||||
// 在线且状态为活动告警
|
||||
if isOnline && alarmStatus == "1" {
|
||||
// 进行清除
|
||||
clearAlarm, err := s.alarmClear(neInfo, alarmIdArr[0])
|
||||
if err != nil {
|
||||
result[neTypeAndId] = err.Error()
|
||||
continue
|
||||
}
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, clearAlarm)
|
||||
result[neTypeAndId] = "alarm clear"
|
||||
}
|
||||
|
||||
// 不在线
|
||||
if !isOnline && alarmStatus == "" {
|
||||
// 进行新增
|
||||
newAlarm, err := s.alarmNew(neInfo, params)
|
||||
if err != nil {
|
||||
result[neTypeAndId] = err.Error()
|
||||
continue
|
||||
}
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, newAlarm)
|
||||
result[neTypeAndId] = "alarm new"
|
||||
// 告警状态
|
||||
alarmStatus := oam.ALARM_STATUS_ACTIVE
|
||||
if isOnline {
|
||||
alarmStatus = oam.ALARM_STATUS_CLEAR
|
||||
}
|
||||
// 创建告警
|
||||
alarm := oam.Alarm{
|
||||
NeUid: neInfo.RmUID, // 网元唯一标识
|
||||
AlarmTime: time.Now().UnixMilli(), // 事件产生时间
|
||||
AlarmId: params.AlarmId, // 告警ID 唯一,清除时对应
|
||||
AlarmCode: constants.ALARM_STATE_CHECK, // 告警状态码
|
||||
AlarmType: params.AlarmType, // 告警类型
|
||||
AlarmTitle: params.AlarmTitle, // 告警标题
|
||||
PerceivedSeverity: params.OrigSeverity, // 告警级别
|
||||
AlarmStatus: alarmStatus, // 告警状态
|
||||
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
||||
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
||||
AddInfo: params.AddInfo, // 告警辅助信息
|
||||
LocationInfo: "NE State: Heartbeat", // 告警定位信息
|
||||
}
|
||||
if err = oamService.NewAlarm.Resolve(alarm); err == nil {
|
||||
result[neInfo.RmUID] = "state alarm"
|
||||
}
|
||||
}
|
||||
|
||||
// 返回结果,用于记录执行结果
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// alarmClear 清除告警
|
||||
func (s NeAlarmStateCheckProcessor) alarmClear(neInfo neModel.NeInfo, v neDataModel.Alarm) (neDataModel.Alarm, error) {
|
||||
// 变更告警ID为告警清除ID
|
||||
v.AlarmId = fmt.Sprintf("%d%d", v.AlarmCode, v.EventTime)
|
||||
v.AlarmStatus = "0"
|
||||
// 告警清除
|
||||
v.ClearType = 1
|
||||
v.ClearTime = neInfo.UpdateTime
|
||||
v.ClearUser = "system"
|
||||
rows := s.alarmService.Update(v)
|
||||
if rows > 0 {
|
||||
return v, nil
|
||||
}
|
||||
return neDataModel.Alarm{}, fmt.Errorf("clear alarm fail")
|
||||
}
|
||||
|
||||
// alarmNew 新增告警
|
||||
func (s NeAlarmStateCheckProcessor) alarmNew(neInfo neModel.NeInfo, v alarmParams) (neDataModel.Alarm, error) {
|
||||
// seq 告警序号
|
||||
lastSeq := s.alarmService.FindAlarmSeqLast(neInfo.NeType, neInfo.NeId)
|
||||
lastTime := neInfo.UpdateTime // 网元最后更新时间
|
||||
if lastTime < neInfo.CreateTime {
|
||||
lastTime = time.Now().UnixMilli()
|
||||
}
|
||||
alarm := neDataModel.Alarm{
|
||||
NeType: neInfo.NeType,
|
||||
NeId: neInfo.NeId,
|
||||
NeName: neInfo.NeName,
|
||||
Province: neInfo.Province,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
AlarmSeq: lastSeq + 1,
|
||||
AlarmId: v.AlarmId,
|
||||
AlarmTitle: v.AlarmTitle,
|
||||
AlarmCode: constants.ALARM_STATE_CHECK,
|
||||
EventTime: lastTime,
|
||||
AlarmType: v.AlarmType,
|
||||
OrigSeverity: v.OrigSeverity,
|
||||
PerceivedSeverity: v.OrigSeverity,
|
||||
ObjectUid: neInfo.RmUID,
|
||||
ObjectName: "NE State",
|
||||
ObjectType: "state",
|
||||
LocationInfo: "NE State: Heartbeat",
|
||||
AlarmStatus: "1", // 活动告警
|
||||
SpecificProblem: v.SpecificProblem,
|
||||
SpecificProblemId: v.SpecificProblemID,
|
||||
AddInfo: v.AddInfo,
|
||||
}
|
||||
insertId := s.alarmService.InsertAndForword(alarm)
|
||||
if insertId > 0 {
|
||||
alarm.ID = insertId
|
||||
return alarm, nil
|
||||
}
|
||||
return neDataModel.Alarm{}, fmt.Errorf("new alarm fail")
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/tsmask/go-oam"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/cron"
|
||||
"be.ems/src/framework/logger"
|
||||
@@ -18,6 +20,7 @@ import (
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neModel "be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
oamService "be.ems/src/modules/oam/service"
|
||||
wsService "be.ems/src/modules/ws/service"
|
||||
)
|
||||
|
||||
@@ -28,22 +31,18 @@ var (
|
||||
)
|
||||
|
||||
var NewProcessor = &NeAlarmStateCheckCMDProcessor{
|
||||
neConfigBackupService: neService.NewNeConfigBackup,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neStateService: neDataService.NewNEState,
|
||||
alarmService: neDataService.NewAlarm,
|
||||
wsSendService: wsService.NewWSSend,
|
||||
count: 0,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neStateService: neDataService.NewNEState,
|
||||
wsSendService: wsService.NewWSSend,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// NeAlarmStateCheckCMDProcessor 网元告警内存/CPU/磁盘检查
|
||||
type NeAlarmStateCheckCMDProcessor struct {
|
||||
neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neStateService *neDataService.NEState // 网元状态信息服务
|
||||
alarmService *neDataService.Alarm // 告警信息服务
|
||||
wsSendService *wsService.WSSend // ws发送服务
|
||||
count int // 执行次数
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neStateService *neDataService.NEState // 网元状态信息服务
|
||||
wsSendService *wsService.WSSend // ws发送服务
|
||||
count int // 执行次数
|
||||
}
|
||||
|
||||
// alarmParams 告警参数
|
||||
@@ -103,65 +102,84 @@ func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) {
|
||||
}
|
||||
|
||||
// 检查状态
|
||||
err := s.serverState(neInfo.ServerState, params.CPUUseGt, params.MemUseGt, params.DiskUseGt)
|
||||
sysCpuUsage, sysMemUsage, sysDiskUsage := s.serverState(neInfo.ServerState)
|
||||
// 检查CPU/Menory/Disk使用率
|
||||
warnMsg := []string{}
|
||||
if int64(sysCpuUsage) >= params.CPUUseGt {
|
||||
warnMsg = append(warnMsg, fmt.Sprintf("cpu usage %.2f%%", sysCpuUsage))
|
||||
}
|
||||
if int64(sysMemUsage) >= params.MemUseGt {
|
||||
warnMsg = append(warnMsg, fmt.Sprintf("memory usage %.2f%%", sysMemUsage))
|
||||
}
|
||||
if int64(sysDiskUsage) >= params.DiskUseGt {
|
||||
warnMsg = append(warnMsg, fmt.Sprintf("disk usage %.2f%%", sysDiskUsage))
|
||||
}
|
||||
var err error
|
||||
if len(warnMsg) > 0 {
|
||||
currentTime := time.Now()
|
||||
validTimes := []time.Time{}
|
||||
if v, ok := triggerCount.Load(neInfo.RmUID); ok {
|
||||
times := v.([]time.Time)
|
||||
// 清理过期的记录:10秒前的触发记录不再计入
|
||||
for _, t := range times {
|
||||
if currentTime.Sub(t) <= triggerWindow {
|
||||
validTimes = append(validTimes, t)
|
||||
}
|
||||
}
|
||||
validTimes = append(validTimes, currentTime)
|
||||
triggerCount.Store(neInfo.RmUID, validTimes)
|
||||
} else {
|
||||
// 事件第一次触发,初始化记录
|
||||
validTimes = append(validTimes, currentTime)
|
||||
triggerCount.Store(neInfo.RmUID, validTimes)
|
||||
}
|
||||
if int64(len(validTimes)) >= triggerMax {
|
||||
err = fmt.Errorf("greater than %s", strings.Join(warnMsg, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
// 检查状态连续触发
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
addInfo := params.AddInfo
|
||||
if addInfo != "" {
|
||||
addInfo = addInfo + ", " + err.Error()
|
||||
} else {
|
||||
addInfo = err.Error()
|
||||
}
|
||||
|
||||
neTypeAndId := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId)
|
||||
// 事件产生时间
|
||||
alarmTime := time.Now().UnixMilli()
|
||||
// 告警ID
|
||||
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_CMD_CHECK, neInfo.CreateTime)
|
||||
// 检查网元告警ID是否唯一
|
||||
alarmIdArr := s.alarmService.Find(neDataModel.Alarm{
|
||||
NeType: neInfo.NeType,
|
||||
NeId: neInfo.NeId,
|
||||
AlarmId: params.AlarmId,
|
||||
})
|
||||
// 告警状态, 存在的需要手动清除
|
||||
alarmStatus := ""
|
||||
if len(alarmIdArr) > 0 {
|
||||
alarmStatus = fmt.Sprint(alarmIdArr[0].AlarmStatus)
|
||||
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_CMD_CHECK, alarmTime)
|
||||
// 创建告警
|
||||
alarm := oam.Alarm{
|
||||
NeUid: neInfo.RmUID, // 网元唯一标识
|
||||
AlarmTime: alarmTime, // 事件产生时间
|
||||
AlarmId: params.AlarmId, // 告警ID 唯一,清除时对应
|
||||
AlarmCode: constants.ALARM_CMD_CHECK, // 告警状态码
|
||||
AlarmType: params.AlarmType, // 告警类型
|
||||
AlarmTitle: params.AlarmTitle, // 告警标题
|
||||
PerceivedSeverity: params.OrigSeverity, // 告警级别
|
||||
AlarmStatus: oam.ALARM_STATUS_ACTIVE, // 告警状态
|
||||
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
||||
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
||||
AddInfo: addInfo, // 告警辅助信息
|
||||
LocationInfo: "NE CPU/Menory/Disk: Heartbeat", // 告警定位信息
|
||||
}
|
||||
// 活动告警进行清除
|
||||
if alarmStatus == "1" {
|
||||
clearAlarm, err := s.alarmClear(neInfo, alarmIdArr[0])
|
||||
if err != nil {
|
||||
result[neTypeAndId] = err.Error()
|
||||
continue
|
||||
}
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, clearAlarm)
|
||||
result[neTypeAndId] = "alarm clear"
|
||||
alarmStatus = "" // 标记为未记录再次发起新告警
|
||||
}
|
||||
// 未记录
|
||||
if alarmStatus == "" {
|
||||
addInfo := params.AddInfo
|
||||
if params.AddInfo != "" {
|
||||
params.AddInfo = params.AddInfo + ", " + err.Error()
|
||||
} else {
|
||||
params.AddInfo = err.Error()
|
||||
}
|
||||
// 进行新增
|
||||
newAlarm, err := s.alarmNew(neInfo, params)
|
||||
params.AddInfo = addInfo // 恢复附加信息
|
||||
triggerCount.Clear() // 重置连续触发次数
|
||||
if err != nil {
|
||||
result[neTypeAndId] = err.Error()
|
||||
continue
|
||||
}
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, newAlarm)
|
||||
result[neTypeAndId] = "alarm new"
|
||||
if err = oamService.NewAlarm.Resolve(alarm); err == nil {
|
||||
result[neInfo.RmUID] = "cmd alarm"
|
||||
}
|
||||
triggerCount.Delete(neInfo.RmUID)
|
||||
}
|
||||
|
||||
// 返回结果,用于记录执行结果
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// serverState 网元状态
|
||||
func (s NeAlarmStateCheckCMDProcessor) serverState(state map[string]any, cpuUseGt, memUseGt, diskUseGt int64) error {
|
||||
// serverState 网元状态记录
|
||||
func (s NeAlarmStateCheckCMDProcessor) serverState(state map[string]any) (float64, float64, float64) {
|
||||
// 网元CPU使用率
|
||||
var nfCpuUsage float64 = 0
|
||||
// CPU使用率
|
||||
@@ -224,94 +242,5 @@ func (s NeAlarmStateCheckCMDProcessor) serverState(state map[string]any, cpuUseG
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_NE_STATE, neState.NeType, neState.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, neState)
|
||||
|
||||
// 检查CPU/Menory/Disk使用率
|
||||
warnMsg := []string{}
|
||||
if int64(sysCpuUsage) >= cpuUseGt {
|
||||
warnMsg = append(warnMsg, fmt.Sprintf("cpu usage %.2f%%", sysCpuUsage))
|
||||
}
|
||||
if int64(sysMemUsage) >= memUseGt {
|
||||
warnMsg = append(warnMsg, fmt.Sprintf("memory usage %.2f%%", sysMemUsage))
|
||||
}
|
||||
if int64(sysDiskUsage) >= diskUseGt {
|
||||
warnMsg = append(warnMsg, fmt.Sprintf("disk usage %.2f%%", sysDiskUsage))
|
||||
}
|
||||
if len(warnMsg) > 0 {
|
||||
currentTime := time.Now()
|
||||
neTypeAndId := fmt.Sprintf("%s_%s", neState.NeType, neState.NeId)
|
||||
validTimes := []time.Time{}
|
||||
if v, ok := triggerCount.Load(neTypeAndId); ok {
|
||||
times := v.([]time.Time)
|
||||
// 清理过期的记录:10秒前的触发记录不再计入
|
||||
for _, t := range times {
|
||||
if currentTime.Sub(t) <= triggerWindow {
|
||||
validTimes = append(validTimes, t)
|
||||
}
|
||||
}
|
||||
validTimes = append(validTimes, currentTime)
|
||||
triggerCount.Store(neTypeAndId, validTimes)
|
||||
} else {
|
||||
// 事件第一次触发,初始化记录
|
||||
validTimes = append(validTimes, currentTime)
|
||||
triggerCount.Store(neTypeAndId, validTimes)
|
||||
}
|
||||
if int64(len(validTimes)) >= triggerMax {
|
||||
return fmt.Errorf("greater than %s", strings.Join(warnMsg, ", "))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// alarmClear 清除告警
|
||||
func (s NeAlarmStateCheckCMDProcessor) alarmClear(neInfo neModel.NeInfo, v neDataModel.Alarm) (neDataModel.Alarm, error) {
|
||||
// 变更告警ID为告警清除ID
|
||||
v.AlarmId = fmt.Sprintf("%d%d", v.AlarmCode, v.EventTime)
|
||||
v.AlarmStatus = "0"
|
||||
// 告警清除
|
||||
v.ClearType = 1
|
||||
v.ClearTime = neInfo.UpdateTime
|
||||
v.ClearUser = "system"
|
||||
rows := s.alarmService.Update(v)
|
||||
if rows > 0 {
|
||||
return v, nil
|
||||
}
|
||||
return neDataModel.Alarm{}, fmt.Errorf("clear alarm fail")
|
||||
}
|
||||
|
||||
// alarmNew 新增告警
|
||||
func (s NeAlarmStateCheckCMDProcessor) alarmNew(neInfo neModel.NeInfo, v alarmParams) (neDataModel.Alarm, error) {
|
||||
// seq 告警序号
|
||||
lastSeq := s.alarmService.FindAlarmSeqLast(neInfo.NeType, neInfo.NeId)
|
||||
lastTime := neInfo.UpdateTime // 网元最后更新时间
|
||||
if lastTime < neInfo.CreateTime {
|
||||
lastTime = time.Now().UnixMilli()
|
||||
}
|
||||
alarm := neDataModel.Alarm{
|
||||
NeType: neInfo.NeType,
|
||||
NeId: neInfo.NeId,
|
||||
NeName: neInfo.NeName,
|
||||
Province: neInfo.Province,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
AlarmSeq: lastSeq + 1,
|
||||
AlarmId: v.AlarmId,
|
||||
AlarmTitle: v.AlarmTitle,
|
||||
AlarmCode: constants.ALARM_CMD_CHECK,
|
||||
EventTime: lastTime,
|
||||
AlarmType: v.AlarmType,
|
||||
OrigSeverity: v.OrigSeverity,
|
||||
PerceivedSeverity: v.OrigSeverity,
|
||||
ObjectUid: neInfo.RmUID,
|
||||
ObjectName: "NE CPU/Menory/Disk",
|
||||
ObjectType: "cmd",
|
||||
LocationInfo: "NE CPU/Menory/Disk: Heartbeat",
|
||||
AlarmStatus: "1", // 活动告警
|
||||
SpecificProblem: v.SpecificProblem,
|
||||
SpecificProblemId: v.SpecificProblemID,
|
||||
AddInfo: v.AddInfo,
|
||||
}
|
||||
insertId := s.alarmService.InsertAndForword(alarm)
|
||||
if insertId > 0 {
|
||||
alarm.ID = insertId
|
||||
return alarm, nil
|
||||
}
|
||||
return neDataModel.Alarm{}, fmt.Errorf("new alarm fail")
|
||||
return sysCpuUsage, sysMemUsage, sysDiskUsage
|
||||
}
|
||||
|
||||
@@ -10,29 +10,22 @@ import (
|
||||
"be.ems/src/framework/cron"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"github.com/tsmask/go-oam"
|
||||
|
||||
neDataModel "be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neModel "be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
wsService "be.ems/src/modules/ws/service"
|
||||
oamService "be.ems/src/modules/oam/service"
|
||||
)
|
||||
|
||||
var NewProcessor = &NeAlarmStateCheckLicenseProcessor{
|
||||
neConfigBackupService: neService.NewNeConfigBackup,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
alarmService: neDataService.NewAlarm,
|
||||
wsSendService: wsService.NewWSSend,
|
||||
count: 0,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// NeAlarmStateCheckLicenseProcessor 网元告警License到期检查
|
||||
type NeAlarmStateCheckLicenseProcessor struct {
|
||||
neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
alarmService *neDataService.Alarm // 告警信息服务
|
||||
wsSendService *wsService.WSSend // ws发送服务
|
||||
count int // 执行次数
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
count int // 执行次数
|
||||
}
|
||||
|
||||
// alarmParams 告警参数
|
||||
@@ -83,60 +76,36 @@ func (s *NeAlarmStateCheckLicenseProcessor) Execute(data any) (any, error) {
|
||||
}
|
||||
|
||||
// 检查状态
|
||||
err := s.serverState(neInfo.ServerState, params.DayLt)
|
||||
err := s.cheackState(neInfo.ServerState, params.DayLt)
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
if params.AddInfo != "" {
|
||||
params.AddInfo = params.AddInfo + ", " + err.Error()
|
||||
addInfo := params.AddInfo
|
||||
if addInfo != "" {
|
||||
addInfo = addInfo + ", " + err.Error()
|
||||
} else {
|
||||
params.AddInfo = err.Error()
|
||||
addInfo = err.Error()
|
||||
}
|
||||
|
||||
neTypeAndId := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId)
|
||||
// 告警ID
|
||||
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_LICENSE_CHECK, neInfo.CreateTime)
|
||||
// 检查网元告警ID是否唯一
|
||||
alarmIdArr := s.alarmService.Find(neDataModel.Alarm{
|
||||
NeType: neInfo.NeType,
|
||||
NeId: neInfo.NeId,
|
||||
AlarmId: params.AlarmId,
|
||||
})
|
||||
// 告警状态, 存在的需要手动清除
|
||||
alarmStatus := ""
|
||||
if len(alarmIdArr) > 0 {
|
||||
alarmStatus = fmt.Sprint(alarmIdArr[0].AlarmStatus)
|
||||
// 创建告警
|
||||
alarm := oam.Alarm{
|
||||
NeUid: neInfo.RmUID, // 网元唯一标识
|
||||
AlarmTime: time.Now().UnixMilli(), // 事件产生时间
|
||||
AlarmId: params.AlarmId, // 告警ID 唯一,清除时对应
|
||||
AlarmCode: constants.ALARM_LICENSE_CHECK, // 告警状态码
|
||||
AlarmType: params.AlarmType, // 告警类型
|
||||
AlarmTitle: params.AlarmTitle, // 告警标题
|
||||
PerceivedSeverity: params.OrigSeverity, // 告警级别
|
||||
AlarmStatus: oam.ALARM_STATUS_ACTIVE, // 告警状态
|
||||
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
||||
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
||||
AddInfo: addInfo, // 告警辅助信息
|
||||
LocationInfo: "NE License: Heartbeat", // 告警定位信息
|
||||
}
|
||||
// 活动告警进行清除
|
||||
if alarmStatus == "1" {
|
||||
clearAlarm, err := s.alarmClear(neInfo, alarmIdArr[0])
|
||||
if err != nil {
|
||||
result[neTypeAndId] = err.Error()
|
||||
continue
|
||||
}
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, clearAlarm)
|
||||
result[neTypeAndId] = "alarm clear"
|
||||
alarmStatus = "" // 标记为未记录再次发起新告警
|
||||
}
|
||||
// 未记录
|
||||
if alarmStatus == "" {
|
||||
addInfo := params.AddInfo
|
||||
if params.AddInfo != "" {
|
||||
params.AddInfo = params.AddInfo + ", " + err.Error()
|
||||
} else {
|
||||
params.AddInfo = err.Error()
|
||||
}
|
||||
// 进行新增
|
||||
newAlarm, err := s.alarmNew(neInfo, params)
|
||||
params.AddInfo = addInfo // 恢复附加信息
|
||||
if err != nil {
|
||||
result[neTypeAndId] = err.Error()
|
||||
continue
|
||||
}
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, newAlarm)
|
||||
result[neTypeAndId] = "alarm new"
|
||||
if err = oamService.NewAlarm.Resolve(alarm); err == nil {
|
||||
result[neInfo.RmUID] = "license alarm"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,8 +113,8 @@ func (s *NeAlarmStateCheckLicenseProcessor) Execute(data any) (any, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// serverState 网元状态
|
||||
func (s NeAlarmStateCheckLicenseProcessor) serverState(state map[string]any, dayLt int64) error {
|
||||
// cheackState 检查网元状态
|
||||
func (s NeAlarmStateCheckLicenseProcessor) cheackState(state map[string]any, dayLt int64) error {
|
||||
expire := fmt.Sprint(state["expire"])
|
||||
if expire == "" || expire == "<nil>" || expire == "-" || expire == "2099-12-31" {
|
||||
return nil
|
||||
@@ -168,58 +137,3 @@ func (s NeAlarmStateCheckLicenseProcessor) serverState(state map[string]any, day
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// alarmClear 清除告警
|
||||
func (s NeAlarmStateCheckLicenseProcessor) alarmClear(neInfo neModel.NeInfo, v neDataModel.Alarm) (neDataModel.Alarm, error) {
|
||||
// 变更告警ID为告警清除ID
|
||||
v.AlarmId = fmt.Sprintf("%d%d", v.AlarmCode, v.EventTime)
|
||||
v.AlarmStatus = "0"
|
||||
// 告警清除
|
||||
v.ClearType = 1
|
||||
v.ClearTime = neInfo.UpdateTime
|
||||
v.ClearUser = "system"
|
||||
rows := s.alarmService.Update(v)
|
||||
if rows > 0 {
|
||||
return v, nil
|
||||
}
|
||||
return neDataModel.Alarm{}, fmt.Errorf("clear alarm fail")
|
||||
}
|
||||
|
||||
// alarmNew 新增告警
|
||||
func (s NeAlarmStateCheckLicenseProcessor) alarmNew(neInfo neModel.NeInfo, v alarmParams) (neDataModel.Alarm, error) {
|
||||
// seq 告警序号
|
||||
lastSeq := s.alarmService.FindAlarmSeqLast(neInfo.NeType, neInfo.NeId)
|
||||
lastTime := neInfo.UpdateTime // 网元最后更新时间
|
||||
if lastTime < neInfo.CreateTime {
|
||||
lastTime = time.Now().UnixMilli()
|
||||
}
|
||||
alarm := neDataModel.Alarm{
|
||||
NeType: neInfo.NeType,
|
||||
NeId: neInfo.NeId,
|
||||
NeName: neInfo.NeName,
|
||||
Province: neInfo.Province,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
AlarmSeq: lastSeq + 1,
|
||||
AlarmId: v.AlarmId,
|
||||
AlarmTitle: v.AlarmTitle,
|
||||
AlarmCode: constants.ALARM_LICENSE_CHECK,
|
||||
EventTime: lastTime,
|
||||
AlarmType: v.AlarmType,
|
||||
OrigSeverity: v.OrigSeverity,
|
||||
PerceivedSeverity: v.OrigSeverity,
|
||||
ObjectUid: neInfo.RmUID,
|
||||
ObjectName: "NE License",
|
||||
ObjectType: "license",
|
||||
LocationInfo: "NE License: Heartbeat",
|
||||
AlarmStatus: "1", // 活动告警
|
||||
SpecificProblem: v.SpecificProblem,
|
||||
SpecificProblemId: v.SpecificProblemID,
|
||||
AddInfo: v.AddInfo,
|
||||
}
|
||||
insertId := s.alarmService.InsertAndForword(alarm)
|
||||
if insertId > 0 {
|
||||
alarm.ID = insertId
|
||||
return alarm, nil
|
||||
}
|
||||
return neDataModel.Alarm{}, fmt.Errorf("new alarm fail")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
s := MonitorInfo{}
|
||||
s.load(0.5) // 0.5 半分钟
|
||||
s.Load(5 * time.Second) // 0.5 半分钟
|
||||
|
||||
fmt.Println(s)
|
||||
select {}
|
||||
@@ -28,34 +29,22 @@ type MonitorInfo struct {
|
||||
}
|
||||
|
||||
// load 执行资源获取
|
||||
func (m *MonitorInfo) load(interval float64) {
|
||||
var itemBase MonitorBase
|
||||
itemBase.CreateTime = time.Now().UnixMilli()
|
||||
|
||||
loadInfo, _ := load.Avg()
|
||||
itemBase.CPULoad1 = loadInfo.Load1
|
||||
itemBase.CPULoad5 = loadInfo.Load5
|
||||
itemBase.CPULoad15 = loadInfo.Load15
|
||||
|
||||
totalPercent, _ := cpu.Percent(3*time.Second, false)
|
||||
if len(totalPercent) > 0 {
|
||||
itemBase.CPU = totalPercent[0]
|
||||
}
|
||||
cpuCount, _ := cpu.Counts(false)
|
||||
cpuAvg := (float64(cpuCount*2) * 0.75) * 100
|
||||
itemBase.LoadUsage = 0
|
||||
if cpuAvg > 0 {
|
||||
itemBase.LoadUsage = loadInfo.Load1 / cpuAvg
|
||||
}
|
||||
|
||||
memoryInfo, _ := mem.VirtualMemory()
|
||||
itemBase.Memory = memoryInfo.UsedPercent
|
||||
|
||||
m.MonitorBase = itemBase
|
||||
|
||||
// 求平均
|
||||
m.MonitorIO = loadDiskIO(interval)
|
||||
m.MonitorNetwork = loadNetIO(interval)
|
||||
func (m *MonitorInfo) Load(duration time.Duration) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(3)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
m.MonitorBase = loadCPUMem(duration)
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
m.MonitorIO = loadDiskIO(duration)
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
m.MonitorNetwork = loadNetIO(duration)
|
||||
}()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// MonitorBase 监控_基本信息 monitor_base
|
||||
@@ -73,25 +62,49 @@ type MonitorBase struct {
|
||||
type MonitorIO struct {
|
||||
CreateTime int64 `json:"createTime"` // 创建时间
|
||||
Name string `json:"name"` // 磁盘名
|
||||
Read int64 `json:"read"` // 读取K
|
||||
Write int64 `json:"write"` // 写入K
|
||||
Count int64 `json:"count"` // 次数
|
||||
Time int64 `json:"time"` // 耗时
|
||||
Read uint64 `json:"read"` // 读取 Bytes
|
||||
Write uint64 `json:"write"` // 写入 Bytes
|
||||
Count uint64 `json:"count"` // 次数
|
||||
Time uint64 `json:"time"` // 耗时
|
||||
}
|
||||
|
||||
// MonitorNetwork 监控_网络IO monitor_network
|
||||
type MonitorNetwork struct {
|
||||
CreateTime int64 `json:"createTime"` // 创建时间
|
||||
Name string `json:"name"` // 网卡名
|
||||
Up float64 `json:"up"` // 上行
|
||||
Down float64 `json:"down"` // 下行
|
||||
CreateTime int64 `json:"createTime"` // 创建时间
|
||||
Name string `json:"name"` // 网卡名
|
||||
Up uint64 `json:"up"` // 上行 bytes
|
||||
Down uint64 `json:"down"` // 下行 bytes
|
||||
}
|
||||
|
||||
// loadCPUMem CPU内存使用率,interval表示采集的平均值(分钟)
|
||||
func loadCPUMem(duration time.Duration) MonitorBase {
|
||||
var itemBase MonitorBase
|
||||
itemBase.CreateTime = time.Now().UnixMilli()
|
||||
|
||||
loadInfo, _ := load.Avg()
|
||||
itemBase.CPULoad1 = loadInfo.Load1
|
||||
itemBase.CPULoad5 = loadInfo.Load5
|
||||
itemBase.CPULoad15 = loadInfo.Load15
|
||||
totalPercent, _ := cpu.Percent(duration, false)
|
||||
if len(totalPercent) > 0 {
|
||||
itemBase.CPU = totalPercent[0]
|
||||
}
|
||||
if cpuCount, _ := cpu.Counts(false); cpuCount > 0 {
|
||||
itemBase.LoadUsage = loadInfo.Load1 / float64(cpuCount)
|
||||
} else {
|
||||
itemBase.LoadUsage = 0
|
||||
}
|
||||
|
||||
memoryInfo, _ := mem.VirtualMemory()
|
||||
itemBase.Memory = memoryInfo.UsedPercent
|
||||
return itemBase
|
||||
}
|
||||
|
||||
// loadDiskIO 磁盘读写,interval表示采集的平均值(分钟)
|
||||
func loadDiskIO(interval float64) []MonitorIO {
|
||||
func loadDiskIO(duration time.Duration) []MonitorIO {
|
||||
ioStat, _ := disk.IOCounters()
|
||||
|
||||
time.Sleep(time.Duration(interval) * time.Minute)
|
||||
time.Sleep(duration)
|
||||
|
||||
ioStat2, _ := disk.IOCounters()
|
||||
var ioList []MonitorIO
|
||||
@@ -104,32 +117,24 @@ func loadDiskIO(interval float64) []MonitorIO {
|
||||
itemIO.Name = io1.Name
|
||||
|
||||
if io2.ReadBytes != 0 && io1.ReadBytes != 0 && io2.ReadBytes > io1.ReadBytes {
|
||||
itemIO.Read = int64(float64(io2.ReadBytes-io1.ReadBytes) / interval / 60)
|
||||
itemIO.Read = io2.ReadBytes - io1.ReadBytes
|
||||
}
|
||||
if io2.WriteBytes != 0 && io1.WriteBytes != 0 && io2.WriteBytes > io1.WriteBytes {
|
||||
itemIO.Write = int64(float64(io2.WriteBytes-io1.WriteBytes) / interval / 60)
|
||||
itemIO.Write = io2.WriteBytes - io1.WriteBytes
|
||||
}
|
||||
|
||||
if io2.ReadCount != 0 && io1.ReadCount != 0 && io2.ReadCount > io1.ReadCount {
|
||||
itemIO.Count = int64(float64(io2.ReadCount-io1.ReadCount) / interval / 60)
|
||||
itemIO.Count = io2.ReadCount - io1.ReadCount
|
||||
}
|
||||
writeCount := int64(0)
|
||||
if io2.WriteCount != 0 && io1.WriteCount != 0 && io2.WriteCount > io1.WriteCount {
|
||||
writeCount = int64(float64(io2.WriteCount-io1.WriteCount) / interval * 60)
|
||||
}
|
||||
if writeCount > itemIO.Count {
|
||||
itemIO.Count = writeCount
|
||||
itemIO.Count += io2.WriteCount - io1.WriteCount
|
||||
}
|
||||
|
||||
if io2.ReadTime != 0 && io1.ReadTime != 0 && io2.ReadTime > io1.ReadTime {
|
||||
itemIO.Time = int64(float64(io2.ReadTime-io1.ReadTime) / interval / 60)
|
||||
itemIO.Time = io2.ReadTime - io1.ReadTime
|
||||
}
|
||||
writeTime := int64(0)
|
||||
if io2.WriteTime != 0 && io1.WriteTime != 0 && io2.WriteTime > io1.WriteTime {
|
||||
writeTime = int64(float64(io2.WriteTime-io1.WriteTime) / interval / 60)
|
||||
}
|
||||
if writeTime > itemIO.Time {
|
||||
itemIO.Time = writeTime
|
||||
itemIO.Time += io2.WriteTime - io1.WriteTime
|
||||
}
|
||||
ioList = append(ioList, itemIO)
|
||||
break
|
||||
@@ -140,7 +145,7 @@ func loadDiskIO(interval float64) []MonitorIO {
|
||||
}
|
||||
|
||||
// loadNetIO 网络接口(包括虚拟接口),interval表示采集的平均值(分钟)
|
||||
func loadNetIO(interval float64) []MonitorNetwork {
|
||||
func loadNetIO(duration time.Duration) []MonitorNetwork {
|
||||
// 获取当前时刻
|
||||
netStat, _ := net.IOCounters(true)
|
||||
netStatAll, _ := net.IOCounters(false)
|
||||
@@ -148,7 +153,7 @@ func loadNetIO(interval float64) []MonitorNetwork {
|
||||
netStatList = append(netStatList, netStat...)
|
||||
netStatList = append(netStatList, netStatAll...)
|
||||
|
||||
time.Sleep(time.Duration(interval) * time.Minute)
|
||||
time.Sleep(duration)
|
||||
|
||||
// 获取结束时刻
|
||||
netStat2, _ := net.IOCounters(true)
|
||||
@@ -168,10 +173,10 @@ func loadNetIO(interval float64) []MonitorNetwork {
|
||||
|
||||
// 如果结束时刻发送字节数和当前时刻发送字节数都不为零,并且结束时刻发送字节数大于当前时刻发送字节数
|
||||
if net2.BytesSent != 0 && net1.BytesSent != 0 && net2.BytesSent > net1.BytesSent {
|
||||
itemNet.Up = float64(net2.BytesSent-net1.BytesSent) / 1024 / interval / 60
|
||||
itemNet.Up = net2.BytesSent - net1.BytesSent
|
||||
}
|
||||
if net2.BytesRecv != 0 && net1.BytesRecv != 0 && net2.BytesRecv > net1.BytesRecv {
|
||||
itemNet.Down = float64(net2.BytesRecv-net1.BytesRecv) / 1024 / interval / 60
|
||||
itemNet.Down = net2.BytesRecv - net1.BytesRecv
|
||||
}
|
||||
netList = append(netList, itemNet)
|
||||
break
|
||||
|
||||
@@ -199,9 +199,10 @@ func (s SysJob) ExportData(rows []model.SysJob, fileName string) (string, error)
|
||||
}
|
||||
}
|
||||
misfirePolicy := "放弃执行"
|
||||
if row.MisfirePolicy == "1" {
|
||||
switch row.MisfirePolicy {
|
||||
case "1":
|
||||
misfirePolicy = "立即执行"
|
||||
} else if row.MisfirePolicy == "2" {
|
||||
case "2":
|
||||
misfirePolicy = "执行一次"
|
||||
}
|
||||
concurrent := "禁止"
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
@@ -42,7 +43,7 @@ type AlarmController struct {
|
||||
// @Param pvFlag query string false "PV Flag" Enums(PNF,VNF)
|
||||
// @Param alarmCode query string false "alarm status code"
|
||||
// @Param alarmType query string false "Alarm type Communication alarms=1, Equipment alarms=2, Processing faults=3, Environmental alarms=4, Quality of service alarms=5" Enums(1,2,3,4,5)
|
||||
// @Param alarmStatus query string false "Alarm status 0:clear, 1:active" Enums(0,1)
|
||||
// @Param alarmStatus query string false "Alarm status Clear Active" Enums(0,1)
|
||||
// @Param origSeverity query string false "Alarm Type 1: Critical, 2: Major, 3: Minor, 4: Warning" Enums(1,2,3,4)
|
||||
// @Param sortField query string false "Sort fields, fill in result fields" default(event_time)
|
||||
// @Param sortOrder query string false "Sort by ascending or descending order, asc desc" default(asc)
|
||||
@@ -107,7 +108,7 @@ func (s AlarmController) Clear(c *gin.Context) {
|
||||
}
|
||||
|
||||
clearUser := reqctx.LoginUserToUserName(c)
|
||||
rows, err := s.alarmService.AlarmClearByIds(body.Ids, clearUser)
|
||||
rows, err := s.alarmService.ClearByIds(body.Ids, clearUser, constants.ALARM_CLEAR_TYPE_MANUAL_CLEAR)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
@@ -130,7 +131,7 @@ func (s AlarmController) Ack(c *gin.Context) {
|
||||
}
|
||||
|
||||
ackUser := reqctx.LoginUserToUserName(c)
|
||||
rows, err := s.alarmService.AlarmAckByIds(body.Ids, ackUser, body.AckState)
|
||||
rows, err := s.alarmService.AckByIds(body.Ids, ackUser, constants.ALARM_ACK_STATE_ACK)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
@@ -138,6 +139,58 @@ func (s AlarmController) Ack(c *gin.Context) {
|
||||
c.JSON(200, resp.OkData(rows))
|
||||
}
|
||||
|
||||
// 告警级别数量
|
||||
//
|
||||
// GET /count/severity
|
||||
func (s AlarmController) CountSeverity(c *gin.Context) {
|
||||
var query struct {
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"required,oneof=Clear Active"` // 告警状态
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.alarmService.CountSeverity(query.AlarmStatus)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 告警类别数量
|
||||
//
|
||||
// GET /count/type
|
||||
func (s AlarmController) CountType(c *gin.Context) {
|
||||
var query struct {
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"required,oneof=Clear Active"` // 告警状态
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.alarmService.CountType(query.AlarmStatus)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 告警状态前几排名
|
||||
//
|
||||
// GET /count/ne
|
||||
func (s AlarmController) CountNe(c *gin.Context) {
|
||||
var query struct {
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"required,oneof=Clear Active"` // 告警状态
|
||||
Top int `json:"top" form:"top" binding:"required"` // 前几
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
data := s.alarmService.CountNe(query.AlarmStatus, query.Top)
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 告警列表导出
|
||||
//
|
||||
// GET /export
|
||||
|
||||
183
src/modules/network_data/controller/all_kpi_c.go
Normal file
183
src/modules/network_data/controller/all_kpi_c.go
Normal file
@@ -0,0 +1,183 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 KPICController 结构体
|
||||
var NewKPIC = &KPICController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
kpicReportService: neDataService.NewKpiCReport,
|
||||
}
|
||||
|
||||
// 性能统计
|
||||
//
|
||||
// PATH /kpic
|
||||
type KPICController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
kpicReportService *neDataService.KpiCReport // 指标统计服务
|
||||
}
|
||||
|
||||
// 获取统计数据
|
||||
//
|
||||
// GET /data
|
||||
//
|
||||
// @Tags network_data/kpi
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) default(AMF)
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param beginTime query number true "begin time (timestamped milliseconds)" default(1729162507596)
|
||||
// @Param endTime query number true "end time (timestamped milliseconds)" default(1729164187611)
|
||||
// @Param interval query number true "interval" Enums(5,10,15,30,60,300,600,900,1800,3600) default(60)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Access to statistical data
|
||||
// @Description Access to statistical data
|
||||
// @Router /neData/kpic/data [get]
|
||||
func (s KPICController) KPIData(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.KPICQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
kpiData := s.kpicReportService.FindData(querys)
|
||||
c.JSON(200, resp.OkData(kpiData))
|
||||
}
|
||||
|
||||
// 自定义标题列表
|
||||
//
|
||||
// GET /titlelist
|
||||
func (s KPICController) ListTitle(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
if v, ok := query["status"]; ok && v == "" {
|
||||
query["status"] = "1"
|
||||
}
|
||||
rows, total := s.kpicReportService.TitleFindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
}
|
||||
|
||||
// 自定义标题新增
|
||||
//
|
||||
// POST /title
|
||||
func (s KPICController) AddTitle(c *gin.Context) {
|
||||
var body model.KpiCTitle
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 校验指标是否存在
|
||||
kpicTitles := s.kpicReportService.TitleFind(model.KpiCTitle{
|
||||
NeType: body.NeType,
|
||||
KpiId: body.KpiId,
|
||||
})
|
||||
if len(kpicTitles) > 0 {
|
||||
for _, v := range kpicTitles {
|
||||
if v.Status == "2" {
|
||||
c.JSON(200, resp.ErrMsg("custom indicator already exist"))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成自定义指标ID
|
||||
if body.KpiId == "" {
|
||||
body.KpiId = fmt.Sprintf("%s.C.01", strings.ToUpper(body.NeType))
|
||||
} else {
|
||||
// 网元类型最后指标ID
|
||||
lastKpiId := s.kpicReportService.TitleLastKPIId(body.NeType)
|
||||
if lastKpiId != "" {
|
||||
// title like AMF.C.01 截断 .C. 并获取后面的数字部分
|
||||
parts := strings.Split(lastKpiId, ".C.")
|
||||
if len(parts) == 2 {
|
||||
numStr := parts[1]
|
||||
if num, err := strconv.Atoi(numStr); err == nil {
|
||||
num++ // 数字加 1
|
||||
// 转换为前面补零的 2 位字符串
|
||||
body.KpiId = fmt.Sprintf("%s.C.%02d", strings.ToUpper(body.NeType), num)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.CreatedBy = reqctx.LoginUserToUserName(c)
|
||||
insertId := s.kpicReportService.TitleInsert(body)
|
||||
if insertId > 0 {
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Err(nil))
|
||||
}
|
||||
|
||||
// 自定义标题修改
|
||||
//
|
||||
// PUT /title
|
||||
func (s KPICController) EditTitle(c *gin.Context) {
|
||||
var body model.KpiCTitle
|
||||
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
rows := s.kpicReportService.TitleUpdate(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Err(nil))
|
||||
}
|
||||
|
||||
// 自定义标题删除
|
||||
//
|
||||
// DELETE /title/:id
|
||||
func (s KPICController) RemoveTitle(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
id := c.Query("id")
|
||||
if id == "" {
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
uniqueIDs := parse.RemoveDuplicatesToArray(id, ",")
|
||||
// 转换成int64数组类型
|
||||
ids := make([]int64, 0)
|
||||
for _, v := range uniqueIDs {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.kpicReportService.TitleDeleteByIds(ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
}
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, resp.OkMsg(msg))
|
||||
}
|
||||
@@ -72,7 +72,7 @@ func (s NBStateController) List(c *gin.Context) {
|
||||
|
||||
// 历史记录列表导出
|
||||
//
|
||||
// POST /export
|
||||
// GET /export
|
||||
//
|
||||
// @Tags network_data/amf,network_data/mme
|
||||
// @Accept json
|
||||
@@ -82,7 +82,7 @@ func (s NBStateController) List(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary Base Station Status List Export
|
||||
// @Description Base Station Status List Export
|
||||
// @Router /nb-state/export [post]
|
||||
// @Router /nb-state/export [get]
|
||||
func (s NBStateController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
@@ -19,15 +18,15 @@ import (
|
||||
// 实例化控制层 AMFController 结构体
|
||||
var NewAMF = &AMFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
ueEventService: neDataService.NewUEEventAMF,
|
||||
ueEventService: neDataService.NewUEEvent,
|
||||
}
|
||||
|
||||
// 网元AMF
|
||||
//
|
||||
// PATH /amf
|
||||
type AMFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEventAMF // UE会话事件服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEvent // UE会话事件服务
|
||||
}
|
||||
|
||||
// UE会话列表
|
||||
@@ -49,23 +48,20 @@ type AMFController struct {
|
||||
// @Router /neData/amf/ue/list [get]
|
||||
func (s *AMFController) UEList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.UEEventAMFQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID("AMF", querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
@@ -98,7 +94,7 @@ func (s *AMFController) UERemove(c *gin.Context) {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.ueEventService.DeleteByIds(ids)
|
||||
rows, err := s.ueEventService.DeleteByIds("AMF", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -109,7 +105,7 @@ func (s *AMFController) UERemove(c *gin.Context) {
|
||||
|
||||
// UE会话列表导出
|
||||
//
|
||||
// POST /ue/export
|
||||
// GET /ue/export
|
||||
//
|
||||
// @Tags network_data/amf
|
||||
// @Accept json
|
||||
@@ -119,28 +115,23 @@ func (s *AMFController) UERemove(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session List Export
|
||||
// @Description UE Session List Export
|
||||
// @Router /neData/amf/ue/export [post]
|
||||
// @Router /neData/amf/ue/export [get]
|
||||
func (s *AMFController) UEExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.UEEventAMFQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
if querys.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID("AMF", querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
@@ -150,7 +141,7 @@ func (s *AMFController) UEExport(c *gin.Context) {
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("amf_ue_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.ueEventService.ExportXlsx(rows, fileName, language)
|
||||
saveFilePath, err := s.ueEventService.ExportAMF(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
|
||||
317
src/modules/network_data/controller/cbc.go
Normal file
317
src/modules/network_data/controller/cbc.go
Normal file
@@ -0,0 +1,317 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
neType = "CBC" // 网元类型
|
||||
)
|
||||
|
||||
// 实例化控制层 CBCController 结构体
|
||||
var NewCBC = &CBCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neCBCMessageService: neDataService.NewCBCMessage,
|
||||
}
|
||||
|
||||
// 网元CBC
|
||||
type CBCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neCBCMessageService *neDataService.CBCMessage // CBC消息服务
|
||||
}
|
||||
|
||||
func (m *CBCController) List(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
neId := c.Query("neId")
|
||||
if neId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
var query model.CBCMessageQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
query.NeType = neType
|
||||
query.NeId = neId
|
||||
|
||||
data, total, err := neDataService.NewCBCMessage.SelectByPage(query)
|
||||
if err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 转换数据格式,确保 MessageJson 正确序列化
|
||||
processedData := make([]map[string]interface{}, len(data))
|
||||
for i, msg := range data {
|
||||
var messageJson interface{}
|
||||
if len(msg.MessageJson) > 0 {
|
||||
// 尝试解析为 JSON 对象
|
||||
if err := json.Unmarshal(msg.MessageJson, &messageJson); err != nil {
|
||||
// 如果解析失败,就作为字符串
|
||||
messageJson = string(msg.MessageJson)
|
||||
}
|
||||
}
|
||||
|
||||
processedData[i] = map[string]interface{}{
|
||||
"id": msg.Id,
|
||||
"neType": msg.NeType,
|
||||
"neId": msg.NeId,
|
||||
"messageJson": messageJson, // 这里是解析后的 JSON 对象
|
||||
"status": msg.Status.Enum(),
|
||||
"detail": msg.Detail,
|
||||
"createdAt": msg.CreatedAt,
|
||||
"updatedAt": msg.UpdatedAt,
|
||||
}
|
||||
}
|
||||
c.JSON(200, resp.Ok(gin.H{
|
||||
"total": total,
|
||||
"data": processedData,
|
||||
}))
|
||||
}
|
||||
|
||||
// Update 更新CB消息
|
||||
func (m *CBCController) Insert(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 绑定请求体
|
||||
var msg model.CBCMessage
|
||||
msg.NeType = neType
|
||||
msg.NeId = c.Query("neId")
|
||||
msg.Status = model.CBCEventStatusInactive // 默认状态为 INACTIVE
|
||||
if msg.NeId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
now := time.Now().UnixMilli()
|
||||
msg.CreatedAt = now
|
||||
msg.UpdatedAt = now
|
||||
|
||||
// 使用 ShouldBindBodyWithJSON 读取请求体
|
||||
var jsonData interface{}
|
||||
if err := c.ShouldBindBodyWithJSON(&jsonData); err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 将绑定的数据转换为 JSON
|
||||
jsonBytes, err := json.Marshal(jsonData)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
msg.MessageJson = json.RawMessage(jsonBytes)
|
||||
|
||||
if err := neDataService.NewCBCMessage.Insert(msg); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// Update 更新CB消息
|
||||
func (m *CBCController) Update(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
// 获取路径参数
|
||||
messageId := c.Param("id")
|
||||
if messageId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(messageId, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
// 直接读取body为json.RawMessage
|
||||
var jsonData interface{}
|
||||
if err := c.ShouldBindBodyWithJSON(&jsonData); err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 将绑定的数据转换为 JSON
|
||||
jsonBytes, err := json.Marshal(jsonData)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
messageJson := json.RawMessage(jsonBytes)
|
||||
|
||||
if err := neDataService.NewCBCMessage.Update(id, messageJson); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// UpdateStatus 更新CB消息状态
|
||||
// 这里的 neId 参数是为了兼容性,实际更新状态时不需要使用它
|
||||
// 但为了保持与原有接口一致,仍然保留该参数
|
||||
// 如果需要根据 neId 进行特定的逻辑处理,可以在服务层实现
|
||||
// 但在当前实现中,neId 仅用于验证请求的有效性
|
||||
// 实际的状态更新逻辑不依赖于 neId
|
||||
// 该接口用于更新 CB 消息的状态,状态值通过查询参数传递
|
||||
// 例如:PUT /:neId/message/status?status=ACTIVE
|
||||
func (m *CBCController) UpdateStatus(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
neId := c.Query("neId")
|
||||
status := c.Param("status")
|
||||
if neId == "" || status == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
messageId := c.Param("id")
|
||||
if messageId != "" {
|
||||
id, err := strconv.ParseInt(messageId, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
// 如果提供了 messageId,则更新特定消息的状态
|
||||
if err := neDataService.NewCBCMessage.UpdateStatus(id, status); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
return
|
||||
}
|
||||
// 如果没有提供 messageId,则更新所有消息的状态
|
||||
if err := neDataService.NewCBCMessage.UpdateStatusByNeId(neId, status); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// Delete 删除CB消息
|
||||
func (m *CBCController) Delete(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
// 获取路径参数
|
||||
messageId := c.Param("id")
|
||||
if messageId == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(messageId, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
if err := neDataService.NewCBCMessage.Delete(id); err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(nil))
|
||||
}
|
||||
|
||||
// ListById 根据ID获取CB消息
|
||||
func (m *CBCController) ListById(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
|
||||
// 获取路径参数
|
||||
idStr := c.Param("id")
|
||||
if idStr == "" {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(idStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(400, resp.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
data, err := neDataService.NewCBCMessage.SelectById(id)
|
||||
if err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
c.JSON(404, resp.CodeMsg(404, i18n.TKey(language, "app.common.err404")))
|
||||
return
|
||||
}
|
||||
// 转换数据格式,确保 MessageJson 正确序列化
|
||||
var messageJson interface{}
|
||||
if len(data.MessageJson) > 0 {
|
||||
// 尝试解析为 JSON 对象
|
||||
if err := json.Unmarshal(data.MessageJson, &messageJson); err != nil {
|
||||
// 如果解析失败,就作为字符串
|
||||
messageJson = string(data.MessageJson)
|
||||
}
|
||||
}
|
||||
|
||||
processedData := map[string]interface{}{
|
||||
"id": data.Id,
|
||||
"neType": data.NeType,
|
||||
"neId": data.NeId,
|
||||
"messageJson": messageJson, // 这里是解析后的 JSON 对象
|
||||
"status": data.Status.Enum(),
|
||||
"detail": data.Detail,
|
||||
"createdAt": data.CreatedAt,
|
||||
"updatedAt": data.UpdatedAt,
|
||||
}
|
||||
|
||||
c.JSON(200, resp.Ok(gin.H{
|
||||
"data": processedData,
|
||||
}))
|
||||
}
|
||||
|
||||
func (m *CBCController) Export(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var query model.CBCMessageQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
// 限制导出数据集
|
||||
if query.PageSize > 10000 {
|
||||
query.PageSize = 10000
|
||||
}
|
||||
// 查询数据
|
||||
rows, total, err := m.neCBCMessageService.SelectByPage(query)
|
||||
if err != nil {
|
||||
c.JSON(500, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
return
|
||||
}
|
||||
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("cbc_message_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := m.neCBCMessageService.ExportXlsx(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
@@ -19,15 +18,15 @@ import (
|
||||
// 实例化控制层 IMSController 结构体
|
||||
var NewIMS = &IMSController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventIMS,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
}
|
||||
|
||||
// 网元IMS
|
||||
//
|
||||
// PATH /ims
|
||||
type IMSController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventIMS // CDR会话事件服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
@@ -50,23 +49,20 @@ type IMSController struct {
|
||||
// @Router /neData/ims/cdr/list [get]
|
||||
func (s *IMSController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.CDREventIMSQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
@@ -99,7 +95,7 @@ func (s *IMSController) CDRRemove(c *gin.Context) {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds(ids)
|
||||
rows, err := s.cdrEventService.DeleteByIds("IMS", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -110,7 +106,7 @@ func (s *IMSController) CDRRemove(c *gin.Context) {
|
||||
|
||||
// CDR会话列表导出
|
||||
//
|
||||
// POST /cdr/export
|
||||
// GET /cdr/export
|
||||
//
|
||||
// @Tags network_data/ims
|
||||
// @Accept json
|
||||
@@ -120,28 +116,23 @@ func (s *IMSController) CDRRemove(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List Export
|
||||
// @Description CDR Session List Export
|
||||
// @Router /neData/ims/cdr/export [post]
|
||||
// @Router /neData/ims/cdr/export [get]
|
||||
func (s *IMSController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventIMSQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
if querys.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
@@ -151,7 +142,7 @@ func (s *IMSController) CDRExport(c *gin.Context) {
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("ims_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportXlsx(rows, fileName, language)
|
||||
saveFilePath, err := s.cdrEventService.ExportIMS(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
@@ -19,15 +18,15 @@ import (
|
||||
// 实例化控制层 MMEController 结构体
|
||||
var NewMME = &MMEController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
ueEventService: neDataService.NewUEEventMME,
|
||||
ueEventService: neDataService.NewUEEvent,
|
||||
}
|
||||
|
||||
// 网元MME
|
||||
//
|
||||
// PATH /mme
|
||||
type MMEController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEventMME // UE会话事件服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
ueEventService *neDataService.UEEvent // UE会话事件服务
|
||||
}
|
||||
|
||||
// UE会话列表
|
||||
@@ -49,23 +48,20 @@ type MMEController struct {
|
||||
// @Router /neData/mme/ue/list [get]
|
||||
func (s *MMEController) UEList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.UEEventMMEQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID("MME", querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
@@ -98,7 +94,7 @@ func (s *MMEController) UERemove(c *gin.Context) {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.ueEventService.DeleteByIds(ids)
|
||||
rows, err := s.ueEventService.DeleteByIds("MME", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -109,7 +105,7 @@ func (s *MMEController) UERemove(c *gin.Context) {
|
||||
|
||||
// UE会话列表导出
|
||||
//
|
||||
// POST /ue/export
|
||||
// GET /ue/export
|
||||
//
|
||||
// @Tags network_data/mme
|
||||
// @Accept json
|
||||
@@ -119,28 +115,23 @@ func (s *MMEController) UERemove(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary UE Session List Export
|
||||
// @Description UE Session List Export
|
||||
// @Router /neData/mme/ue/export [post]
|
||||
// @Router /neData/mme/ue/export [get]
|
||||
func (s *MMEController) UEExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.UEEventMMEQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
if querys.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID("MME", querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
rows, total := s.ueEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.ueEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
@@ -150,7 +141,7 @@ func (s *MMEController) UEExport(c *gin.Context) {
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("mme_ue_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.ueEventService.ExportXlsx(rows, fileName, language)
|
||||
saveFilePath, err := s.ueEventService.ExportMME(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
|
||||
70
src/modules/network_data/controller/n3iwf.go
Normal file
70
src/modules/network_data/controller/n3iwf.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 N3IWFController 结构体
|
||||
var NewN3IWF = &N3IWFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// 网元N3IWF
|
||||
//
|
||||
// PATH /n3iwf
|
||||
type N3IWFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// 在线订阅用户列表信息
|
||||
//
|
||||
// GET /sub/list
|
||||
//
|
||||
// @Tags network_data/n3iwf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Param imsi query string false "imsi"
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/n3iwf/sub/list [get]
|
||||
func (s N3IWFController) SubUserList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
IMSI string `form:"imsi"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID("N3IWF", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.N3IWFSubInfoList(neInfo, map[string]string{
|
||||
"imsi": query.IMSI,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
107
src/modules/network_data/controller/nssf.go
Normal file
107
src/modules/network_data/controller/nssf.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 实例化控制层 NSSFController 结构体
|
||||
var NewNSSF = &NSSFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
}
|
||||
|
||||
// 网元NSSF
|
||||
//
|
||||
// PATH /NSSF
|
||||
type NSSFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
}
|
||||
|
||||
// 在线订阅用户列表信息
|
||||
//
|
||||
// GET /sub/list
|
||||
//
|
||||
// @Tags network_data/nssf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/nssf/sub/list [get]
|
||||
func (s NSSFController) SubUserList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID("NSSF", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.NSSFSubInfoList(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
|
||||
// 可用AMF列表信息
|
||||
//
|
||||
// GET /amf/list
|
||||
//
|
||||
// @Tags network_data/nssf
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param neId query string true "NE ID" default(001)
|
||||
// @Success 200 {object} object "Response Results"
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/nssf/amf/list [get]
|
||||
func (s NSSFController) AvailableList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID("NSSF", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.NSSFAvailableAMFList(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, resp.OkData(data))
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -17,7 +16,7 @@ import (
|
||||
// 实例化控制层 SGWCController 结构体
|
||||
var NewSGWC = &SGWCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventSGWC,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
UDMExtendService: neDataService.NewUDMExtend,
|
||||
}
|
||||
|
||||
@@ -25,9 +24,9 @@ var NewSGWC = &SGWCController{
|
||||
//
|
||||
// PATH /sgwc
|
||||
type SGWCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventSGWC // CDR会话事件服务
|
||||
UDMExtendService *neDataService.UDMExtend // UDM用户信息服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
UDMExtendService *neDataService.UDMExtend // UDM用户信息服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
@@ -50,23 +49,20 @@ type SGWCController struct {
|
||||
// @Router /neData/sgwc/cdr/list [get]
|
||||
func (s *SGWCController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.CDREventSGWCQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
@@ -99,7 +95,7 @@ func (s *SGWCController) CDRRemove(c *gin.Context) {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds(ids)
|
||||
rows, err := s.cdrEventService.DeleteByIds("SGWC", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -123,25 +119,20 @@ func (s *SGWCController) CDRRemove(c *gin.Context) {
|
||||
// @Router /neData/sgwc/cdr/export [post]
|
||||
func (s *SGWCController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventSGWCQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
if querys.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
@@ -151,7 +142,7 @@ func (s *SGWCController) CDRExport(c *gin.Context) {
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("sgwc_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportXlsx(rows, fileName)
|
||||
saveFilePath, err := s.cdrEventService.ExportSGWC(rows, fileName)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
@@ -20,7 +19,7 @@ import (
|
||||
// 实例化控制层 SMFController 结构体
|
||||
var NewSMF = &SMFController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventSMF,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
UDMExtendService: neDataService.NewUDMExtend,
|
||||
}
|
||||
|
||||
@@ -28,9 +27,9 @@ var NewSMF = &SMFController{
|
||||
//
|
||||
// PATH /smf
|
||||
type SMFController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventSMF // CDR会话事件服务
|
||||
UDMExtendService *neDataService.UDMExtend // UDM用户信息服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
UDMExtendService *neDataService.UDMExtend // UDM用户信息服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
@@ -52,23 +51,20 @@ type SMFController struct {
|
||||
// @Router /neData/smf/cdr/list [get]
|
||||
func (s *SMFController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.CDREventSMFQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
@@ -101,7 +97,7 @@ func (s *SMFController) CDRRemove(c *gin.Context) {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds(ids)
|
||||
rows, err := s.cdrEventService.DeleteByIds("SMF", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -112,7 +108,7 @@ func (s *SMFController) CDRRemove(c *gin.Context) {
|
||||
|
||||
// CDR会话列表导出
|
||||
//
|
||||
// POST /cdr/export
|
||||
// GET /cdr/export
|
||||
//
|
||||
// @Tags network_data/smf
|
||||
// @Accept json
|
||||
@@ -122,28 +118,23 @@ func (s *SMFController) CDRRemove(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List Export
|
||||
// @Description CDR Session List Export
|
||||
// @Router /neData/smf/cdr/export [post]
|
||||
// @Router /neData/smf/cdr/export [get]
|
||||
func (s *SMFController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventSMFQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
if querys.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
@@ -153,7 +144,7 @@ func (s *SMFController) CDRExport(c *gin.Context) {
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("smf_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportXlsx(rows, fileName)
|
||||
saveFilePath, err := s.cdrEventService.ExportSMF(rows, fileName)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
@@ -219,7 +210,7 @@ func (s *SMFController) SubUserNum(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary Online session user list information
|
||||
// @Description Online session user list information
|
||||
// @Router /neData/smf/session/list [get]
|
||||
// @Router /neData/smf/sub/list [get]
|
||||
func (s *SMFController) SubUserList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
|
||||
@@ -18,15 +17,15 @@ import (
|
||||
// 实例化控制层 SMSCController 结构体
|
||||
var NewSMSC = &SMSCController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
cdrEventService: neDataService.NewCDREventSMSC,
|
||||
cdrEventService: neDataService.NewCDREvent,
|
||||
}
|
||||
|
||||
// 网元SMSC
|
||||
//
|
||||
// PATH /smsc
|
||||
type SMSCController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREventSMSC // CDR会话事件服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
cdrEventService *neDataService.CDREvent // CDR会话事件服务
|
||||
}
|
||||
|
||||
// CDR会话列表
|
||||
@@ -49,23 +48,20 @@ type SMSCController struct {
|
||||
// @Router /neData/smsc/cdr/list [get]
|
||||
func (s *SMSCController) CDRList(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
var querys model.CDREventSMSCQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
@@ -98,7 +94,7 @@ func (s *SMSCController) CDRRemove(c *gin.Context) {
|
||||
ids = append(ids, parse.Number(v))
|
||||
}
|
||||
|
||||
rows, err := s.cdrEventService.DeleteByIds(ids)
|
||||
rows, err := s.cdrEventService.DeleteByIds("SMSC", ids)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
|
||||
return
|
||||
@@ -109,7 +105,7 @@ func (s *SMSCController) CDRRemove(c *gin.Context) {
|
||||
|
||||
// CDR会话列表导出
|
||||
//
|
||||
// POST /cdr/export
|
||||
// GET /cdr/export
|
||||
//
|
||||
// @Tags network_data/smsc
|
||||
// @Accept json
|
||||
@@ -119,28 +115,23 @@ func (s *SMSCController) CDRRemove(c *gin.Context) {
|
||||
// @Security TokenAuth
|
||||
// @Summary CDR Session List Export
|
||||
// @Description CDR Session List Export
|
||||
// @Router /neData/smsc/cdr/export [post]
|
||||
// @Router /neData/smsc/cdr/export [get]
|
||||
func (s *SMSCController) CDRExport(c *gin.Context) {
|
||||
language := reqctx.AcceptLanguage(c)
|
||||
// 查询结果,根据查询条件结果,单页最大值限制
|
||||
var querys model.CDREventSMSCQuery
|
||||
if err := c.ShouldBindBodyWithJSON(&querys); err != nil {
|
||||
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
|
||||
return
|
||||
}
|
||||
query := reqctx.QueryMap(c)
|
||||
// 限制导出数据集
|
||||
if querys.PageSize > 10000 {
|
||||
querys.PageSize = 10000
|
||||
pageSize := parse.Number(query["pageSize"])
|
||||
if pageSize > 10000 {
|
||||
query["pageSize"] = "10000"
|
||||
}
|
||||
// 查询网元信息 rmUID
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query["neType"], query["neId"])
|
||||
if neInfo.NeType == "" {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(querys)
|
||||
query["rmUID"] = neInfo.RmUID
|
||||
rows, total := s.cdrEventService.FindByPage(neInfo.NeType, query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
@@ -150,7 +141,7 @@ func (s *SMSCController) CDRExport(c *gin.Context) {
|
||||
// 导出文件名称
|
||||
fileName := fmt.Sprintf("smsc_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
|
||||
// 导出数据表格
|
||||
saveFilePath, err := s.cdrEventService.ExportXlsx(rows, fileName, language)
|
||||
saveFilePath, err := s.cdrEventService.ExportSMSC(rows, fileName, language)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
|
||||
@@ -77,8 +77,8 @@ func (s *UDMAuthController) ResetData(c *gin.Context) {
|
||||
// @Router /neData/udm/auth/list [get]
|
||||
func (s *UDMAuthController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmAuthService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
rows, total := s.udmAuthService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDM鉴权用户信息
|
||||
@@ -478,7 +478,7 @@ func (s *UDMAuthController) Export(c *gin.Context) {
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmAuthService.FindByPage(query)
|
||||
rows, total := s.udmAuthService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
|
||||
@@ -77,8 +77,8 @@ func (s *UDMSubController) ResetData(c *gin.Context) {
|
||||
// @Router /neData/udm/sub/list [get]
|
||||
func (s *UDMSubController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmSubService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
rows, total := s.udmSubService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDM签约用户信息
|
||||
@@ -484,7 +484,7 @@ func (s *UDMSubController) Export(c *gin.Context) {
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmSubService.FindByPage(query)
|
||||
rows, total := s.udmSubService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
|
||||
@@ -76,8 +76,8 @@ func (s *UDMVOIPController) ResetData(c *gin.Context) {
|
||||
// @Router /neData/udm/voip/list [get]
|
||||
func (s *UDMVOIPController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmVOIPService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
rows, total := s.udmVOIPService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDMVOIP用户信息
|
||||
@@ -416,7 +416,7 @@ func (s *UDMVOIPController) Export(c *gin.Context) {
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmVOIPService.FindByPage(query)
|
||||
rows, total := s.udmVOIPService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
|
||||
@@ -76,8 +76,8 @@ func (s *UDMVolteIMSController) ResetData(c *gin.Context) {
|
||||
// @Router /neData/udm/volte-ims/list [get]
|
||||
func (s *UDMVolteIMSController) List(c *gin.Context) {
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmVolteIMSService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows}))
|
||||
rows, total := s.udmVolteIMSService.FindByPage(query)
|
||||
c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total}))
|
||||
}
|
||||
|
||||
// UDMVolteIMS用户信息
|
||||
@@ -462,7 +462,7 @@ func (s *UDMVolteIMSController) Export(c *gin.Context) {
|
||||
}
|
||||
|
||||
query := reqctx.QueryMap(c)
|
||||
total, rows := s.udmVolteIMSService.FindByPage(query)
|
||||
rows, total := s.udmVolteIMSService.FindByPage(query)
|
||||
if total == 0 {
|
||||
// 导出数据记录为空
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||
|
||||
@@ -8,26 +8,26 @@ type Alarm struct {
|
||||
NeName string `json:"neName" gorm:"column:ne_name"` // 网元名称
|
||||
Province string `json:"province" gorm:"column:province"` // 网元省份地域
|
||||
PvFlag string `json:"pvFlag" gorm:"column:pv_flag"` // 网元标识虚拟化标识
|
||||
AlarmSeq int64 `json:"alarmSeq" gorm:"column:alarm_seq"` // 告警序号 同网元类型连续递增
|
||||
AlarmSeq int64 `json:"alarmSeq" gorm:"column:alarm_seq"` // 告警序号 连续递增
|
||||
AlarmId string `json:"alarmId" gorm:"column:alarm_id"` // 告警ID
|
||||
AlarmTitle string `json:"alarmTitle" gorm:"column:alarm_title"` // 告警标题
|
||||
AlarmCode int64 `json:"alarmCode" gorm:"column:alarm_code"` // 告警状态码
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间 秒级
|
||||
AlarmType string `json:"alarmType" gorm:"column:alarm_type"` // 告警类型 CommunicationAlarm=1,EquipmentAlarm=2,ProcessingFailure=3,EnvironmentalAlarm=4,QualityOfServiceAlarm=5
|
||||
OrigSeverity string `json:"origSeverity" gorm:"column:orig_severity"` // 严重程度 1: Critical, 2: Major, 3: Minor, 4: Warning, 5: Event(Only VNF)
|
||||
PerceivedSeverity string `json:"perceivedSeverity" gorm:"column:perceived_severity"` // 告警级别 1: Critical, 2: Major, 3: Minor, 4: Warning, 5: Event(Only VNF)
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间
|
||||
AlarmType string `json:"alarmType" gorm:"column:alarm_type"` // 告警类型
|
||||
OrigSeverity string `json:"origSeverity" gorm:"column:orig_severity"` // 严重程度
|
||||
PerceivedSeverity string `json:"perceivedSeverity" gorm:"column:perceived_severity"` // 告警级别
|
||||
ObjectUid string `json:"objectUid" gorm:"column:object_uid"` // 对象ID
|
||||
ObjectName string `json:"objectName" gorm:"column:object_name"` // 对象名称
|
||||
ObjectType string `json:"objectType" gorm:"column:object_type"` // 对象类型
|
||||
LocationInfo string `json:"locationInfo" gorm:"column:location_info"` // 告警定位信息
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态 0:clear, 1:active
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态
|
||||
SpecificProblem string `json:"specificProblem" gorm:"column:specific_problem"` // 告警问题原因
|
||||
SpecificProblemId string `json:"specificProblemId" gorm:"column:specific_problem_id"` // 告警问题原因ID
|
||||
AddInfo string `json:"addInfo" gorm:"column:add_info"` // 告警辅助信息
|
||||
AckState int64 `json:"ackState" gorm:"column:ack_state"` // 确认状态 0: Unacked, 1: Acked
|
||||
AckTime int64 `json:"ackTime" gorm:"column:ack_time"` // 确认时间 秒级
|
||||
AckState string `json:"ackState" gorm:"column:ack_state"` // 确认状态
|
||||
AckTime int64 `json:"ackTime" gorm:"column:ack_time"` // 确认时间
|
||||
AckUser string `json:"ackUser" gorm:"column:ack_user"` // 确认用户
|
||||
ClearType int64 `json:"clearType" gorm:"column:clear_type"` // 清除状态 0: Unclear, 1: AutoClear, 2: ManualClear
|
||||
ClearType string `json:"clearType" gorm:"column:clear_type"` // 清除状态
|
||||
ClearTime int64 `json:"clearTime" gorm:"column:clear_time"` // 清除时间
|
||||
ClearUser string `json:"clearUser" gorm:"column:clear_user"` // 清除用户
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 创建时间
|
||||
@@ -46,9 +46,9 @@ type AlarmQuery struct {
|
||||
PvFlag string `json:"pvFlag" form:"pvFlag"`
|
||||
AlarmCode string `json:"alarmCode" form:"alarmCode"`
|
||||
AlarmType string `json:"alarmType" form:"alarmType"`
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"omitempty,oneof=0 1"` // 告警状态 0:clear, 1:active
|
||||
OrigSeverity string `json:"origSeverity" form:"origSeverity"` // 告警类型 1: Critical, 2: Major, 3: Minor, 4: Warning, 5: Event(Only VNF)
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查event_time
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"omitempty,oneof=Clear Active"` // 告警状态
|
||||
OrigSeverity string `json:"origSeverity" form:"origSeverity"` // 告警类型
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查event_time
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=event_time id"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
|
||||
@@ -9,16 +9,16 @@ type AlarmEvent struct {
|
||||
AlarmId string `json:"alarmId" gorm:"column:alarm_id"` // 告警ID
|
||||
AlarmTitle string `json:"alarmTitle" gorm:"column:alarm_title"` // 告警标题
|
||||
AlarmCode int64 `json:"alarmCode" gorm:"column:alarm_code"` // 告警状态码
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间 秒级
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间
|
||||
ObjectUid string `json:"objectUid" gorm:"column:object_uid"` // 对象ID
|
||||
ObjectName string `json:"objectName" gorm:"column:object_name"` // 对象名称
|
||||
ObjectType string `json:"objectType" gorm:"column:object_type"` // 对象类型
|
||||
LocationInfo string `json:"locationInfo" gorm:"column:location_info"` // 告警定位信息
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态 0:clear, 1:active
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态
|
||||
SpecificProblem string `json:"specificProblem" gorm:"column:specific_problem"` // 告警问题原因
|
||||
SpecificProblemId string `json:"specificProblemId" gorm:"column:specific_problem_id"` // 告警问题原因ID
|
||||
AddInfo string `json:"addInfo" gorm:"column:add_info"` // 告警辅助信息
|
||||
ClearType int64 `json:"clearType" gorm:"column:clear_type"` // 清除状态 0: Unclear, 1: AutoClear, 2: ManualClear
|
||||
ClearType string `json:"clearType" gorm:"column:clear_type"` // 清除状态
|
||||
ClearTime int64 `json:"clearTime" gorm:"column:clear_time"` // 清除时间
|
||||
ClearUser string `json:"clearUser" gorm:"column:clear_user"` // 清除用户
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 创建时间
|
||||
@@ -34,8 +34,8 @@ type AlarmEventQuery struct {
|
||||
NeType string `json:"neType" form:"neType"` // 网元类型
|
||||
NeID string `json:"neId" form:"neId"` // 网元ID
|
||||
AlarmCode string `json:"alarmCode" form:"alarmCode"`
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"omitempty,oneof=0 1"` // 告警状态 0:clear, 1:active
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查event_time
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"omitempty,oneof=Clear Active"` // 告警状态
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查event_time
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=event_time id"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
|
||||
@@ -5,16 +5,16 @@ type AlarmForwardLog struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeId string `json:"neId" gorm:"column:ne_id"`
|
||||
AlarmSeq int64 `json:"alarmSeq" gorm:"column:alarm_seq"` // 告警序号 同网元类型连续递增
|
||||
AlarmSeq int64 `json:"alarmSeq" gorm:"column:alarm_seq"` // 告警序号 连续递增
|
||||
AlarmId string `json:"alarmId" gorm:"column:alarm_id"` // 告警ID
|
||||
AlarmCode int64 `json:"alarmCode" gorm:"column:alarm_code"` // 告警状态码
|
||||
AlarmTitle string `json:"alarmTitle" gorm:"column:alarm_title"` // 告警标题
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态 0:clear, 1:active
|
||||
AlarmType string `json:"alarmType" gorm:"column:alarm_type"` // 告警类型 CommunicationAlarm=1,EquipmentAlarm=2,ProcessingFailure=3,EnvironmentalAlarm=4,QualityOfServiceAlarm=5
|
||||
OrigSeverity string `json:"origSeverity" gorm:"column:orig_severity"` // 严重程度 1: Critical, 2: Major, 3: Minor, 4: Warning, 5: Event(Only VNF)
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间 秒级
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态
|
||||
AlarmType string `json:"alarmType" gorm:"column:alarm_type"` // 告警类型
|
||||
OrigSeverity string `json:"origSeverity" gorm:"column:orig_severity"` // 严重程度
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 创建时间
|
||||
Type string `json:"type" gorm:"column:type"` // 转发方式 SMS/EMAIL
|
||||
Type string `json:"type" gorm:"column:type"` // 转发方式 SMS/EMAIL/SMSC
|
||||
Target string `json:"target" gorm:"column:target"` // 发送目标用户
|
||||
Result string `json:"result" gorm:"column:result"` // 发送结果
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (*AlarmForwardLog) TableName() string {
|
||||
type AlarmForwardLogQuery struct {
|
||||
NeType string `json:"neType" form:"neType"` // 网元类型
|
||||
NeID string `json:"neId" form:"neId"` // 网元ID
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查event_time
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=event_time id"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
|
||||
@@ -5,14 +5,14 @@ type AlarmLog struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeId string `json:"neId" gorm:"column:ne_id"`
|
||||
AlarmSeq int64 `json:"alarmSeq" gorm:"column:alarm_seq"` // 告警序号 同网元类型连续递增
|
||||
AlarmSeq int64 `json:"alarmSeq" gorm:"column:alarm_seq"` // 告警序号 连续递增
|
||||
AlarmId string `json:"alarmId" gorm:"column:alarm_id"` // 告警ID
|
||||
AlarmCode int64 `json:"alarmCode" gorm:"column:alarm_code"` // 告警状态码
|
||||
AlarmTitle string `json:"alarmTitle" gorm:"column:alarm_title"` // 告警标题
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态 0:clear, 1:active
|
||||
AlarmType string `json:"alarmType" gorm:"column:alarm_type"` // 告警类型 CommunicationAlarm=1,EquipmentAlarm=2,ProcessingFailure=3,EnvironmentalAlarm=4,QualityOfServiceAlarm=5
|
||||
OrigSeverity string `json:"origSeverity" gorm:"column:orig_severity"` // 严重程度 1: Critical, 2: Major, 3: Minor, 4: Warning, 5: Event(Only VNF)
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间 秒级
|
||||
AlarmStatus string `json:"alarmStatus" gorm:"column:alarm_status"` // 告警状态
|
||||
AlarmType string `json:"alarmType" gorm:"column:alarm_type"` // 告警类型
|
||||
OrigSeverity string `json:"origSeverity" gorm:"column:orig_severity"` // 严重程度
|
||||
EventTime int64 `json:"eventTime" gorm:"column:event_time"` // 事件产生时间
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 创建时间
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ func (*AlarmLog) TableName() string {
|
||||
|
||||
// AlarmLogQuery 告警日志数据查询参数结构体
|
||||
type AlarmLogQuery struct {
|
||||
NeType string `json:"neType" form:"neType"` // 网元类型
|
||||
NeID string `json:"neId" form:"neId"` // 网元ID
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"omitempty,oneof=0 1"` // 告警状态 0:clear, 1:active
|
||||
OrigSeverity string `json:"origSeverity" form:"origSeverity"` // 告警类型 1: Critical, 2: Major, 3: Minor, 4: Warning, 5: Event(Only VNF)
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查event_time
|
||||
NeType string `json:"neType" form:"neType"` // 网元类型
|
||||
NeID string `json:"neId" form:"neId"` // 网元ID
|
||||
AlarmStatus string `json:"alarmStatus" form:"alarmStatus" binding:"omitempty,oneof=Clear Active"` // 告警状态
|
||||
OrigSeverity string `json:"origSeverity" form:"origSeverity"` // 告警类型
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查event_time
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=event_time id"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
|
||||
112
src/modules/network_data/model/cbc_message.go
Normal file
112
src/modules/network_data/model/cbc_message.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CBCEventStatus int
|
||||
|
||||
// CBCEventStatus CB事件状态枚举
|
||||
const (
|
||||
CBCEventStatusNull CBCEventStatus = iota // 未知状态
|
||||
CBCEventStatusActive
|
||||
CBCEventStatusInactive
|
||||
)
|
||||
|
||||
func (status CBCEventStatus) Enum() string {
|
||||
switch status {
|
||||
case CBCEventStatusNull:
|
||||
return "NULL"
|
||||
case CBCEventStatusActive:
|
||||
return "ACTIVE"
|
||||
case CBCEventStatusInactive:
|
||||
return "INACTIVE"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
func (status CBCEventStatus) String() string {
|
||||
return fmt.Sprintf("%d", status)
|
||||
}
|
||||
|
||||
// ParseCBCEventStatus 将字符串转换为 枚举类型
|
||||
func ParseCBCEventStatus(s string) CBCEventStatus {
|
||||
if i, err := strconv.Atoi(s); err == nil {
|
||||
return CBCEventStatus(i)
|
||||
}
|
||||
// 如果转换失败,则按名称匹配(忽略大小写)
|
||||
switch strings.ToUpper(s) {
|
||||
case "NULL":
|
||||
return CBCEventStatusNull
|
||||
case "ACTIVE":
|
||||
return CBCEventStatusActive
|
||||
case "INACTIVE":
|
||||
return CBCEventStatusInactive
|
||||
case "":
|
||||
// 如果字符串为空,则返回未知状态
|
||||
return CBCEventStatusNull
|
||||
default:
|
||||
// 默认返回未知状态
|
||||
return CBCEventStatusNull
|
||||
}
|
||||
}
|
||||
|
||||
// CBCMessageQuery 查询条件结构体
|
||||
type CBCMessageQuery struct {
|
||||
NeType string `form:"neType"` // 网元类型
|
||||
NeId string `form:"neId"` // 网元ID
|
||||
EventName string `form:"eventName"` // 事件名称
|
||||
Status string `form:"status"` // 消息状态
|
||||
StartTime string `form:"startTime"` // 创建时间范围-起始
|
||||
EndTime string `form:"endTime"` // 创建时间范围-结束
|
||||
PageNum int `form:"pageNum" binding:"required"`
|
||||
PageSize int `form:"pageSize" binding:"required"`
|
||||
}
|
||||
|
||||
// @Description CBCMessage CB消息
|
||||
type CBCMessage struct {
|
||||
Id int64 `json:"id" gorm:"column:id"` // CB消息ID
|
||||
NeType string `json:"neType" gorm:"column:ne_type"` // 网元类型
|
||||
NeId string `json:"neId" gorm:"column:ne_id"` // 网元ID
|
||||
MessageJson json.RawMessage `json:"messageJson" gorm:"column:message_json"` // 消息内容JSON
|
||||
Status CBCEventStatus `json:"status" gorm:"column:status"` // 消息状态
|
||||
Detail string `json:"detail" gorm:"column:detail"` // 详情
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 创建时间
|
||||
UpdatedAt int64 `json:"updatedAt" gorm:"column:updated_at"` // 更新时间
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CBCMessage) TableName() string {
|
||||
return "cbc_message"
|
||||
}
|
||||
|
||||
// Scan 实现 sql.Scanner 接口,支持从数据库字符串转为 CBCEventStatus
|
||||
func (s *CBCEventStatus) Scan(value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
*s = ParseCBCEventStatus(v)
|
||||
return nil
|
||||
case []byte:
|
||||
*s = ParseCBCEventStatus(string(v))
|
||||
return nil
|
||||
case int64:
|
||||
*s = CBCEventStatus(v)
|
||||
return nil
|
||||
case int:
|
||||
*s = CBCEventStatus(v)
|
||||
return nil
|
||||
default:
|
||||
return errors.New("unsupported Scan type for CBCEventStatus")
|
||||
}
|
||||
}
|
||||
|
||||
// Value 实现 driver.Valuer 接口,支持将 CBCEventStatus 存为字符串
|
||||
func (s CBCEventStatus) Value() (driver.Value, error) {
|
||||
return s.Enum(), nil
|
||||
}
|
||||
17
src/modules/network_data/model/cdr_event.go
Normal file
17
src/modules/network_data/model/cdr_event.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package model
|
||||
|
||||
// CDREvent CDR会话对象 cdr_event
|
||||
type CDREvent struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUid string `json:"rmUid" gorm:"column:rm_uid"` // 可能没有
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
CdrJson string `json:"cdrJSON" gorm:"column:cdr_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CDREvent) TableName() string {
|
||||
return "cdr_event"
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package model
|
||||
|
||||
// CDREventIMS CDR会话对象IMS cdr_event_ims
|
||||
type CDREventIMS struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUid string `json:"rmUid" gorm:"column:rm_uid"`
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
CdrJson string `json:"cdrJSON" gorm:"column:cdr_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CDREventIMS) TableName() string {
|
||||
return "cdr_event_ims"
|
||||
}
|
||||
|
||||
// CDREventIMSQuery CDR会话对象IMS查询参数结构体
|
||||
type CDREventIMSQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required,oneof=IMS"` // 网元类型IMS
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
RecordType string `json:"recordType" form:"recordType"` // 记录行为 MOC MTC
|
||||
CallerParty string `json:"callerParty" form:"callerParty"` // 主叫号码
|
||||
CalledParty string `json:"calledParty" form:"calledParty"` // 被叫号码
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查timestamp
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package model
|
||||
|
||||
// CDREventSGWC CDR会话对象SGWC cdr_event_sgwc
|
||||
type CDREventSGWC struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUid string `json:"rmUid" gorm:"column:rm_uid"`
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
CdrJson string `json:"cdrJSON" gorm:"column:cdr_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CDREventSGWC) TableName() string {
|
||||
return "cdr_event_sgwc"
|
||||
}
|
||||
|
||||
// CDREventSGWCQuery CDR会话对象SGWC查询参数结构体
|
||||
type CDREventSGWCQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required,oneof=SGWC"` // SGWC
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
IMSI string `json:"imsi" form:"imsi"`
|
||||
MSISDN string `json:"msisdn" form:"msisdn"`
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查timestamp
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package model
|
||||
|
||||
// CDREventSMF CDR会话对象SMF cdr_event_smf
|
||||
type CDREventSMF struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUid string `json:"rmUid" gorm:"column:rm_uid"`
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
CdrJson string `json:"cdrJSON" gorm:"column:cdr_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CDREventSMF) TableName() string {
|
||||
return "cdr_event_smf"
|
||||
}
|
||||
|
||||
// CDREventSMFQuery CDR会话对象SMF查询参数结构体
|
||||
type CDREventSMFQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required,oneof=SMF"` // 网元类型, 暂时支持SMF
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
RecordType string `json:"recordType" form:"recordType"` // 暂时没用到
|
||||
SubscriberID string `json:"subscriberID" form:"subscriberID"`
|
||||
DNN string `json:"dnn" form:"dnn"`
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查timestamp
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package model
|
||||
|
||||
// CDREventSMSC CDR会话对象SMSC cdr_event_smsc
|
||||
type CDREventSMSC struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUid string `json:"rmUid" gorm:"column:rm_uid"` // 可能没有
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
CdrJson string `json:"cdrJSON" gorm:"column:cdr_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*CDREventSMSC) TableName() string {
|
||||
return "cdr_event_smsc"
|
||||
}
|
||||
|
||||
// CDREventSMSCQuery CDR会话对象SMSC查询参数结构体
|
||||
type CDREventSMSCQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required,oneof=SMSC"` // 网元类型, 暂时支持SMSC
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
RecordType string `json:"recordType" form:"recordType"` // 记录行为 MOSM MTSM
|
||||
CallerParty string `json:"callerParty" form:"callerParty"` // 主叫号码
|
||||
CalledParty string `json:"calledParty" form:"calledParty"` // 被叫号码
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查timestamp
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
18
src/modules/network_data/model/ue_event.go
Normal file
18
src/modules/network_data/model/ue_event.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
// UEEvent UE会话对象 ue_event
|
||||
type UEEvent struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUID string `json:"rmUID" gorm:"column:rm_uid"` // 可能没有
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到时间
|
||||
EventType string `json:"eventType" gorm:"column:event_type"` // 事件类型
|
||||
EventJSONStr string `json:"eventJSON" gorm:"column:event_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UEEvent) TableName() string {
|
||||
return "ue_event"
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package model
|
||||
|
||||
// UEEventAMF UE会话对象AMF ue_event_amf
|
||||
type UEEventAMF struct {
|
||||
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUID string `json:"rmUID" gorm:"column:rm_uid"` // 可能没有
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
EventType string `json:"eventType" gorm:"column:event_type"` // 事件类型 auth-result detach cm-state
|
||||
EventJSONStr string `json:"eventJSON" gorm:"column:event_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UEEventAMF) TableName() string {
|
||||
return "ue_event_amf"
|
||||
}
|
||||
|
||||
// UEEventAMFQuery UE会话对象AMF查询参数结构体
|
||||
type UEEventAMFQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required,oneof=AMF"` // 网元类型, 暂时支持AMF
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
EventType string `json:"eventType" form:"eventType"` // 事件类型 auth-result detach cm-state
|
||||
IMSI string `json:"imsi" form:"imsi"` // imsi
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查timestamp
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package model
|
||||
|
||||
// UEEventMME UE会话对象MME ue_event_mme
|
||||
type UEEventMME struct {
|
||||
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||
RmUID string `json:"rmUID" gorm:"column:rm_uid"` // 可能没有
|
||||
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"` // 接收到的timestamp秒级存储毫秒时间戳
|
||||
EventType string `json:"eventType" gorm:"column:event_type"` // 事件类型 auth-result detach cm-state
|
||||
EventJSONStr string `json:"eventJSON" gorm:"column:event_json"` // data JSON String
|
||||
CreatedAt int64 `json:"createdAt" gorm:"column:created_at"` // 记录创建存储毫秒
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
func (*UEEventMME) TableName() string {
|
||||
return "ue_event_mme"
|
||||
}
|
||||
|
||||
// UEEventMMEQuery UE会话对象MME查询参数结构体
|
||||
type UEEventMMEQuery struct {
|
||||
NeType string `json:"neType" form:"neType" binding:"required,oneof=MME"` // 网元类型, 暂时支持MME
|
||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||
RmUID string `json:"rmUID" form:"rmUID"`
|
||||
EventType string `json:"eventType" form:"eventType"` // 事件类型 auth-result detach cm-state
|
||||
IMSI string `json:"imsi" form:"imsi"` // imsi
|
||||
BeginTime int64 `json:"beginTime" form:"beginTime"` // 开始时间 查timestamp
|
||||
EndTime int64 `json:"endTime" form:"endTime"`
|
||||
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
||||
@@ -33,6 +33,31 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 性能自定义统计信息
|
||||
kpicGroup := neDataGroup.Group("/kpic")
|
||||
{
|
||||
kpicGroup.GET("/data",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewKPIC.KPIData,
|
||||
)
|
||||
kpicGroup.GET("/title/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewKPIC.ListTitle,
|
||||
)
|
||||
kpicGroup.POST("/title",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewKPIC.AddTitle,
|
||||
)
|
||||
kpicGroup.PUT("/title",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewKPIC.EditTitle,
|
||||
)
|
||||
kpicGroup.DELETE("/title",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewKPIC.RemoveTitle,
|
||||
)
|
||||
}
|
||||
|
||||
// 告警数据信息
|
||||
alarmGroup := neDataGroup.Group("/alarm")
|
||||
{
|
||||
@@ -59,6 +84,18 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.alarm", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewAlarm.Export,
|
||||
)
|
||||
alarmGroup.GET("/count/type",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAlarm.CountType,
|
||||
)
|
||||
alarmGroup.GET("/count/severity",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAlarm.CountSeverity,
|
||||
)
|
||||
alarmGroup.GET("/count/ne",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewAlarm.CountNe,
|
||||
)
|
||||
}
|
||||
|
||||
// 告警日志数据信息
|
||||
@@ -100,7 +137,7 @@ func Setup(router *gin.Engine) {
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewNBState.List,
|
||||
)
|
||||
nbStateGroup.POST("/export",
|
||||
nbStateGroup.GET("/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewNBState.Export,
|
||||
)
|
||||
@@ -118,7 +155,7 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.imsCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewIMS.CDRRemove,
|
||||
)
|
||||
imsGroup.POST("/cdr/export",
|
||||
imsGroup.GET("/cdr/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.imsCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewIMS.CDRExport,
|
||||
@@ -145,7 +182,7 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smscCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSMSC.CDRRemove,
|
||||
)
|
||||
smscGroup.POST("/cdr/export",
|
||||
smscGroup.GET("/cdr/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smscCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSMSC.CDRExport,
|
||||
@@ -164,7 +201,7 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSMF.CDRRemove,
|
||||
)
|
||||
smfGroup.POST("/cdr/export",
|
||||
smfGroup.GET("/cdr/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSMF.CDRExport,
|
||||
@@ -191,7 +228,7 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.amfUE", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewAMF.UERemove,
|
||||
)
|
||||
amfGroup.POST("/ue/export",
|
||||
amfGroup.GET("/ue/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.amfUE", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewAMF.UEExport,
|
||||
@@ -215,6 +252,29 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 网元N3IWF
|
||||
n3iwfGroup := neDataGroup.Group("/n3iwf")
|
||||
{
|
||||
n3iwfGroup.GET("/sub/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewN3IWF.SubUserList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元N3IWF
|
||||
nssf := controller.NewNSSF
|
||||
nssfGroup := neDataGroup.Group("/nssf")
|
||||
{
|
||||
nssfGroup.GET("/sub/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
nssf.SubUserList,
|
||||
)
|
||||
nssfGroup.GET("/amf/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
nssf.AvailableList,
|
||||
)
|
||||
}
|
||||
|
||||
// 备份数据
|
||||
backupGroup := neDataGroup.Group("/backup")
|
||||
{
|
||||
@@ -452,7 +512,7 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.mmeUE", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewMME.UERemove,
|
||||
)
|
||||
mmeGroup.POST("/ue/export",
|
||||
mmeGroup.GET("/ue/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.mmeUE", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewMME.UEExport,
|
||||
@@ -519,6 +579,44 @@ func Setup(router *gin.Engine) {
|
||||
controller.NewPCF.RuleInfoImport,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元CBC
|
||||
cbcGroup := neDataGroup.Group("/cbc")
|
||||
{
|
||||
cbcGroup.GET("/message/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewCBC.List,
|
||||
)
|
||||
cbcGroup.GET("/message/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewCBC.ListById,
|
||||
)
|
||||
cbcGroup.POST("/message",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||
controller.NewCBC.Insert,
|
||||
)
|
||||
cbcGroup.PUT("/message/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewCBC.Update,
|
||||
)
|
||||
cbcGroup.PUT("/message/:id/:status",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewCBC.UpdateStatus,
|
||||
)
|
||||
cbcGroup.DELETE("/message/:id",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewCBC.Delete,
|
||||
)
|
||||
cbcGroup.GET("/message/export",
|
||||
middleware.AuthorizeUser(nil),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.cbcMessage", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewCBC.Export,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// InitLoad 初始参数
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -32,7 +33,7 @@ func (r Alarm) SelectByPage(query model.AlarmQuery) ([]model.Alarm, int64) {
|
||||
tx = tx.Where("pv_flag = ?", query.PvFlag)
|
||||
}
|
||||
if query.AlarmCode != "" {
|
||||
tx = tx.Where("alarm_code = ?", query.AlarmCode)
|
||||
tx = tx.Where("alarm_code like ?", fmt.Sprintf("%%%s%%", query.AlarmCode))
|
||||
}
|
||||
if query.AlarmType != "" {
|
||||
tx = tx.Where("alarm_type in (?)", strings.Split(query.AlarmType, ","))
|
||||
@@ -192,3 +193,21 @@ func (r Alarm) SelectAlarmSeqLast(neType, neId string) int64 {
|
||||
}
|
||||
return alarmSeq
|
||||
}
|
||||
|
||||
// GroupTotal 分组统计
|
||||
func (r Alarm) GroupTotal(alarmStatus string, group string, limit int) []map[string]any {
|
||||
tx := db.DB("").Model(&model.Alarm{})
|
||||
tx = tx.Select("count(*) as total", group)
|
||||
tx = tx.Where("alarm_status=?", alarmStatus)
|
||||
tx = tx.Group(group).Order("total DESC")
|
||||
// 查询数据
|
||||
var rows []map[string]any = make([]map[string]any, 0)
|
||||
if limit > 0 {
|
||||
tx = tx.Limit(limit)
|
||||
}
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ func (r AlarmLog) SelectByPage(query model.AlarmLogQuery) ([]model.AlarmLog, int
|
||||
if query.NeID != "" {
|
||||
tx = tx.Where("ne_id = ?", query.NeID)
|
||||
}
|
||||
if query.AlarmStatus != "" {
|
||||
tx = tx.Where("alarm_status = ?", query.AlarmStatus)
|
||||
}
|
||||
if query.BeginTime != 0 {
|
||||
tx = tx.Where("created_at >= ?", query.BeginTime)
|
||||
}
|
||||
|
||||
273
src/modules/network_data/repository/cbc_message.go
Normal file
273
src/modules/network_data/repository/cbc_message.go
Normal file
@@ -0,0 +1,273 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEvent 结构体
|
||||
var NewCBCMessage = &CBCMessage{}
|
||||
|
||||
// UEEvent UE会话事件 数据层处理
|
||||
type CBCMessage struct{}
|
||||
|
||||
// SelectCBCMessage 根据条件分页查询CB消息
|
||||
func (s *CBCMessage) SelectByPage(query model.CBCMessageQuery) ([]model.CBCMessage, int, error) {
|
||||
var msg []model.CBCMessage
|
||||
var total int64
|
||||
|
||||
tx := db.DB("").Table("cbc_message")
|
||||
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.NeId != "" {
|
||||
tx = tx.Where("ne_id = ?", query.NeId)
|
||||
}
|
||||
if query.EventName != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(message_json, '$.eventName') = ?", query.EventName)
|
||||
}
|
||||
if query.Status != "" {
|
||||
tx = tx.Where("status = ?", query.Status)
|
||||
}
|
||||
|
||||
var startMicro, endMicro int64
|
||||
var err error
|
||||
if query.StartTime != "" {
|
||||
startMicro, err = parseTimeToMilli(query.StartTime)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("invalid start time: %w", err)
|
||||
}
|
||||
}
|
||||
if query.EndTime != "" {
|
||||
endMicro, err = parseTimeToMilli(query.EndTime)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("invalid end time: %w", err)
|
||||
}
|
||||
}
|
||||
if startMicro > 0 && endMicro > 0 {
|
||||
tx = tx.Where("created_at BETWEEN ? AND ?", startMicro, endMicro)
|
||||
} else if startMicro > 0 {
|
||||
tx = tx.Where("created_at >= ?", startMicro)
|
||||
} else if endMicro > 0 {
|
||||
tx = tx.Where("created_at <= ?", endMicro)
|
||||
}
|
||||
|
||||
// 统计总数
|
||||
if err := tx.Count(&total).Error; err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to count CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (query.PageNum - 1) * query.PageSize
|
||||
if err := tx.Limit(query.PageSize).Offset(offset).Order("created_at desc").Find(&msg).Error; err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to select CBC message: %w", err)
|
||||
}
|
||||
|
||||
return msg, int(total), nil
|
||||
}
|
||||
|
||||
// SelectCBCMessageByPage 分页查询CB消息
|
||||
// @Description 分页查询CB消息
|
||||
// @param page 页码
|
||||
// @param pageSize 每页大小
|
||||
// @return []model.CBCMessage CB消息列表
|
||||
// @return int 总记录数
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// SelectByPage(1, 10)
|
||||
// func (s *CBCMessage) SelectByPage(pageNum int, pageSize int) ([]model.CBCMessage, int, error) {
|
||||
// var tickets []model.CBCMessage
|
||||
// var total int64
|
||||
|
||||
// // 统计总数
|
||||
// if err := db.DB("").Table("cbc_message").Count(&total).Error; err != nil {
|
||||
// return nil, 0, fmt.Errorf("failed to count CBC message: %w", err)
|
||||
// }
|
||||
|
||||
// // 分页查询
|
||||
// offset := (pageNum - 1) * pageSize
|
||||
// if err := db.DB("").Table("cbc_message").
|
||||
// Limit(pageSize).
|
||||
// Offset(offset).
|
||||
// Find(&tickets).Error; err != nil {
|
||||
// return nil, 0, fmt.Errorf("failed to select CBC message: %w", err)
|
||||
// }
|
||||
|
||||
// return tickets, int(total), nil
|
||||
// }
|
||||
|
||||
// InsertCBCMessage 插入CB消息
|
||||
// @Description 插入CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// CBCMessage.InsertCBCMessage(msg)
|
||||
func (s *CBCMessage) Insert(msg model.CBCMessage) error {
|
||||
msg.CreatedAt = time.Now().UnixMilli()
|
||||
// 这里可以使用ORM或其他方式将ticket插入到数据库中
|
||||
if err := db.DB("").Table("cbc_message").Create(&msg).Error; err != nil {
|
||||
return fmt.Errorf("failed to insert CBC message: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectCBCMessageById 根据工单ID查询CB消息
|
||||
// @Description 根据工单ID查询CB消息
|
||||
// @param id 工单ID
|
||||
// @return *model.CBCMessage CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// CBCMessage.SelectCBCMessageById(12345)
|
||||
func (s *CBCMessage) SelectById(id int64) (*model.CBCMessage, error) {
|
||||
var msg model.CBCMessage
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
First(&msg).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to select CBC message: %w", err)
|
||||
}
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// SelectByEventName 根据事件名称查询CB消息
|
||||
func (s *CBCMessage) SelectByEventName(eventName string) (*model.CBCMessage, error) {
|
||||
var msg model.CBCMessage
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("JSON_EXTRACT(message_json, '$.eventName') = ?", eventName).
|
||||
First(&msg).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// mfCBCMessageService.UpdateCBCMessage(msg)
|
||||
func (s *CBCMessage) Update(id int64, messageJson json.RawMessage) (*model.CBCMessage, error) {
|
||||
var msg model.CBCMessage
|
||||
now := time.Now().UnixMilli()
|
||||
|
||||
err := db.DB("").Transaction(func(tx *gorm.DB) error {
|
||||
// 在事务中更新
|
||||
if err := tx.Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
Updates(map[string]any{
|
||||
"message_json": messageJson,
|
||||
"updated_at": now,
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("failed to update CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 在事务中查询更新后的记录
|
||||
if err := tx.Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
First(&msg).Error; err != nil {
|
||||
return fmt.Errorf("failed to fetch updated CBC message: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &msg, nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// UpdateCBCMessageDetail(msg)
|
||||
func (s *CBCMessage) UpdateDetail(eventName, detail string) error {
|
||||
now := time.Now().UnixMilli()
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("JSON_EXTRACT(message_json, '$.eventName') = ?", eventName).
|
||||
Updates(map[string]any{
|
||||
"detail": detail,
|
||||
"updated_at": now,
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("failed to update CBC message: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCBCMessage 删除CB消息
|
||||
// @Description 删除CB消息
|
||||
// @param id 工单ID
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// DeleteCBCMessage(12345)
|
||||
func (s *CBCMessage) Delete(id int64) error {
|
||||
// 执行删除操作
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
Delete(&model.CBCMessage{}).Error; err != nil {
|
||||
return fmt.Errorf("failed to delete CBC message: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateStatus(id int64, status model.CBCEventStatus) error {
|
||||
// 更新数据库状态
|
||||
now := time.Now().UnixMilli()
|
||||
if err := db.DB("").Table("cbc_message").
|
||||
Where("id = ?", id).
|
||||
Updates(map[string]interface{}{
|
||||
"status": status,
|
||||
"updated_at": now,
|
||||
}).Error; err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Select 查询所有CB消息
|
||||
func (s *CBCMessage) Select(msgs *[]model.CBCMessage) error {
|
||||
if err := db.DB("").Table("cbc_message").Find(&msgs).Error; err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectByNeId 根据网元ID查询CB消息
|
||||
func (s *CBCMessage) SelectByNeId(neId string, msgs *[]model.CBCMessage) error {
|
||||
if err := db.DB("").Table("cbc_message").Where("ne_id = ?", neId).Find(&msgs).Error; err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 假设 query.StartTime 和 query.EndTime 是 "2006-01-02 15:04:05" 格式字符串
|
||||
func parseTimeToMilli(ts string) (int64, error) {
|
||||
if ts == "" {
|
||||
return 0, nil
|
||||
}
|
||||
t, err := time.ParseInLocation("2006-01-02 15:04:05", ts, time.Local)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return t.UnixMilli(), nil
|
||||
}
|
||||
167
src/modules/network_data/repository/cdr_event.go
Normal file
167
src/modules/network_data/repository/cdr_event.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREvent 结构体
|
||||
var NewCDREvent = &CDREvent{}
|
||||
|
||||
// CDREvent CDR会话事件 数据层处理
|
||||
type CDREvent struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r CDREvent) SelectByPage(neType string, query map[string]string) ([]model.CDREvent, int64) {
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["rmUID"]; ok && v != "" {
|
||||
tx = tx.Where("rm_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["beginTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at >= ?", v)
|
||||
}
|
||||
if v, ok := query["endTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at <= ?", v)
|
||||
}
|
||||
|
||||
// 各个网元特殊查询条件
|
||||
switch neType {
|
||||
case "SMSC":
|
||||
if v, ok := query["callerParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["calledParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["recordType"]; ok && v != "" {
|
||||
recordTypes := strings.Split(v, ",")
|
||||
var querytrArr []string
|
||||
for _, recordType := range recordTypes {
|
||||
querytrArr = append(querytrArr, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') = '%s'", recordType))
|
||||
}
|
||||
tx = tx.Where(fmt.Sprintf("( %s )", strings.Join(querytrArr, " OR ")))
|
||||
}
|
||||
case "SMF":
|
||||
if v, ok := query["recordType"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.recordType') = ?", v)
|
||||
}
|
||||
if v, ok := query["subscriberID"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["dnn"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.pDUSessionChargingInformation.dNNID') = ?", v)
|
||||
}
|
||||
case "SGWC":
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedIMSI') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["msisdn"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedMSISDN') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
case "IMS":
|
||||
if v, ok := query["callerParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
if v, ok := query["calledParty"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
}
|
||||
|
||||
var total int64 = 0
|
||||
rows := []model.CDREvent{}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := db.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
tx = tx.Offset(int(pageNum * pageSize)).Limit(int(pageSize))
|
||||
|
||||
// 排序
|
||||
if v, ok := query["sortField"]; ok && v != "" {
|
||||
sortSql := v
|
||||
if o, ok := query["sortOrder"]; ok && o != "" {
|
||||
if o == "desc" {
|
||||
sortSql += " desc "
|
||||
} else {
|
||||
sortSql += " asc "
|
||||
}
|
||||
}
|
||||
tx = tx.Order(sortSql)
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r CDREvent) SelectByIds(neType string, ids []int64) []model.CDREvent {
|
||||
rows := []model.CDREvent{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r CDREvent) DeleteByIds(neType string, ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.CDREvent{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// Insert 新增信息 返回新增数据ID
|
||||
func (r CDREvent) Insert(param model.CDREvent) int64 {
|
||||
if param.NeType == "" {
|
||||
return 0
|
||||
}
|
||||
if param.CreatedAt == 0 {
|
||||
param.CreatedAt = time.Now().UnixMilli()
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(param.NeType))
|
||||
// 执行插入
|
||||
if err := db.DB("").Table(tableName).Create(¶m).Error; err != nil {
|
||||
logger.Errorf("insert err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return param.ID
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventIMS 结构体
|
||||
var NewCDREventIMS = &CDREventIMS{}
|
||||
|
||||
// CDREventIMS CDR会话事件 数据层处理
|
||||
type CDREventIMS struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r CDREventIMS) SelectByPage(query model.CDREventIMSQuery) ([]model.CDREventIMS, int64) {
|
||||
tx := db.DB("").Model(&model.CDREventIMS{})
|
||||
// 查询条件拼接
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.RmUID != "" {
|
||||
tx = tx.Where("rm_uid = ?", query.RmUID)
|
||||
}
|
||||
if query.BeginTime != 0 {
|
||||
tx = tx.Where("created_at >= ?", query.BeginTime)
|
||||
}
|
||||
if query.EndTime != 0 {
|
||||
tx = tx.Where("created_at <= ?", query.EndTime)
|
||||
}
|
||||
if query.CallerParty != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') = ?", query.CallerParty)
|
||||
}
|
||||
if query.CalledParty != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') = ?", query.CalledParty)
|
||||
}
|
||||
|
||||
if query.RecordType != "" {
|
||||
recordTypes := strings.Split(query.RecordType, ",")
|
||||
var querytrArr []string
|
||||
for _, recordType := range recordTypes {
|
||||
querytrArr = append(querytrArr, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') = '%s'", recordType))
|
||||
}
|
||||
tx = tx.Where(fmt.Sprintf("( %s )", strings.Join(querytrArr, " OR ")))
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.CDREventIMS{}
|
||||
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 排序
|
||||
if query.SortField != "" {
|
||||
sortField := query.SortField
|
||||
if query.SortOrder == "desc" {
|
||||
sortField = sortField + " desc"
|
||||
}
|
||||
tx = tx.Order(sortField)
|
||||
}
|
||||
|
||||
// 查询数据分页
|
||||
pageNum, pageSize := db.PageNumSize(query.PageNum, query.PageSize)
|
||||
tx = tx.Limit(pageSize).Offset(pageSize * pageNum)
|
||||
err := tx.Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows, total
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r *CDREventIMS) SelectByIds(ids []int64) []model.CDREventIMS {
|
||||
rows := []model.CDREventIMS{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
tx := db.DB("").Model(&model.CDREventIMS{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventIMS) DeleteByIds(ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.CDREventIMS{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventSGWC 结构体
|
||||
var NewCDREventSGWC = &CDREventSGWC{}
|
||||
|
||||
// CDREventSGWC CDR会话事件 数据层处理
|
||||
type CDREventSGWC struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r CDREventSGWC) SelectByPage(query model.CDREventSGWCQuery) ([]model.CDREventSGWC, int64) {
|
||||
tx := db.DB("").Model(&model.CDREventSGWC{})
|
||||
// 查询条件拼接
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.RmUID != "" {
|
||||
tx = tx.Where("rm_uid = ?", query.RmUID)
|
||||
}
|
||||
if query.BeginTime != 0 {
|
||||
tx = tx.Where("timestamp >= ?", query.BeginTime)
|
||||
}
|
||||
if query.EndTime != 0 {
|
||||
tx = tx.Where("timestamp <= ?", query.EndTime)
|
||||
}
|
||||
if query.IMSI != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedIMSI') = ?", query.IMSI)
|
||||
}
|
||||
if query.MSISDN != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedMSISDN') = ?", query.MSISDN)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.CDREventSGWC{}
|
||||
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 排序
|
||||
if query.SortField != "" {
|
||||
sortField := query.SortField
|
||||
if query.SortOrder == "desc" {
|
||||
sortField = sortField + " desc"
|
||||
}
|
||||
tx = tx.Order(sortField)
|
||||
}
|
||||
|
||||
// 查询数据分页
|
||||
pageNum, pageSize := db.PageNumSize(query.PageNum, query.PageSize)
|
||||
tx = tx.Limit(pageSize).Offset(pageSize * pageNum)
|
||||
err := tx.Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows, total
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r *CDREventSGWC) SelectByIds(ids []int64) []model.CDREventSGWC {
|
||||
rows := []model.CDREventSGWC{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
tx := db.DB("").Model(&model.CDREventSGWC{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventSGWC) DeleteByIds(ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.CDREventSGWC{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventSMF 结构体
|
||||
var NewCDREventSMF = &CDREventSMF{}
|
||||
|
||||
// CDREventSMF CDR会话事件 数据层处理
|
||||
type CDREventSMF struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r CDREventSMF) SelectByPage(query model.CDREventSMFQuery) ([]model.CDREventSMF, int64) {
|
||||
tx := db.DB("").Model(&model.CDREventSMF{})
|
||||
// 查询条件拼接
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.RmUID != "" {
|
||||
tx = tx.Where("rm_uid = ?", query.RmUID)
|
||||
}
|
||||
if query.BeginTime != 0 {
|
||||
tx = tx.Where("timestamp >= ?", query.BeginTime)
|
||||
}
|
||||
if query.EndTime != 0 {
|
||||
tx = tx.Where("timestamp <= ?", query.EndTime)
|
||||
}
|
||||
if query.RecordType != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.recordType') = ?", query.RecordType)
|
||||
}
|
||||
if query.SubscriberID != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') = ?", query.SubscriberID)
|
||||
}
|
||||
if query.DNN != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.pDUSessionChargingInformation.dNNID') = ?", query.DNN)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.CDREventSMF{}
|
||||
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 排序
|
||||
if query.SortField != "" {
|
||||
sortField := query.SortField
|
||||
if query.SortOrder == "desc" {
|
||||
sortField = sortField + " desc"
|
||||
}
|
||||
tx = tx.Order(sortField)
|
||||
}
|
||||
|
||||
// 查询数据分页
|
||||
pageNum, pageSize := db.PageNumSize(query.PageNum, query.PageSize)
|
||||
tx = tx.Limit(pageSize).Offset(pageSize * pageNum)
|
||||
err := tx.Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows, total
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r *CDREventSMF) SelectByIds(ids []int64) []model.CDREventSMF {
|
||||
rows := []model.CDREventSMF{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
tx := db.DB("").Model(&model.CDREventSMF{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventSMF) DeleteByIds(ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.CDREventSMF{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventSMSC 结构体
|
||||
var NewCDREventSMSC = &CDREventSMSC{}
|
||||
|
||||
// CDREventSMSC CDR会话事件 数据层处理
|
||||
type CDREventSMSC struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r CDREventSMSC) SelectByPage(query model.CDREventSMSCQuery) ([]model.CDREventSMSC, int64) {
|
||||
tx := db.DB("").Model(&model.CDREventSMSC{})
|
||||
// 查询条件拼接
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.RmUID != "" {
|
||||
tx = tx.Where("rm_uid = ?", query.RmUID)
|
||||
}
|
||||
if query.BeginTime != 0 {
|
||||
tx = tx.Where("timestamp >= ?", query.BeginTime)
|
||||
}
|
||||
if query.EndTime != 0 {
|
||||
tx = tx.Where("timestamp <= ?", query.EndTime)
|
||||
}
|
||||
if query.CallerParty != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') = ?", query.CallerParty)
|
||||
}
|
||||
if query.CalledParty != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') = ?", query.CalledParty)
|
||||
}
|
||||
|
||||
if query.RecordType != "" {
|
||||
recordTypes := strings.Split(query.RecordType, ",")
|
||||
var querytrArr []string
|
||||
for _, recordType := range recordTypes {
|
||||
querytrArr = append(querytrArr, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') = '%s'", recordType))
|
||||
}
|
||||
tx = tx.Where(fmt.Sprintf("( %s )", strings.Join(querytrArr, " OR ")))
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.CDREventSMSC{}
|
||||
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 排序
|
||||
if query.SortField != "" {
|
||||
sortField := query.SortField
|
||||
if query.SortOrder == "desc" {
|
||||
sortField = sortField + " desc"
|
||||
}
|
||||
tx = tx.Order(sortField)
|
||||
}
|
||||
|
||||
// 查询数据分页
|
||||
pageNum, pageSize := db.PageNumSize(query.PageNum, query.PageSize)
|
||||
tx = tx.Limit(pageSize).Offset(pageSize * pageNum)
|
||||
err := tx.Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows, total
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r *CDREventSMSC) SelectByIds(ids []int64) []model.CDREventSMSC {
|
||||
rows := []model.CDREventSMSC{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
tx := db.DB("").Model(&model.CDREventSMSC{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventSMSC) DeleteByIds(ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.CDREventSMSC{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -17,7 +17,7 @@ var NewKpiCReport = &KpiCReport{}
|
||||
type KpiCReport struct{}
|
||||
|
||||
// SelectGoldKPI 通过网元指标数据信息
|
||||
func (r KpiCReport) SelectKPI(query model.KPIQuery) []model.KpiCReport {
|
||||
func (r KpiCReport) SelectKPI(query model.KPICQuery) []model.KpiCReport {
|
||||
rows := []model.KpiCReport{}
|
||||
if query.NeType == "" {
|
||||
return rows
|
||||
@@ -87,3 +87,132 @@ func (r KpiCReport) SelectKPITitle(neType string) []model.KpiCTitle {
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// TitleLastKPIId 查询指标标题最后kpiid
|
||||
func (r KpiCReport) TitleLastKPIId(neType string) string {
|
||||
tx := db.DB("").Model(&model.KpiCTitle{})
|
||||
tx = tx.Where("ne_type=?", neType)
|
||||
tx = tx.Select("kpi_id").Order("kpi_id DESC")
|
||||
// 查询数据
|
||||
var kpiId string = ""
|
||||
if err := tx.Limit(1).Find(&kpiId).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return kpiId
|
||||
}
|
||||
return kpiId
|
||||
}
|
||||
|
||||
// SelectByPageTitle 分页查询集合
|
||||
func (r KpiCReport) TitleSelectByPage(query map[string]string) ([]model.KpiCTitle, int64) {
|
||||
tx := db.DB("").Model(&model.KpiCTitle{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["neType"]; ok && v != "" {
|
||||
tx = tx.Where("ne_type = ?", v)
|
||||
}
|
||||
if v, ok := query["status"]; ok && v != "" {
|
||||
tx = tx.Where("status = ?", v)
|
||||
} else {
|
||||
tx = tx.Where("status != ?", "2")
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.KpiCTitle{}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := db.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
tx = tx.Offset(int(pageNum * pageSize)).Limit(int(pageSize))
|
||||
|
||||
// 排序
|
||||
if v, ok := query["sortField"]; ok && v != "" {
|
||||
sortSql := v
|
||||
if o, ok := query["sortOrder"]; ok && o != "" {
|
||||
if o == "desc" {
|
||||
sortSql += " desc "
|
||||
} else {
|
||||
sortSql += " asc "
|
||||
}
|
||||
}
|
||||
tx = tx.Order(sortSql)
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// TitleSelect 网元对应的指标名称
|
||||
func (r KpiCReport) TitleSelect(param model.KpiCTitle) []model.KpiCTitle {
|
||||
tx := db.DB("").Model(&model.KpiCTitle{})
|
||||
// 构建查询条件
|
||||
if param.NeType != "" {
|
||||
tx = tx.Where("ne_type =?", param.NeType)
|
||||
}
|
||||
if param.Title != "" {
|
||||
tx = tx.Where("title = ?", param.Title)
|
||||
}
|
||||
if param.Status != "" {
|
||||
tx = tx.Where("status = ?", param.Status)
|
||||
}
|
||||
// 查询数据
|
||||
rows := []model.KpiCTitle{}
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// TitleInsert 新增信息
|
||||
func (r KpiCReport) TitleInsert(param model.KpiCTitle) int64 {
|
||||
if param.CreatedBy != "" {
|
||||
param.UpdatedAt = time.Now().UnixMilli()
|
||||
}
|
||||
param.Status = "1"
|
||||
tx := db.DB("").Create(¶m)
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("CreateInBatches err => %v", err)
|
||||
}
|
||||
return param.ID
|
||||
}
|
||||
|
||||
// TitleUpdate 修改信息
|
||||
func (r KpiCReport) TitleUpdate(param model.KpiCTitle) int64 {
|
||||
if param.ID <= 0 {
|
||||
return 0
|
||||
}
|
||||
param.UpdatedAt = time.Now().UnixMilli()
|
||||
tx := db.DB("").Model(&model.KpiCTitle{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id = ?", param.ID)
|
||||
tx = tx.Omit("id", "created_by")
|
||||
// 执行更新
|
||||
if err := tx.Updates(param).Error; err != nil {
|
||||
logger.Errorf("update err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// TitleDeleteByIds 批量删除信息
|
||||
func (r KpiCReport) TitleDeleteByIds(ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Model(&model.KpiCTitle{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
if err := tx.Update("status", 2).Error; err != nil {
|
||||
logger.Errorf("update err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
@@ -36,14 +35,14 @@ func (r NBState) SelectByPage(query model.NBStateQuery) ([]model.NBState, int64)
|
||||
if len(startTime) == 10 {
|
||||
startTime = startTime + "000"
|
||||
}
|
||||
tx = tx.Where("time >= ?", date.ParseDateToStr(startTime, date.YYYY_MM_DDTHH_MM_SSZ))
|
||||
tx = tx.Where("create_time >= ?", startTime)
|
||||
}
|
||||
if query.EndTime != "" {
|
||||
endTime := query.EndTime
|
||||
if len(endTime) == 10 {
|
||||
endTime = endTime + "999"
|
||||
}
|
||||
tx = tx.Where("time <= ?", date.ParseDateToStr(endTime, date.YYYY_MM_DDTHH_MM_SSZ))
|
||||
tx = tx.Where("create_time <= ?", endTime)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
|
||||
@@ -27,7 +27,7 @@ func (r *UDMAuthUser) ClearAndInsert(neId string, uArr []model.UDMAuthUser) int6
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r *UDMAuthUser) SelectPage(query map[string]string) (int64, []model.UDMAuthUser) {
|
||||
func (r *UDMAuthUser) SelectPage(query map[string]string) ([]model.UDMAuthUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMAuthUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
@@ -48,7 +48,7 @@ func (r *UDMAuthUser) SelectPage(query map[string]string) (int64, []model.UDMAut
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
@@ -73,7 +73,7 @@ func (r *UDMAuthUser) SelectPage(query map[string]string) (int64, []model.UDMAut
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
|
||||
@@ -27,7 +27,7 @@ func (r *UDMSubUser) ClearAndInsert(neId string, u []model.UDMSubUser) int64 {
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询字典类型
|
||||
func (r *UDMSubUser) SelectPage(query map[string]string) (int64, []model.UDMSubUser) {
|
||||
func (r *UDMSubUser) SelectPage(query map[string]string) ([]model.UDMSubUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMSubUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
@@ -51,7 +51,7 @@ func (r *UDMSubUser) SelectPage(query map[string]string) (int64, []model.UDMSubU
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
@@ -76,7 +76,7 @@ func (r *UDMSubUser) SelectPage(query map[string]string) (int64, []model.UDMSubU
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
|
||||
@@ -27,7 +27,7 @@ func (r UDMVOIPUser) ClearAndInsert(neId string, uArr []model.UDMVOIPUser) int64
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r UDMVOIPUser) SelectPage(query map[string]string) (int64, []model.UDMVOIPUser) {
|
||||
func (r UDMVOIPUser) SelectPage(query map[string]string) ([]model.UDMVOIPUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMVOIPUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["username"]; ok && v != "" {
|
||||
@@ -48,7 +48,7 @@ func (r UDMVOIPUser) SelectPage(query map[string]string) (int64, []model.UDMVOIP
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
@@ -75,7 +75,7 @@ func (r UDMVOIPUser) SelectPage(query map[string]string) (int64, []model.UDMVOIP
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
|
||||
@@ -27,7 +27,7 @@ func (r UDMVolteIMSUser) ClearAndInsert(neId string, uArr []model.UDMVolteIMSUse
|
||||
}
|
||||
|
||||
// SelectPage 根据条件分页查询
|
||||
func (r UDMVolteIMSUser) SelectPage(query map[string]string) (int64, []model.UDMVolteIMSUser) {
|
||||
func (r UDMVolteIMSUser) SelectPage(query map[string]string) ([]model.UDMVolteIMSUser, int64) {
|
||||
tx := db.DB("").Model(&model.UDMVolteIMSUser{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
@@ -57,7 +57,7 @@ func (r UDMVolteIMSUser) SelectPage(query map[string]string) (int64, []model.UDM
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
@@ -84,7 +84,7 @@ func (r UDMVolteIMSUser) SelectPage(query map[string]string) (int64, []model.UDM
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return total, rows
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectList 根据实体查询
|
||||
|
||||
132
src/modules/network_data/repository/ue_event.go
Normal file
132
src/modules/network_data/repository/ue_event.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEvent 结构体
|
||||
var NewUEEvent = &UEEvent{}
|
||||
|
||||
// UEEvent UE会话事件 数据层处理
|
||||
type UEEvent struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r UEEvent) SelectByPage(neType string, query map[string]string) ([]model.UEEvent, int64) {
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
|
||||
// 查询条件拼接
|
||||
if v, ok := query["rmUID"]; ok && v != "" {
|
||||
tx = tx.Where("rm_uid = ?", v)
|
||||
}
|
||||
if v, ok := query["beginTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at >= ?", v)
|
||||
}
|
||||
if v, ok := query["endTime"]; ok && v != "" {
|
||||
if len(v) == 10 {
|
||||
v = v + "000"
|
||||
}
|
||||
tx = tx.Where("created_at <= ?", v)
|
||||
}
|
||||
if v, ok := query["eventType"]; ok && v != "" {
|
||||
eventTypes := strings.Split(v, ",")
|
||||
tx = tx.Where("event_type in ?", eventTypes)
|
||||
}
|
||||
if v, ok := query["imsi"]; ok && v != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(event_json, '$.imsi') like ?", fmt.Sprintf("%%%s%%", v))
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.UEEvent{}
|
||||
|
||||
// 查询数量 长度为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 分页
|
||||
pageNum, pageSize := db.PageNumSize(query["pageNum"], query["pageSize"])
|
||||
tx = tx.Offset(int(pageNum * pageSize)).Limit(int(pageSize))
|
||||
|
||||
// 排序
|
||||
if v, ok := query["sortField"]; ok && v != "" {
|
||||
sortSql := v
|
||||
if o, ok := query["sortOrder"]; ok && o != "" {
|
||||
if o == "desc" {
|
||||
sortSql += " desc "
|
||||
} else {
|
||||
sortSql += " asc "
|
||||
}
|
||||
}
|
||||
tx = tx.Order(sortSql)
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
}
|
||||
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r UEEvent) SelectByIds(neType string, ids []int64) []model.UEEvent {
|
||||
rows := []model.UEEvent{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Model(&model.UEEvent{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r UEEvent) DeleteByIds(neType string, ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(neType))
|
||||
tx := db.DB("").Table(tableName).Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.UEEvent{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// Insert 新增信息 返回新增数据ID
|
||||
func (r UEEvent) Insert(param model.UEEvent) int64 {
|
||||
if param.NeType == "" {
|
||||
return 0
|
||||
}
|
||||
if param.CreatedAt == 0 {
|
||||
param.CreatedAt = time.Now().UnixMilli()
|
||||
}
|
||||
// 表名
|
||||
tableName := fmt.Sprintf("ue_event_%s", strings.ToLower(param.NeType))
|
||||
// 执行插入
|
||||
if err := db.DB("").Table(tableName).Create(¶m).Error; err != nil {
|
||||
logger.Errorf("insert err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return param.ID
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEventAMF 结构体
|
||||
var NewUEEventAMF = &UEEventAMF{}
|
||||
|
||||
// UEEventAMF UE会话事件 数据层处理
|
||||
type UEEventAMF struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r UEEventAMF) SelectByPage(query model.UEEventAMFQuery) ([]model.UEEventAMF, int64) {
|
||||
tx := db.DB("").Model(&model.UEEventAMF{})
|
||||
// 查询条件拼接
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.RmUID != "" {
|
||||
tx = tx.Where("rm_uid = ?", query.RmUID)
|
||||
}
|
||||
if query.BeginTime != 0 {
|
||||
tx = tx.Where("timestamp >= ?", query.BeginTime)
|
||||
}
|
||||
if query.EndTime != 0 {
|
||||
tx = tx.Where("timestamp <= ?", query.EndTime)
|
||||
}
|
||||
if query.EventType != "" {
|
||||
eventTypes := strings.Split(query.EventType, ",")
|
||||
tx = tx.Where("event_type in ?", eventTypes)
|
||||
}
|
||||
if query.IMSI != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(event_json, '$.imsi') = ?", query.IMSI)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.UEEventAMF{}
|
||||
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 排序
|
||||
if query.SortField != "" {
|
||||
sortField := query.SortField
|
||||
if query.SortOrder == "desc" {
|
||||
sortField = sortField + " desc"
|
||||
}
|
||||
tx = tx.Order(sortField)
|
||||
}
|
||||
|
||||
// 查询数据分页
|
||||
pageNum, pageSize := db.PageNumSize(query.PageNum, query.PageSize)
|
||||
tx = tx.Limit(pageSize).Offset(pageSize * pageNum)
|
||||
err := tx.Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows, total
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r UEEventAMF) SelectByIds(ids []int64) []model.UEEventAMF {
|
||||
rows := []model.UEEventAMF{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
tx := db.DB("").Model(&model.UEEventAMF{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r UEEventAMF) DeleteByIds(ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.UEEventAMF{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEventMME 结构体
|
||||
var NewUEEventMME = &UEEventMME{}
|
||||
|
||||
// UEEventMME UE会话事件 数据层处理
|
||||
type UEEventMME struct{}
|
||||
|
||||
// SelectByPage 分页查询集合
|
||||
func (r UEEventMME) SelectByPage(query model.UEEventMMEQuery) ([]model.UEEventMME, int64) {
|
||||
tx := db.DB("").Model(&model.UEEventMME{})
|
||||
// 查询条件拼接
|
||||
if query.NeType != "" {
|
||||
tx = tx.Where("ne_type = ?", query.NeType)
|
||||
}
|
||||
if query.RmUID != "" {
|
||||
tx = tx.Where("rm_uid = ?", query.RmUID)
|
||||
}
|
||||
if query.BeginTime != 0 {
|
||||
tx = tx.Where("timestamp >= ?", query.BeginTime)
|
||||
}
|
||||
if query.EndTime != 0 {
|
||||
tx = tx.Where("timestamp <= ?", query.EndTime)
|
||||
}
|
||||
if query.EventType != "" {
|
||||
eventTypes := strings.Split(query.EventType, ",")
|
||||
tx = tx.Where("event_type in ?", eventTypes)
|
||||
}
|
||||
if query.IMSI != "" {
|
||||
tx = tx.Where("JSON_EXTRACT(event_json, '$.imsi') = ?", query.IMSI)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
var total int64 = 0
|
||||
rows := []model.UEEventMME{}
|
||||
|
||||
// 查询数量为0直接返回
|
||||
if err := tx.Count(&total).Error; err != nil || total <= 0 {
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// 排序
|
||||
if query.SortField != "" {
|
||||
sortField := query.SortField
|
||||
if query.SortOrder == "desc" {
|
||||
sortField = sortField + " desc"
|
||||
}
|
||||
tx = tx.Order(sortField)
|
||||
}
|
||||
|
||||
// 查询数据分页
|
||||
pageNum, pageSize := db.PageNumSize(query.PageNum, query.PageSize)
|
||||
tx = tx.Limit(pageSize).Offset(pageSize * pageNum)
|
||||
err := tx.Find(&rows).Error
|
||||
if err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows, total
|
||||
}
|
||||
return rows, total
|
||||
}
|
||||
|
||||
// SelectByIds 通过ID查询
|
||||
func (r UEEventMME) SelectByIds(ids []int64) []model.UEEventMME {
|
||||
rows := []model.UEEventMME{}
|
||||
if len(ids) <= 0 {
|
||||
return rows
|
||||
}
|
||||
tx := db.DB("").Model(&model.UEEventMME{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id in ?", ids)
|
||||
// 查询数据
|
||||
if err := tx.Find(&rows).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return rows
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r UEEventMME) DeleteByIds(ids []int64) int64 {
|
||||
if len(ids) <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("id in ?", ids)
|
||||
if err := tx.Delete(&model.UEEventMME{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/tsmask/go-oam"
|
||||
"github.com/tsmask/go-oam/framework/utils/parse"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/date"
|
||||
@@ -65,8 +68,8 @@ func (s Alarm) FindAlarmSeqLast(neType, neId string) int64 {
|
||||
return s.alarmRepository.SelectAlarmSeqLast(neType, neId)
|
||||
}
|
||||
|
||||
// AlarmClearByIds 批量清除告警信息
|
||||
func (r Alarm) AlarmClearByIds(ids []int64, clearUser string) (int64, error) {
|
||||
// ClearByIds 批量清除告警信息
|
||||
func (r Alarm) ClearByIds(ids []int64, clearUser, clearType string) (int64, error) {
|
||||
// 检查是否存在
|
||||
arr := r.alarmRepository.SelectByIds(ids)
|
||||
if len(arr) <= 0 {
|
||||
@@ -80,21 +83,20 @@ func (r Alarm) AlarmClearByIds(ids []int64, clearUser string) (int64, error) {
|
||||
if v.AlarmCode == constants.ALARM_STATE_CHECK || v.AlarmCode == constants.ALARM_CMD_CHECK || v.AlarmCode == constants.ALARM_LICENSE_CHECK {
|
||||
v.AlarmId = fmt.Sprintf("%d%d", v.AlarmCode, v.EventTime)
|
||||
}
|
||||
v.AlarmStatus = "0"
|
||||
v.AlarmStatus = oam.ALARM_STATUS_CLEAR
|
||||
// 告警清除
|
||||
v.ClearType = 2
|
||||
v.ClearTime = time.Now().UnixMilli()
|
||||
v.ClearType = clearType
|
||||
v.ClearUser = clearUser
|
||||
v.ClearTime = time.Now().UnixMilli()
|
||||
rows += r.alarmRepository.Update(v)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
// 清除失败!
|
||||
return 0, fmt.Errorf("clear fail")
|
||||
}
|
||||
|
||||
// AlarmAckByIds 批量确认清除告警信息
|
||||
func (r Alarm) AlarmAckByIds(ids []int64, ackUser string, ackState bool) (int64, error) {
|
||||
// AckByIds 批量确认清除告警信息
|
||||
func (r Alarm) AckByIds(ids []int64, ackUser, ackState string) (int64, error) {
|
||||
// 检查是否存在
|
||||
arr := r.alarmRepository.SelectByIds(ids)
|
||||
if len(arr) <= 0 {
|
||||
@@ -104,29 +106,86 @@ func (r Alarm) AlarmAckByIds(ids []int64, ackUser string, ackState bool) (int64,
|
||||
if len(arr) == len(ids) {
|
||||
var rows int64 = 0
|
||||
for _, v := range arr {
|
||||
// 确认清除
|
||||
if ackState {
|
||||
v.AckState = 1
|
||||
} else {
|
||||
v.AckState = 0
|
||||
}
|
||||
v.AckState = ackState
|
||||
v.AckTime = time.Now().UnixMilli()
|
||||
v.AckUser = ackUser
|
||||
rows += r.alarmRepository.Update(v)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
// 清除失败!
|
||||
return 0, fmt.Errorf("ack fail")
|
||||
}
|
||||
|
||||
// InsertAndForword 新增信息并转发通知
|
||||
func (s Alarm) InsertAndForword(param model.Alarm) int64 {
|
||||
rows := s.alarmRepository.Insert(param)
|
||||
if rows > 0 {
|
||||
// 转发通知 TODO
|
||||
// CountType 告警类别数量
|
||||
func (s Alarm) CountType(alarmStatus string) []map[string]any {
|
||||
data := []map[string]any{}
|
||||
alarmTypeArr := []string{
|
||||
oam.ALARM_TYPE_COMMUNICATION_ALARM,
|
||||
oam.ALARM_TYPE_EQUIPMENT_ALARM,
|
||||
oam.ALARM_TYPE_PROCESSING_FAILURE,
|
||||
oam.ALARM_TYPE_ENVIRONMENTAL_ALARM,
|
||||
oam.ALARM_TYPE_QUALITY_OF_SERVICE_ALARM,
|
||||
}
|
||||
return rows
|
||||
for _, v := range alarmTypeArr {
|
||||
data = append(data, map[string]any{
|
||||
"alarmType": v,
|
||||
"total": 0,
|
||||
})
|
||||
}
|
||||
|
||||
// 告警类别数量
|
||||
rows := s.alarmRepository.GroupTotal(alarmStatus, "alarm_type", -1)
|
||||
for _, item := range data {
|
||||
for _, v := range rows {
|
||||
str := fmt.Sprint(v["alarm_type"])
|
||||
if str == item["alarmType"] {
|
||||
item["alarmType"] = str
|
||||
item["total"] = parse.Number(v["total"])
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// CountSeverity 告警级别数量
|
||||
func (s Alarm) CountSeverity(alarmStatus string) []map[string]any {
|
||||
data := []map[string]any{}
|
||||
alarmTypeArr := []string{
|
||||
oam.ALARM_SEVERITY_CRITICAL,
|
||||
oam.ALARM_SEVERITY_MAJOR,
|
||||
oam.ALARM_SEVERITY_MINOR,
|
||||
oam.ALARM_SEVERITY_WARNING,
|
||||
}
|
||||
for _, v := range alarmTypeArr {
|
||||
data = append(data, map[string]any{
|
||||
"severity": v,
|
||||
"total": 0,
|
||||
})
|
||||
}
|
||||
|
||||
// 数量
|
||||
rows := s.alarmRepository.GroupTotal(alarmStatus, "perceived_severity", -1)
|
||||
for _, item := range data {
|
||||
for _, v := range rows {
|
||||
str := fmt.Sprint(v["perceived_severity"])
|
||||
if str == item["severity"] {
|
||||
item["severity"] = str
|
||||
item["total"] = parse.Number(v["total"])
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// CountNe 告警状态前几排名
|
||||
func (s Alarm) CountNe(alarmStatus string, top int) []map[string]any {
|
||||
data := s.alarmRepository.GroupTotal(alarmStatus, "ne_type", top)
|
||||
for _, v := range data {
|
||||
v["neType"] = fmt.Sprint(v["ne_type"])
|
||||
v["total"] = parse.Number(v["total"])
|
||||
delete(v, "ne_type")
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
|
||||
@@ -2,6 +2,9 @@ package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/tsmask/go-oam"
|
||||
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
@@ -9,44 +12,44 @@ import (
|
||||
|
||||
// 实例化数据层 AlarmEvent 结构体
|
||||
var NewAlarmEvent = &AlarmEvent{
|
||||
AlarmEventRepository: repository.NewAlarmEvent,
|
||||
alarmEventRepository: repository.NewAlarmEvent,
|
||||
}
|
||||
|
||||
// AlarmEvent 告警 服务层处理
|
||||
type AlarmEvent struct {
|
||||
AlarmEventRepository *repository.AlarmEvent // 告警数据信息
|
||||
alarmEventRepository *repository.AlarmEvent // 告警数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r AlarmEvent) FindByPage(query model.AlarmEventQuery) ([]model.AlarmEvent, int64) {
|
||||
return r.AlarmEventRepository.SelectByPage(query)
|
||||
return r.alarmEventRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// Find 查询
|
||||
func (r AlarmEvent) Find(param model.AlarmEvent) []model.AlarmEvent {
|
||||
return r.AlarmEventRepository.Select(param)
|
||||
return r.alarmEventRepository.Select(param)
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (s AlarmEvent) Insert(param model.AlarmEvent) int64 {
|
||||
return s.AlarmEventRepository.Insert(param)
|
||||
return s.alarmEventRepository.Insert(param)
|
||||
}
|
||||
|
||||
// Update 修改信息
|
||||
func (s AlarmEvent) Update(param model.AlarmEvent) int64 {
|
||||
return s.AlarmEventRepository.Update(param)
|
||||
return s.alarmEventRepository.Update(param)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r AlarmEvent) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
data := r.AlarmEventRepository.SelectByIds(ids)
|
||||
data := r.alarmEventRepository.SelectByIds(ids)
|
||||
if len(data) <= 0 {
|
||||
return 0, fmt.Errorf("no data")
|
||||
}
|
||||
|
||||
if len(data) == len(ids) {
|
||||
rows := r.AlarmEventRepository.DeleteByIds(ids)
|
||||
rows := r.alarmEventRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
@@ -55,5 +58,28 @@ func (r AlarmEvent) DeleteByIds(ids []int64) (int64, error) {
|
||||
|
||||
// FindAlarmEventSeqLast 查询网元告警最后一条序号
|
||||
func (s AlarmEvent) FindAlarmEventSeqLast(neType, neId string) int64 {
|
||||
return s.AlarmEventRepository.SelectAlarmEventSeqLast(neType, neId)
|
||||
return s.alarmEventRepository.SelectAlarmEventSeqLast(neType, neId)
|
||||
}
|
||||
|
||||
// ClearByIds 批量清除告警信息
|
||||
func (r AlarmEvent) ClearByIds(ids []int64, clearUser, clearType string) (int64, error) {
|
||||
// 检查是否存在
|
||||
arr := r.alarmEventRepository.SelectByIds(ids)
|
||||
if len(arr) <= 0 {
|
||||
return 0, fmt.Errorf("no data")
|
||||
}
|
||||
|
||||
if len(arr) == len(ids) {
|
||||
var rows int64 = 0
|
||||
for _, v := range arr {
|
||||
v.AlarmStatus = oam.ALARM_STATUS_CLEAR
|
||||
// 告警清除
|
||||
v.ClearType = clearType
|
||||
v.ClearUser = clearUser
|
||||
v.ClearTime = time.Now().UnixMilli()
|
||||
rows += r.alarmEventRepository.Update(v)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
return 0, fmt.Errorf("clear fail")
|
||||
}
|
||||
|
||||
453
src/modules/network_data/service/cbc_message.go
Normal file
453
src/modules/network_data/service/cbc_message.go
Normal file
@@ -0,0 +1,453 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 实例化数据层 CBCMessage 结构体
|
||||
var NewCBCMessage = &CBCMessage{
|
||||
cbcMessageRepository: repository.NewCBCMessage,
|
||||
}
|
||||
|
||||
// CBCMessage CB消息 服务层处理
|
||||
type CBCMessage struct {
|
||||
cbcMessageRepository *repository.CBCMessage // UE会话事件数据信息
|
||||
}
|
||||
|
||||
// SelectByPage 根据条件分页查询CB消息
|
||||
func (s *CBCMessage) SelectByPage(query model.CBCMessageQuery) ([]model.CBCMessage, int, error) {
|
||||
return s.cbcMessageRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// SelectCBCMessageById 根据工单ID查询CB消息
|
||||
// @Description 根据工单ID查询CB消息
|
||||
// @param id 工单ID
|
||||
// @return *model.CBCMessage CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// CBCMessage.SelectCBCMessageById(12345)
|
||||
func (s *CBCMessage) SelectById(id int64) (*model.CBCMessage, error) {
|
||||
return s.cbcMessageRepository.SelectById(id)
|
||||
}
|
||||
|
||||
func (s *CBCMessage) Insert(msg model.CBCMessage) error {
|
||||
// 解析messageJson获取eventName
|
||||
var messageData map[string]interface{}
|
||||
if err := json.Unmarshal(msg.MessageJson, &messageData); err != nil {
|
||||
return fmt.Errorf("failed to parse message_json: %w", err)
|
||||
}
|
||||
|
||||
// 提取eventName
|
||||
eventName, ok := messageData["eventName"].(string)
|
||||
if !ok || eventName == "" {
|
||||
return fmt.Errorf("eventName is required in message_json")
|
||||
}
|
||||
|
||||
// 检查是否已存在相同的eventName
|
||||
var err error
|
||||
var existingMsg *model.CBCMessage
|
||||
if existingMsg, err = s.cbcMessageRepository.SelectByEventName(eventName); err != nil {
|
||||
return fmt.Errorf("failed to check existing CBC message: %w", err)
|
||||
}
|
||||
|
||||
if existingMsg != nil {
|
||||
return fmt.Errorf("CBC message with eventName '%s' already exists for neType '%s' and neId '%s'",
|
||||
eventName, existingMsg.NeType, existingMsg.NeId)
|
||||
}
|
||||
return s.cbcMessageRepository.Insert(msg)
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// mfCBCMessageService.UpdateCBCMessage(msg)
|
||||
func (s *CBCMessage) Update(id int64, messageJson json.RawMessage) error {
|
||||
// 解析messageJson获取eventName
|
||||
var messageData map[string]interface{}
|
||||
if err := json.Unmarshal(messageJson, &messageData); err != nil {
|
||||
return fmt.Errorf("failed to parse message_json: %w", err)
|
||||
}
|
||||
// 提取eventName
|
||||
eventName, ok := messageData["eventName"].(string)
|
||||
if !ok || eventName == "" {
|
||||
return fmt.Errorf("eventName is required in message_json")
|
||||
}
|
||||
|
||||
// 检查是否已存在相同的eventName
|
||||
var err error
|
||||
if _, err = s.cbcMessageRepository.SelectByEventName(eventName); err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return fmt.Errorf("no existing CBC message found with eventName: %s", eventName)
|
||||
}
|
||||
return fmt.Errorf("failed to query existing CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 如果存在,更新记录
|
||||
var msg *model.CBCMessage
|
||||
if msg, err = s.cbcMessageRepository.Update(id, messageJson); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 如果状态是ACTIVE,发送更新请求
|
||||
if msg.Status == model.CBCEventStatusActive {
|
||||
if err := s.sendUpdateRequest(*msg); err != nil {
|
||||
return fmt.Errorf("failed to send update request: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessage 更新CB消息
|
||||
// @Description 更新CB消息
|
||||
// @param msg CB消息对象
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// UpdateCBCMessageDetail(msg)
|
||||
func (s *CBCMessage) UpdateDetail(eventName, detail string) error {
|
||||
if err := s.cbcMessageRepository.UpdateDetail(eventName, detail); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message detail: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCBCMessage 删除CB消息
|
||||
// @Description 删除CB消息
|
||||
// @param id 工单ID
|
||||
// @return error 错误信息
|
||||
// @example
|
||||
// mfCBCMessageService.DeleteCBCMessage(12345)
|
||||
func (s *CBCMessage) Delete(id int64) error {
|
||||
// 先查询记录状态
|
||||
var err error
|
||||
var msg *model.CBCMessage
|
||||
if msg, err = s.cbcMessageRepository.SelectById(id); err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return fmt.Errorf("CBC message with ID %d not found", id)
|
||||
}
|
||||
return fmt.Errorf("failed to query CBC message: %w", err)
|
||||
}
|
||||
|
||||
// 检查状态是否为ACTIVE
|
||||
if msg.Status == model.CBCEventStatusActive {
|
||||
return fmt.Errorf("cannot delete an active CBC message (ID: %d)", id)
|
||||
}
|
||||
|
||||
// 执行删除操作
|
||||
if err := s.cbcMessageRepository.Delete(id); err != nil {
|
||||
return fmt.Errorf("failed to delete CBC message: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateStatus(id int64, status string) error {
|
||||
newStatus := model.ParseCBCEventStatus(status)
|
||||
|
||||
// 查询所有需要更新的记录
|
||||
var err error
|
||||
var msg *model.CBCMessage
|
||||
if msg, err = s.cbcMessageRepository.SelectById(id); err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return fmt.Errorf("CBC message with ID %d not found", id)
|
||||
}
|
||||
return fmt.Errorf("failed to query CBC message: %w", err)
|
||||
}
|
||||
|
||||
oldStatus := msg.Status
|
||||
|
||||
// 检查状态是否发生变化
|
||||
if oldStatus == newStatus {
|
||||
return fmt.Errorf("CBC message status is already %s", newStatus.Enum())
|
||||
}
|
||||
|
||||
// 更新数据库状态
|
||||
if err := s.cbcMessageRepository.UpdateStatus(id, newStatus); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
// 根据状态变化发送HTTP请求
|
||||
if err := s.handleStatusChange(*msg, oldStatus, newStatus); err != nil {
|
||||
// 记录错误但不中断处理其他消息
|
||||
fmt.Printf("Failed to handle status change for message %d: %v\n", msg.Id, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateStatusByNeId(neId string, status string) error {
|
||||
newStatus := model.ParseCBCEventStatus(status)
|
||||
|
||||
// 查询所有需要更新的记录
|
||||
msgs := make([]model.CBCMessage, 0)
|
||||
if err := s.cbcMessageRepository.SelectByNeId(neId, &msgs); err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
oldStatus := msg.Status
|
||||
|
||||
// 检查状态是否发生变化
|
||||
if oldStatus == newStatus {
|
||||
continue // 状态没有变化,跳过
|
||||
}
|
||||
|
||||
// 更新数据库状态
|
||||
if err := s.cbcMessageRepository.UpdateStatus(msg.Id, newStatus); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
// 根据状态变化发送HTTP请求
|
||||
if err := s.handleStatusChange(msg, oldStatus, newStatus); err != nil {
|
||||
// 记录错误但不中断处理其他消息
|
||||
fmt.Printf("Failed to handle status change for message %d: %v\n", msg.Id, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCBCMessageStatus 更新CB消息状态
|
||||
// @Description 更新CB消息状态,并根据状态变化发送相应的HTTP请求
|
||||
// @param status 新状态
|
||||
// @return error 错误信息
|
||||
func (s *CBCMessage) UpdateAllStatus(status string) error {
|
||||
newStatus := model.ParseCBCEventStatus(status)
|
||||
|
||||
// 查询所有需要更新的记录
|
||||
msgs := make([]model.CBCMessage, 0)
|
||||
if err := s.cbcMessageRepository.Select(&msgs); err != nil {
|
||||
return fmt.Errorf("failed to query CB messages: %w", err)
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
oldStatus := msg.Status
|
||||
|
||||
// 检查状态是否发生变化
|
||||
if oldStatus == newStatus {
|
||||
continue // 状态没有变化,跳过
|
||||
}
|
||||
|
||||
// 更新数据库状态
|
||||
if err := s.cbcMessageRepository.UpdateStatus(msg.Id, newStatus); err != nil {
|
||||
return fmt.Errorf("failed to update CBC message status: %w", err)
|
||||
}
|
||||
|
||||
// 根据状态变化发送HTTP请求
|
||||
if err := s.handleStatusChange(msg, oldStatus, newStatus); err != nil {
|
||||
// 记录错误但不中断处理其他消息
|
||||
fmt.Printf("Failed to handle status change for message %d: %v\n", msg.Id, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r CBCMessage) ExportXlsx(rows []model.CBCMessage, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": i18n.TKey(language, "alarm.export.alarmType"),
|
||||
"B1": i18n.TKey(language, "alarm.export.origSeverity"),
|
||||
"C1": i18n.TKey(language, "alarm.export.alarmTitle"),
|
||||
"D1": i18n.TKey(language, "alarm.export.eventTime"),
|
||||
"E1": i18n.TKey(language, "alarm.export.alarmId"),
|
||||
"F1": i18n.TKey(language, "alarm.export.alarmCode"),
|
||||
"G1": i18n.TKey(language, "ne.common.neType"),
|
||||
"H1": i18n.TKey(language, "ne.common.neName"),
|
||||
"I1": i18n.TKey(language, "ne.common.neId"),
|
||||
}
|
||||
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
|
||||
cells := map[string]any{
|
||||
"A" + idx: row.NeType,
|
||||
"B" + idx: row.NeId,
|
||||
"C" + idx: row.MessageJson, // 这里假设 MessageJson 已经是字符串格式
|
||||
"D" + idx: row.Status.Enum(),
|
||||
"E" + idx: row.Detail,
|
||||
"F" + idx: time.UnixMilli(row.CreatedAt).Format(time.RFC3339),
|
||||
"G" + idx: time.UnixMilli(row.UpdatedAt).Format(time.RFC3339),
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, cells)
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// handleStatusChange 处理状态变化时的HTTP请求
|
||||
func (s *CBCMessage) handleStatusChange(msg model.CBCMessage, oldStatus, newStatus model.CBCEventStatus) error {
|
||||
// 从NULL/INACTIVE状态修改为ACTIVE
|
||||
if (oldStatus == model.CBCEventStatusNull || oldStatus == model.CBCEventStatusInactive) &&
|
||||
newStatus == model.CBCEventStatusActive {
|
||||
return s.sendActivateRequest(msg)
|
||||
}
|
||||
|
||||
// 从ACTIVE更改为INACTIVE状态
|
||||
if oldStatus == model.CBCEventStatusActive && newStatus == model.CBCEventStatusInactive {
|
||||
return s.sendDeactivateRequest(msg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCBCNetworkElement 获取CBC网元的IP和端口信息
|
||||
// 这个方法需要根据你的实际网元管理系统来实现
|
||||
func (s *CBCMessage) getCBCNetworkElement(neId string) (string, int64, error) {
|
||||
// 查询网元信息
|
||||
neInfo := neService.NewNeInfo.FindByNeTypeAndNeID("CBC", neId)
|
||||
if neInfo.IP == "" {
|
||||
return "", 0, fmt.Errorf("CBC network element not found for neId: %s", neId)
|
||||
}
|
||||
return neInfo.IP, neInfo.Port, nil
|
||||
}
|
||||
|
||||
// CBCHTTPClient CBC网元HTTP客户端
|
||||
type CBCHTTPClient struct {
|
||||
client *http.Client
|
||||
baseURL string
|
||||
}
|
||||
|
||||
// NewCBCHTTPClient 创建CBC HTTP客户端
|
||||
func NewCBCHTTPClient(baseURL string) *CBCHTTPClient {
|
||||
return &CBCHTTPClient{
|
||||
client: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
baseURL: baseURL,
|
||||
}
|
||||
}
|
||||
|
||||
// PostMessage 发送POST请求创建消息
|
||||
func (c *CBCHTTPClient) PostMessage(messageData []byte) error {
|
||||
url := fmt.Sprintf("%s/api/v1/cbe/message", c.baseURL)
|
||||
return c.sendRequest("POST", url, messageData)
|
||||
}
|
||||
|
||||
// PutMessage 发送PUT请求更新消息
|
||||
func (c *CBCHTTPClient) PutMessage(messageData []byte) error {
|
||||
url := fmt.Sprintf("%s/api/v1/cbe/message", c.baseURL)
|
||||
return c.sendRequest("PUT", url, messageData)
|
||||
}
|
||||
|
||||
// DeleteMessage 发送DELETE请求删除消息
|
||||
func (c *CBCHTTPClient) DeleteMessage(eventName string, deletePayload []byte) error {
|
||||
url := fmt.Sprintf("%s/api/v1/cbe/message/%s", c.baseURL, eventName)
|
||||
return c.sendRequest("DELETE", url, deletePayload)
|
||||
}
|
||||
|
||||
// sendRequest 发送HTTP请求
|
||||
func (c *CBCHTTPClient) sendRequest(method, url string, body []byte) error {
|
||||
req, err := http.NewRequest(method, url, bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create %s request: %w", method, err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send %s request: %w", method, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return fmt.Errorf("%s request failed with status: %d, body: %s",
|
||||
method, resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 在CBCMessageService中添加方法
|
||||
func (s *CBCMessage) getCBCHTTPClient(neId string) (*CBCHTTPClient, error) {
|
||||
cbcIP, cbcPort, err := s.getCBCNetworkElement(neId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get CBC network element info: %w", err)
|
||||
}
|
||||
|
||||
baseURL := fmt.Sprintf("http://%s:%d", cbcIP, cbcPort)
|
||||
return NewCBCHTTPClient(baseURL), nil
|
||||
}
|
||||
|
||||
// 重构后的激活请求
|
||||
func (s *CBCMessage) sendActivateRequest(msg model.CBCMessage) error {
|
||||
client, err := s.getCBCHTTPClient(msg.NeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 直接使用 MessageJson 发送POST请求
|
||||
return client.PostMessage(msg.MessageJson)
|
||||
}
|
||||
|
||||
// 重构后的更新请求
|
||||
func (s *CBCMessage) sendUpdateRequest(msg model.CBCMessage) error {
|
||||
client, err := s.getCBCHTTPClient(msg.NeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 直接使用 MessageJson 发送POST请求
|
||||
return client.PostMessage(msg.MessageJson)
|
||||
}
|
||||
|
||||
// 重构后的停用请求
|
||||
func (s *CBCMessage) sendDeactivateRequest(msg model.CBCMessage) error {
|
||||
client, err := s.getCBCHTTPClient(msg.NeId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析和构造删除载荷的逻辑保持不变
|
||||
var messageData map[string]interface{}
|
||||
if err := json.Unmarshal(msg.MessageJson, &messageData); err != nil {
|
||||
return fmt.Errorf("failed to parse message_json: %w", err)
|
||||
}
|
||||
|
||||
eventName, ok := messageData["eventName"].(string)
|
||||
if !ok || eventName == "" {
|
||||
return fmt.Errorf("eventName not found in message_json")
|
||||
}
|
||||
|
||||
deletePayload := make(map[string]interface{})
|
||||
if messageIdProfile, exists := messageData["messageIdProfile"]; exists {
|
||||
deletePayload["messageIdProfile"] = messageIdProfile
|
||||
}
|
||||
if warningAreaList, exists := messageData["warningAreaList"]; exists {
|
||||
deletePayload["warningAreaList"] = warningAreaList
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(deletePayload)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal delete payload: %w", err)
|
||||
}
|
||||
|
||||
return client.DeleteMessage(eventName, payloadBytes)
|
||||
}
|
||||
645
src/modules/network_data/service/cdr_event.go
Normal file
645
src/modules/network_data/service/cdr_event.go
Normal file
@@ -0,0 +1,645 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREvent 结构体
|
||||
var NewCDREvent = &CDREvent{
|
||||
cdrEventRepository: repository.NewCDREvent,
|
||||
}
|
||||
|
||||
// CDREvent CDR会话事件 服务层处理
|
||||
type CDREvent struct {
|
||||
cdrEventRepository *repository.CDREvent // CDR会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r CDREvent) FindByPage(neType string, query map[string]string) ([]model.CDREvent, int64) {
|
||||
return r.cdrEventRepository.SelectByPage(neType, query)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r CDREvent) DeleteByIds(neType string, ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.cdrEventRepository.SelectByIds(neType, ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("not data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.cdrEventRepository.DeleteByIds(neType, ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (s CDREvent) Insert(param model.CDREvent) int64 {
|
||||
return s.cdrEventRepository.Insert(param)
|
||||
}
|
||||
|
||||
// ExportSMSC 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportSMSC(rows []model.CDREvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Record Behavior",
|
||||
"D1": "Service Type",
|
||||
"E1": "Caller",
|
||||
"F1": "Called",
|
||||
"G1": "Result",
|
||||
"H1": "Time",
|
||||
}
|
||||
// 读取字典数据 CDR 原因码
|
||||
dictCDRCauseCode := sysService.NewSysDictData.FindByType("cdr_cause_code")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
// 服务类型
|
||||
serviceType := ""
|
||||
if v, ok := cdrJSON["serviceType"]; ok && v != nil {
|
||||
serviceType = v.(string)
|
||||
}
|
||||
// 被叫
|
||||
called := ""
|
||||
if v, ok := cdrJSON["calledParty"]; ok && v != nil {
|
||||
called = v.(string)
|
||||
}
|
||||
// 主叫
|
||||
caller := ""
|
||||
if v, ok := cdrJSON["callerParty"]; ok && v != nil {
|
||||
caller = v.(string)
|
||||
}
|
||||
// 呼叫结果 0失败,1成功
|
||||
callResult := "Fail"
|
||||
if v, ok := cdrJSON["result"]; ok && v != nil {
|
||||
resultVal := parse.Number(v)
|
||||
if resultVal == 1 {
|
||||
callResult = "Success"
|
||||
}
|
||||
}
|
||||
// 结果原因
|
||||
if v, ok := cdrJSON["cause"]; ok && v != nil && callResult == "Fail" {
|
||||
cause := fmt.Sprint(v)
|
||||
for _, v := range dictCDRCauseCode {
|
||||
if cause == v.DataValue {
|
||||
callResult = fmt.Sprintf("%s, %s", callResult, i18n.TKey(language, v.DataLabel))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if v, ok := cdrJSON["updateTime"]; ok && v != nil {
|
||||
if releaseTime := parse.Number(v); releaseTime > 0 {
|
||||
timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeName,
|
||||
"C" + idx: recordType,
|
||||
"D" + idx: serviceType,
|
||||
"E" + idx: caller,
|
||||
"F" + idx: called,
|
||||
"G" + idx: callResult,
|
||||
"H" + idx: timeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// ExportSMF 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportSMF(rows []model.CDREvent, fileName string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "Charging ID",
|
||||
"C1": "NE Name",
|
||||
"D1": "Resource Unique ID",
|
||||
"E1": "Subscriber ID Data",
|
||||
"F1": "Subscriber ID Type",
|
||||
"G1": "Data Volume Uplink",
|
||||
"H1": "Data Volume Downlink",
|
||||
"I1": "Data Total Volume",
|
||||
"J1": "Duration",
|
||||
"K1": "Invocation Time",
|
||||
"L1": "User Identifier",
|
||||
"M1": "SSC Mode",
|
||||
"N1": "DNN ID",
|
||||
"O1": "PDU Type",
|
||||
"P1": "RAT Type",
|
||||
"Q1": "PDU IPv4 Address",
|
||||
"R1": "Network Function IPv4",
|
||||
"S1": "PDU IPv6 Address Swith Prefix",
|
||||
"T1": "Record Network Function ID",
|
||||
"U1": "Record Type",
|
||||
"V1": "Record Opening Time",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 计费ID
|
||||
chargingID := ""
|
||||
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
|
||||
chargingID = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 订阅 ID 类型
|
||||
subscriptionIDType := "-"
|
||||
// 订阅 ID 数据
|
||||
subscriptionIDData := "-"
|
||||
if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil {
|
||||
if sub, subOk := v.(map[string]any); subOk && sub != nil {
|
||||
subscriptionIDType = sub["subscriptionIDType"].(string)
|
||||
subscriptionIDData = sub["subscriptionIDData"].(string)
|
||||
}
|
||||
}
|
||||
|
||||
// 网络功能 IPv4 地址
|
||||
networkFunctionIPv4Address := ""
|
||||
if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil {
|
||||
if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil {
|
||||
networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string)
|
||||
}
|
||||
}
|
||||
|
||||
// 数据量上行链路
|
||||
var dataVolumeUplink int64 = 0
|
||||
// 数据量下行链路
|
||||
var dataVolumeDownlink int64 = 0
|
||||
// 数据总量
|
||||
var dataTotalVolume int64 = 0
|
||||
if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil {
|
||||
usageList := v.([]any)
|
||||
if len(usageList) > 0 {
|
||||
for _, used := range usageList {
|
||||
usedUnit := used.(map[string]any)
|
||||
usedUnitList := usedUnit["usedUnitContainer"].([]any)
|
||||
if len(usedUnitList) > 0 {
|
||||
for _, data := range usedUnitList {
|
||||
udata := data.(map[string]any)
|
||||
if dup, dupOk := udata["dataVolumeUplink"]; dupOk {
|
||||
dataVolumeUplink += parse.Number(dup)
|
||||
}
|
||||
if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk {
|
||||
dataVolumeDownlink += parse.Number(ddown)
|
||||
}
|
||||
if dt, dtOk := udata["dataTotalVolume"]; dtOk {
|
||||
dataTotalVolume += parse.Number(dt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["duration"]; ok && v != nil {
|
||||
duration = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 调用时间
|
||||
invocationTimestamp := ""
|
||||
if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil {
|
||||
invocationTimestamp = v.(string)
|
||||
}
|
||||
// 记录打开时间
|
||||
User_Identifier := ""
|
||||
SSC_Mode := ""
|
||||
RAT_Type := ""
|
||||
DNN_ID := ""
|
||||
PDU_Type := ""
|
||||
PDU_IPv4 := ""
|
||||
PDU_IPv6 := ""
|
||||
if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil {
|
||||
pduInfo := v.(map[string]any)
|
||||
|
||||
if v, ok := pduInfo["userIdentifier"]; ok && v != nil {
|
||||
User_Identifier = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["sSCMode"]; ok && v != nil {
|
||||
SSC_Mode = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["rATType"]; ok && v != nil {
|
||||
RAT_Type = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["dNNID"]; ok && v != nil {
|
||||
DNN_ID = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["pDUType"]; ok && v != nil {
|
||||
PDU_Type = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["pDUAddress"]; ok && v != nil {
|
||||
pDUAddress := v.(map[string]any)
|
||||
if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil {
|
||||
PDU_IPv4 = addr.(string)
|
||||
}
|
||||
if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil {
|
||||
PDU_IPv6 = addr.(string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 记录网络参数ID
|
||||
recordNFID := ""
|
||||
if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil {
|
||||
recordNFID = v.(string)
|
||||
}
|
||||
|
||||
//记录开始时间
|
||||
recordOpeningTime := ""
|
||||
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
|
||||
recordOpeningTime = v.(string)
|
||||
}
|
||||
|
||||
//记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: chargingID,
|
||||
"C" + idx: row.NeName,
|
||||
"D" + idx: row.RmUid,
|
||||
"E" + idx: subscriptionIDData,
|
||||
"F" + idx: subscriptionIDType,
|
||||
"G" + idx: dataVolumeUplink,
|
||||
"H" + idx: dataVolumeDownlink,
|
||||
"I" + idx: dataTotalVolume,
|
||||
"J" + idx: duration,
|
||||
"K" + idx: invocationTimestamp,
|
||||
"L" + idx: User_Identifier,
|
||||
"M" + idx: SSC_Mode,
|
||||
"N" + idx: DNN_ID,
|
||||
"O" + idx: PDU_Type,
|
||||
"P" + idx: RAT_Type,
|
||||
"Q" + idx: PDU_IPv4,
|
||||
"R" + idx: networkFunctionIPv4Address,
|
||||
"S" + idx: PDU_IPv6,
|
||||
"T" + idx: recordNFID,
|
||||
"U" + idx: recordType,
|
||||
"V" + idx: recordOpeningTime,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// ExportSGWC 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportSGWC(rows []model.CDREvent, fileName string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Resource Unique ID",
|
||||
"D1": "Charging ID",
|
||||
"E1": "IMSI",
|
||||
"F1": "MSISDN",
|
||||
"G1": "GPRS Uplink",
|
||||
"H1": "GPRS Downlink",
|
||||
"I1": "Duration",
|
||||
"J1": "Invocation Time",
|
||||
"K1": "PGW Address",
|
||||
"L1": "SGW Address",
|
||||
"M1": "RAT Type",
|
||||
"N1": "PDPPDN Type",
|
||||
"O1": "PDPPDN Address",
|
||||
"P1": "Node Address",
|
||||
"Q1": "Node Type",
|
||||
"R1": "Record Access Point Name NI",
|
||||
"S1": "Record Cause For Rec Closing",
|
||||
"T1": "Record Sequence Number",
|
||||
"U1": "Local Record Sequence Number",
|
||||
"V1": "Record Type",
|
||||
"W1": "Record Opening Time",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 计费ID
|
||||
chargingID := ""
|
||||
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
|
||||
chargingID = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// IMSI
|
||||
servedIMSI := ""
|
||||
if v, ok := cdrJSON["servedIMSI"]; ok && v != nil {
|
||||
servedIMSI = fmt.Sprint(v)
|
||||
}
|
||||
// MSISDN
|
||||
servedMSISDN := ""
|
||||
if v, ok := cdrJSON["servedMSISDN"]; ok && v != nil {
|
||||
servedMSISDN = fmt.Sprint(v)
|
||||
}
|
||||
// pGWAddressUsed
|
||||
pGWAddressUsed := ""
|
||||
if v, ok := cdrJSON["pGWAddressUsed"]; ok && v != nil {
|
||||
pGWAddressUsed = fmt.Sprint(v)
|
||||
headerCells["K1"] = "PGW Address"
|
||||
}
|
||||
if v, ok := cdrJSON["GGSNAddress"]; ok && v != nil {
|
||||
pGWAddressUsed = fmt.Sprint(v)
|
||||
headerCells["K1"] = "GGSN Address"
|
||||
}
|
||||
// sGWAddress
|
||||
sGWAddress := ""
|
||||
if v, ok := cdrJSON["sGWAddress"]; ok && v != nil {
|
||||
sGWAddress = fmt.Sprint(v)
|
||||
headerCells["L1"] = "SGW Address"
|
||||
}
|
||||
if v, ok := cdrJSON["SGSNAddress"]; ok && v != nil {
|
||||
sGWAddress = fmt.Sprint(v)
|
||||
headerCells["L1"] = "SGSN Address"
|
||||
}
|
||||
// recordType
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = fmt.Sprint(v)
|
||||
}
|
||||
// rATType
|
||||
rATType := ""
|
||||
if v, ok := cdrJSON["rATType"]; ok && v != nil {
|
||||
rATType = fmt.Sprint(v)
|
||||
}
|
||||
// pdpPDNType
|
||||
pdpPDNType := ""
|
||||
if v, ok := cdrJSON["pdpPDNType"]; ok && v != nil {
|
||||
pdpPDNType = fmt.Sprint(v)
|
||||
}
|
||||
// servedPDPPDNAddress
|
||||
servedPDPPDNAddress := ""
|
||||
if v, ok := cdrJSON["servedPDPPDNAddress"]; ok && v != nil {
|
||||
servedPDPPDNAddress = fmt.Sprint(v)
|
||||
}
|
||||
// servedPDPPDNAddress
|
||||
servingNodeAddress := []string{}
|
||||
if v, ok := cdrJSON["servingNodeAddress"]; ok && v != nil {
|
||||
for _, v := range v.([]any) {
|
||||
servingNodeAddress = append(servingNodeAddress, fmt.Sprint(v))
|
||||
}
|
||||
}
|
||||
// servingNodeType
|
||||
servingNodeType := []string{}
|
||||
if v, ok := cdrJSON["servingNodeType"]; ok && v != nil {
|
||||
for _, v := range v.([]any) {
|
||||
if v, ok := v.(map[string]any)["servingNodeType"]; ok && v != nil {
|
||||
servingNodeType = append(servingNodeType, fmt.Sprint(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
// accessPointNameNI
|
||||
accessPointNameNI := ""
|
||||
if v, ok := cdrJSON["accessPointNameNI"]; ok && v != nil {
|
||||
accessPointNameNI = fmt.Sprint(v)
|
||||
}
|
||||
// causeForRecClosing
|
||||
causeForRecClosing := ""
|
||||
if v, ok := cdrJSON["causeForRecClosing"]; ok && v != nil {
|
||||
causeForRecClosing = fmt.Sprint(v)
|
||||
}
|
||||
// recordSequenceNumber
|
||||
recordSequenceNumber := ""
|
||||
if v, ok := cdrJSON["recordSequenceNumber"]; ok && v != nil {
|
||||
recordSequenceNumber = fmt.Sprint(v)
|
||||
}
|
||||
// localRecordSequenceNumber
|
||||
localRecordSequenceNumber := ""
|
||||
if v, ok := cdrJSON["localRecordSequenceNumber"]; ok && v != nil {
|
||||
localRecordSequenceNumber = fmt.Sprint(v)
|
||||
}
|
||||
// 数据量上行链路
|
||||
var dataVolumeGPRSUplink int64 = 0
|
||||
// 数据量下行链路
|
||||
var dataVolumeGPRSDownlink int64 = 0
|
||||
if v, ok := cdrJSON["listOfTrafficVolumes"]; ok && v != nil {
|
||||
usageList := v.([]any)
|
||||
if len(usageList) > 0 {
|
||||
for _, used := range usageList {
|
||||
usedUnit := used.(map[string]any)
|
||||
if dup, dupOk := usedUnit["dataVolumeGPRSUplink"]; dupOk {
|
||||
dataVolumeGPRSUplink = parse.Number(dup)
|
||||
}
|
||||
if ddown, ddownOk := usedUnit["dataVolumeGPRSDownlink"]; ddownOk {
|
||||
dataVolumeGPRSDownlink = parse.Number(ddown)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["duration"]; ok && v != nil {
|
||||
duration = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 调用时间
|
||||
invocationTimestamp := ""
|
||||
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
|
||||
invocationTimestamp = v.(string)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeName,
|
||||
"C" + idx: row.RmUid,
|
||||
"D" + idx: chargingID,
|
||||
"E" + idx: servedIMSI,
|
||||
"F" + idx: servedMSISDN,
|
||||
"G" + idx: dataVolumeGPRSUplink,
|
||||
"H" + idx: dataVolumeGPRSDownlink,
|
||||
"I" + idx: duration,
|
||||
"J" + idx: invocationTimestamp,
|
||||
"K" + idx: pGWAddressUsed,
|
||||
"L" + idx: sGWAddress,
|
||||
"M" + idx: rATType,
|
||||
"N" + idx: pdpPDNType,
|
||||
"O" + idx: servedPDPPDNAddress,
|
||||
"P" + idx: strings.Join(servingNodeAddress, ","),
|
||||
"Q" + idx: strings.Join(servingNodeType, ","),
|
||||
"R" + idx: accessPointNameNI,
|
||||
"S" + idx: causeForRecClosing,
|
||||
"T" + idx: recordSequenceNumber,
|
||||
"U" + idx: localRecordSequenceNumber,
|
||||
"V" + idx: recordType,
|
||||
"W" + idx: invocationTimestamp,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// ExportIMS 导出数据到 xlsx 文件
|
||||
func (r CDREvent) ExportIMS(rows []model.CDREvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Record Behavior",
|
||||
"D1": "Type",
|
||||
"E1": "Caller",
|
||||
"F1": "Called",
|
||||
"G1": "Duration",
|
||||
"H1": "Result Code",
|
||||
"I1": "Result Cause",
|
||||
"J1": "Call Start Time",
|
||||
"K1": "Hangup Time",
|
||||
}
|
||||
// 读取字典数据 CDR SIP响应代码类别类型
|
||||
dictCDRSipCode := sysService.NewSysDictData.FindByType("cdr_sip_code")
|
||||
// 读取字典数据 CDR SIP响应代码类别类型原因
|
||||
dictCDRSipCodeCause := sysService.NewSysDictData.FindByType("cdr_sip_code_cause")
|
||||
// 读取字典数据 CDR 呼叫类型
|
||||
dictCDRCallType := sysService.NewSysDictData.FindByType("cdr_call_type")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]any
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
// 呼叫类型
|
||||
callType := "sms"
|
||||
callTypeLable := "SMS"
|
||||
if v, ok := cdrJSON["callType"]; ok && v != nil {
|
||||
callType = v.(string)
|
||||
for _, v := range dictCDRCallType {
|
||||
if callType == v.DataValue {
|
||||
callTypeLable = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 被叫
|
||||
called := ""
|
||||
if v, ok := cdrJSON["calledParty"]; ok && v != nil {
|
||||
called = v.(string)
|
||||
}
|
||||
// 主叫
|
||||
caller := ""
|
||||
if v, ok := cdrJSON["callerParty"]; ok && v != nil {
|
||||
caller = v.(string)
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" {
|
||||
duration = fmt.Sprintf("%ds", parse.Number(v))
|
||||
}
|
||||
// 呼叫结果 非短信都有code作为结果 sms短信都ok
|
||||
callResult := "Other"
|
||||
callCause := "Call failure for other reason"
|
||||
if callType == "sms" {
|
||||
callResult = "Success"
|
||||
callCause = "Normal Send"
|
||||
} else {
|
||||
if v, ok := cdrJSON["cause"]; ok && v != nil {
|
||||
cause := fmt.Sprint(v)
|
||||
for _, v := range dictCDRSipCode {
|
||||
if cause == v.DataValue {
|
||||
callResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, v := range dictCDRSipCodeCause {
|
||||
if cause == v.DataValue {
|
||||
callCause = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 呼叫时间
|
||||
seizureTimeStr := ""
|
||||
if v, ok := cdrJSON["seizureTime"]; ok && v != nil {
|
||||
if seizureTime := parse.Number(v); seizureTime > 0 {
|
||||
seizureTimeStr = date.ParseDateToStr(seizureTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
seizureTimeStr = v.(string)
|
||||
}
|
||||
}
|
||||
// 挂断时间
|
||||
releaseTimeStr := ""
|
||||
if v, ok := cdrJSON["releaseTime"]; ok && v != nil {
|
||||
if releaseTime := parse.Number(v); releaseTime > 0 {
|
||||
releaseTimeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
releaseTimeStr = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeName,
|
||||
"C" + idx: recordType,
|
||||
"D" + idx: callTypeLable,
|
||||
"E" + idx: caller,
|
||||
"F" + idx: called,
|
||||
"G" + idx: duration,
|
||||
"H" + idx: callResult,
|
||||
"I" + idx: callCause,
|
||||
"J" + idx: seizureTimeStr,
|
||||
"K" + idx: releaseTimeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventIMS 结构体
|
||||
var NewCDREventIMS = &CDREventIMS{
|
||||
cdrEventIMSRepository: repository.NewCDREventIMS,
|
||||
}
|
||||
|
||||
// CDREventImpl CDR会话事件IMS 服务层处理
|
||||
type CDREventIMS struct {
|
||||
cdrEventIMSRepository *repository.CDREventIMS // CDR会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r *CDREventIMS) FindByPage(query model.CDREventIMSQuery) ([]model.CDREventIMS, int64) {
|
||||
return r.cdrEventIMSRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventIMS) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.cdrEventIMSRepository.SelectByIds(ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("not data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.cdrEventIMSRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r CDREventIMS) ExportXlsx(rows []model.CDREventIMS, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Record Behavior",
|
||||
"D1": "Type",
|
||||
"E1": "Caller",
|
||||
"F1": "Called",
|
||||
"G1": "Duration",
|
||||
"H1": "Result Code",
|
||||
"I1": "Result Cause",
|
||||
"J1": "Call Start Time",
|
||||
"K1": "Hangup Time",
|
||||
}
|
||||
// 读取字典数据 CDR SIP响应代码类别类型
|
||||
dictCDRSipCode := sysService.NewSysDictData.FindByType("cdr_sip_code")
|
||||
// 读取字典数据 CDR SIP响应代码类别类型原因
|
||||
dictCDRSipCodeCause := sysService.NewSysDictData.FindByType("cdr_sip_code_cause")
|
||||
// 读取字典数据 CDR 呼叫类型
|
||||
dictCDRCallType := sysService.NewSysDictData.FindByType("cdr_call_type")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]any
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
// 呼叫类型
|
||||
callType := "sms"
|
||||
callTypeLable := "SMS"
|
||||
if v, ok := cdrJSON["callType"]; ok && v != nil {
|
||||
callType = v.(string)
|
||||
for _, v := range dictCDRCallType {
|
||||
if callType == v.DataValue {
|
||||
callTypeLable = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 被叫
|
||||
called := ""
|
||||
if v, ok := cdrJSON["calledParty"]; ok && v != nil {
|
||||
called = v.(string)
|
||||
}
|
||||
// 主叫
|
||||
caller := ""
|
||||
if v, ok := cdrJSON["callerParty"]; ok && v != nil {
|
||||
caller = v.(string)
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" {
|
||||
duration = fmt.Sprintf("%ds", parse.Number(v))
|
||||
}
|
||||
// 呼叫结果 非短信都有code作为结果 sms短信都ok
|
||||
callResult := "Other"
|
||||
callCause := "Call failure for other reason"
|
||||
if callType == "sms" {
|
||||
callResult = "Success"
|
||||
callCause = "Normal Send"
|
||||
} else {
|
||||
if v, ok := cdrJSON["cause"]; ok && v != nil {
|
||||
cause := fmt.Sprint(v)
|
||||
for _, v := range dictCDRSipCode {
|
||||
if cause == v.DataValue {
|
||||
callResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, v := range dictCDRSipCodeCause {
|
||||
if cause == v.DataValue {
|
||||
callCause = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 呼叫时间
|
||||
seizureTimeStr := ""
|
||||
if v, ok := cdrJSON["seizureTime"]; ok && v != nil {
|
||||
if seizureTime := parse.Number(v); seizureTime > 0 {
|
||||
seizureTimeStr = date.ParseDateToStr(seizureTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
seizureTimeStr = v.(string)
|
||||
}
|
||||
}
|
||||
// 挂断时间
|
||||
releaseTimeStr := ""
|
||||
if v, ok := cdrJSON["releaseTime"]; ok && v != nil {
|
||||
if releaseTime := parse.Number(v); releaseTime > 0 {
|
||||
releaseTimeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
releaseTimeStr = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeName,
|
||||
"C" + idx: recordType,
|
||||
"D" + idx: callTypeLable,
|
||||
"E" + idx: caller,
|
||||
"F" + idx: called,
|
||||
"G" + idx: duration,
|
||||
"H" + idx: callResult,
|
||||
"I" + idx: callCause,
|
||||
"J" + idx: seizureTimeStr,
|
||||
"K" + idx: releaseTimeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventSGWC 结构体
|
||||
var NewCDREventSGWC = &CDREventSGWC{
|
||||
cdrEventRepository: repository.NewCDREventSGWC,
|
||||
}
|
||||
|
||||
// CDREventSGWC CDR会话事件SGWC 服务层处理
|
||||
type CDREventSGWC struct {
|
||||
cdrEventRepository *repository.CDREventSGWC // CDR会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r *CDREventSGWC) FindByPage(query model.CDREventSGWCQuery) ([]model.CDREventSGWC, int64) {
|
||||
return r.cdrEventRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventSGWC) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.cdrEventRepository.SelectByIds(ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("not data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.cdrEventRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r CDREventSGWC) ExportXlsx(rows []model.CDREventSGWC, fileName string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Resource Unique ID",
|
||||
"D1": "Charging ID",
|
||||
"E1": "IMSI",
|
||||
"F1": "MSISDN",
|
||||
"G1": "GPRS Uplink",
|
||||
"H1": "GPRS Downlink",
|
||||
"I1": "Duration",
|
||||
"J1": "Invocation Time",
|
||||
"K1": "PGW Address",
|
||||
"L1": "SGW Address",
|
||||
"M1": "RAT Type",
|
||||
"N1": "PDPPDN Type",
|
||||
"O1": "PDPPDN Address",
|
||||
"P1": "Node Address",
|
||||
"Q1": "Node Type",
|
||||
"R1": "Record Access Point Name NI",
|
||||
"S1": "Record Cause For Rec Closing",
|
||||
"T1": "Record Sequence Number",
|
||||
"U1": "Local Record Sequence Number",
|
||||
"V1": "Record Type",
|
||||
"W1": "Record Opening Time",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 计费ID
|
||||
chargingID := ""
|
||||
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
|
||||
chargingID = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// IMSI
|
||||
servedIMSI := ""
|
||||
if v, ok := cdrJSON["servedIMSI"]; ok && v != nil {
|
||||
servedIMSI = fmt.Sprint(v)
|
||||
}
|
||||
// MSISDN
|
||||
servedMSISDN := ""
|
||||
if v, ok := cdrJSON["servedMSISDN"]; ok && v != nil {
|
||||
servedMSISDN = fmt.Sprint(v)
|
||||
}
|
||||
// pGWAddressUsed
|
||||
pGWAddressUsed := ""
|
||||
if v, ok := cdrJSON["pGWAddressUsed"]; ok && v != nil {
|
||||
pGWAddressUsed = fmt.Sprint(v)
|
||||
headerCells["K1"] = "PGW Address"
|
||||
}
|
||||
if v, ok := cdrJSON["GGSNAddress"]; ok && v != nil {
|
||||
pGWAddressUsed = fmt.Sprint(v)
|
||||
headerCells["K1"] = "GGSN Address"
|
||||
}
|
||||
// sGWAddress
|
||||
sGWAddress := ""
|
||||
if v, ok := cdrJSON["sGWAddress"]; ok && v != nil {
|
||||
sGWAddress = fmt.Sprint(v)
|
||||
headerCells["L1"] = "SGW Address"
|
||||
}
|
||||
if v, ok := cdrJSON["SGSNAddress"]; ok && v != nil {
|
||||
sGWAddress = fmt.Sprint(v)
|
||||
headerCells["L1"] = "SGSN Address"
|
||||
}
|
||||
// recordType
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = fmt.Sprint(v)
|
||||
}
|
||||
// rATType
|
||||
rATType := ""
|
||||
if v, ok := cdrJSON["rATType"]; ok && v != nil {
|
||||
rATType = fmt.Sprint(v)
|
||||
}
|
||||
// pdpPDNType
|
||||
pdpPDNType := ""
|
||||
if v, ok := cdrJSON["pdpPDNType"]; ok && v != nil {
|
||||
pdpPDNType = fmt.Sprint(v)
|
||||
}
|
||||
// servedPDPPDNAddress
|
||||
servedPDPPDNAddress := ""
|
||||
if v, ok := cdrJSON["servedPDPPDNAddress"]; ok && v != nil {
|
||||
servedPDPPDNAddress = fmt.Sprint(v)
|
||||
}
|
||||
// servedPDPPDNAddress
|
||||
servingNodeAddress := []string{}
|
||||
if v, ok := cdrJSON["servingNodeAddress"]; ok && v != nil {
|
||||
for _, v := range v.([]any) {
|
||||
servingNodeAddress = append(servingNodeAddress, fmt.Sprint(v))
|
||||
}
|
||||
}
|
||||
// servingNodeType
|
||||
servingNodeType := []string{}
|
||||
if v, ok := cdrJSON["servingNodeType"]; ok && v != nil {
|
||||
for _, v := range v.([]any) {
|
||||
if v, ok := v.(map[string]any)["servingNodeType"]; ok && v != nil {
|
||||
servingNodeType = append(servingNodeType, fmt.Sprint(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
// accessPointNameNI
|
||||
accessPointNameNI := ""
|
||||
if v, ok := cdrJSON["accessPointNameNI"]; ok && v != nil {
|
||||
accessPointNameNI = fmt.Sprint(v)
|
||||
}
|
||||
// causeForRecClosing
|
||||
causeForRecClosing := ""
|
||||
if v, ok := cdrJSON["causeForRecClosing"]; ok && v != nil {
|
||||
causeForRecClosing = fmt.Sprint(v)
|
||||
}
|
||||
// recordSequenceNumber
|
||||
recordSequenceNumber := ""
|
||||
if v, ok := cdrJSON["recordSequenceNumber"]; ok && v != nil {
|
||||
recordSequenceNumber = fmt.Sprint(v)
|
||||
}
|
||||
// localRecordSequenceNumber
|
||||
localRecordSequenceNumber := ""
|
||||
if v, ok := cdrJSON["localRecordSequenceNumber"]; ok && v != nil {
|
||||
localRecordSequenceNumber = fmt.Sprint(v)
|
||||
}
|
||||
// 数据量上行链路
|
||||
var dataVolumeGPRSUplink int64 = 0
|
||||
// 数据量下行链路
|
||||
var dataVolumeGPRSDownlink int64 = 0
|
||||
if v, ok := cdrJSON["listOfTrafficVolumes"]; ok && v != nil {
|
||||
usageList := v.([]any)
|
||||
if len(usageList) > 0 {
|
||||
for _, used := range usageList {
|
||||
usedUnit := used.(map[string]any)
|
||||
if dup, dupOk := usedUnit["dataVolumeGPRSUplink"]; dupOk {
|
||||
dataVolumeGPRSUplink = parse.Number(dup)
|
||||
}
|
||||
if ddown, ddownOk := usedUnit["dataVolumeGPRSDownlink"]; ddownOk {
|
||||
dataVolumeGPRSDownlink = parse.Number(ddown)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["duration"]; ok && v != nil {
|
||||
duration = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 调用时间
|
||||
invocationTimestamp := ""
|
||||
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
|
||||
invocationTimestamp = v.(string)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeName,
|
||||
"C" + idx: row.RmUid,
|
||||
"D" + idx: chargingID,
|
||||
"E" + idx: servedIMSI,
|
||||
"F" + idx: servedMSISDN,
|
||||
"G" + idx: dataVolumeGPRSUplink,
|
||||
"H" + idx: dataVolumeGPRSDownlink,
|
||||
"I" + idx: duration,
|
||||
"J" + idx: invocationTimestamp,
|
||||
"K" + idx: pGWAddressUsed,
|
||||
"L" + idx: sGWAddress,
|
||||
"M" + idx: rATType,
|
||||
"N" + idx: pdpPDNType,
|
||||
"O" + idx: servedPDPPDNAddress,
|
||||
"P" + idx: strings.Join(servingNodeAddress, ","),
|
||||
"Q" + idx: strings.Join(servingNodeType, ","),
|
||||
"R" + idx: accessPointNameNI,
|
||||
"S" + idx: causeForRecClosing,
|
||||
"T" + idx: recordSequenceNumber,
|
||||
"U" + idx: localRecordSequenceNumber,
|
||||
"V" + idx: recordType,
|
||||
"W" + idx: invocationTimestamp,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventSMF 结构体
|
||||
var NewCDREventSMF = &CDREventSMF{
|
||||
cdrEventRepository: repository.NewCDREventSMF,
|
||||
}
|
||||
|
||||
// CDREventSMF CDR会话事件SMF 服务层处理
|
||||
type CDREventSMF struct {
|
||||
cdrEventRepository *repository.CDREventSMF // CDR会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r *CDREventSMF) FindByPage(querys model.CDREventSMFQuery) ([]model.CDREventSMF, int64) {
|
||||
return r.cdrEventRepository.SelectByPage(querys)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventSMF) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.cdrEventRepository.SelectByIds(ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("not data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.cdrEventRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r CDREventSMF) ExportXlsx(rows []model.CDREventSMF, fileName string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "Charging ID",
|
||||
"C1": "NE Name",
|
||||
"D1": "Resource Unique ID",
|
||||
"E1": "Subscriber ID Data",
|
||||
"F1": "Subscriber ID Type",
|
||||
"G1": "Data Volume Uplink",
|
||||
"H1": "Data Volume Downlink",
|
||||
"I1": "Data Total Volume",
|
||||
"J1": "Duration",
|
||||
"K1": "Invocation Time",
|
||||
"L1": "User Identifier",
|
||||
"M1": "SSC Mode",
|
||||
"N1": "DNN ID",
|
||||
"O1": "PDU Type",
|
||||
"P1": "RAT Type",
|
||||
"Q1": "PDU IPv4 Address",
|
||||
"R1": "Network Function IPv4",
|
||||
"S1": "PDU IPv6 Address Swith Prefix",
|
||||
"T1": "Record Network Function ID",
|
||||
"U1": "Record Type",
|
||||
"V1": "Record Opening Time",
|
||||
}
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 计费ID
|
||||
chargingID := ""
|
||||
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
|
||||
chargingID = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 订阅 ID 类型
|
||||
subscriptionIDType := "-"
|
||||
// 订阅 ID 数据
|
||||
subscriptionIDData := "-"
|
||||
if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil {
|
||||
if sub, subOk := v.(map[string]any); subOk && sub != nil {
|
||||
subscriptionIDType = sub["subscriptionIDType"].(string)
|
||||
subscriptionIDData = sub["subscriptionIDData"].(string)
|
||||
}
|
||||
}
|
||||
|
||||
// 网络功能 IPv4 地址
|
||||
networkFunctionIPv4Address := ""
|
||||
if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil {
|
||||
if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil {
|
||||
networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string)
|
||||
}
|
||||
}
|
||||
|
||||
// 数据量上行链路
|
||||
var dataVolumeUplink int64 = 0
|
||||
// 数据量下行链路
|
||||
var dataVolumeDownlink int64 = 0
|
||||
// 数据总量
|
||||
var dataTotalVolume int64 = 0
|
||||
if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil {
|
||||
usageList := v.([]any)
|
||||
if len(usageList) > 0 {
|
||||
for _, used := range usageList {
|
||||
usedUnit := used.(map[string]any)
|
||||
usedUnitList := usedUnit["usedUnitContainer"].([]any)
|
||||
if len(usedUnitList) > 0 {
|
||||
for _, data := range usedUnitList {
|
||||
udata := data.(map[string]any)
|
||||
if dup, dupOk := udata["dataVolumeUplink"]; dupOk {
|
||||
dataVolumeUplink += parse.Number(dup)
|
||||
}
|
||||
if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk {
|
||||
dataVolumeDownlink += parse.Number(ddown)
|
||||
}
|
||||
if dt, dtOk := udata["dataTotalVolume"]; dtOk {
|
||||
dataTotalVolume += parse.Number(dt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 时长
|
||||
duration := "-"
|
||||
if v, ok := cdrJSON["duration"]; ok && v != nil {
|
||||
duration = fmt.Sprint(parse.Number(v))
|
||||
}
|
||||
// 调用时间
|
||||
invocationTimestamp := ""
|
||||
if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil {
|
||||
invocationTimestamp = v.(string)
|
||||
}
|
||||
// 记录打开时间
|
||||
User_Identifier := ""
|
||||
SSC_Mode := ""
|
||||
RAT_Type := ""
|
||||
DNN_ID := ""
|
||||
PDU_Type := ""
|
||||
PDU_IPv4 := ""
|
||||
PDU_IPv6 := ""
|
||||
if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil {
|
||||
pduInfo := v.(map[string]any)
|
||||
|
||||
if v, ok := pduInfo["userIdentifier"]; ok && v != nil {
|
||||
User_Identifier = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["sSCMode"]; ok && v != nil {
|
||||
SSC_Mode = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["rATType"]; ok && v != nil {
|
||||
RAT_Type = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["dNNID"]; ok && v != nil {
|
||||
DNN_ID = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["pDUType"]; ok && v != nil {
|
||||
PDU_Type = v.(string)
|
||||
}
|
||||
if v, ok := pduInfo["pDUAddress"]; ok && v != nil {
|
||||
pDUAddress := v.(map[string]any)
|
||||
if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil {
|
||||
PDU_IPv4 = addr.(string)
|
||||
}
|
||||
if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil {
|
||||
PDU_IPv6 = addr.(string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 记录网络参数ID
|
||||
recordNFID := ""
|
||||
if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil {
|
||||
recordNFID = v.(string)
|
||||
}
|
||||
|
||||
//记录开始时间
|
||||
recordOpeningTime := ""
|
||||
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
|
||||
recordOpeningTime = v.(string)
|
||||
}
|
||||
|
||||
//记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: chargingID,
|
||||
"C" + idx: row.NeName,
|
||||
"D" + idx: row.RmUid,
|
||||
"E" + idx: subscriptionIDData,
|
||||
"F" + idx: subscriptionIDType,
|
||||
"G" + idx: dataVolumeUplink,
|
||||
"H" + idx: dataVolumeDownlink,
|
||||
"I" + idx: dataTotalVolume,
|
||||
"J" + idx: duration,
|
||||
"K" + idx: invocationTimestamp,
|
||||
"L" + idx: User_Identifier,
|
||||
"M" + idx: SSC_Mode,
|
||||
"N" + idx: DNN_ID,
|
||||
"O" + idx: PDU_Type,
|
||||
"P" + idx: RAT_Type,
|
||||
"Q" + idx: PDU_IPv4,
|
||||
"R" + idx: networkFunctionIPv4Address,
|
||||
"S" + idx: PDU_IPv6,
|
||||
"T" + idx: recordNFID,
|
||||
"U" + idx: recordType,
|
||||
"V" + idx: recordOpeningTime,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化数据层 CDREventSMSC 结构体
|
||||
var NewCDREventSMSC = &CDREventSMSC{
|
||||
cdrEventRepository: repository.NewCDREventSMSC,
|
||||
}
|
||||
|
||||
// CDREventSMSC CDR会话事件SMSC 服务层处理
|
||||
type CDREventSMSC struct {
|
||||
cdrEventRepository *repository.CDREventSMSC // CDR会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r *CDREventSMSC) FindByPage(query model.CDREventSMSCQuery) ([]model.CDREventSMSC, int64) {
|
||||
return r.cdrEventRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *CDREventSMSC) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.cdrEventRepository.SelectByIds(ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("not data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.cdrEventRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r CDREventSMSC) ExportXlsx(rows []model.CDREventSMSC, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "NE Name",
|
||||
"C1": "Record Behavior",
|
||||
"D1": "Service Type",
|
||||
"E1": "Caller",
|
||||
"F1": "Called",
|
||||
"G1": "Result",
|
||||
"H1": "Time",
|
||||
}
|
||||
// 读取字典数据 CDR 原因码
|
||||
dictCDRCauseCode := sysService.NewSysDictData.FindByType("cdr_cause_code")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var cdrJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.CdrJson), &cdrJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
// 记录类型
|
||||
recordType := ""
|
||||
if v, ok := cdrJSON["recordType"]; ok && v != nil {
|
||||
recordType = v.(string)
|
||||
}
|
||||
// 服务类型
|
||||
serviceType := ""
|
||||
if v, ok := cdrJSON["serviceType"]; ok && v != nil {
|
||||
serviceType = v.(string)
|
||||
}
|
||||
// 被叫
|
||||
called := ""
|
||||
if v, ok := cdrJSON["calledParty"]; ok && v != nil {
|
||||
called = v.(string)
|
||||
}
|
||||
// 主叫
|
||||
caller := ""
|
||||
if v, ok := cdrJSON["callerParty"]; ok && v != nil {
|
||||
caller = v.(string)
|
||||
}
|
||||
// 呼叫结果 0失败,1成功
|
||||
callResult := "Fail"
|
||||
if v, ok := cdrJSON["result"]; ok && v != nil {
|
||||
resultVal := parse.Number(v)
|
||||
if resultVal == 1 {
|
||||
callResult = "Success"
|
||||
}
|
||||
}
|
||||
// 结果原因
|
||||
if v, ok := cdrJSON["cause"]; ok && v != nil && callResult == "Fail" {
|
||||
cause := fmt.Sprint(v)
|
||||
for _, v := range dictCDRCauseCode {
|
||||
if cause == v.DataValue {
|
||||
callResult = fmt.Sprintf("%s, %s", callResult, i18n.TKey(language, v.DataLabel))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if v, ok := cdrJSON["updateTime"]; ok && v != nil {
|
||||
if releaseTime := parse.Number(v); releaseTime > 0 {
|
||||
timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
} else {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: row.NeName,
|
||||
"C" + idx: recordType,
|
||||
"D" + idx: serviceType,
|
||||
"E" + idx: caller,
|
||||
"F" + idx: called,
|
||||
"G" + idx: callResult,
|
||||
"H" + idx: timeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
@@ -21,7 +21,13 @@ type KpiCReport struct {
|
||||
}
|
||||
|
||||
// FindKPI 通过网元指标数据信息
|
||||
func (s KpiCReport) FindData(query model.KPIQuery) []map[string]any {
|
||||
func (s KpiCReport) FindData(query model.KPICQuery) []map[string]any {
|
||||
// 标题单位映射
|
||||
kpicTitles := s.kpiCReportRepository.SelectKPITitle(query.NeType)
|
||||
kpicTitleUnitMap := map[string]string{}
|
||||
for _, v := range kpicTitles {
|
||||
kpicTitleUnitMap[v.KpiId] = v.Unit
|
||||
}
|
||||
// 原始数据
|
||||
rows := s.kpiCReportRepository.SelectKPI(query)
|
||||
if len(rows) <= 0 {
|
||||
@@ -100,17 +106,24 @@ func (s KpiCReport) FindData(query model.KPIQuery) []map[string]any {
|
||||
// 遍历kpiIds数组对lastRecord赋值
|
||||
for _, kpiId := range kpiIds {
|
||||
if v, ok := record[kpiId]; ok {
|
||||
// 特殊字段,只取一次收到的非0值
|
||||
if kpiId == "AMF.01" || kpiId == "UDM.01" || kpiId == "UDM.02" || kpiId == "UDM.03" || kpiId == "SMF.01" {
|
||||
// startItem[kpiId] = parse.Number(v)
|
||||
continue // startIndex的值不累加不取最后
|
||||
} else {
|
||||
value := parse.Number(startItem[kpiId])
|
||||
startItem[kpiId] = value + parse.Number(v)
|
||||
}
|
||||
value := v.(float64) + startItem[kpiId].(float64)
|
||||
startItem[kpiId] = value
|
||||
// value := parse.Number(startItem[kpiId])
|
||||
// startItem[kpiId] = value + parse.Number(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理单位
|
||||
for _, kpiId := range kpiIds {
|
||||
unit, ok := kpicTitleUnitMap[kpiId]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// "Mbps" "%"
|
||||
if unit == "%" {
|
||||
startItem[kpiId] = startItem[kpiId].(float64) / float64(len(records))
|
||||
}
|
||||
}
|
||||
}
|
||||
data = append(data, startItem)
|
||||
}
|
||||
@@ -136,3 +149,38 @@ func (s KpiCReport) Insert(param model.KpiCReport) int64 {
|
||||
func (r KpiCReport) FindTitle(neType string) []model.KpiCTitle {
|
||||
return r.kpiCReportRepository.SelectKPITitle(neType)
|
||||
}
|
||||
|
||||
// TitleLastKPIId 指标标题最后kpiid
|
||||
func (r KpiCReport) TitleLastKPIId(neType string) string {
|
||||
return r.kpiCReportRepository.TitleLastKPIId(neType)
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r KpiCReport) TitleFindByPage(query map[string]string) ([]model.KpiCTitle, int64) {
|
||||
return r.kpiCReportRepository.TitleSelectByPage(query)
|
||||
}
|
||||
|
||||
// TitleFind 查询信息
|
||||
func (r KpiCReport) TitleFind(param model.KpiCTitle) []model.KpiCTitle {
|
||||
return r.kpiCReportRepository.TitleSelect(param)
|
||||
}
|
||||
|
||||
// TitleUpdate 更新信息
|
||||
func (r KpiCReport) TitleUpdate(param model.KpiCTitle) int64 {
|
||||
return r.kpiCReportRepository.TitleUpdate(param)
|
||||
}
|
||||
|
||||
// TitleDeleteByIds 批量删除信息
|
||||
func (r KpiCReport) TitleDeleteByIds(ids []int64) (int64, error) {
|
||||
rows := r.kpiCReportRepository.TitleDeleteByIds(ids)
|
||||
if rows > 0 {
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// TitleInsert 新增信息
|
||||
func (r KpiCReport) TitleInsert(param model.KpiCTitle) int64 {
|
||||
return r.kpiCReportRepository.TitleInsert(param)
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ func (r *UDMAuthUser) ParseInfo(imsi, neId string, data map[string]string) model
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r *UDMAuthUser) FindByPage(query map[string]string) (int64, []model.UDMAuthUser) {
|
||||
func (r *UDMAuthUser) FindByPage(query map[string]string) ([]model.UDMAuthUser, int64) {
|
||||
return r.udmAuthRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ func (r *UDMSubUser) ParseInfo(imsi, neId string, data map[string]string) model.
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r *UDMSubUser) FindByPage(query map[string]string) (int64, []model.UDMSubUser) {
|
||||
func (r *UDMSubUser) FindByPage(query map[string]string) ([]model.UDMSubUser, int64) {
|
||||
return r.udmSubRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
@@ -318,6 +318,12 @@ func (r *UDMSubUser) ParseCommandParams(item model.UDMSubUser) string {
|
||||
if item.CnTypeRestrictions != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("cn=%s", item.CnTypeRestrictions))
|
||||
}
|
||||
if item.RfspIndex != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("rfsp=%s", item.RfspIndex))
|
||||
}
|
||||
if item.UeUsageType != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("usagetype=%s", item.UeUsageType))
|
||||
}
|
||||
if item.MicoAllowed != "" {
|
||||
conditions = append(conditions, fmt.Sprintf("mico=%s", item.MicoAllowed))
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func (r UDMVOIPUser) ParseInfo(neId string, data map[string]string) model.UDMVOI
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r UDMVOIPUser) FindByPage(query map[string]string) (int64, []model.UDMVOIPUser) {
|
||||
func (r UDMVOIPUser) FindByPage(query map[string]string) ([]model.UDMVOIPUser, int64) {
|
||||
return r.udmVOIPRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ func (r UDMVolteIMSUser) ParseInfo(neId string, data map[string]string) model.UD
|
||||
}
|
||||
|
||||
// FindByPage 分页查询数据库
|
||||
func (r UDMVolteIMSUser) FindByPage(query map[string]string) (int64, []model.UDMVolteIMSUser) {
|
||||
func (r UDMVolteIMSUser) FindByPage(query map[string]string) ([]model.UDMVolteIMSUser, int64) {
|
||||
return r.udmVolteIMSRepository.SelectPage(query)
|
||||
}
|
||||
|
||||
|
||||
229
src/modules/network_data/service/ue_event.go
Normal file
229
src/modules/network_data/service/ue_event.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
"github.com/tsmask/go-oam"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEvent 结构体
|
||||
var NewUEEvent = &UEEvent{
|
||||
ueEventRepository: repository.NewUEEvent,
|
||||
}
|
||||
|
||||
// UEEvent UE会话事件 服务层处理
|
||||
type UEEvent struct {
|
||||
ueEventRepository *repository.UEEvent // UE会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r UEEvent) FindByPage(neType string, query map[string]string) ([]model.UEEvent, int64) {
|
||||
return r.ueEventRepository.SelectByPage(neType, query)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r UEEvent) DeleteByIds(neType string, ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.ueEventRepository.SelectByIds(neType, ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("no data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.ueEventRepository.DeleteByIds(neType, ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// Insert 新增信息
|
||||
func (r UEEvent) Insert(param model.UEEvent) int64 {
|
||||
return r.ueEventRepository.Insert(param)
|
||||
}
|
||||
|
||||
// ExportAMF 导出数据到 xlsx 文件
|
||||
func (r UEEvent) ExportAMF(rows []model.UEEvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "IMSI",
|
||||
"C1": "Event Type",
|
||||
"D1": "Result",
|
||||
"E1": "Time",
|
||||
}
|
||||
// 读取字典数据 UE 事件类型
|
||||
dictUEEventType := sysService.NewSysDictData.FindByType("ue_event_type")
|
||||
// 读取字典数据 UE 事件认证代码类型
|
||||
dictUEAauthCode := sysService.NewSysDictData.FindByType("ue_auth_code")
|
||||
// 读取字典数据 UE 事件CM状态
|
||||
dictUEEventCmState := sysService.NewSysDictData.FindByType("ue_event_cm_state")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var eventJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.EventJSONStr), &eventJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("UEExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// 取IMSI
|
||||
imsi := ""
|
||||
if v, ok := eventJSON["imsi"]; ok && v != nil {
|
||||
imsi = v.(string)
|
||||
}
|
||||
// 取类型
|
||||
eventType := ""
|
||||
for _, v := range dictUEEventType {
|
||||
if row.EventType == v.DataValue {
|
||||
eventType = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
// 取结果
|
||||
eventResult := ""
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if row.EventType == oam.UENB_TYPE_AUTH {
|
||||
if v, ok := eventJSON["authTime"]; ok && v != nil {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
if v, ok := eventJSON["authCode"]; ok && v != nil {
|
||||
eventResult = v.(string)
|
||||
for _, v := range dictUEAauthCode {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if row.EventType == oam.UENB_TYPE_DETACH {
|
||||
if v, ok := eventJSON["detachTime"]; ok && v != nil {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
eventResult = "Success"
|
||||
}
|
||||
if row.EventType == oam.UENB_TYPE_CM {
|
||||
if v, ok := eventJSON["changeTime"]; ok && v != nil {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
if v, ok := eventJSON["status"]; ok && v != nil {
|
||||
eventResult = fmt.Sprint(v)
|
||||
for _, v := range dictUEEventCmState {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: imsi,
|
||||
"C" + idx: eventType,
|
||||
"D" + idx: eventResult,
|
||||
"E" + idx: timeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
|
||||
// ExportMME 导出数据到 xlsx 文件
|
||||
func (r UEEvent) ExportMME(rows []model.UEEvent, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "IMSI",
|
||||
"C1": "Event Type",
|
||||
"D1": "Result",
|
||||
"E1": "Time",
|
||||
}
|
||||
// 读取字典数据 UE 事件类型
|
||||
dictUEEventType := sysService.NewSysDictData.FindByType("ue_event_type")
|
||||
// 读取字典数据 UE 事件认证代码类型
|
||||
dictUEAauthCode := sysService.NewSysDictData.FindByType("ue_auth_code")
|
||||
// 读取字典数据 UE 事件CM状态
|
||||
dictUEEventCmState := sysService.NewSysDictData.FindByType("ue_event_cm_state")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var eventJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.EventJSONStr), &eventJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("UEExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// 取IMSI
|
||||
imsi := ""
|
||||
if v, ok := eventJSON["imsi"]; ok && v != nil {
|
||||
imsi = v.(string)
|
||||
}
|
||||
// 取类型
|
||||
eventType := row.EventType
|
||||
for _, v := range dictUEEventType {
|
||||
if row.EventType == v.DataValue {
|
||||
eventType = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
// 取结果
|
||||
eventResult := ""
|
||||
if v, ok := eventJSON["result"]; ok && v != nil {
|
||||
eventResult = v.(string)
|
||||
if row.EventType == oam.UENB_TYPE_AUTH {
|
||||
for _, v := range dictUEAauthCode {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if row.EventType == oam.UENB_TYPE_CM {
|
||||
for _, v := range dictUEEventCmState {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if v, ok := eventJSON["timestamp"]; ok && v != nil {
|
||||
rowTime := parse.Number(v)
|
||||
timeStr = date.ParseDateToStr(rowTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: imsi,
|
||||
"C" + idx: eventType,
|
||||
"D" + idx: eventResult,
|
||||
"E" + idx: timeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEventAMF 结构体
|
||||
var NewUEEventAMF = &UEEventAMF{
|
||||
ueEventRepository: repository.NewUEEventAMF,
|
||||
}
|
||||
|
||||
// UEEventAMF UE会话事件AMF 服务层处理
|
||||
type UEEventAMF struct {
|
||||
ueEventRepository *repository.UEEventAMF // UE会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r *UEEventAMF) FindByPage(querys model.UEEventAMFQuery) ([]model.UEEventAMF, int64) {
|
||||
return r.ueEventRepository.SelectByPage(querys)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *UEEventAMF) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.ueEventRepository.SelectByIds(ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("no data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.ueEventRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r UEEventAMF) ExportXlsx(rows []model.UEEventAMF, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "IMSI",
|
||||
"C1": "Event Type",
|
||||
"D1": "Result",
|
||||
"E1": "Time",
|
||||
}
|
||||
// 读取字典数据 UE 事件类型
|
||||
dictUEEventType := sysService.NewSysDictData.FindByType("ue_event_type")
|
||||
// 读取字典数据 UE 事件认证代码类型
|
||||
dictUEAauthCode := sysService.NewSysDictData.FindByType("ue_auth_code")
|
||||
// 读取字典数据 UE 事件CM状态
|
||||
dictUEEventCmState := sysService.NewSysDictData.FindByType("ue_event_cm_state")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var eventJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.EventJSONStr), &eventJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("UEExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// 取IMSI
|
||||
imsi := ""
|
||||
if v, ok := eventJSON["imsi"]; ok && v != nil {
|
||||
imsi = v.(string)
|
||||
}
|
||||
// 取类型
|
||||
eventType := ""
|
||||
for _, v := range dictUEEventType {
|
||||
if row.EventType == v.DataValue {
|
||||
eventType = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
// 取结果
|
||||
eventResult := ""
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if row.EventType == "auth-result" {
|
||||
if v, ok := eventJSON["authTime"]; ok && v != nil {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
if v, ok := eventJSON["authCode"]; ok && v != nil {
|
||||
eventResult = v.(string)
|
||||
for _, v := range dictUEAauthCode {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if row.EventType == "detach" {
|
||||
if v, ok := eventJSON["detachTime"]; ok && v != nil {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
eventResult = "Success"
|
||||
}
|
||||
if row.EventType == "cm-state" {
|
||||
if v, ok := eventJSON["changeTime"]; ok && v != nil {
|
||||
timeStr = v.(string)
|
||||
}
|
||||
if v, ok := eventJSON["status"]; ok && v != nil {
|
||||
eventResult = fmt.Sprint(v)
|
||||
for _, v := range dictUEEventCmState {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: imsi,
|
||||
"C" + idx: eventType,
|
||||
"D" + idx: eventResult,
|
||||
"E" + idx: timeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/date"
|
||||
"be.ems/src/framework/utils/file"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
)
|
||||
|
||||
// 实例化数据层 UEEventMME 结构体
|
||||
var NewUEEventMME = &UEEventMME{
|
||||
ueEventRepository: repository.NewUEEventMME,
|
||||
}
|
||||
|
||||
// UEEventMME UE会话事件MME 服务层处理
|
||||
type UEEventMME struct {
|
||||
ueEventRepository *repository.UEEventMME // UE会话事件数据信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r *UEEventMME) FindByPage(querys model.UEEventMMEQuery) ([]model.UEEventMME, int64) {
|
||||
return r.ueEventRepository.SelectByPage(querys)
|
||||
}
|
||||
|
||||
// DeleteByIds 批量删除信息
|
||||
func (r *UEEventMME) DeleteByIds(ids []int64) (int64, error) {
|
||||
// 检查是否存在
|
||||
rows := r.ueEventRepository.SelectByIds(ids)
|
||||
if len(rows) <= 0 {
|
||||
return 0, fmt.Errorf("no data")
|
||||
}
|
||||
|
||||
if len(rows) == len(ids) {
|
||||
rows := r.ueEventRepository.DeleteByIds(ids)
|
||||
return rows, nil
|
||||
}
|
||||
// 删除信息失败!
|
||||
return 0, fmt.Errorf("delete fail")
|
||||
}
|
||||
|
||||
// ExportXlsx 导出数据到 xlsx 文件
|
||||
func (r UEEventMME) ExportXlsx(rows []model.UEEventMME, fileName, language string) (string, error) {
|
||||
// 第一行表头标题
|
||||
headerCells := map[string]string{
|
||||
"A1": "ID",
|
||||
"B1": "IMSI",
|
||||
"C1": "Event Type",
|
||||
"D1": "Result",
|
||||
"E1": "Time",
|
||||
}
|
||||
// 读取字典数据 UE 事件类型
|
||||
dictUEEventType := sysService.NewSysDictData.FindByType("ue_event_type")
|
||||
// 读取字典数据 UE 事件认证代码类型
|
||||
dictUEAauthCode := sysService.NewSysDictData.FindByType("ue_auth_code")
|
||||
// 读取字典数据 UE 事件CM状态
|
||||
dictUEEventCmState := sysService.NewSysDictData.FindByType("ue_event_cm_state")
|
||||
// 从第二行开始的数据
|
||||
dataCells := make([]map[string]any, 0)
|
||||
for i, row := range rows {
|
||||
idx := strconv.Itoa(i + 2)
|
||||
// 解析 JSON 字符串为 map
|
||||
var eventJSON map[string]interface{}
|
||||
err := json.Unmarshal([]byte(row.EventJSONStr), &eventJSON)
|
||||
if err != nil {
|
||||
logger.Warnf("UEExport Error parsing JSON: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// 取IMSI
|
||||
imsi := ""
|
||||
if v, ok := eventJSON["imsi"]; ok && v != nil {
|
||||
imsi = v.(string)
|
||||
}
|
||||
// 取类型
|
||||
eventType := row.EventType
|
||||
for _, v := range dictUEEventType {
|
||||
if row.EventType == v.DataValue {
|
||||
eventType = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
// 取结果
|
||||
eventResult := ""
|
||||
if v, ok := eventJSON["result"]; ok && v != nil {
|
||||
eventResult = v.(string)
|
||||
if row.EventType == "auth-result" {
|
||||
for _, v := range dictUEAauthCode {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if row.EventType == "cm-state" {
|
||||
for _, v := range dictUEEventCmState {
|
||||
if eventResult == v.DataValue {
|
||||
eventResult = i18n.TKey(language, v.DataLabel)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 取时间
|
||||
timeStr := ""
|
||||
if v, ok := eventJSON["timestamp"]; ok && v != nil {
|
||||
rowTime := parse.Number(v)
|
||||
timeStr = date.ParseDateToStr(rowTime, date.YYYY_MM_DDTHH_MM_SSZ)
|
||||
}
|
||||
|
||||
dataCells = append(dataCells, map[string]any{
|
||||
"A" + idx: row.ID,
|
||||
"B" + idx: imsi,
|
||||
"C" + idx: eventType,
|
||||
"D" + idx: eventResult,
|
||||
"E" + idx: timeStr,
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据表格
|
||||
return file.WriteSheet(headerCells, dataCells, fileName, "")
|
||||
|
||||
}
|
||||
@@ -438,9 +438,10 @@ func (s *NeActionController) Service(c *gin.Context) {
|
||||
|
||||
neTypeLower := strings.ToLower(neInfo.NeType)
|
||||
cmdStr := fmt.Sprintf("sudo systemctl %s %s", body.Action, neTypeLower)
|
||||
if neTypeLower == "omc" {
|
||||
cmdStr = fmt.Sprintf("nohup sh -c \"sleep 5s && sudo systemctl %s omc\" > /dev/null 2>&1 &", body.Action)
|
||||
} else if neTypeLower == "ims" {
|
||||
switch neTypeLower {
|
||||
case "omc":
|
||||
cmdStr = fmt.Sprintf("nohup sh -c \"sudo systemctl stop omc && sleep 5s && sudo systemctl %s omc\" > /dev/null 2>&1 &", body.Action)
|
||||
case "ims":
|
||||
if body.Action == "restart" {
|
||||
cmdStr = "ims-stop || true && ims-start"
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
cm_omc "be.ems/features/cm/omc"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
@@ -215,16 +214,6 @@ func (s NeConfigController) DataInfo(c *gin.Context) {
|
||||
}
|
||||
|
||||
if query.NeType == "OMC" {
|
||||
if query.ParamName == "alarmEmailForward" || query.ParamName == "alarmSMSForward" {
|
||||
var o *cm_omc.ConfigOMC
|
||||
resData, err := o.Query(query.ParamName)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.OkData(resData))
|
||||
return
|
||||
}
|
||||
resData := s.neConfigService.GetOMCYaml(query.ParamName)
|
||||
c.JSON(200, resp.OkData(resData))
|
||||
return
|
||||
@@ -274,16 +263,6 @@ func (s NeConfigController) DataEdit(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if body.NeType == "OMC" {
|
||||
if body.ParamName == "alarmEmailForward" || body.ParamName == "alarmSMSForward" {
|
||||
var o *cm_omc.ConfigOMC
|
||||
resData, err := o.Modify(body.ParamName, body.ParamData)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
c.JSON(200, resp.OkData(resData))
|
||||
return
|
||||
}
|
||||
err := s.neConfigService.ModifyOMCYaml(body.ParamName, body.Loc, body.ParamData)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg(err.Error()))
|
||||
|
||||
64
src/modules/network_element/fetch_link/n3iwf.go
Normal file
64
src/modules/network_element/fetch_link/n3iwf.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// N3IWFSubInfoList N3IWF在线列表信息
|
||||
//
|
||||
// 查询参数 {"imsi":"460302072701181"}
|
||||
//
|
||||
// 返回结果 {"rows":[],"total":0}
|
||||
func N3IWFSubInfoList(neInfo model.NeInfo, data map[string]string) (map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/n3iwf/objectType/ueInfo", neInfo.IP, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["imsi"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("imsi=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
logger.Warnf("N3IWFSubInfo Get \"%s\"", neUrl)
|
||||
logger.Errorf("N3IWFSubInfo %s", err.Error())
|
||||
return nil, fmt.Errorf("NeService N3IWF API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
// {
|
||||
// "data": [
|
||||
// {
|
||||
// "activeTime": "2023-11-29 06:35:43",
|
||||
// "imsi": "460302072701181",
|
||||
// "nai": "0460302072701181@nai.epc.mnc030.mcc460.3gppnetwork.org",
|
||||
// "regState": 1
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("N3IWFSubInfo Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
resData["rows"] = v.([]any)
|
||||
resData["total"] = len(v.([]any))
|
||||
delete(resData, "data")
|
||||
} else {
|
||||
resData["rows"] = []any{}
|
||||
resData["total"] = 0
|
||||
}
|
||||
return resData, nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user