1
0

marge: 合并代码

This commit is contained in:
TsMask
2023-12-08 10:32:06 +08:00
parent 6fe7464779
commit 56310cc3c9
22 changed files with 473 additions and 50 deletions

View File

@@ -20,11 +20,12 @@ func AlarmEmailForward(alarmData *Alarm) error {
<p>Alarm information</p> <p>Alarm information</p>
<p style="text-indent:2.5em">Sequence: %d</p> <p style="text-indent:2.5em">Sequence: %d</p>
<p style="text-indent:3em">NE name: %s</p> <p style="text-indent:3em">NE name: %s</p>
<p style="text-indent:5em">Title: %s</p> <p style="text-indent:4em">Title: %s</p>
<p style="text-indent:3em">Severity: %s</p> <p style="text-indent:2.5em">Severity: %s</p>
<p style="text-indent:2em">Event Time: %s</p> <p style="text-indent:1.5em">Event Time: %s</p>
<p style="text-indent:2em">Automatic send by OMC, don't reply!</p> <p style="text-indent:0.5em">Alarm Status: %d</p>
`, alarmData.AlarmSeq, alarmData.NeName, alarmData.AlarmTitle, alarmData.OrigSeverity, alarmData.EventTime) <p>Automatic sent by OMC, please do not reply!</p>
`, alarmData.AlarmSeq, alarmData.NeName, alarmData.AlarmTitle, alarmData.OrigSeverity, alarmData.EventTime, alarmData.AlarmStatus)
// message := fmt.Sprintf(` // message := fmt.Sprintf(`
// Alarm information // Alarm information
@@ -75,10 +76,9 @@ func AlarmEmailForward(alarmData *Alarm) error {
EventTime: alarmData.EventTime, EventTime: alarmData.EventTime,
ToUser: strings.Join(*emails, ","), ToUser: strings.Join(*emails, ","),
} }
for _, email := range *emails {
m.SetHeader("To", email) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
}
m.SetHeader("To", *emails...) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
//m.SetHeader("To", strings.Join(*emails, " ")) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
//m.SetHeader("To", "zhangshuzhong@agrandtech.com", "simonzhangsz@outlook.com") // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接 //m.SetHeader("To", "zhangshuzhong@agrandtech.com", "simonzhangsz@outlook.com") // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
//m.SetHeader("Cc", "******@qq.com") // 抄送,可以多个 //m.SetHeader("Cc", "******@qq.com") // 抄送,可以多个
//m.SetHeader("Bcc", "******@qq.com") // 暗送,可以多个 //m.SetHeader("Bcc", "******@qq.com") // 暗送,可以多个

View File

@@ -112,21 +112,8 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
} }
if neInfo != nil { if neInfo != nil {
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
conn, err := net.Dial("tcp", hostMML)
if err != nil {
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
log.Error(errMsg)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
conn.SetDeadline(time.Now().Add(10 * time.Second))
switch strings.ToLower(neType) { switch strings.ToLower(neType) {
case "upf": case "xxx":
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
if err != nil { if err != nil {
log.Error("io.ReadAll is failed:", err) log.Error("io.ReadAll is failed:", err)
@@ -148,16 +135,29 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
// } // }
// log.Debug(string(buf[0:n])) // log.Debug(string(buf[0:n]))
loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) // hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
_, err = conn.Write([]byte(loginStr)) // conn, err := net.Dial("tcp", hostMML)
if err != nil { // if err != nil {
log.Error("Failed to write:", err) // errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
mmlResult = append(mmlResult, err.Error()) // log.Error(errMsg)
response := Response{mmlResult} // mmlResult = append(mmlResult, errMsg)
services.ResponseWithJson(w, http.StatusOK, response) // response := Response{mmlResult}
return // services.ResponseWithJson(w, http.StatusOK, response)
} // return
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) // }
// defer conn.Close()
// conn.SetDeadline(time.Now().Add(10 * time.Second))
// loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
// _, err = conn.Write([]byte(loginStr))
// if err != nil {
// log.Error("Failed to write:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// n, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n")) // n, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n"))
// if err != nil { // if err != nil {
@@ -203,6 +203,30 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
// log.Debug(string(buf[0:n])) // log.Debug(string(buf[0:n]))
for _, mml := range mmlRequest.MML { for _, mml := range mmlRequest.MML {
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
conn, err := net.Dial("tcp", hostMML)
if err != nil {
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
log.Error(errMsg)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
conn.SetDeadline(time.Now().Add(10 * time.Second))
loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
_, err = conn.Write([]byte(loginStr))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
mmlCommand := fmt.Sprintf("%s\n", mml) mmlCommand := fmt.Sprintf("%s\n", mml)
log.Debug("mml command:", mmlCommand) log.Debug("mml command:", mmlCommand)
_, err = conn.Write([]byte(mmlCommand)) _, err = conn.Write([]byte(mmlCommand))
@@ -233,12 +257,157 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
result := re1.ReplaceAllString(string(buf[config.GetYamlConfig().MML.UpfHeaderLength:n-len(neType)-2]), "") result := re1.ReplaceAllString(string(buf[config.GetYamlConfig().MML.UpfHeaderLength:n-len(neType)-2]), "")
result = re2.ReplaceAllString(result, "") result = re2.ReplaceAllString(result, "")
mmlResult = append(mmlResult, result) mmlResult = append(mmlResult, result)
conn.Close()
//mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2])) //mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2]))
// can't read buffer from upf telnet server, so return ok always // can't read buffer from upf telnet server, so return ok always
// mmlResult = append(mmlResult, "COMMAND OK\n") // mmlResult = append(mmlResult, "COMMAND OK\n")
} }
case "ims":
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
if err != nil {
log.Error("io.ReadAll is failed:", err)
services.ResponseNotFound404UriNotExist(w, r)
return
}
log.Trace("Body:", string(body))
mmlRequest := new(MMLRequest)
_ = json.Unmarshal(body, mmlRequest)
for _, mml := range mmlRequest.MML {
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
conn, err := net.Dial("tcp", hostMML)
if err != nil {
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
log.Error(errMsg)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
// localAddr := conn.LocalAddr()
// remoteAddr := conn.RemoteAddr()
// if localAddr == nil || remoteAddr == nil {
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
conn.SetDeadline(time.Now().Add(10 * time.Second))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Debug(string(buf[0:n]))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
// _, err = conn.Write([]byte(loginStr))
// if err != nil {
// log.Error("Failed to write:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Trace(string(buf[0 : n-len(neType)-2]))
mmlCommand := fmt.Sprintf("%s\n", mml)
log.Debug("mml command:", mmlCommand)
_, err = conn.Write([]byte(mmlCommand))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Trace(string(buf[0 : n-len(neType)-2]))
re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符
//re2 := regexp.MustCompile(`\x00`) // 匹配空字符
re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
// upf telnet buffer只能读取一次需要去掉前面的多余字符
//result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
result := re1.ReplaceAllString(string(buf[0:]), "")
result = re2.ReplaceAllString(result, "")
mmlResult = append(mmlResult, result)
conn.Close()
}
default: default:
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
conn, err := net.Dial("tcp", hostMML)
if err != nil {
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
log.Error(errMsg)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
// localAddr := conn.LocalAddr()
// remoteAddr := conn.RemoteAddr()
// if localAddr == nil || remoteAddr == nil {
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
conn.SetDeadline(time.Now().Add(10 * time.Second))
loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
_, err = conn.Write([]byte(loginStr)) _, err = conn.Write([]byte(loginStr))
if err != nil { if err != nil {

View File

@@ -38,12 +38,12 @@ database:
type: mysql type: mysql
user: root user: root
# password: "1000omc@kp!" # password: "1000omc@kp!"
# host: "192.168.2.219" # host: "192.168.5.57"
# port: 33066 # port: 33066
# name: omc_db # name: omc_db
backup: d:/local.git/ems.agt/restagent/database backup: d:/local.git/ems.agt/restagent/database
password: "root@1234" password: "root@1234"
host: "192.168.2.152" host: "192.168.5.57"
port: 3306 port: 3306
name: "omc_db" name: "omc_db"
# Redis 缓存数据,数据源声明全小写 # Redis 缓存数据,数据源声明全小写
@@ -52,8 +52,8 @@ redis:
# OMC系统使用库 # OMC系统使用库
default: default:
port: 6379 # Redis port port: 6379 # Redis port
host: "192.168.2.152" # Redis host host: "192.168.5.57" # Redis host
password: "redis@1234" password: ""
db: 10 # Redis db_num db: 10 # Redis db_num
# UDM网元用户库 # UDM网元用户库
udmuser: udmuser:
@@ -117,7 +117,7 @@ omc:
# Forward interface: # Forward interface:
# email/sms # email/sms
alarm: alarm:
forwardAlarm: true forwardAlarm: false
email: email:
smtp: mail.agrandtech.com smtp: mail.agrandtech.com
port: 25 port: 25

View File

@@ -1,7 +1,7 @@
# Makefile for rest agent project # Makefile for rest agent project
PROJECT = OMC PROJECT = OMC
VERSION = 2.2311.8 VERSION = 2.2312.8
PLATFORM = amd64 PLATFORM = amd64
ARMPLATFORM = aarch64 ARMPLATFORM = aarch64
BUILDDIR = ../../build BUILDDIR = ../../build

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -13,7 +13,7 @@ server:
# 日志 # 日志
logger: logger:
fileDir: "/usr/local/omc/log" fileDir: "/usr/local/omc/log"
fileName: "restagent.log" fileName: "ems_agt.log"
level: 2 # 日志记录的等级 0:silent<1:info<2:warn<3:error level: 2 # 日志记录的等级 0:silent<1:info<2:warn<3:error
maxDay: 180 # 日志会保留 180 天 maxDay: 180 # 日志会保留 180 天
maxSize: 10 # 调整按 10MB 大小的切割 maxSize: 10 # 调整按 10MB 大小的切割

View File

@@ -26,11 +26,11 @@ func Setup(router *gin.Engine) {
// 系统可暴露的配置信息 // 系统可暴露的配置信息
indexGroup.GET("/sys-conf", controller.NewCommont.SysConfig) indexGroup.GET("/sys-conf", controller.NewCommont.SysConfig)
// 系统使用文档转存 // 转存上传文件到静态资源
indexGroup.POST("/helpDoc", indexGroup.POST("/transferStaticFile",
middleware.PreAuthorize(nil), middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.helpDoc", collectlogs.BUSINESS_TYPE_UPDATE)), collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.helpDoc", collectlogs.BUSINESS_TYPE_UPDATE)),
controller.NewCommont.HelpDoc, controller.NewCommont.TransferStaticFile,
) )
// 验证码操作处理 // 验证码操作处理

View File

@@ -77,13 +77,14 @@ func (s *CommontController) SysConfig(c *gin.Context) {
c.JSON(200, result.OkData(data)) c.JSON(200, result.OkData(data))
} }
// 转存帮助文档 // 转存指定对应文件
// //
// POST /helpDoc // POST /transferStaticFile
func (s *CommontController) HelpDoc(c *gin.Context) { func (s *CommontController) TransferStaticFile(c *gin.Context) {
language := ctx.AcceptLanguage(c) language := ctx.AcceptLanguage(c)
var body struct { var body struct {
UploadPath string `json:"uploadPath" binding:"required"` UploadPath string `json:"uploadPath" binding:"required"`
StaticPath string `json:"staticPath" binding:"required"`
Language string `json:"language" binding:"required"` Language string `json:"language" binding:"required"`
} }
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
@@ -102,8 +103,9 @@ func (s *CommontController) HelpDoc(c *gin.Context) {
return return
} }
newFile := fmt.Sprintf("%s/helpDoc/%s_doc.pdf", dir, lang) delPrefix := strings.Replace(body.StaticPath, static["prefix"].(string), "", 1)
fmt.Println(newFile) staticPath := strings.Replace(delPrefix, "{language}", lang, 1)
newFile := fmt.Sprintf("%s%s", dir, staticPath)
err = file.CopyUploadFile(body.UploadPath, newFile) err = file.CopyUploadFile(body.UploadPath, newFile)
if err != nil { if err != nil {

View File

@@ -47,5 +47,11 @@ func (s *CommontImpl) SystemConfigInfo() map[string]string {
// 系统设置-系统使用文档 // 系统设置-系统使用文档
helpDoc := s.sysConfigService.SelectConfigValueByKey("sys.helpDoc") helpDoc := s.sysConfigService.SelectConfigValueByKey("sys.helpDoc")
infoMap["helpDoc"] = helpDoc infoMap["helpDoc"] = helpDoc
// 国际化切换
i18nOpen := s.sysConfigService.SelectConfigValueByKey("sys.i18n.open")
infoMap["i18nOpen"] = i18nOpen
// 国际化默认语言
i18nDefault := s.sysConfigService.SelectConfigValueByKey("sys.i18n.default")
infoMap["i18nDefault"] = i18nDefault
return infoMap return infoMap
} }

View File

@@ -0,0 +1,90 @@
package controller
import (
"ems.agt/lib/core/utils/date"
"ems.agt/src/framework/i18n"
"ems.agt/src/framework/utils/ctx"
"ems.agt/src/framework/vo/result"
neService "ems.agt/src/modules/network_element/service"
"github.com/gin-gonic/gin"
)
// 实例化控制层 PerfKPIController 结构体
var NewPerfKPI = &PerfKPIController{
neInfoService: neService.NewNeInfoImpl,
perfKPIService: neService.NewPerfKPIImpl,
}
// 性能统计
//
// PATH /kpi
type PerfKPIController struct {
// 网元信息服务
neInfoService neService.INeInfo
// 统计信息服务
perfKPIService neService.IPerfKPI
}
// 获取统计数据
//
// GET /data
func (s *PerfKPIController) GoldKPI(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
StartTime string `form:"startTime" binding:"required"`
EndTime string `form:"endTime" binding:"required"`
Interval int64 `form:"interval" binding:"required"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 时间格式校验
startTime := date.ParseStrToDate(querys.StartTime, date.YYYY_MM_DD_HH_MM_SS)
if startTime.IsZero() {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
}
startTimeStr := startTime.Format(date.YYYY_MM_DD_HH_MM_SS)
endTime := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS)
if startTime.IsZero() {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
}
endTimeStr := endTime.Format(date.YYYY_MM_DD_HH_MM_SS)
// 查询网元获取IP
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
// 获取数据指标id
var kpiIds []string
kpiTitles := s.perfKPIService.SelectGoldKPITitle(neInfo.NeType)
for _, kpiId := range kpiTitles {
kpiIds = append(kpiIds, kpiId.KPIID)
}
// 查询数据
kpiData := s.perfKPIService.SelectGoldKPI(neInfo.RmUID, neInfo.NeType, startTimeStr, endTimeStr, kpiIds, querys.Interval)
c.JSON(200, result.OkData(kpiData))
}
// 获取统计标题
//
// GET /title
func (s *PerfKPIController) Title(c *gin.Context) {
language := ctx.AcceptLanguage(c)
neType := c.Query("neType")
if neType == "" {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
kpiTitles := s.perfKPIService.SelectGoldKPITitle(neType)
c.JSON(200, result.OkData(kpiTitles))
}

View File

@@ -0,0 +1,11 @@
package model
// GoldKPITitle 黄金指标标题信息对象 kpi_title
type GoldKPITitle struct {
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
NeType string `json:"neType" gorm:"column:ne_type"`
KPIID string `json:"kpiId" gorm:"column:kpi_id"`
TitleJson string `json:"titleJson" gorm:"column:title_json"`
CnTitle string `json:"cnTitle" gorm:"column:cn_title"`
EnTitle string `json:"enTitle" gorm:"column:en_title"`
}

View File

@@ -141,4 +141,17 @@ func Setup(router *gin.Engine) {
) )
} }
// 性能统计信息
kpiGroup := neGroup.Group("/kpi")
{
kpiGroup.GET("/title",
middleware.PreAuthorize(nil),
controller.NewPerfKPI.Title,
)
kpiGroup.GET("/data",
middleware.PreAuthorize(nil),
controller.NewPerfKPI.GoldKPI,
)
}
} }

View File

@@ -0,0 +1,12 @@
package repository
import "ems.agt/src/modules/network_element/model"
// 性能统计 数据层接口
type IPerfKPI interface {
// SelectGoldKPI 通过ne_type和ne_id查询网元信息
SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any
// SelectGoldKPITitle
SelectGoldKPITitle(neType string) []model.GoldKPITitle
}

View File

@@ -0,0 +1,77 @@
package repository
import (
"fmt"
"strings"
"ems.agt/src/framework/datasource"
"ems.agt/src/framework/logger"
"ems.agt/src/modules/network_element/model"
)
// 实例化数据层 PerfKPIImpl 结构体
var NewPerfKPIImpl = &PerfKPIImpl{}
// PerfKPIImpl 性能统计 数据层处理
type PerfKPIImpl struct{}
// SelectGoldKPI 通过网元指标数据信息
func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any {
// 查询条件拼接
var conditions []string
var params []any
if rmUID != "" {
conditions = append(conditions, "gk.rm_uid = ?")
params = append(params, rmUID)
}
if neType != "" {
conditions = append(conditions, "gk.ne_type = ?")
params = append(params, neType)
}
if startTime != "" {
conditions = append(conditions, "gk.start_time >= ?")
params = append(params, startTime)
}
if endTime != "" {
conditions = append(conditions, "gk.start_time <= ?")
params = append(params, endTime)
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
// 查询字段列
timeFormat := "DATE_FORMAT(gk.start_time, '%Y-%m-%d %H:')"
minuteGroup := fmt.Sprintf("LPAD(FLOOR(MINUTE(gk.start_time) / %d) * %d, 2, '0')", interval, interval)
groupByField := fmt.Sprintf("CONCAT( %s, %s ) AS timeGroup", timeFormat, minuteGroup)
var fields = []string{
groupByField,
"min(CASE WHEN gk.index != '' THEN gk.index ELSE 0 END) AS startIndex",
"min(CASE WHEN gk.ne_name != '' THEN gk.ne_name ELSE 0 END) AS neName",
}
for _, kid := range kpiIds {
str := fmt.Sprintf("sum(CASE WHEN gk.kpi_id = '%s' THEN gk.value ELSE 0 END) AS '%s'", kid, kid)
fields = append(fields, str)
}
fieldsSql := strings.Join(fields, ",")
// 查询数据
querySql := fmt.Sprintf("SELECT %s FROM gold_kpi gk %s GROUP BY timeGroup", fieldsSql, whereSql)
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
}
return results
}
// SelectGoldKPITitle 通过网元指标数据信息
func (r *PerfKPIImpl) SelectGoldKPITitle(neType string) []model.GoldKPITitle {
result := []model.GoldKPITitle{}
tx := datasource.DefaultDB().Table("kpi_title").Where("ne_type = ?", neType).Find(&result)
if err := tx.Error; err != nil {
logger.Errorf("Delete err => %v", err)
}
return result
}

View File

@@ -67,7 +67,7 @@ func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any {
var params []any var params []any
if v, ok := query["imsi"]; ok && v != "" { if v, ok := query["imsi"]; ok && v != "" {
conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") conditions = append(conditions, "imsi like concat(concat('%', ?), '%')")
params = append(params, v) params = append(params, strings.Trim(v.(string), " "))
} }
if v, ok := query["neId"]; ok && v != "" { if v, ok := query["neId"]; ok && v != "" {
conditions = append(conditions, "ne_id = ?") conditions = append(conditions, "ne_id = ?")

View File

@@ -83,11 +83,11 @@ func (r *UDMSubImpl) SelectPage(query map[string]any) map[string]any {
var params []any var params []any
if v, ok := query["msisdn"]; ok && v != "" { if v, ok := query["msisdn"]; ok && v != "" {
conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')") conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')")
params = append(params, v) params = append(params, strings.Trim(v.(string), " "))
} }
if v, ok := query["imsi"]; ok && v != "" { if v, ok := query["imsi"]; ok && v != "" {
conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") conditions = append(conditions, "imsi like concat(concat('%', ?), '%')")
params = append(params, v) params = append(params, strings.Trim(v.(string), " "))
} }
if v, ok := query["neId"]; ok && v != "" { if v, ok := query["neId"]; ok && v != "" {
conditions = append(conditions, "ne_id = ?") conditions = append(conditions, "ne_id = ?")

View File

@@ -0,0 +1,12 @@
package service
import "ems.agt/src/modules/network_element/model"
// 性能统计 数据层接口
type IPerfKPI interface {
// SelectGoldKPI 通过ne_type和ne_id查询网元信息
SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any
// SelectGoldKPITitle
SelectGoldKPITitle(neType string) []model.GoldKPITitle
}

View File

@@ -0,0 +1,31 @@
package service
import (
"ems.agt/src/modules/network_element/model"
"ems.agt/src/modules/network_element/repository"
)
// 实例化数据层 PerfKPIImpl 结构体
var NewPerfKPIImpl = &PerfKPIImpl{
perfKPIRepository: repository.NewPerfKPIImpl,
}
// PerfKPIImpl 性能统计 数据层处理
type PerfKPIImpl struct {
// 性能统计数据信息
perfKPIRepository repository.IPerfKPI
}
// SelectGoldKPI 通过网元指标数据信息
func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any {
data := r.perfKPIRepository.SelectGoldKPI(rmUID, neType, startTime, endTime, kpiIds, interval)
if data == nil {
return []map[string]any{}
}
return data
}
// SelectGoldKPITitle 通过网元指标数据信息
func (r *PerfKPIImpl) SelectGoldKPITitle(neType string) []model.GoldKPITitle {
return r.perfKPIRepository.SelectGoldKPITitle(neType)
}